diff --git a/.changeset/plenty-geese-enter.md b/.changeset/plenty-geese-enter.md
new file mode 100644
index 000000000..27c7c5457
--- /dev/null
+++ b/.changeset/plenty-geese-enter.md
@@ -0,0 +1,5 @@
+---
+"@solidjs/start": minor
+---
+
+seroval json mode
diff --git a/apps/tests/src/e2e/server-function.test.ts b/apps/tests/src/e2e/server-function.test.ts
index 7a8131be9..861495e3b 100644
--- a/apps/tests/src/e2e/server-function.test.ts
+++ b/apps/tests/src/e2e/server-function.test.ts
@@ -67,4 +67,14 @@ test.describe("server-function", () => {
await page.goto("http://localhost:3000/generator-server-function");
await expect(page.locator("#server-fn-test")).toContainText("¡Hola, Mundo!");
});
+
+ test("should build with a server function ping", async ({ page }) => {
+ await page.goto("http://localhost:3000/server-function-ping");
+ await expect(page.locator("#server-fn-test")).toContainText('{"result":true}');
+ });
+
+ test("should build with a server function w/ form data", async ({ page }) => {
+ await page.goto("http://localhost:3000/server-function-form-data");
+ await expect(page.locator("#server-fn-test")).toContainText('{"result":true}');
+ });
});
diff --git a/apps/tests/src/routes/server-function-form-data.tsx b/apps/tests/src/routes/server-function-form-data.tsx
new file mode 100644
index 000000000..d54ad095a
--- /dev/null
+++ b/apps/tests/src/routes/server-function-form-data.tsx
@@ -0,0 +1,26 @@
+import { createEffect, createSignal } from "solid-js";
+
+async function ping(value: FormData) {
+ "use server";
+ const file = value.get('example') as File;
+ return await file.text();
+}
+
+export default function App() {
+ const [output, setOutput] = createSignal<{ result?: boolean }>({});
+
+ createEffect(async () => {
+ const file = new File(['Hello, World!'], 'hello-world.txt');
+ const formData = new FormData();
+ formData.append('example', file);
+ const result = await ping(formData);
+ const value = await file.text();
+ setOutput(prev => ({ ...prev, result: value === result }));
+ });
+
+ return (
+
+ {JSON.stringify(output())}
+
+ );
+}
diff --git a/apps/tests/src/routes/server-function-ping.tsx b/apps/tests/src/routes/server-function-ping.tsx
new file mode 100644
index 000000000..70f9d2617
--- /dev/null
+++ b/apps/tests/src/routes/server-function-ping.tsx
@@ -0,0 +1,23 @@
+import { createEffect, createSignal } from "solid-js";
+
+async function ping(value: string) {
+ "use server";
+
+ return await Promise.resolve(value);
+}
+
+export default function App() {
+ const [output, setOutput] = createSignal<{ result?: boolean }>({});
+
+ createEffect(async () => {
+ const value = `${Math.random() * 1000}`;
+ const result = await ping(value);
+ setOutput(prev => ({ ...prev, result: value === result }));
+ });
+
+ return (
+
+ {JSON.stringify(output())}
+
+ );
+}
diff --git a/packages/start/package.json b/packages/start/package.json
index 9170468d3..af2bbca6c 100644
--- a/packages/start/package.json
+++ b/packages/start/package.json
@@ -56,7 +56,7 @@
"path-to-regexp": "^8.2.0",
"pathe": "^2.0.3",
"radix3": "^1.1.2",
- "seroval": "^1.4.1",
+ "seroval": "^1.5.0",
"seroval-plugins": "^1.4.0",
"shiki": "^1.26.1",
"solid-js": "^1.9.9",
diff --git a/packages/start/src/config/index.ts b/packages/start/src/config/index.ts
index 4b1c82179..869aef0cf 100644
--- a/packages/start/src/config/index.ts
+++ b/packages/start/src/config/index.ts
@@ -21,6 +21,10 @@ export interface SolidStartOptions {
routeDir?: string;
extensions?: string[];
middleware?: string;
+ serialization?: {
+ // This only matters for server function responses
+ mode?: 'js' | 'json';
+ };
}
const absolute = (path: string, root: string) =>
@@ -131,6 +135,7 @@ export function solidStart(options?: SolidStartOptions): Array {
"import.meta.env.START_APP_ENTRY": JSON.stringify(appEntryPath),
"import.meta.env.START_CLIENT_ENTRY": JSON.stringify(handlers.client),
"import.meta.env.START_DEV_OVERLAY": JSON.stringify(start.devOverlay),
+ "import.meta.env.SEROVAL_MODE": JSON.stringify(start.serialization?.mode || 'json'),
},
builder: {
sharedPlugins: true,
diff --git a/packages/start/src/server/serialization.ts b/packages/start/src/server/serialization.ts
new file mode 100644
index 000000000..c157d157e
--- /dev/null
+++ b/packages/start/src/server/serialization.ts
@@ -0,0 +1,253 @@
+import {
+ crossSerializeStream,
+ deserialize,
+ Feature,
+ fromCrossJSON,
+ getCrossReferenceHeader,
+ type SerovalNode,
+ toCrossJSONStream,
+} from "seroval";
+import {
+ AbortSignalPlugin,
+ CustomEventPlugin,
+ DOMExceptionPlugin,
+ EventPlugin,
+ FormDataPlugin,
+ HeadersPlugin,
+ ReadableStreamPlugin,
+ RequestPlugin,
+ ResponsePlugin,
+ URLPlugin,
+ URLSearchParamsPlugin,
+} from "seroval-plugins/web";
+
+// TODO(Alexis): if we can, allow providing an option to extend these.
+const DEFAULT_PLUGINS = [
+ AbortSignalPlugin,
+ CustomEventPlugin,
+ DOMExceptionPlugin,
+ EventPlugin,
+ FormDataPlugin,
+ HeadersPlugin,
+ ReadableStreamPlugin,
+ RequestPlugin,
+ ResponsePlugin,
+ URLSearchParamsPlugin,
+ URLPlugin,
+];
+const MAX_SERIALIZATION_DEPTH_LIMIT = 64;
+const DISABLED_FEATURES = Feature.RegExp;
+
+/**
+ * Alexis:
+ *
+ * A "chunk" is a piece of data emitted by the streaming serializer.
+ * Each chunk is represented by a 32-bit value (encoded in hexadecimal),
+ * followed by the encoded string (8-bit representation). This format
+ * is important so we know how much of the chunk being streamed we
+ * are expecting before parsing the entire string data.
+ *
+ * This is sort of a bootleg "multipart/form-data" except it's bad at
+ * handling File/Blob LOL
+ *
+ * The format is as follows:
+ * ;0xFFFFFFFF;
+ */
+function createChunk(data: string): Uint8Array {
+ const encodeData = new TextEncoder().encode(data);
+ const bytes = encodeData.length;
+ const baseHex = bytes.toString(16);
+ const totalHex = "00000000".substring(0, 8 - baseHex.length) + baseHex; // 32-bit
+ const head = new TextEncoder().encode(`;0x${totalHex};`);
+
+ const chunk = new Uint8Array(12 + bytes);
+ chunk.set(head);
+ chunk.set(encodeData, 12);
+ return chunk;
+}
+
+export function serializeToJSStream(id: string, value: any) {
+ return new ReadableStream({
+ start(controller) {
+ crossSerializeStream(value, {
+ scopeId: id,
+ plugins: DEFAULT_PLUGINS,
+ onSerialize(data: string, initial: boolean) {
+ controller.enqueue(
+ createChunk(
+ initial ? `(${getCrossReferenceHeader(id)},${data})` : data,
+ ),
+ );
+ },
+ onDone() {
+ controller.close();
+ },
+ onError(error: any) {
+ controller.error(error);
+ },
+ });
+ },
+ });
+}
+
+export function serializeToJSONStream(value: any) {
+ return new ReadableStream({
+ start(controller) {
+ toCrossJSONStream(value, {
+ disabledFeatures: DISABLED_FEATURES,
+ depthLimit: MAX_SERIALIZATION_DEPTH_LIMIT,
+ plugins: DEFAULT_PLUGINS,
+ onParse(node) {
+ controller.enqueue(createChunk(JSON.stringify(node)));
+ },
+ onDone() {
+ controller.close();
+ },
+ onError(error) {
+ controller.error(error);
+ },
+ });
+ },
+ });
+}
+
+class SerovalChunkReader {
+ reader: ReadableStreamDefaultReader;
+ buffer: Uint8Array;
+ done: boolean;
+ constructor(stream: ReadableStream) {
+ this.reader = stream.getReader();
+ this.buffer = new Uint8Array(0);
+ this.done = false;
+ }
+
+ async readChunk() {
+ // if there's no chunk, read again
+ const chunk = await this.reader.read();
+ if (!chunk.done) {
+ // repopulate the buffer
+ const newBuffer = new Uint8Array(this.buffer.length + chunk.value.length);
+ newBuffer.set(this.buffer);
+ newBuffer.set(chunk.value, this.buffer.length);
+ this.buffer = newBuffer;
+ } else {
+ this.done = true;
+ }
+ }
+
+ async next(): Promise<
+ { done: true; value: undefined } | { done: false; value: string }
+ > {
+ // Check if the buffer is empty
+ if (this.buffer.length === 0) {
+ // if we are already done...
+ if (this.done) {
+ return {
+ done: true,
+ value: undefined,
+ };
+ }
+ // Otherwise, read a new chunk
+ await this.readChunk();
+ return await this.next();
+ }
+ // Read the "byte header"
+ // The byte header tells us how big the expected data is
+ // so we know how much data we should wait before we
+ // deserialize the data
+ const head = new TextDecoder().decode(this.buffer.subarray(1, 11));
+ const bytes = Number.parseInt(head, 16); // ;0x00000000;
+ // Check if the buffer has enough bytes to be parsed
+ while (bytes > this.buffer.length - 12) {
+ // If it's not enough, and the reader is done
+ // then the chunk is invalid.
+ if (this.done) {
+ throw new Error("Malformed server function stream.");
+ }
+ // Otherwise, we read more chunks
+ await this.readChunk();
+ }
+ // Extract the exact chunk as defined by the byte header
+ const partial = new TextDecoder().decode(
+ this.buffer.subarray(12, 12 + bytes),
+ );
+ // The rest goes to the buffer
+ this.buffer = this.buffer.subarray(12 + bytes);
+
+ // Deserialize the chunk
+ return {
+ done: false,
+ value: partial,
+ };
+ }
+
+ async drain(interpret: (chunk: string) => void) {
+ while (true) {
+ const result = await this.next();
+ if (result.done) {
+ break;
+ } else {
+ interpret(result.value);
+ }
+ }
+ }
+}
+
+export async function serializeToJSONString(value: any) {
+ const response = new Response(serializeToJSONStream(value));
+ return await response.text();
+}
+
+export async function deserializeFromJSONString(json: string) {
+ const blob = new Response(json);
+ return await deserializeJSONStream(blob);
+}
+
+export async function deserializeJSONStream(response: Response | Request) {
+ if (!response.body) {
+ throw new Error("missing body");
+ }
+ const reader = new SerovalChunkReader(response.body);
+ const result = await reader.next();
+ if (!result.done) {
+ const refs = new Map();
+
+ function interpretChunk(chunk: string): unknown {
+ const value = fromCrossJSON(JSON.parse(chunk) as SerovalNode, {
+ refs,
+ disabledFeatures: DISABLED_FEATURES,
+ depthLimit: MAX_SERIALIZATION_DEPTH_LIMIT,
+ plugins: DEFAULT_PLUGINS,
+ });
+ return value;
+ }
+
+ void reader.drain(interpretChunk);
+
+ return interpretChunk(result.value);
+ }
+ return undefined;
+}
+
+export async function deserializeJSStream(id: string, response: Response) {
+ if (!response.body) {
+ throw new Error("missing body");
+ }
+ const reader = new SerovalChunkReader(response.body);
+
+ const result = await reader.next();
+
+ if (!result.done) {
+ reader.drain(deserialize).then(
+ () => {
+ // @ts-ignore
+ delete $R[id];
+ },
+ () => {
+ // no-op
+ },
+ );
+ return deserialize(result.value);
+ }
+ return undefined;
+}
diff --git a/packages/start/src/server/server-functions-handler.ts b/packages/start/src/server/server-functions-handler.ts
index 160672684..c03340dae 100644
--- a/packages/start/src/server/server-functions-handler.ts
+++ b/packages/start/src/server/server-functions-handler.ts
@@ -1,74 +1,22 @@
-import { getServerFnById } from "solidstart:server-fn-manifest";
import { parseSetCookie } from "cookie-es";
import { type H3Event, parseCookies } from "h3";
-import { crossSerializeStream, fromJSON, getCrossReferenceHeader } from "seroval";
-import {
- CustomEventPlugin,
- DOMExceptionPlugin,
- EventPlugin,
- FormDataPlugin,
- HeadersPlugin,
- ReadableStreamPlugin,
- RequestPlugin,
- ResponsePlugin,
- URLPlugin,
- URLSearchParamsPlugin,
-} from "seroval-plugins/web";
import { sharedConfig } from "solid-js";
import { renderToString } from "solid-js/web";
import { provideRequestEvent } from "solid-js/web/storage";
+import { getServerFnById } from "solidstart:server-fn-manifest";
import { getFetchEvent, mergeResponseHeaders } from "./fetchEvent.ts";
import { createPageEvent } from "./handler.ts";
+import {
+ deserializeFromJSONString,
+ deserializeJSONStream,
+ serializeToJSONStream,
+ serializeToJSStream,
+} from "./serialization.ts";
+import { BODY_FORMAL_FILE, BODY_FORMAT_KEY, BodyFormat } from "./server-functions-shared.ts";
import type { FetchEvent, PageEvent } from "./types.ts";
import { getExpectedRedirectStatus } from "./util.ts";
-function createChunk(data: string) {
- const encodeData = new TextEncoder().encode(data);
- const bytes = encodeData.length;
- const baseHex = bytes.toString(16);
- const totalHex = "00000000".substring(0, 8 - baseHex.length) + baseHex; // 32-bit
- const head = new TextEncoder().encode(`;0x${totalHex};`);
-
- const chunk = new Uint8Array(12 + bytes);
- chunk.set(head);
- chunk.set(encodeData, 12);
- return chunk;
-}
-
-function serializeToStream(id: string, value: any) {
- return new ReadableStream({
- start(controller) {
- crossSerializeStream(value, {
- scopeId: id,
- plugins: [
- CustomEventPlugin,
- DOMExceptionPlugin,
- EventPlugin,
- FormDataPlugin,
- HeadersPlugin,
- ReadableStreamPlugin,
- RequestPlugin,
- ResponsePlugin,
- URLSearchParamsPlugin,
- URLPlugin,
- ],
- onSerialize(data: string, initial: boolean) {
- controller.enqueue(
- createChunk(initial ? `(${getCrossReferenceHeader(id)},${data})` : data),
- );
- },
- onDone() {
- controller.close();
- },
- onError(error: any) {
- controller.error(error);
- },
- });
- },
- });
-}
-
export async function handleServerFunction(h3Event: H3Event) {
const event = getFetchEvent(h3Event);
const request = event.request;
@@ -96,54 +44,49 @@ export async function handleServerFunction(h3Event: H3Event) {
let parsed: any[] = [];
// grab bound arguments from url when no JS
- if (!instance || h3Event.method === "GET") {
+ if (!instance || request.method === "GET") {
const args = url.searchParams.get("args");
if (args) {
- const json = JSON.parse(args);
- (json.t
- ? (fromJSON(json, {
- plugins: [
- CustomEventPlugin,
- DOMExceptionPlugin,
- EventPlugin,
- FormDataPlugin,
- HeadersPlugin,
- ReadableStreamPlugin,
- RequestPlugin,
- ResponsePlugin,
- URLSearchParamsPlugin,
- URLPlugin,
- ],
- }) as any)
- : json
- ).forEach((arg: any) => {
+ const result = (await deserializeFromJSONString(args)) as any[];
+ for (const arg of result) {
parsed.push(arg);
- });
+ }
}
}
- if (h3Event.method === "POST") {
+ if (request.method === "POST") {
const contentType = request.headers.get("content-type");
+ const startType = request.headers.get(BODY_FORMAT_KEY);
+ const clone = request.clone();
- if (
- contentType?.startsWith("multipart/form-data") ||
- contentType?.startsWith("application/x-www-form-urlencoded")
- ) {
- parsed.push(await event.request.formData());
- } else if (contentType?.startsWith("application/json")) {
- parsed = fromJSON(await event.request.json(), {
- plugins: [
- CustomEventPlugin,
- DOMExceptionPlugin,
- EventPlugin,
- FormDataPlugin,
- HeadersPlugin,
- ReadableStreamPlugin,
- RequestPlugin,
- ResponsePlugin,
- URLSearchParamsPlugin,
- URLPlugin,
- ],
- });
+ switch (true) {
+ case startType === BodyFormat.Seroval:
+ parsed = (await deserializeJSONStream(clone)) as any[];
+ break;
+ case startType === BodyFormat.String:
+ parsed.push(await clone.text());
+ break;
+ case startType === BodyFormat.File: {
+ const formData = await clone.formData();
+ parsed.push(formData.get(BODY_FORMAL_FILE));
+ break;
+ }
+ case startType === BodyFormat.FormData:
+ case contentType?.startsWith("multipart/form-data"):
+ parsed.push(await clone.formData());
+ break;
+ case startType === BodyFormat.URLSearchParams:
+ case contentType?.startsWith("application/x-www-form-urlencoded"):
+ parsed.push(new URLSearchParams(await clone.text()));
+ break;
+ case startType === BodyFormat.Blob:
+ parsed.push(await clone.blob());
+ break;
+ case startType === BodyFormat.ArrayBuffer:
+ parsed.push(await clone.arrayBuffer());
+ break;
+ case startType === BodyFormat.Uint8Array:
+ parsed.push(await clone.bytes());
+ break;
}
}
try {
@@ -171,16 +114,19 @@ export async function handleServerFunction(h3Event: H3Event) {
h3Event.res.status = result.status;
if ((result as any).customBody) {
result = await (result as any).customBody();
- } else if (result.body == undefined) result = null;
+ } else if (result.body == null) result = null;
}
}
// handle no JS success case
if (!instance) return handleNoJS(result, request, parsed);
- h3Event.res.headers.set("content-type", "text/javascript");
-
- return serializeToStream(instance, result);
+ h3Event.res.headers.set(BODY_FORMAT_KEY, "true");
+ if (import.meta.env.SEROVAL_MODE === "js") {
+ h3Event.res.headers.set("content-type", "text/javascript");
+ return serializeToJSStream(instance, result);
+ }
+ return serializeToJSONStream(result);
} catch (x) {
if (x instanceof Response) {
if (singleFlight && instance) {
@@ -189,28 +135,41 @@ export async function handleServerFunction(h3Event: H3Event) {
// forward headers
if ((x as any).headers) mergeResponseHeaders(h3Event, (x as any).headers);
// forward non-redirect statuses
- if ((x as any).status && (!instance || (x as any).status < 300 || (x as any).status >= 400))
+ if (
+ (x as any).status &&
+ (!instance || (x as any).status < 300 || (x as any).status >= 400)
+ )
h3Event.res.status = (x as any).status;
if ((x as any).customBody) {
x = (x as any).customBody();
} else if ((x as any).body === undefined) x = null;
h3Event.res.headers.set("X-Error", "true");
} else if (instance) {
- const error = x instanceof Error ? x.message : typeof x === "string" ? x : "true";
+ const error =
+ x instanceof Error ? x.message : typeof x === "string" ? x : "true";
h3Event.res.headers.set("X-Error", error.replace(/[\r\n]+/g, ""));
} else {
x = handleNoJS(x, request, parsed, true);
}
if (instance) {
- h3Event.res.headers.set("content-type", "text/javascript");
- return serializeToStream(instance, x);
+ h3Event.res.headers.set(BODY_FORMAT_KEY, "true");
+ if (import.meta.env.SEROVAL_MODE === "js") {
+ h3Event.res.headers.set("content-type", "text/javascript");
+ return serializeToJSStream(instance, x);
+ }
+ return serializeToJSONStream(x);
}
return x;
}
}
-function handleNoJS(result: any, request: Request, parsed: any[], thrown?: boolean) {
+function handleNoJS(
+ result: any,
+ request: Request,
+ parsed: any[],
+ thrown?: boolean,
+) {
const url = new URL(request.url);
const isError = result instanceof Error;
let statusCode = 302;
@@ -220,7 +179,10 @@ function handleNoJS(result: any, request: Request, parsed: any[], thrown?: boole
if (result.headers.has("Location")) {
headers.set(
`Location`,
- new URL(result.headers.get("Location")!, url.origin + import.meta.env.BASE_URL).toString(),
+ new URL(
+ result.headers.get("Location")!,
+ url.origin + import.meta.env.BASE_URL,
+ ).toString(),
);
statusCode = getExpectedRedirectStatus(result);
}
@@ -237,7 +199,10 @@ function handleNoJS(result: any, request: Request, parsed: any[], thrown?: boole
result: isError ? result.message : result,
thrown: thrown,
error: isError,
- input: [...parsed.slice(0, -1), [...parsed[parsed.length - 1].entries()]],
+ input: [
+ ...parsed.slice(0, -1),
+ [...parsed[parsed.length - 1].entries()],
+ ],
}),
)}; Secure; HttpOnly;`,
);
@@ -263,7 +228,7 @@ function createSingleFlightHeaders(sourceEvent: FetchEvent) {
// useH3Internals = true;
// sourceEvent.nativeEvent.node.req.headers.cookie = "";
// }
- SetCookies.forEach(cookie => {
+ SetCookies.forEach((cookie) => {
if (!cookie) return;
const { maxAge, expires, name, value } = parseSetCookie(cookie);
if (maxAge != null && maxAge <= 0) {
@@ -284,7 +249,10 @@ function createSingleFlightHeaders(sourceEvent: FetchEvent) {
return headers;
}
-async function handleSingleFlight(sourceEvent: FetchEvent, result: any): Promise {
+async function handleSingleFlight(
+ sourceEvent: FetchEvent,
+ result: any,
+): Promise {
let revalidate: string[];
let url = new URL(sourceEvent.request.headers.get("referer")!).toString();
if (result instanceof Response) {
diff --git a/packages/start/src/server/server-functions-shared.ts b/packages/start/src/server/server-functions-shared.ts
new file mode 100644
index 000000000..f7c253dd8
--- /dev/null
+++ b/packages/start/src/server/server-functions-shared.ts
@@ -0,0 +1,15 @@
+
+export const BODY_FORMAT_KEY = "X-Start-Type";
+
+export const BODY_FORMAL_FILE = "__START__";
+
+export const enum BodyFormat {
+ Seroval = "0",
+ String = "1",
+ FormData = "2",
+ URLSearchParams = "3",
+ Blob = "4",
+ File = "5",
+ ArrayBuffer = "6",
+ Uint8Array = "7",
+}
diff --git a/packages/start/src/server/server-runtime.ts b/packages/start/src/server/server-runtime.ts
index 8bbabe40b..cb2b889f2 100644
--- a/packages/start/src/server/server-runtime.ts
+++ b/packages/start/src/server/server-runtime.ts
@@ -1,146 +1,136 @@
-// @ts-ignore - seroval exports issue with NodeNext
-import { join } from "pathe";
-import { deserialize, toJSONAsync } from "seroval";
-import {
- CustomEventPlugin,
- DOMExceptionPlugin,
- EventPlugin,
- FormDataPlugin,
- HeadersPlugin,
- ReadableStreamPlugin,
- RequestPlugin,
- ResponsePlugin,
- URLPlugin,
- URLSearchParamsPlugin,
-} from "seroval-plugins/web";
import { type Component } from "solid-js";
+import {
+ deserializeJSONStream,
+ deserializeJSStream,
+ // serializeToJSONStream,
+ serializeToJSONString,
+} from "./serialization.ts";
+import { BODY_FORMAL_FILE, BODY_FORMAT_KEY, BodyFormat } from "./server-functions-shared.ts";
-class SerovalChunkReader {
- reader: ReadableStreamDefaultReader;
- buffer: Uint8Array;
- done: boolean;
- constructor(stream: ReadableStream) {
- this.reader = stream.getReader();
- this.buffer = new Uint8Array(0);
- this.done = false;
- }
-
- async readChunk() {
- // if there's no chunk, read again
- const chunk = await this.reader.read();
- if (!chunk.done) {
- // repopulate the buffer
- let newBuffer = new Uint8Array(this.buffer.length + chunk.value.length);
- newBuffer.set(this.buffer);
- newBuffer.set(chunk.value, this.buffer.length);
- this.buffer = newBuffer;
- } else {
- this.done = true;
- }
- }
-
- async next(): Promise {
- // Check if the buffer is empty
- if (this.buffer.length === 0) {
- // if we are already done...
- if (this.done) {
- return {
- done: true,
- value: undefined,
- };
- }
- // Otherwise, read a new chunk
- await this.readChunk();
- return await this.next();
- }
- // Read the "byte header"
- // The byte header tells us how big the expected data is
- // so we know how much data we should wait before we
- // deserialize the data
- const head = new TextDecoder().decode(this.buffer.subarray(1, 11));
- const bytes = Number.parseInt(head, 16); // ;0x00000000;
- // Check if the buffer has enough bytes to be parsed
- while (bytes > this.buffer.length - 12) {
- // If it's not enough, and the reader is done
- // then the chunk is invalid.
- if (this.done) {
- throw new Error("Malformed server function stream.");
- }
- // Otherwise, we read more chunks
- await this.readChunk();
- }
- // Extract the exact chunk as defined by the byte header
- const partial = new TextDecoder().decode(this.buffer.subarray(12, 12 + bytes));
- // The rest goes to the buffer
- this.buffer = this.buffer.subarray(12 + bytes);
+let INSTANCE = 0;
- // Deserialize the chunk
- return {
- done: false,
- value: deserialize(partial),
- };
- }
+function createRequest(
+ base: string,
+ id: string,
+ instance: string,
+ options: RequestInit,
+) {
+ return fetch(base, {
+ method: "POST",
+ ...options,
+ headers: {
+ ...options.headers,
+ "X-Server-Id": id,
+ "X-Server-Instance": instance,
+ },
+ });
+}
- async drain() {
- while (true) {
- const result = await this.next();
- if (result.done) {
- break;
- }
+function getHeadersAndBody(body: any): {
+ headers?: HeadersInit;
+ body: BodyInit;
+} | undefined {
+ switch (true) {
+ case typeof body === "string":
+ return {
+ headers: {
+ "Content-Type": "text/plain",
+ [BODY_FORMAT_KEY]: BodyFormat.String,
+ },
+ body,
+ };
+ case body instanceof FormData:
+ return {
+ headers: {
+ [BODY_FORMAT_KEY]: BodyFormat.FormData,
+ },
+ body,
+ };
+ case body instanceof URLSearchParams:
+ return {
+ headers: {
+ "Content-Type": "application/x-www-form-urlencoded",
+ [BODY_FORMAT_KEY]: BodyFormat.URLSearchParams,
+ },
+ body,
+ };
+ case body instanceof File: {
+ const formData = new FormData();
+ formData.append(BODY_FORMAL_FILE, body, body.name);
+ return {
+ headers: {
+ [BODY_FORMAT_KEY]: BodyFormat.File,
+ },
+ body: formData,
+ };
}
+ case body instanceof Blob:
+ return {
+ headers: {
+ [BODY_FORMAT_KEY]: BodyFormat.Blob,
+ },
+ body,
+ };
+ case body instanceof ArrayBuffer:
+ return {
+ headers: {
+ [BODY_FORMAT_KEY]: BodyFormat.ArrayBuffer,
+ },
+ body,
+ };
+ case body instanceof Uint8Array:
+ return {
+ headers: {
+ [BODY_FORMAT_KEY]: BodyFormat.Uint8Array,
+ },
+ body: new Uint8Array(body),
+ };
+ default:
+ return undefined;
}
}
-async function deserializeStream(id: string, response: Response) {
- if (!response.body) {
- throw new Error("missing body");
+async function initializeResponse(
+ base: string,
+ id: string,
+ instance: string,
+ options: RequestInit,
+ args: any[],
+) {
+ // No args, skip serialization
+ if (args.length === 0) {
+ return createRequest(base, id, instance, options);
}
- const reader = new SerovalChunkReader(response.body);
-
- const result = await reader.next();
-
- if (!result.done) {
- reader.drain().then(
- () => {
- // @ts-ignore
- delete $R[id];
- },
- () => {
- // no-op
- },
- );
+ // For single arguments, we can directly encode as body
+ if (args.length === 1) {
+ const body = args[0];
+ const result = getHeadersAndBody(body);
+ if (result) {
+ return createRequest(base, id, instance, {
+ ...options,
+ body: result.body,
+ headers: {
+ ...options.headers,
+ ...result.headers,
+ },
+ });
+ }
}
-
- return result.value;
-}
-
-let INSTANCE = 0;
-
-function createRequest(base: string, id: string, instance: string, options: RequestInit) {
- return fetch(base, {
- method: "POST",
+ // Fallback to seroval
+ return createRequest(base, id, instance, {
...options,
+ // TODO(Alexis): move to serializeToJSONStream
+ body: await serializeToJSONString(args),
+ // duplex: 'half',
+ // body: serializeToJSONStream(args),
headers: {
...options.headers,
- "X-Server-Id": id,
- "X-Server-Instance": instance,
+ "Content-Type": "text/plain",
+ [BODY_FORMAT_KEY]: BodyFormat.Seroval,
},
});
}
-const plugins = [
- CustomEventPlugin,
- DOMExceptionPlugin,
- EventPlugin,
- FormDataPlugin,
- HeadersPlugin,
- ReadableStreamPlugin,
- RequestPlugin,
- ResponsePlugin,
- URLSearchParamsPlugin,
- URLPlugin,
-];
-
async function fetchServerFunction(
base: string,
id: string,
@@ -148,21 +138,8 @@ async function fetchServerFunction(
args: any[],
) {
const instance = `server-fn:${INSTANCE++}`;
- const response = await (args.length === 0
- ? createRequest(base, id, instance, options)
- : args.length === 1 && args[0] instanceof FormData
- ? createRequest(base, id, instance, { ...options, body: args[0] })
- : args.length === 1 && args[0] instanceof URLSearchParams
- ? createRequest(base, id, instance, {
- ...options,
- body: args[0],
- headers: { ...options.headers, "Content-Type": "application/x-www-form-urlencoded" },
- })
- : createRequest(base, id, instance, {
- ...options,
- body: JSON.stringify(await Promise.resolve(toJSONAsync(args, { plugins }))),
- headers: { ...options.headers, "Content-Type": "application/json" },
- }));
+
+ const response = await initializeResponse(base, id, instance, options, args);
if (
response.headers.has("Location") ||
@@ -172,20 +149,28 @@ async function fetchServerFunction(
if (response.body) {
/* @ts-ignore-next-line */
response.customBody = () => {
- return deserializeStream(instance, response);
+ if (import.meta.env.SEROVAL_MODE === "js") {
+ return deserializeJSStream(instance, response.clone());
+ }
+ return deserializeJSONStream(response.clone());
};
}
return response;
}
const contentType = response.headers.get("Content-Type");
+ const clone = response.clone();
let result;
- if (contentType && contentType.startsWith("text/plain")) {
- result = await response.text();
- } else if (contentType && contentType.startsWith("application/json")) {
- result = await response.json();
- } else {
- result = await deserializeStream(instance, response);
+ if (contentType?.startsWith("text/plain")) {
+ result = await clone.text();
+ } else if (contentType?.startsWith("application/json")) {
+ result = await clone.json();
+ } else if (response.headers.get(BODY_FORMAT_KEY)) {
+ if (import.meta.env.SEROVAL_MODE === "js") {
+ result = await deserializeJSStream(instance, clone);
+ } else {
+ result = await deserializeJSONStream(clone);
+ }
}
if (response.headers.has("X-Error")) {
throw result;
@@ -197,7 +182,8 @@ export function createServerReference(id: string) {
let baseURL = import.meta.env.BASE_URL ?? "/";
if (!baseURL.endsWith("/")) baseURL += "/";
- const fn = (...args: any[]) => fetchServerFunction(`${baseURL}_server`, id, {}, args);
+ const fn = (...args: any[]) =>
+ fetchServerFunction(`${baseURL}_server`, id, {}, args);
return new Proxy(fn, {
get(target, prop, receiver) {
@@ -211,15 +197,16 @@ export function createServerReference(id: string) {
const url = `${baseURL}_server?id=${encodeURIComponent(id)}`;
return (options: RequestInit) => {
const fn = async (...args: any[]) => {
- const encodeArgs = options.method && options.method.toUpperCase() === "GET";
+ const encodeArgs =
+ options.method && options.method.toUpperCase() === "GET";
return fetchServerFunction(
encodeArgs
? url +
- (args.length
- ? `&args=${encodeURIComponent(
- JSON.stringify(await Promise.resolve(toJSONAsync(args, { plugins }))),
- )}`
- : "")
+ (args.length
+ ? `&args=${encodeURIComponent(
+ await serializeToJSONString(args),
+ )}`
+ : "")
: `${baseURL}_server`,
id,
options,
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 25d67e8e2..5d53df2d7 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -15,7 +15,7 @@ importers:
devDependencies:
'@changesets/cli':
specifier: ^2.29.8
- version: 2.29.8(@types/node@25.0.1)
+ version: 2.29.8(@types/node@25.0.3)
citty:
specifier: ^0.1.5
version: 0.1.6
@@ -42,7 +42,7 @@ importers:
version: 1.9.9
vite:
specifier: 7.1.10
- version: 7.1.10(@types/node@25.0.1)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(tsx@4.19.2)(yaml@2.8.1)
+ version: 7.1.10(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(tsx@4.19.2)(yaml@2.8.1)
apps/fixtures/basic:
dependencies:
@@ -60,7 +60,7 @@ importers:
version: 1.9.9
vite:
specifier: 7.1.10
- version: 7.1.10(@types/node@25.0.1)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(tsx@4.19.2)(yaml@2.8.1)
+ version: 7.1.10(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(tsx@4.19.2)(yaml@2.8.1)
apps/fixtures/css:
dependencies:
@@ -78,11 +78,11 @@ importers:
version: 1.9.9
vite:
specifier: 7.1.10
- version: 7.1.10(@types/node@25.0.1)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(tsx@4.19.2)(yaml@2.8.1)
+ version: 7.1.10(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(tsx@4.19.2)(yaml@2.8.1)
devDependencies:
'@tailwindcss/vite':
specifier: ^4.1.12
- version: 4.1.17(vite@7.1.10(@types/node@25.0.1)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(tsx@4.19.2)(yaml@2.8.1))
+ version: 4.1.17(vite@7.1.10(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(tsx@4.19.2)(yaml@2.8.1))
tailwindcss:
specifier: ^4.1.12
version: 4.1.17
@@ -103,7 +103,7 @@ importers:
version: 1.9.9
vite:
specifier: 7.1.10
- version: 7.1.10(@types/node@25.0.1)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(tsx@4.19.2)(yaml@2.8.1)
+ version: 7.1.10(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(tsx@4.19.2)(yaml@2.8.1)
apps/fixtures/hackernews:
dependencies:
@@ -115,13 +115,13 @@ importers:
version: link:../../../packages/start
nitro:
specifier: 3.0.1-alpha.0
- version: 3.0.1-alpha.0(@netlify/blobs@10.4.1)(better-sqlite3@11.8.1)(chokidar@4.0.3)(drizzle-orm@0.31.4(@opentelemetry/api@1.9.0)(@prisma/client@5.22.0(prisma@5.22.0))(@types/better-sqlite3@7.6.12)(better-sqlite3@11.8.1)(prisma@5.22.0))(ioredis@5.6.1)(vite@7.1.10(@types/node@25.0.1)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(tsx@4.19.2)(yaml@2.8.1))
+ version: 3.0.1-alpha.0(@netlify/blobs@10.4.1)(better-sqlite3@11.8.1)(chokidar@4.0.3)(drizzle-orm@0.31.4(@opentelemetry/api@1.9.0)(@prisma/client@5.22.0(prisma@5.22.0))(@types/better-sqlite3@7.6.12)(better-sqlite3@11.8.1)(prisma@5.22.0))(ioredis@5.6.1)(vite@7.1.10(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(tsx@4.19.2)(yaml@2.8.1))
solid-js:
specifier: ^1.9.9
version: 1.9.9
vite:
specifier: 7.1.10
- version: 7.1.10(@types/node@25.0.1)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(tsx@4.19.2)(yaml@2.8.1)
+ version: 7.1.10(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(tsx@4.19.2)(yaml@2.8.1)
apps/fixtures/nitro-3:
dependencies:
@@ -136,13 +136,13 @@ importers:
version: link:../../../packages/start
nitro:
specifier: ^3.0.1-alpha.1
- version: 3.0.1-alpha.1(@netlify/blobs@10.4.1)(better-sqlite3@11.8.1)(chokidar@4.0.3)(drizzle-orm@0.31.4(@opentelemetry/api@1.9.0)(@prisma/client@5.22.0(prisma@5.22.0))(@types/better-sqlite3@7.6.12)(better-sqlite3@11.8.1)(prisma@5.22.0))(ioredis@5.6.1)(rollup@4.52.5)(vite@7.1.10(@types/node@25.0.1)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(tsx@4.19.2)(yaml@2.8.1))
+ version: 3.0.1-alpha.1(@netlify/blobs@10.4.1)(better-sqlite3@11.8.1)(chokidar@4.0.3)(drizzle-orm@0.31.4(@opentelemetry/api@1.9.0)(@prisma/client@5.22.0(prisma@5.22.0))(@types/better-sqlite3@7.6.12)(better-sqlite3@11.8.1)(prisma@5.22.0))(ioredis@5.6.1)(rollup@4.52.5)(vite@7.1.10(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(tsx@4.19.2)(yaml@2.8.1))
solid-js:
specifier: ^1.9.9
version: 1.9.9
vite:
specifier: 7.1.10
- version: 7.1.10(@types/node@25.0.1)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(tsx@4.19.2)(yaml@2.8.1)
+ version: 7.1.10(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(tsx@4.19.2)(yaml@2.8.1)
apps/fixtures/notes:
dependencies:
@@ -166,7 +166,7 @@ importers:
version: 1.10.2(ioredis@5.6.1)
vite:
specifier: 7.1.10
- version: 7.1.10(@types/node@25.0.1)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(tsx@4.19.2)(yaml@2.8.1)
+ version: 7.1.10(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(tsx@4.19.2)(yaml@2.8.1)
apps/fixtures/todomvc:
dependencies:
@@ -178,7 +178,7 @@ importers:
version: link:../../../packages/start
nitro:
specifier: 3.0.1-alpha.0
- version: 3.0.1-alpha.0(@netlify/blobs@10.4.1)(better-sqlite3@11.8.1)(chokidar@4.0.3)(drizzle-orm@0.31.4(@opentelemetry/api@1.9.0)(@prisma/client@5.22.0(prisma@5.22.0))(@types/better-sqlite3@7.6.12)(better-sqlite3@11.8.1)(prisma@5.22.0))(ioredis@5.6.1)(vite@7.1.10(@types/node@25.0.1)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(tsx@4.19.2)(yaml@2.8.1))
+ version: 3.0.1-alpha.0(@netlify/blobs@10.4.1)(better-sqlite3@11.8.1)(chokidar@4.0.3)(drizzle-orm@0.31.4(@opentelemetry/api@1.9.0)(@prisma/client@5.22.0(prisma@5.22.0))(@types/better-sqlite3@7.6.12)(better-sqlite3@11.8.1)(prisma@5.22.0))(ioredis@5.6.1)(vite@7.1.10(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(tsx@4.19.2)(yaml@2.8.1))
solid-js:
specifier: ^1.9.9
version: 1.9.9
@@ -187,7 +187,7 @@ importers:
version: 1.10.2(ioredis@5.6.1)
vite:
specifier: 7.1.10
- version: 7.1.10(@types/node@25.0.1)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(tsx@4.19.2)(yaml@2.8.1)
+ version: 7.1.10(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(tsx@4.19.2)(yaml@2.8.1)
apps/landing-page:
dependencies:
@@ -248,7 +248,7 @@ importers:
version: 6.3.7
vite:
specifier: ^7.1.10
- version: 7.1.10(@types/node@25.0.1)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(tsx@4.19.2)(yaml@2.8.1)
+ version: 7.1.10(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(tsx@4.19.2)(yaml@2.8.1)
apps/tests:
dependencies:
@@ -284,13 +284,13 @@ importers:
version: 1.9.9
vite:
specifier: ^7.1.10
- version: 7.1.10(@types/node@25.0.1)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(tsx@4.19.2)(yaml@2.8.1)
+ version: 7.1.10(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(tsx@4.19.2)(yaml@2.8.1)
vite-plugin-solid:
specifier: ^2.11.9
- version: 2.11.9(patch_hash=71233f1afab9e3ea2dbb03dbda3d84894ef1c6bfbbe69df9f864d03bfe67b6f5)(@testing-library/jest-dom@6.6.2)(solid-js@1.9.9)(vite@7.1.10(@types/node@25.0.1)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(tsx@4.19.2)(yaml@2.8.1))
+ version: 2.11.9(patch_hash=71233f1afab9e3ea2dbb03dbda3d84894ef1c6bfbbe69df9f864d03bfe67b6f5)(@testing-library/jest-dom@6.6.2)(solid-js@1.9.9)(vite@7.1.10(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(tsx@4.19.2)(yaml@2.8.1))
vitest:
specifier: ^4.0.10
- version: 4.0.10(@types/debug@4.1.12)(@types/node@25.0.1)(@vitest/browser-playwright@4.0.10)(@vitest/ui@4.0.10)(jiti@2.6.1)(jsdom@25.0.1)(lightningcss@1.30.2)(msw@2.7.0(@types/node@25.0.1)(typescript@5.7.3))(terser@5.44.0)(tsx@4.19.2)(yaml@2.8.1)
+ version: 4.0.10(@types/debug@4.1.12)(@types/node@25.0.3)(@vitest/browser-playwright@4.0.10)(@vitest/ui@4.0.10)(jiti@2.6.1)(jsdom@25.0.1)(lightningcss@1.30.2)(msw@2.7.0(@types/node@25.0.3)(typescript@5.7.3))(terser@5.44.0)(tsx@4.19.2)(yaml@2.8.1)
devDependencies:
'@playwright/test':
specifier: ^1.56.1
@@ -300,10 +300,10 @@ importers:
version: 4.17.14
'@vitest/browser':
specifier: ^4.0.10
- version: 4.0.10(msw@2.7.0(@types/node@25.0.1)(typescript@5.7.3))(vite@7.1.10(@types/node@25.0.1)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(tsx@4.19.2)(yaml@2.8.1))(vitest@4.0.10)
+ version: 4.0.10(msw@2.7.0(@types/node@25.0.3)(typescript@5.7.3))(vite@7.1.10(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(tsx@4.19.2)(yaml@2.8.1))(vitest@4.0.10)
'@vitest/browser-playwright':
specifier: ^4.0.10
- version: 4.0.10(msw@2.7.0(@types/node@25.0.1)(typescript@5.7.3))(playwright@1.56.1)(vite@7.1.10(@types/node@25.0.1)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(tsx@4.19.2)(yaml@2.8.1))(vitest@4.0.10)
+ version: 4.0.10(msw@2.7.0(@types/node@25.0.3)(typescript@5.7.3))(playwright@1.56.1)(vite@7.1.10(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(tsx@4.19.2)(yaml@2.8.1))(vitest@4.0.10)
playwright:
specifier: ^1.56.1
version: 1.56.1
@@ -324,7 +324,7 @@ importers:
version: 0.29.4(solid-js@1.9.9)
'@tanstack/server-functions-plugin':
specifier: 1.134.5
- version: 1.134.5(vite@7.1.10(@types/node@25.0.1)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(tsx@4.19.2)(yaml@2.8.1))
+ version: 1.134.5(vite@7.1.10(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(tsx@4.19.2)(yaml@2.8.1))
'@types/babel__traverse':
specifier: ^7.28.0
version: 7.28.0
@@ -368,11 +368,11 @@ importers:
specifier: ^1.1.2
version: 1.1.2
seroval:
- specifier: ^1.4.1
- version: 1.4.1
+ specifier: ^1.5.0
+ version: 1.5.0
seroval-plugins:
specifier: ^1.4.0
- version: 1.4.0(seroval@1.4.1)
+ version: 1.4.0(seroval@1.5.0)
shiki:
specifier: ^1.26.1
version: 1.26.1
@@ -390,17 +390,17 @@ importers:
version: 1.0.6(solid-js@1.9.9)
vite-plugin-solid:
specifier: ^2.11.9
- version: 2.11.9(patch_hash=71233f1afab9e3ea2dbb03dbda3d84894ef1c6bfbbe69df9f864d03bfe67b6f5)(@testing-library/jest-dom@6.6.2)(solid-js@1.9.9)(vite@7.1.10(@types/node@25.0.1)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(tsx@4.19.2)(yaml@2.8.1))
+ version: 2.11.9(patch_hash=71233f1afab9e3ea2dbb03dbda3d84894ef1c6bfbbe69df9f864d03bfe67b6f5)(@testing-library/jest-dom@6.6.2)(solid-js@1.9.9)(vite@7.1.10(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(tsx@4.19.2)(yaml@2.8.1))
devDependencies:
'@types/babel__core':
specifier: ^7.20.5
version: 7.20.5
vite:
specifier: ^7.1.10
- version: 7.1.10(@types/node@25.0.1)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(tsx@4.19.2)(yaml@2.8.1)
+ version: 7.1.10(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(tsx@4.19.2)(yaml@2.8.1)
vitest:
specifier: ^4.0.10
- version: 4.0.10(@types/debug@4.1.12)(@types/node@25.0.1)(@vitest/browser-playwright@4.0.10)(@vitest/ui@4.0.10)(jiti@2.6.1)(jsdom@25.0.1)(lightningcss@1.30.2)(msw@2.7.0(@types/node@25.0.1)(typescript@5.7.3))(terser@5.44.0)(tsx@4.19.2)(yaml@2.8.1)
+ version: 4.0.10(@types/debug@4.1.12)(@types/node@25.0.3)(@vitest/browser-playwright@4.0.10)(@vitest/ui@4.0.10)(jiti@2.6.1)(jsdom@25.0.1)(lightningcss@1.30.2)(msw@2.7.0(@types/node@25.0.3)(typescript@5.7.3))(terser@5.44.0)(tsx@4.19.2)(yaml@2.8.1)
packages/start-nitro-v2-vite-plugin:
dependencies:
@@ -410,7 +410,7 @@ importers:
devDependencies:
vite:
specifier: ^7.1.10
- version: 7.1.10(@types/node@25.0.1)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(tsx@4.19.2)(yaml@2.8.1)
+ version: 7.1.10(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(tsx@4.19.2)(yaml@2.8.1)
packages:
@@ -2221,9 +2221,6 @@ packages:
'@types/node@24.9.1':
resolution: {integrity: sha512-QoiaXANRkSXK6p0Duvt56W208du4P9Uye9hWLWgGMDTEoKPhuenzNcC4vGUmrNkiOKTlIrBoyNQYNpSwfEZXSg==}
- '@types/node@25.0.1':
- resolution: {integrity: sha512-czWPzKIAXucn9PtsttxmumiQ9N0ok9FrBwgRWrwmVLlp86BrMExzvXRLFYRJ+Ex3g6yqj+KuaxfX1JTgV2lpfg==}
-
'@types/node@25.0.3':
resolution: {integrity: sha512-W609buLVRVmeW693xKfzHeIV6nJGGz98uCPfeXI1ELMLXVeKYZ9m15fAMSaUPBHYLGFsVRcMmSCksQOrZV9BYA==}
@@ -4854,8 +4851,8 @@ packages:
resolution: {integrity: sha512-RbcPH1n5cfwKrru7v7+zrZvjLurgHhGyso3HTyGtRivGWgYjbOmGuivCQaORNELjNONoK35nj28EoWul9sb1zQ==}
engines: {node: '>=10'}
- seroval@1.4.1:
- resolution: {integrity: sha512-9GOc+8T6LN4aByLN75uRvMbrwY5RDBW6lSlknsY4LEa9ZmWcxKcRe1G/Q3HZXjltxMHTrStnvrwAICxZrhldtg==}
+ seroval@1.5.0:
+ resolution: {integrity: sha512-OE4cvmJ1uSPrKorFIH9/w/Qwuvi/IMcGbv5RKgcJ/zjA/IohDLU6SVaxFN9FwajbP7nsX0dQqMDes1whk3y+yw==}
engines: {node: '>=10'}
serve-placeholder@2.0.2:
@@ -6163,7 +6160,7 @@ snapshots:
dependencies:
'@changesets/types': 6.1.0
- '@changesets/cli@2.29.8(@types/node@25.0.1)':
+ '@changesets/cli@2.29.8(@types/node@25.0.3)':
dependencies:
'@changesets/apply-release-plan': 7.0.14
'@changesets/assemble-release-plan': 6.0.9
@@ -6179,7 +6176,7 @@ snapshots:
'@changesets/should-skip-package': 0.1.2
'@changesets/types': 6.1.0
'@changesets/write': 0.4.0
- '@inquirer/external-editor': 1.0.3(@types/node@25.0.1)
+ '@inquirer/external-editor': 1.0.3(@types/node@25.0.3)
'@manypkg/get-packages': 1.1.3
ansi-colors: 4.1.3
ci-info: 3.9.0
@@ -6562,41 +6559,41 @@ snapshots:
'@inquirer/ansi@1.0.2':
optional: true
- '@inquirer/confirm@5.1.21(@types/node@25.0.1)':
+ '@inquirer/confirm@5.1.21(@types/node@25.0.3)':
dependencies:
- '@inquirer/core': 10.3.2(@types/node@25.0.1)
- '@inquirer/type': 3.0.10(@types/node@25.0.1)
+ '@inquirer/core': 10.3.2(@types/node@25.0.3)
+ '@inquirer/type': 3.0.10(@types/node@25.0.3)
optionalDependencies:
- '@types/node': 25.0.1
+ '@types/node': 25.0.3
optional: true
- '@inquirer/core@10.3.2(@types/node@25.0.1)':
+ '@inquirer/core@10.3.2(@types/node@25.0.3)':
dependencies:
'@inquirer/ansi': 1.0.2
'@inquirer/figures': 1.0.15
- '@inquirer/type': 3.0.10(@types/node@25.0.1)
+ '@inquirer/type': 3.0.10(@types/node@25.0.3)
cli-width: 4.1.0
mute-stream: 2.0.0
signal-exit: 4.1.0
wrap-ansi: 6.2.0
yoctocolors-cjs: 2.1.3
optionalDependencies:
- '@types/node': 25.0.1
+ '@types/node': 25.0.3
optional: true
- '@inquirer/external-editor@1.0.3(@types/node@25.0.1)':
+ '@inquirer/external-editor@1.0.3(@types/node@25.0.3)':
dependencies:
chardet: 2.1.1
iconv-lite: 0.7.1
optionalDependencies:
- '@types/node': 25.0.1
+ '@types/node': 25.0.3
'@inquirer/figures@1.0.15':
optional: true
- '@inquirer/type@3.0.10(@types/node@25.0.1)':
+ '@inquirer/type@3.0.10(@types/node@25.0.3)':
optionalDependencies:
- '@types/node': 25.0.1
+ '@types/node': 25.0.3
optional: true
'@internationalized/date@3.5.4':
@@ -7548,14 +7545,14 @@ snapshots:
postcss-selector-parser: 6.0.10
tailwindcss: 3.4.17
- '@tailwindcss/vite@4.1.17(vite@7.1.10(@types/node@25.0.1)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(tsx@4.19.2)(yaml@2.8.1))':
+ '@tailwindcss/vite@4.1.17(vite@7.1.10(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(tsx@4.19.2)(yaml@2.8.1))':
dependencies:
'@tailwindcss/node': 4.1.17
'@tailwindcss/oxide': 4.1.17
tailwindcss: 4.1.17
- vite: 7.1.10(@types/node@25.0.1)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(tsx@4.19.2)(yaml@2.8.1)
+ vite: 7.1.10(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(tsx@4.19.2)(yaml@2.8.1)
- '@tanstack/directive-functions-plugin@1.134.5(vite@7.1.10(@types/node@25.0.1)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(tsx@4.19.2)(yaml@2.8.1))':
+ '@tanstack/directive-functions-plugin@1.134.5(vite@7.1.10(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(tsx@4.19.2)(yaml@2.8.1))':
dependencies:
'@babel/code-frame': 7.27.1
'@babel/core': 7.28.3
@@ -7565,7 +7562,7 @@ snapshots:
babel-dead-code-elimination: 1.0.10
pathe: 2.0.3
tiny-invariant: 1.3.3
- vite: 7.1.10(@types/node@25.0.1)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(tsx@4.19.2)(yaml@2.8.1)
+ vite: 7.1.10(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(tsx@4.19.2)(yaml@2.8.1)
transitivePeerDependencies:
- supports-color
@@ -7582,7 +7579,7 @@ snapshots:
transitivePeerDependencies:
- supports-color
- '@tanstack/server-functions-plugin@1.134.5(vite@7.1.10(@types/node@25.0.1)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(tsx@4.19.2)(yaml@2.8.1))':
+ '@tanstack/server-functions-plugin@1.134.5(vite@7.1.10(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(tsx@4.19.2)(yaml@2.8.1))':
dependencies:
'@babel/code-frame': 7.27.1
'@babel/core': 7.28.3
@@ -7591,7 +7588,7 @@ snapshots:
'@babel/template': 7.27.2
'@babel/traverse': 7.28.5
'@babel/types': 7.28.5
- '@tanstack/directive-functions-plugin': 1.134.5(vite@7.1.10(@types/node@25.0.1)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(tsx@4.19.2)(yaml@2.8.1))
+ '@tanstack/directive-functions-plugin': 1.134.5(vite@7.1.10(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(tsx@4.19.2)(yaml@2.8.1))
babel-dead-code-elimination: 1.0.10
tiny-invariant: 1.3.3
transitivePeerDependencies:
@@ -7699,11 +7696,6 @@ snapshots:
undici-types: 7.16.0
optional: true
- '@types/node@25.0.1':
- dependencies:
- undici-types: 7.16.0
- optional: true
-
'@types/node@25.0.3':
dependencies:
undici-types: 7.16.0
@@ -7789,29 +7781,29 @@ snapshots:
- rollup
- supports-color
- '@vitest/browser-playwright@4.0.10(msw@2.7.0(@types/node@25.0.1)(typescript@5.7.3))(playwright@1.56.1)(vite@7.1.10(@types/node@25.0.1)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(tsx@4.19.2)(yaml@2.8.1))(vitest@4.0.10)':
+ '@vitest/browser-playwright@4.0.10(msw@2.7.0(@types/node@25.0.3)(typescript@5.7.3))(playwright@1.56.1)(vite@7.1.10(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(tsx@4.19.2)(yaml@2.8.1))(vitest@4.0.10)':
dependencies:
- '@vitest/browser': 4.0.10(msw@2.7.0(@types/node@25.0.1)(typescript@5.7.3))(vite@7.1.10(@types/node@25.0.1)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(tsx@4.19.2)(yaml@2.8.1))(vitest@4.0.10)
- '@vitest/mocker': 4.0.10(msw@2.7.0(@types/node@25.0.1)(typescript@5.7.3))(vite@7.1.10(@types/node@25.0.1)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(tsx@4.19.2)(yaml@2.8.1))
+ '@vitest/browser': 4.0.10(msw@2.7.0(@types/node@25.0.3)(typescript@5.7.3))(vite@7.1.10(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(tsx@4.19.2)(yaml@2.8.1))(vitest@4.0.10)
+ '@vitest/mocker': 4.0.10(msw@2.7.0(@types/node@25.0.3)(typescript@5.7.3))(vite@7.1.10(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(tsx@4.19.2)(yaml@2.8.1))
playwright: 1.56.1
tinyrainbow: 3.0.3
- vitest: 4.0.10(@types/debug@4.1.12)(@types/node@25.0.1)(@vitest/browser-playwright@4.0.10)(@vitest/ui@4.0.10)(jiti@2.6.1)(jsdom@25.0.1)(lightningcss@1.30.2)(msw@2.7.0(@types/node@25.0.1)(typescript@5.7.3))(terser@5.44.0)(tsx@4.19.2)(yaml@2.8.1)
+ vitest: 4.0.10(@types/debug@4.1.12)(@types/node@25.0.3)(@vitest/browser-playwright@4.0.10)(@vitest/ui@4.0.10)(jiti@2.6.1)(jsdom@25.0.1)(lightningcss@1.30.2)(msw@2.7.0(@types/node@25.0.3)(typescript@5.7.3))(terser@5.44.0)(tsx@4.19.2)(yaml@2.8.1)
transitivePeerDependencies:
- bufferutil
- msw
- utf-8-validate
- vite
- '@vitest/browser@4.0.10(msw@2.7.0(@types/node@25.0.1)(typescript@5.7.3))(vite@7.1.10(@types/node@25.0.1)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(tsx@4.19.2)(yaml@2.8.1))(vitest@4.0.10)':
+ '@vitest/browser@4.0.10(msw@2.7.0(@types/node@25.0.3)(typescript@5.7.3))(vite@7.1.10(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(tsx@4.19.2)(yaml@2.8.1))(vitest@4.0.10)':
dependencies:
- '@vitest/mocker': 4.0.10(msw@2.7.0(@types/node@25.0.1)(typescript@5.7.3))(vite@7.1.10(@types/node@25.0.1)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(tsx@4.19.2)(yaml@2.8.1))
+ '@vitest/mocker': 4.0.10(msw@2.7.0(@types/node@25.0.3)(typescript@5.7.3))(vite@7.1.10(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(tsx@4.19.2)(yaml@2.8.1))
'@vitest/utils': 4.0.10
magic-string: 0.30.21
pixelmatch: 7.1.0
pngjs: 7.0.0
sirv: 3.0.2
tinyrainbow: 3.0.3
- vitest: 4.0.10(@types/debug@4.1.12)(@types/node@25.0.1)(@vitest/browser-playwright@4.0.10)(@vitest/ui@4.0.10)(jiti@2.6.1)(jsdom@25.0.1)(lightningcss@1.30.2)(msw@2.7.0(@types/node@25.0.1)(typescript@5.7.3))(terser@5.44.0)(tsx@4.19.2)(yaml@2.8.1)
+ vitest: 4.0.10(@types/debug@4.1.12)(@types/node@25.0.3)(@vitest/browser-playwright@4.0.10)(@vitest/ui@4.0.10)(jiti@2.6.1)(jsdom@25.0.1)(lightningcss@1.30.2)(msw@2.7.0(@types/node@25.0.3)(typescript@5.7.3))(terser@5.44.0)(tsx@4.19.2)(yaml@2.8.1)
ws: 8.18.3
transitivePeerDependencies:
- bufferutil
@@ -7828,14 +7820,14 @@ snapshots:
chai: 6.2.1
tinyrainbow: 3.0.3
- '@vitest/mocker@4.0.10(msw@2.7.0(@types/node@25.0.1)(typescript@5.7.3))(vite@7.1.10(@types/node@25.0.1)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(tsx@4.19.2)(yaml@2.8.1))':
+ '@vitest/mocker@4.0.10(msw@2.7.0(@types/node@25.0.3)(typescript@5.7.3))(vite@7.1.10(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(tsx@4.19.2)(yaml@2.8.1))':
dependencies:
'@vitest/spy': 4.0.10
estree-walker: 3.0.3
magic-string: 0.30.21
optionalDependencies:
- msw: 2.7.0(@types/node@25.0.1)(typescript@5.7.3)
- vite: 7.1.10(@types/node@25.0.1)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(tsx@4.19.2)(yaml@2.8.1)
+ msw: 2.7.0(@types/node@25.0.3)(typescript@5.7.3)
+ vite: 7.1.10(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(tsx@4.19.2)(yaml@2.8.1)
'@vitest/pretty-format@4.0.10':
dependencies:
@@ -7863,7 +7855,7 @@ snapshots:
sirv: 3.0.2
tinyglobby: 0.2.15
tinyrainbow: 3.0.3
- vitest: 4.0.10(@types/debug@4.1.12)(@types/node@25.0.1)(@vitest/browser-playwright@4.0.10)(@vitest/ui@4.0.10)(jiti@2.6.1)(jsdom@25.0.1)(lightningcss@1.30.2)(msw@2.7.0(@types/node@25.0.1)(typescript@5.7.3))(terser@5.44.0)(tsx@4.19.2)(yaml@2.8.1)
+ vitest: 4.0.10(@types/debug@4.1.12)(@types/node@25.0.3)(@vitest/browser-playwright@4.0.10)(@vitest/ui@4.0.10)(jiti@2.6.1)(jsdom@25.0.1)(lightningcss@1.30.2)(msw@2.7.0(@types/node@25.0.3)(typescript@5.7.3))(terser@5.44.0)(tsx@4.19.2)(yaml@2.8.1)
'@vitest/utils@4.0.10':
dependencies:
@@ -9589,12 +9581,12 @@ snapshots:
ms@2.1.3: {}
- msw@2.7.0(@types/node@25.0.1)(typescript@5.7.3):
+ msw@2.7.0(@types/node@25.0.3)(typescript@5.7.3):
dependencies:
'@bundled-es-modules/cookie': 2.0.1
'@bundled-es-modules/statuses': 1.0.1
'@bundled-es-modules/tough-cookie': 0.1.6
- '@inquirer/confirm': 5.1.21(@types/node@25.0.1)
+ '@inquirer/confirm': 5.1.21(@types/node@25.0.3)
'@mswjs/interceptors': 0.37.6
'@open-draft/deferred-promise': 2.2.0
'@open-draft/until': 2.1.0
@@ -9642,7 +9634,7 @@ snapshots:
nf3@0.1.12: {}
- nitro@3.0.1-alpha.0(@netlify/blobs@10.4.1)(better-sqlite3@11.8.1)(chokidar@4.0.3)(drizzle-orm@0.31.4(@opentelemetry/api@1.9.0)(@prisma/client@5.22.0(prisma@5.22.0))(@types/better-sqlite3@7.6.12)(better-sqlite3@11.8.1)(prisma@5.22.0))(ioredis@5.6.1)(vite@7.1.10(@types/node@25.0.1)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(tsx@4.19.2)(yaml@2.8.1)):
+ nitro@3.0.1-alpha.0(@netlify/blobs@10.4.1)(better-sqlite3@11.8.1)(chokidar@4.0.3)(drizzle-orm@0.31.4(@opentelemetry/api@1.9.0)(@prisma/client@5.22.0(prisma@5.22.0))(@types/better-sqlite3@7.6.12)(better-sqlite3@11.8.1)(prisma@5.22.0))(ioredis@5.6.1)(vite@7.1.10(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(tsx@4.19.2)(yaml@2.8.1)):
dependencies:
consola: 3.4.2
cookie-es: 2.0.0
@@ -9662,7 +9654,7 @@ snapshots:
unenv: 2.0.0-rc.21
unstorage: 2.0.0-alpha.3(@netlify/blobs@10.4.1)(chokidar@4.0.3)(db0@0.3.4(better-sqlite3@11.8.1)(drizzle-orm@0.31.4(@opentelemetry/api@1.9.0)(@prisma/client@5.22.0(prisma@5.22.0))(@types/better-sqlite3@7.6.12)(better-sqlite3@11.8.1)(prisma@5.22.0)))(ioredis@5.6.1)(ofetch@1.4.1)
optionalDependencies:
- vite: 7.1.10(@types/node@25.0.1)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(tsx@4.19.2)(yaml@2.8.1)
+ vite: 7.1.10(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(tsx@4.19.2)(yaml@2.8.1)
transitivePeerDependencies:
- '@azure/app-configuration'
- '@azure/cosmos'
@@ -9692,7 +9684,7 @@ snapshots:
- sqlite3
- uploadthing
- nitro@3.0.1-alpha.1(@netlify/blobs@10.4.1)(better-sqlite3@11.8.1)(chokidar@4.0.3)(drizzle-orm@0.31.4(@opentelemetry/api@1.9.0)(@prisma/client@5.22.0(prisma@5.22.0))(@types/better-sqlite3@7.6.12)(better-sqlite3@11.8.1)(prisma@5.22.0))(ioredis@5.6.1)(rollup@4.52.5)(vite@7.1.10(@types/node@25.0.1)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(tsx@4.19.2)(yaml@2.8.1)):
+ nitro@3.0.1-alpha.1(@netlify/blobs@10.4.1)(better-sqlite3@11.8.1)(chokidar@4.0.3)(drizzle-orm@0.31.4(@opentelemetry/api@1.9.0)(@prisma/client@5.22.0(prisma@5.22.0))(@types/better-sqlite3@7.6.12)(better-sqlite3@11.8.1)(prisma@5.22.0))(ioredis@5.6.1)(rollup@4.52.5)(vite@7.1.10(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(tsx@4.19.2)(yaml@2.8.1)):
dependencies:
consola: 3.4.2
crossws: 0.4.1(srvx@0.9.6)
@@ -9710,7 +9702,7 @@ snapshots:
unstorage: 2.0.0-alpha.4(@netlify/blobs@10.4.1)(chokidar@4.0.3)(db0@0.3.4(better-sqlite3@11.8.1)(drizzle-orm@0.31.4(@opentelemetry/api@1.9.0)(@prisma/client@5.22.0(prisma@5.22.0))(@types/better-sqlite3@7.6.12)(better-sqlite3@11.8.1)(prisma@5.22.0)))(ioredis@5.6.1)(ofetch@2.0.0-alpha.3)
optionalDependencies:
rollup: 4.52.5
- vite: 7.1.10(@types/node@25.0.1)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(tsx@4.19.2)(yaml@2.8.1)
+ vite: 7.1.10(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(tsx@4.19.2)(yaml@2.8.1)
transitivePeerDependencies:
- '@azure/app-configuration'
- '@azure/cosmos'
@@ -10518,13 +10510,13 @@ snapshots:
dependencies:
seroval: 1.3.2
- seroval-plugins@1.4.0(seroval@1.4.1):
+ seroval-plugins@1.4.0(seroval@1.5.0):
dependencies:
- seroval: 1.4.1
+ seroval: 1.5.0
seroval@1.3.2: {}
- seroval@1.4.1: {}
+ seroval@1.5.0: {}
serve-placeholder@2.0.2:
dependencies:
@@ -11205,7 +11197,7 @@ snapshots:
'@types/unist': 3.0.3
vfile-message: 4.0.2
- vite-plugin-solid@2.11.9(patch_hash=71233f1afab9e3ea2dbb03dbda3d84894ef1c6bfbbe69df9f864d03bfe67b6f5)(@testing-library/jest-dom@6.6.2)(solid-js@1.9.9)(vite@7.1.10(@types/node@25.0.1)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(tsx@4.19.2)(yaml@2.8.1)):
+ vite-plugin-solid@2.11.9(patch_hash=71233f1afab9e3ea2dbb03dbda3d84894ef1c6bfbbe69df9f864d03bfe67b6f5)(@testing-library/jest-dom@6.6.2)(solid-js@1.9.9)(vite@7.1.10(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(tsx@4.19.2)(yaml@2.8.1)):
dependencies:
'@babel/core': 7.28.3
'@types/babel__core': 7.20.5
@@ -11213,14 +11205,14 @@ snapshots:
merge-anything: 5.1.7
solid-js: 1.9.9
solid-refresh: 0.6.3(solid-js@1.9.9)
- vite: 7.1.10(@types/node@25.0.1)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(tsx@4.19.2)(yaml@2.8.1)
- vitefu: 1.1.1(vite@7.1.10(@types/node@25.0.1)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(tsx@4.19.2)(yaml@2.8.1))
+ vite: 7.1.10(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(tsx@4.19.2)(yaml@2.8.1)
+ vitefu: 1.1.1(vite@7.1.10(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(tsx@4.19.2)(yaml@2.8.1))
optionalDependencies:
'@testing-library/jest-dom': 6.6.2
transitivePeerDependencies:
- supports-color
- vite@7.1.10(@types/node@25.0.1)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(tsx@4.19.2)(yaml@2.8.1):
+ vite@7.1.10(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(tsx@4.19.2)(yaml@2.8.1):
dependencies:
esbuild: 0.25.11
fdir: 6.5.0(picomatch@4.0.3)
@@ -11229,7 +11221,7 @@ snapshots:
rollup: 4.52.5
tinyglobby: 0.2.15
optionalDependencies:
- '@types/node': 25.0.1
+ '@types/node': 25.0.3
fsevents: 2.3.3
jiti: 2.6.1
lightningcss: 1.30.2
@@ -11237,14 +11229,14 @@ snapshots:
tsx: 4.19.2
yaml: 2.8.1
- vitefu@1.1.1(vite@7.1.10(@types/node@25.0.1)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(tsx@4.19.2)(yaml@2.8.1)):
+ vitefu@1.1.1(vite@7.1.10(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(tsx@4.19.2)(yaml@2.8.1)):
optionalDependencies:
- vite: 7.1.10(@types/node@25.0.1)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(tsx@4.19.2)(yaml@2.8.1)
+ vite: 7.1.10(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(tsx@4.19.2)(yaml@2.8.1)
- vitest@4.0.10(@types/debug@4.1.12)(@types/node@25.0.1)(@vitest/browser-playwright@4.0.10)(@vitest/ui@4.0.10)(jiti@2.6.1)(jsdom@25.0.1)(lightningcss@1.30.2)(msw@2.7.0(@types/node@25.0.1)(typescript@5.7.3))(terser@5.44.0)(tsx@4.19.2)(yaml@2.8.1):
+ vitest@4.0.10(@types/debug@4.1.12)(@types/node@25.0.3)(@vitest/browser-playwright@4.0.10)(@vitest/ui@4.0.10)(jiti@2.6.1)(jsdom@25.0.1)(lightningcss@1.30.2)(msw@2.7.0(@types/node@25.0.3)(typescript@5.7.3))(terser@5.44.0)(tsx@4.19.2)(yaml@2.8.1):
dependencies:
'@vitest/expect': 4.0.10
- '@vitest/mocker': 4.0.10(msw@2.7.0(@types/node@25.0.1)(typescript@5.7.3))(vite@7.1.10(@types/node@25.0.1)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(tsx@4.19.2)(yaml@2.8.1))
+ '@vitest/mocker': 4.0.10(msw@2.7.0(@types/node@25.0.3)(typescript@5.7.3))(vite@7.1.10(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(tsx@4.19.2)(yaml@2.8.1))
'@vitest/pretty-format': 4.0.10
'@vitest/runner': 4.0.10
'@vitest/snapshot': 4.0.10
@@ -11261,12 +11253,12 @@ snapshots:
tinyexec: 0.3.2
tinyglobby: 0.2.15
tinyrainbow: 3.0.3
- vite: 7.1.10(@types/node@25.0.1)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(tsx@4.19.2)(yaml@2.8.1)
+ vite: 7.1.10(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(tsx@4.19.2)(yaml@2.8.1)
why-is-node-running: 2.3.0
optionalDependencies:
'@types/debug': 4.1.12
- '@types/node': 25.0.1
- '@vitest/browser-playwright': 4.0.10(msw@2.7.0(@types/node@25.0.1)(typescript@5.7.3))(playwright@1.56.1)(vite@7.1.10(@types/node@25.0.1)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(tsx@4.19.2)(yaml@2.8.1))(vitest@4.0.10)
+ '@types/node': 25.0.3
+ '@vitest/browser-playwright': 4.0.10(msw@2.7.0(@types/node@25.0.3)(typescript@5.7.3))(playwright@1.56.1)(vite@7.1.10(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(tsx@4.19.2)(yaml@2.8.1))(vitest@4.0.10)
'@vitest/ui': 4.0.10(vitest@4.0.10)
jsdom: 25.0.1
transitivePeerDependencies: