diff --git a/apps/tests/cypress/e2e/server-function.cy.ts b/apps/tests/cypress/e2e/server-function.cy.ts index 0bafe5c88..d4aef64c3 100644 --- a/apps/tests/cypress/e2e/server-function.cy.ts +++ b/apps/tests/cypress/e2e/server-function.cy.ts @@ -52,4 +52,8 @@ describe("server-function", () => { cy.visit("/generator-server-function"); cy.get("#server-fn-test").contains('¡Hola, Mundo!'); }); + it("should remove non-function exports in a module-level use server file", () => { + cy.visit("/server-function-query-toplevel"); + cy.get("#server-fn-test").contains("false"); + }); }); diff --git a/apps/tests/src/functions/solid-router-query.ts b/apps/tests/src/functions/solid-router-query.ts new file mode 100644 index 000000000..5008b0c84 --- /dev/null +++ b/apps/tests/src/functions/solid-router-query.ts @@ -0,0 +1,6 @@ +"use server"; + +import { query } from "@solidjs/router"; +import { isServer } from "solid-js/web"; + +export const testQuery = query(() => isServer, "testQuery"); diff --git a/apps/tests/src/routes/server-function-query-toplevel.tsx b/apps/tests/src/routes/server-function-query-toplevel.tsx new file mode 100644 index 000000000..21383adb3 --- /dev/null +++ b/apps/tests/src/routes/server-function-query-toplevel.tsx @@ -0,0 +1,16 @@ +import { createEffect, createSignal } from "solid-js"; +import * as testModule from "~/functions/solid-router-query"; + +export default function App() { + const [output, setOutput] = createSignal(); + + createEffect(() => { + setOutput("testQuery" in testModule); + }); + + return ( +
+ {JSON.stringify(output())} +
+ ); +} diff --git a/packages/start/config/index.js b/packages/start/config/index.js index afc40039e..8480dcc7a 100644 --- a/packages/start/config/index.js +++ b/packages/start/config/index.js @@ -1,4 +1,3 @@ -import { createTanStackServerFnPlugin } from "@tanstack/server-functions-plugin"; import defu from "defu"; import { existsSync } from "node:fs"; import { join } from "node:path"; @@ -7,6 +6,7 @@ import { createApp, resolve } from "vinxi"; import { normalize } from "vinxi/lib/path"; import { config } from "vinxi/plugins/config"; import solid from "vite-plugin-solid"; +import { serverFunctionsPlugin } from "../dist/directives/index.js"; import { SolidStartClientFileRouter, SolidStartServerFileRouter } from "./fs-router.js"; import { serverComponents } from "./server-components.js"; @@ -37,36 +37,6 @@ function solidStartServerFsRouter(config) { ); } -const SolidStartServerFnsPlugin = createTanStackServerFnPlugin({ - // This is the ID that will be available to look up and import - // our server function manifest and resolve its module - manifestVirtualImportId: "solidstart:server-fn-manifest", - client: { - getRuntimeCode: () => - `import { createServerReference } from "${normalize( - fileURLToPath(new URL("../dist/runtime/server-runtime.js", import.meta.url)) - )}"`, - replacer: opts => - `createServerReference(${() => {}}, '${opts.functionId}', '${opts.extractedFilename}')` - }, - ssr: { - getRuntimeCode: () => - `import { createServerReference } from '${normalize( - fileURLToPath(new URL("../dist/runtime/server-fns-runtime.js", import.meta.url)) - )}'`, - replacer: opts => - `createServerReference(${opts.fn}, '${opts.functionId}', '${opts.extractedFilename}')` - }, - server: { - getRuntimeCode: () => - `import { createServerReference } from '${normalize( - fileURLToPath(new URL("../dist/runtime/server-fns-runtime.js", import.meta.url)) - )}'`, - replacer: opts => - `createServerReference(${opts.fn}, '${opts.functionId}', '${opts.extractedFilename}')` - } -}); - export function defineConfig(baseConfig = {}) { let { vite = {}, ...start } = baseConfig; const extensions = [...DEFAULT_EXTENSIONS, ...(start.extensions || [])]; @@ -145,7 +115,9 @@ export function defineConfig(baseConfig = {}) { } }), ...plugins, - SolidStartServerFnsPlugin.ssr, + ...serverFunctionsPlugin({ + manifest: "solidstart:server-fn-manifest" + }), start.experimental.islands ? serverComponents.server() : null, solid({ ...start.solid, ssr: true, extensions: extensions.map(ext => `.${ext}`) }), config("app-server", { @@ -207,7 +179,9 @@ export function defineConfig(baseConfig = {}) { } }), ...plugins, - SolidStartServerFnsPlugin.client, + ...serverFunctionsPlugin({ + manifest: "solidstart:server-fn-manifest" + }), start.experimental.islands ? serverComponents.client() : null, solid({ ...start.solid, ssr: start.ssr, extensions: extensions.map(ext => `.${ext}`) }), config("app-client", { @@ -274,7 +248,9 @@ export function defineConfig(baseConfig = {}) { cacheDir: "node_modules/.vinxi/server-fns" }), ...plugins, - SolidStartServerFnsPlugin.server, + ...serverFunctionsPlugin({ + manifest: "solidstart:server-fn-manifest" + }), start.experimental.islands ? serverComponents.server() : null, solid({ ...start.solid, ssr: true, extensions: extensions.map(ext => `.${ext}`) }), config("app-server", { diff --git a/packages/start/package.json b/packages/start/package.json index 04f8a478d..0b7d42e02 100644 --- a/packages/start/package.json +++ b/packages/start/package.json @@ -61,12 +61,17 @@ } }, "devDependencies": { + "@types/babel__core": "^7.20.5", + "@types/babel__traverse": "^7.28.0", "solid-js": "^1.9.11", + "vite": "^6.3.6", "vinxi": "^0.5.7", "vitest": "3.0.5" }, "dependencies": { - "@tanstack/server-functions-plugin": "1.121.21", + "@babel/core": "^7.28.3", + "@babel/traverse": "^7.28.3", + "@babel/types": "^7.28.5", "@vinxi/plugin-directives": "^0.5.0", "@vinxi/server-components": "^0.5.0", "cookie-es": "^2.0.0", diff --git a/packages/start/src/directives/bubble-function-declaration.ts b/packages/start/src/directives/bubble-function-declaration.ts new file mode 100644 index 000000000..147f1dc10 --- /dev/null +++ b/packages/start/src/directives/bubble-function-declaration.ts @@ -0,0 +1,30 @@ +import type * as babel from "@babel/core"; +import * as t from "@babel/types"; + +export function bubbleFunctionDeclaration(path: babel.NodePath): void { + const decl = path.node; + if (decl.id) { + const block = (path.findParent(current => current.isBlockStatement()) || + path.scope.getProgramParent().path) as babel.NodePath; + + const [tmp] = block.unshiftContainer( + "body", + t.variableDeclaration("const", [ + t.variableDeclarator( + decl.id, + t.functionExpression(decl.id, decl.params, decl.body, decl.generator, decl.async), + ), + ]), + ); + path.scope.registerDeclaration(tmp); + if (path.parentPath.isExportNamedDeclaration()) { + path.parentPath.replaceWith( + t.exportNamedDeclaration(undefined, [t.exportSpecifier(decl.id, decl.id)]), + ); + } else if (path.parentPath.isExportDefaultDeclaration()) { + path.replaceWith(decl.id); + } else { + path.remove(); + } + } +} diff --git a/packages/start/src/directives/compile.ts b/packages/start/src/directives/compile.ts new file mode 100644 index 000000000..f8b3aa020 --- /dev/null +++ b/packages/start/src/directives/compile.ts @@ -0,0 +1,55 @@ +import * as babel from "@babel/core"; +import path from "node:path"; +import { directivesPlugin, type StateContext } from "./plugin.js"; +import xxHash32 from "./xxhash32.js"; + +export interface CompileResult { + valid: boolean; + code: string; + map: babel.BabelFileResult["map"]; +} + +export type CompileOptions = Omit; + +export async function compile( + id: string, + code: string, + options: CompileOptions, +): Promise { + const context: StateContext = { + ...options, + file: id, + valid: false, + hash: xxHash32(id).toString(16), + count: 0, + imports: new Map(), + }; + const pluginOption = [directivesPlugin, context]; + const plugins: NonNullable["plugins"]> = [ + "jsx", + ]; + if (/\.[mc]?tsx?$/i.test(id)) { + plugins.push("typescript"); + } + const result = await babel.transformAsync(code, { + plugins: [pluginOption], + parserOpts: { + plugins, + }, + filename: path.basename(id), + ast: false, + sourceMaps: true, + configFile: false, + babelrc: false, + sourceFileName: id, + }); + + if (result) { + return { + valid: context.valid, + code: result.code || "", + map: result.map, + }; + } + throw new Error("invariant"); +} diff --git a/packages/start/src/directives/generate-unique-name.ts b/packages/start/src/directives/generate-unique-name.ts new file mode 100644 index 000000000..2a85039c2 --- /dev/null +++ b/packages/start/src/directives/generate-unique-name.ts @@ -0,0 +1,22 @@ +import type * as babel from "@babel/core"; +import * as t from "@babel/types"; + +export function generateUniqueName(path: babel.NodePath, name: string): t.Identifier { + let uid: string; + let i = 1; + do { + uid = name + "_" + i; + i++; + } while ( + path.scope.hasLabel(uid) || + path.scope.hasBinding(uid) || + path.scope.hasGlobal(uid) || + path.scope.hasReference(uid) + ); + + const program = path.scope.getProgramParent(); + program.references[uid] = true; + program.uids[uid] = true; + + return t.identifier(uid); +} diff --git a/packages/start/src/directives/get-descriptive-name.ts b/packages/start/src/directives/get-descriptive-name.ts new file mode 100644 index 000000000..9a856a998 --- /dev/null +++ b/packages/start/src/directives/get-descriptive-name.ts @@ -0,0 +1,39 @@ +import type { NodePath } from "@babel/core"; + +export function getDescriptiveName(path: NodePath, defaultName: string): string { + let current: NodePath | null = path; + while (current) { + switch (current.node.type) { + case "FunctionDeclaration": + case "FunctionExpression": { + if (current.node.id) { + return current.node.id.name; + } + break; + } + case "VariableDeclarator": { + if (current.node.id.type === "Identifier") { + return current.node.id.name; + } + break; + } + case "ClassPrivateMethod": + case "ClassMethod": + case "ObjectMethod": { + switch (current.node.key.type) { + case "Identifier": + return current.node.key.name; + case "PrivateName": + return current.node.key.id.name; + default: + break; + } + break; + } + default: + break; + } + current = current.parentPath; + } + return defaultName; +} diff --git a/packages/start/src/directives/get-import-identifier.ts b/packages/start/src/directives/get-import-identifier.ts new file mode 100644 index 000000000..7eadbdb94 --- /dev/null +++ b/packages/start/src/directives/get-import-identifier.ts @@ -0,0 +1,34 @@ +import type * as babel from "@babel/core"; +import * as t from "@babel/types"; +import { generateUniqueName } from "./generate-unique-name.js"; +import type { ImportDefinition } from "./types.js"; + +export function getImportIdentifier( + imports: Map, + path: babel.NodePath, + registration: ImportDefinition, +): t.Identifier { + const name = registration.kind === "named" ? registration.name : "default"; + const target = `${registration.source}[${name}]`; + const current = imports.get(target); + if (current) { + return current; + } + const programParent = path.scope.getProgramParent(); + const uid = generateUniqueName(programParent.path, name); + programParent.registerDeclaration( + (programParent.path as babel.NodePath).unshiftContainer( + "body", + t.importDeclaration( + [ + registration.kind === "named" + ? t.importSpecifier(uid, t.identifier(registration.name)) + : t.importDefaultSpecifier(uid), + ], + t.stringLiteral(registration.source), + ), + )[0], + ); + imports.set(target, uid); + return uid; +} diff --git a/packages/start/src/directives/get-root-statement-path.ts b/packages/start/src/directives/get-root-statement-path.ts new file mode 100644 index 000000000..347e92387 --- /dev/null +++ b/packages/start/src/directives/get-root-statement-path.ts @@ -0,0 +1,14 @@ +import type * as babel from "@babel/core"; +import * as t from "@babel/types"; + +export function getRootStatementPath(path: babel.NodePath): babel.NodePath { + let current = path.parentPath; + while (current) { + const next = current.parentPath; + if (next && t.isProgram(next.node)) { + return current; + } + current = next; + } + return path; +} diff --git a/packages/start/src/directives/index.ts b/packages/start/src/directives/index.ts new file mode 100644 index 000000000..b6073bbca --- /dev/null +++ b/packages/start/src/directives/index.ts @@ -0,0 +1,232 @@ +import { fileURLToPath } from "node:url"; +import { + createFilter, + normalizePath, + type EnvironmentModuleGraph, + type FilterPattern, + type Plugin, + type ViteDevServer, +} from "vite"; +import { compile, type CompileOptions } from "./compile.js"; + +export interface ServerFunctionsFilter { + include?: FilterPattern; + exclude?: FilterPattern; +} + +export interface ServerFunctionsOptions { + manifest: string; + filter?: ServerFunctionsFilter; +} + +const CLIENT_PATH = normalizePath( + fileURLToPath(new URL("../runtime/server-runtime.js", import.meta.url)), +); +const SERVER_PATH = normalizePath( + fileURLToPath(new URL("../runtime/server-fns-runtime.js", import.meta.url)), +); + +const DEFAULT_INCLUDE = "src/**/*.{jsx,tsx,ts,js,mjs,cjs}"; +const DEFAULT_EXCLUDE = "node_modules/**/*.{jsx,tsx,ts,js,mjs,cjs}"; +const DIRECTIVE = "use server"; + +const CLIENT_OPTIONS: Pick = { + directive: DIRECTIVE, + definitions: { + register: { + kind: "named", + name: "createServerReference", + source: CLIENT_PATH, + }, + clone: { + kind: "named", + name: "cloneServerReference", + source: CLIENT_PATH, + }, + }, +}; +const SERVER_OPTIONS: Pick = { + directive: DIRECTIVE, + definitions: { + register: { + kind: "named", + name: "createServerReference", + source: SERVER_PATH, + }, + clone: { + kind: "named", + name: "cloneServerReference", + source: SERVER_PATH, + }, + }, +}; + +type Manifest = Record>; + +function createManifest(): Manifest { + return { + server: new Set(), + client: new Set(), + }; +} + +interface DeferredPromise { + reference: Promise; + resolve: (value: T) => void; + reject: (value: any) => void; +} + +function createDeferredPromise(): DeferredPromise { + let resolve: DeferredPromise["resolve"]; + let reject: DeferredPromise["reject"]; + + return { + reference: new Promise((res, rej) => { + resolve = res; + reject = rej; + }), + resolve(value) { + resolve(value); + }, + reject(value) { + reject(value); + }, + }; +} + +class Debouncer { + promise: DeferredPromise; + + private timeout: ReturnType | undefined; + + constructor(private source: () => T) { + this.promise = createDeferredPromise(); + this.defer(); + } + + defer(): void { + if (this.timeout) { + clearTimeout(this.timeout); + this.timeout = undefined; + } + this.timeout = setTimeout(() => { + this.promise.resolve(this.source()); + }, 1000); + } +} + +function mergeManifestRecord( + source: Set, + target: Set, +): { invalidPreload: boolean; invalidated: string[] } { + const current = source.size; + for (const entry of target) { + source.add(entry); + } + return { + invalidPreload: current !== source.size, + invalidated: [...source], + }; +} + +function invalidateModule(moduleGraph: EnvironmentModuleGraph, path: string) { + const target = moduleGraph.getModuleById(path); + if (target) { + moduleGraph.invalidateModule(target); + } +} + +function invalidateModules( + server: ViteDevServer | undefined, + result: ReturnType, + manifest: string, +): void { + if (server && result.invalidPreload) { + for (const environment of Object.values(server.environments)) { + invalidateModule(environment.moduleGraph, manifest); + } + } +} + +export function serverFunctionsPlugin(options: ServerFunctionsOptions): Plugin[] { + const filter = createFilter( + options.filter?.include || DEFAULT_INCLUDE, + options.filter?.exclude || DEFAULT_EXCLUDE, + ); + + let env: CompileOptions["env"]; + const manifest = createManifest(); + const preload: Record | undefined> = { + server: undefined, + client: undefined, + }; + let currentServer: ViteDevServer | undefined; + + return [ + { + name: "solid-start:server-functions/setup", + enforce: "pre", + configResolved(config) { + env = config.mode !== "production" ? "development" : "production"; + }, + configureServer(server) { + currentServer = server; + }, + }, + { + name: "solid-start:server-functions/preload", + enforce: "pre", + resolveId(source) { + if (source === options.manifest) { + return { id: options.manifest, moduleSideEffects: true }; + } + return null; + }, + async load(id, opts) { + const mode = opts?.ssr ? "server" : "client"; + if (id === options.manifest) { + const current = new Debouncer(() => + [...manifest[mode]].map(entry => `import "${entry}";`).join("\n"), + ); + preload[mode] = current; + return await current.promise.reference; + } + return null; + }, + }, + { + name: "solid-start:server-functions/compiler", + async transform(code, fileId, opts) { + const mode = opts?.ssr ? "server" : "client"; + const [id] = fileId.split("?"); + if (!id || !filter(id)) { + return null; + } + + const result = await compile(id, code, { + ...(mode === "server" ? SERVER_OPTIONS : CLIENT_OPTIONS), + mode, + env, + }); + + if (result.valid) { + invalidateModules( + currentServer, + mergeManifestRecord(manifest.server, new Set([id])), + options.manifest, + ); + const preloader = preload[mode]; + if (preloader) { + preloader.defer(); + } + + return { + code: result.code || "", + map: result.map, + }; + } + return code; + }, + }, + ]; +} diff --git a/packages/start/src/directives/is-statement-top-level.ts b/packages/start/src/directives/is-statement-top-level.ts new file mode 100644 index 000000000..9b3587208 --- /dev/null +++ b/packages/start/src/directives/is-statement-top-level.ts @@ -0,0 +1,12 @@ +import type * as babel from "@babel/core"; +import type * as t from "@babel/types"; + +export function isStatementTopLevel(path: babel.NodePath): boolean { + let blockParent = path.scope.getBlockParent(); + const programParent = path.scope.getProgramParent(); + if (blockParent.path === path) { + blockParent = blockParent.parent; + } + + return programParent === blockParent; +} diff --git a/packages/start/src/directives/paths.ts b/packages/start/src/directives/paths.ts new file mode 100644 index 000000000..fbb55e7a5 --- /dev/null +++ b/packages/start/src/directives/paths.ts @@ -0,0 +1,65 @@ +import type * as babel from "@babel/core"; +import type * as t from "@babel/types"; + +type TypeFilter = (node: t.Node) => node is V; + +export function isPathValid( + path: unknown, + key: TypeFilter, +): path is babel.NodePath { + const node = (path as babel.NodePath).node; + return node ? key(node) : false; +} + +export type NestedExpression = + | t.ParenthesizedExpression + | t.TypeCastExpression + | t.TSAsExpression + | t.TSSatisfiesExpression + | t.TSNonNullExpression + | t.TSInstantiationExpression + | t.TSTypeAssertion; + +export function isNestedExpression(node: t.Node): node is NestedExpression { + switch (node.type) { + case "ParenthesizedExpression": + case "TypeCastExpression": + case "TSAsExpression": + case "TSSatisfiesExpression": + case "TSNonNullExpression": + case "TSTypeAssertion": + case "TSInstantiationExpression": + return true; + default: + return false; + } +} + +type TypeCheck = K extends TypeFilter ? U : never; + +export function unwrapNode boolean>( + node: t.Node, + key: K, +): TypeCheck | undefined { + if (key(node)) { + return node as TypeCheck; + } + if (isNestedExpression(node)) { + return unwrapNode(node.expression, key); + } + return undefined; +} + +export function unwrapPath( + path: unknown, + key: TypeFilter, +): babel.NodePath | undefined { + if (isPathValid(path, key)) { + return path; + } + if (isPathValid(path, isNestedExpression)) { + const nested = path as babel.NodePath; + return unwrapPath(nested.get("expression"), key); + } + return undefined; +} diff --git a/packages/start/src/directives/plugin.ts b/packages/start/src/directives/plugin.ts new file mode 100644 index 000000000..0a248aefa --- /dev/null +++ b/packages/start/src/directives/plugin.ts @@ -0,0 +1,371 @@ +import type * as babel from "@babel/core"; +import type { Binding } from "@babel/traverse"; +import * as t from "@babel/types"; +import { bubbleFunctionDeclaration } from "./bubble-function-declaration.js"; +import { generateUniqueName } from "./generate-unique-name.js"; +import { getDescriptiveName } from "./get-descriptive-name.js"; +import { getImportIdentifier } from "./get-import-identifier.js"; +import { getRootStatementPath } from "./get-root-statement-path.js"; +import { isStatementTopLevel } from "./is-statement-top-level.js"; +import { isPathValid, unwrapPath } from "./paths.js"; +import { removeUnusedVariables } from "./remove-unused-variables.js"; +import type { ImportDefinition } from "./types.js"; + +export interface StateContext { + file: string; + env: "production" | "development"; + mode: "server" | "client"; + directive: string; + hash: string; + count: number; + imports: Map; + valid: boolean; + definitions: { + register: ImportDefinition; + clone: ImportDefinition; + }; +} + +type ValidFunction = t.ArrowFunctionExpression | t.FunctionExpression; + +function isValidFunction(node: t.Node): node is ValidFunction { + return t.isArrowFunctionExpression(node) || t.isFunctionExpression(node); +} + +function isDirectiveValid(ctx: StateContext, directives: t.Directive[]) { + for (let i = 0, len = directives.length; i < len; i++) { + if (directives[i]!.value.value === ctx.directive) { + return true; + } + } + return false; +} + +function cleanDirectives(path: babel.NodePath, target: string): void { + const newDirectives: t.Directive[] = []; + for (let i = 0, len = path.node.directives.length; i < len; i++) { + const current = path.node.directives[i]!; + if (current.value.value !== target) { + newDirectives.push(current); + } + } + path.node.directives = newDirectives; +} + +function cleanFunctionDirectives( + ctx: StateContext, + path: babel.NodePath, +) { + const body = path.get("body"); + + if (isPathValid(body, t.isBlockStatement)) { + cleanDirectives(body, ctx.directive); + } +} + +function isFunctionDirectiveValid( + ctx: StateContext, + path: babel.NodePath, +) { + const body = path.get("body"); + + if (isPathValid(body, t.isBlockStatement)) { + return isDirectiveValid(ctx, body.node.directives); + } + + return false; +} + +function createID(ctx: StateContext, name: string) { + const base = `${ctx.hash}-${ctx.count++}`; + if (ctx.env === "development") { + return `${base}-${name}@${ctx.file}`; + } + return base; +} + +function transformFunction( + ctx: StateContext, + path: babel.NodePath, + direct: boolean, +) { + if (!direct) { + if (!isFunctionDirectiveValid(ctx, path)) { + return; + } + cleanFunctionDirectives(ctx, path); + } + const rootStatement = getRootStatementPath(path); + const fnID = createID(ctx, getDescriptiveName(path, "anonymous")); + + if (ctx.mode === "server") { + const sourceReference = t.callExpression( + getImportIdentifier(ctx.imports, path, ctx.definitions.register), + [t.stringLiteral(fnID), path.node], + ); + + const sourceID = generateUniqueName(path, "serverFn"); + + rootStatement.insertBefore( + t.variableDeclaration("const", [t.variableDeclarator(sourceID, sourceReference)]), + ); + + path.replaceWith( + t.callExpression(getImportIdentifier(ctx.imports, path, ctx.definitions.clone), [sourceID]), + ); + } else { + path.replaceWith( + t.callExpression(getImportIdentifier(ctx.imports, path, ctx.definitions.clone), [ + t.stringLiteral(fnID), + ]), + ); + } + + path.scope.crawl(); +} + +function traceBinding(path: babel.NodePath, name: string): Binding | undefined { + const current = path.scope.getBinding(name); + if (!current) { + return undefined; + } + switch (current.kind) { + case "const": + case "let": + case "var": { + if (isPathValid(current.path, t.isVariableDeclarator)) { + const left = unwrapPath(current.path.get("id"), t.isIdentifier); + if (left) { + const right = unwrapPath(current.path.get("init"), t.isIdentifier); + if (right) { + return traceBinding(path, right.node.name); + } + + const func = unwrapPath(current.path.get("init"), isValidFunction); + if (func) { + return current; + } + } + } + return undefined; + } + case "hoisted": + case "local": + case "module": + case "param": + case "unknown": + return undefined; + } +} + +function transformBindingForServer(ctx: StateContext, binding: Binding) { + if (isPathValid(binding.path, t.isVariableDeclarator)) { + const right = unwrapPath(binding.path.get("init"), isValidFunction); + if (right) { + transformFunction(ctx, right, true); + } + } +} + +interface State extends babel.PluginPass { + opts: StateContext; +} + +function transformModuleLevelDirective(ctx: StateContext, program: babel.NodePath) { + cleanDirectives(program, ctx.directive); + program.traverse({ + FunctionDeclaration(child) { + if (isStatementTopLevel(child)) { + bubbleFunctionDeclaration(child); + } + }, + }); + program.scope.crawl(); + if (ctx.mode === "server") { + const bindings = new Set(); + + program.traverse({ + ExportDefaultDeclaration(path) { + const id = unwrapPath(path.get("declaration"), t.isIdentifier); + if (id) { + const binding = traceBinding(path, id.node.name); + if (binding) { + bindings.add(binding); + } + } + }, + ExportNamedDeclaration(path) { + if (path.node.source || path.node.exportKind === "type") { + return; + } + for (const specifier of path.get("specifiers")) { + if (isPathValid(specifier, t.isExportSpecifier)) { + const binding = traceBinding(specifier, specifier.node.local.name); + + if (binding) { + bindings.add(binding); + } + } + } + const declarations = path.get("declaration"); + + if (isPathValid(declarations, t.isVariableDeclaration)) { + for (const declaration of declarations.get("declarations")) { + const left = unwrapPath(declaration.get("id"), t.isIdentifier); + if (left) { + const binding = traceBinding(left, left.node.name); + if (binding) { + bindings.add(binding); + } + } + } + } + }, + }); + + for (const binding of bindings) { + transformBindingForServer(ctx, binding); + } + } else { + const uniqueBindings = new Set(); + const exportedBindings = new Map(); + + program.traverse({ + ExportDefaultDeclaration(path) { + const id = unwrapPath(path.get("declaration"), t.isIdentifier); + if (id) { + const binding = traceBinding(path, id.node.name); + if (binding) { + uniqueBindings.add(binding); + exportedBindings.set("default", binding); + } + } + }, + ExportNamedDeclaration(path) { + if (path.node.source || path.node.exportKind === "type") { + return; + } + for (const specifier of path.get("specifiers")) { + if (isPathValid(specifier, t.isExportSpecifier)) { + const binding = traceBinding(specifier, specifier.node.local.name); + + if (binding) { + const key = t.isIdentifier(specifier.node.exported) + ? specifier.node.exported.name + : specifier.node.exported.value; + uniqueBindings.add(binding); + exportedBindings.set(key, binding); + } + } + } + + const declarations = path.get("declaration"); + + if (isPathValid(declarations, t.isVariableDeclaration)) { + for (const declaration of declarations.get("declarations")) { + const left = unwrapPath(declaration.get("id"), t.isIdentifier); + if (left) { + const binding = traceBinding(left, left.node.name); + if (binding) { + uniqueBindings.add(binding); + exportedBindings.set(left.node.name, binding); + } + } + } + } + }, + }); + + const sourceIDs = new Map(); + for (const binding of uniqueBindings) { + if (isPathValid(binding.path, t.isVariableDeclarator)) { + const init = unwrapPath(binding.path.get("init"), isValidFunction); + if (init) { + sourceIDs.set(binding, createID(ctx, getDescriptiveName(init, "anonymous"))); + } + } + } + + program.node.body = []; + + const declarations: t.VariableDeclarator[] = []; + const specifiers: t.ExportSpecifier[] = []; + + const declarationMap = new Map(); + + for (const [exported, binding] of exportedBindings) { + let currentIdentifier = declarationMap.get(binding); + if (!currentIdentifier) { + currentIdentifier = generateUniqueName(program, "fn"); + + const fnID = sourceIDs.get(binding); + + if (fnID) { + declarations.push( + t.variableDeclarator( + currentIdentifier, + t.callExpression(getImportIdentifier(ctx.imports, program, ctx.definitions.clone), [ + t.stringLiteral(fnID), + ]), + ), + ); + + declarationMap.set(binding, currentIdentifier); + } + } + + if (currentIdentifier) { + specifiers.push(t.exportSpecifier(currentIdentifier, t.stringLiteral(exported))); + } + } + + const body: t.Statement[] = []; + + if (declarations.length > 0) { + body.push(t.variableDeclaration("const", declarations)); + } + if (specifiers.length > 0) { + body.push(t.exportNamedDeclaration(null, specifiers, null)); + } + + program.pushContainer("body", body); + } +} + +export function directivesPlugin(): babel.PluginObj { + return { + name: "solid-start:directives", + visitor: { + Program(program, ctx) { + const isModuleLevel = isDirectiveValid(ctx.opts, program.node.directives); + if (isModuleLevel) { + transformModuleLevelDirective(ctx.opts, program); + ctx.opts.valid = true; + } else { + program.traverse({ + FunctionDeclaration(child) { + if (isFunctionDirectiveValid(ctx.opts, child)) { + bubbleFunctionDeclaration(child); + } + }, + }); + program.scope.crawl(); + program.traverse({ + ArrowFunctionExpression(path) { + transformFunction(ctx.opts, path, false); + }, + FunctionExpression(path) { + transformFunction(ctx.opts, path, false); + }, + }); + program.scope.crawl(); + + if (ctx.opts.count > 0) { + ctx.opts.valid = true; + removeUnusedVariables(program); + } + } + }, + }, + }; +} diff --git a/packages/start/src/directives/remove-unused-variables.ts b/packages/start/src/directives/remove-unused-variables.ts new file mode 100644 index 000000000..3aeff4d35 --- /dev/null +++ b/packages/start/src/directives/remove-unused-variables.ts @@ -0,0 +1,50 @@ +import type * as babel from "@babel/core"; +import * as t from "@babel/types"; +import { isPathValid } from "./paths.js"; + +export function removeUnusedVariables(program: babel.NodePath) { + let dirty = true; + + while (dirty) { + dirty = false; + program.traverse({ + BindingIdentifier(path) { + const binding = path.scope.getBinding(path.node.name); + + if (binding) { + switch (binding.kind) { + case "const": + case "let": + case "var": + case "hoisted": + case "module": + if (binding.references === 0 && !binding.path.removed) { + if (isPathValid(binding.path.parentPath, t.isImportDeclaration)) { + const parent = binding.path.parentPath; + if (parent.node.specifiers.length === 1) { + parent.remove(); + } else { + binding.path.remove(); + } + } else { + binding.path.remove(); + } + dirty = true; + } + break; + case "local": + case "param": + case "unknown": + break; + } + } + }, + VariableDeclaration(path) { + if (path.node.declarations.length === 0) { + path.remove(); + } + }, + }); + program.scope.crawl(); + } +} diff --git a/packages/start/src/directives/types.ts b/packages/start/src/directives/types.ts new file mode 100644 index 000000000..4cf5bbc78 --- /dev/null +++ b/packages/start/src/directives/types.ts @@ -0,0 +1,12 @@ +export interface NamedImportDefinition { + kind: "named"; + name: string; + source: string; +} + +export interface DefaultImportDefinition { + kind: "default"; + source: string; +} + +export type ImportDefinition = DefaultImportDefinition | NamedImportDefinition; diff --git a/packages/start/src/directives/xxhash32.ts b/packages/start/src/directives/xxhash32.ts new file mode 100644 index 000000000..aa19c621d --- /dev/null +++ b/packages/start/src/directives/xxhash32.ts @@ -0,0 +1,101 @@ +// @ts-nocheck +const PRIME32_1 = 2654435761; +const PRIME32_2 = 2246822519; +const PRIME32_3 = 3266489917; +const PRIME32_4 = 668265263; +const PRIME32_5 = 374761393; + +function toUtf8(text: string): Uint8Array { + const bytes: number[] = []; + for (let i = 0, n = text.length; i < n; ++i) { + const c = text.charCodeAt(i); + if (c < 0x80) { + bytes.push(c); + } else if (c < 0x800) { + bytes.push(0xc0 | (c >> 6), 0x80 | (c & 0x3f)); + } else if (c < 0xd800 || c >= 0xe000) { + bytes.push(0xe0 | (c >> 12), 0x80 | ((c >> 6) & 0x3f), 0x80 | (c & 0x3f)); + } else { + const cp = 0x10000 + (((c & 0x3ff) << 10) | (text.charCodeAt(++i) & 0x3ff)); + bytes.push( + 0xf0 | ((cp >> 18) & 0x7), + 0x80 | ((cp >> 12) & 0x3f), + 0x80 | ((cp >> 6) & 0x3f), + 0x80 | (cp & 0x3f), + ); + } + } + return new Uint8Array(bytes); +} + +export default function xxHash32(buffer: Uint8Array | string, seed = 0): number { + buffer = typeof buffer === "string" ? toUtf8(buffer) : buffer; + const b = buffer; + + let acc = (seed + PRIME32_5) & 0xffffffff; + let offset = 0; + + if (b.length >= 16) { + const accN = [ + (seed + PRIME32_1 + PRIME32_2) & 0xffffffff, + (seed + PRIME32_2) & 0xffffffff, + (seed + 0) & 0xffffffff, + (seed - PRIME32_1) & 0xffffffff, + ]; + + const b = buffer; + const limit = b.length - 16; + let lane = 0; + for (offset = 0; (offset & 0xfffffff0) <= limit; offset += 4) { + const i = offset; + const laneN0 = b[i + 0] + (b[i + 1] << 8); + const laneN1 = b[i + 2] + (b[i + 3] << 8); + const laneNP = laneN0 * PRIME32_2 + ((laneN1 * PRIME32_2) << 16); + let acc = (accN[lane] + laneNP) & 0xffffffff; + acc = (acc << 13) | (acc >>> 19); + const acc0 = acc & 0xffff; + const acc1 = acc >>> 16; + accN[lane] = (acc0 * PRIME32_1 + ((acc1 * PRIME32_1) << 16)) & 0xffffffff; + lane = (lane + 1) & 0x3; + } + + acc = + (((accN[0] << 1) | (accN[0] >>> 31)) + + ((accN[1] << 7) | (accN[1] >>> 25)) + + ((accN[2] << 12) | (accN[2] >>> 20)) + + ((accN[3] << 18) | (accN[3] >>> 14))) & + 0xffffffff; + } + + acc = (acc + buffer.length) & 0xffffffff; + + const limit = buffer.length - 4; + for (; offset <= limit; offset += 4) { + const i = offset; + const laneN0 = b[i + 0] + (b[i + 1] << 8); + const laneN1 = b[i + 2] + (b[i + 3] << 8); + const laneP = laneN0 * PRIME32_3 + ((laneN1 * PRIME32_3) << 16); + acc = (acc + laneP) & 0xffffffff; + acc = (acc << 17) | (acc >>> 15); + acc = + ((acc & 0xffff) * PRIME32_4 + (((acc >>> 16) * PRIME32_4) << 16)) & 0xffffffff; + } + + for (; offset < b.length; ++offset) { + const lane = b[offset]; + acc += lane * PRIME32_5; + acc = (acc << 11) | (acc >>> 21); + acc = + ((acc & 0xffff) * PRIME32_1 + (((acc >>> 16) * PRIME32_1) << 16)) & 0xffffffff; + } + + acc ^= acc >>> 15; + acc = + (((acc & 0xffff) * PRIME32_2) & 0xffffffff) + (((acc >>> 16) * PRIME32_2) << 16); + acc ^= acc >>> 13; + acc = + (((acc & 0xffff) * PRIME32_3) & 0xffffffff) + (((acc >>> 16) * PRIME32_3) << 16); + acc ^= acc >>> 16; + + return acc < 0 ? acc + 4294967296 : acc; +} diff --git a/packages/start/src/runtime/server-fns-runtime.ts b/packages/start/src/runtime/server-fns-runtime.ts index a648725da..bc342458d 100644 --- a/packages/start/src/runtime/server-fns-runtime.ts +++ b/packages/start/src/runtime/server-fns-runtime.ts @@ -1,14 +1,30 @@ import { getRequestEvent } from "solid-js/web"; import { provideRequestEvent } from "solid-js/web/storage"; import { cloneEvent } from "../server/fetchEvent"; +import { registerServerFunction } from "./server-fns"; -export function createServerReference(fn: Function, id: string, name: string) { - if (typeof fn !== "function") throw new Error("Export from a 'use server' module must be a function"); +interface Registration { + id: string; + fn: (...args: T) => Promise; +} + +export function createServerReference( + id: string, + fn: (...args: T) => Promise, +) { + const registration: Registration = { id, fn }; + registerServerFunction(id, fn); + return registration; +} + +export function cloneServerReference({ id, fn }: Registration) { + if (typeof fn !== "function") + throw new Error("Export from a 'use server' module must be a function"); const baseURL = import.meta.env.SERVER_BASE_URL; return new Proxy(fn, { get(target, prop, receiver) { if (prop === "url") { - return `${baseURL}/_server?id=${encodeURIComponent(id)}&name=${encodeURIComponent(name)}`; + return `${baseURL}/_server?id=${encodeURIComponent(id)}`; } if (prop === "GET") return receiver; return (target as any)[prop]; @@ -18,11 +34,11 @@ export function createServerReference(fn: Function, id: string, name: string) { if (!ogEvt) throw new Error("Cannot call server function outside of a request"); const evt = cloneEvent(ogEvt); evt.locals.serverFunctionMeta = { - id: id + "#" + name, + id, }; evt.serverOnly = true; return provideRequestEvent(evt, () => { - return fn.apply(thisArg, args); + return fn.apply(thisArg, args as T); }); } }); diff --git a/packages/start/src/runtime/server-fns.ts b/packages/start/src/runtime/server-fns.ts new file mode 100644 index 000000000..178c0d954 --- /dev/null +++ b/packages/start/src/runtime/server-fns.ts @@ -0,0 +1,17 @@ +const REGISTRATIONS = new Map(); + +export function registerServerFunction( + id: string, + callback: (...args: T) => Promise, +) { + REGISTRATIONS.set(id, callback); + return callback; +} + +export function getServerFunction(id: string): (...args: T) => Promise { + const fn = REGISTRATIONS.get(id) as ((...args: T) => Promise) | undefined; + if (fn) { + return fn; + } + throw new Error("invalid server function: " + id); +} diff --git a/packages/start/src/runtime/server-handler.ts b/packages/start/src/runtime/server-handler.ts index a7007fee0..75e029a1e 100644 --- a/packages/start/src/runtime/server-handler.ts +++ b/packages/start/src/runtime/server-handler.ts @@ -16,9 +16,9 @@ import { getExpectedRedirectStatus } from "../server/handler"; import { createPageEvent } from "../server/pageEvent"; // @ts-ignore import { FetchEvent, PageEvent } from "../server"; -// @ts-ignore -import serverFnManifest from "solidstart:server-fn-manifest"; import { deserializeFromJSONString, serializeToJSONStream, serializeToJSStream } from "./serialization"; +import "solidstart:server-fn-manifest"; +import { getServerFunction } from "./server-fns"; async function handleServerFunction(h3Event: HTTPEvent) { const event = getFetchEvent(h3Event); @@ -28,43 +28,37 @@ async function handleServerFunction(h3Event: HTTPEvent) { const instance = request.headers.get("X-Server-Instance"); const singleFlight = request.headers.has("X-Single-Flight"); const url = new URL(request.url); - let functionId: string | undefined | null, name: string | undefined | null; + let functionId: string | undefined | null; if (serverReference) { invariant(typeof serverReference === "string", "Invalid server function"); - [functionId, name] = decodeURIComponent(serverReference).split("#"); + [functionId] = decodeURIComponent(serverReference).split("#"); } else { functionId = url.searchParams.get("id"); - name = url.searchParams.get("name"); - if (!functionId || !name) { + if (!functionId) { return process.env.NODE_ENV === "development" ? new Response("Server function not found", { status: 404 }) : new Response(null, { status: 404 }); } } - const serverFnInfo = serverFnManifest[functionId]; - let fnModule: undefined | { [key: string]: any }; - - if (!serverFnInfo) { - return process.env.NODE_ENV === "development" - ? new Response("Server function not found", { status: 404 }) - : new Response(null, { status: 404 }); - } + let serverFunction; + try { + serverFunction = getServerFunction(functionId!); + } catch (error) { + if (process.env.NODE_ENV !== "development") { + throw error; + } - if (process.env.NODE_ENV === "development") { - // In dev, we use Vinxi to get the "server" server-side router - // Then we use that router's devServer.ssrLoadModule to get the serverFn + const at = functionId!.lastIndexOf("@"); + if (at === -1) { + throw error; + } - // This code comes from: - // https://github.com/TanStack/router/blob/266f5cc863cd1a99809d1af2669e58b6b6db9a67/packages/start-server-functions-handler/src/index.tsx#L83-L87 - fnModule = await (globalThis as any).app - .getRouter("server-fns") - .internals.devServer.ssrLoadModule(serverFnInfo.extractedFilename); - } else { - fnModule = await serverFnInfo.importer(); + const moduleId = functionId!.slice(at + 1); + await (globalThis as any).app.getRouter("server-fns").internals.devServer.ssrLoadModule(moduleId); + serverFunction = getServerFunction(functionId!); } - const serverFunction = fnModule![serverFnInfo.functionName]; let parsed: any[] = []; @@ -122,7 +116,7 @@ async function handleServerFunction(h3Event: HTTPEvent) { /* @ts-ignore */ sharedConfig.context = { event }; event.locals.serverFunctionMeta = { - id: functionId + "#" + name + id: functionId }; return serverFunction(...parsed); }); diff --git a/packages/start/src/runtime/server-runtime.ts b/packages/start/src/runtime/server-runtime.ts index baec39ea5..562f42338 100644 --- a/packages/start/src/runtime/server-runtime.ts +++ b/packages/start/src/runtime/server-runtime.ts @@ -94,20 +94,23 @@ async function fetchServerFunction( return result; } -export function createServerReference(fn: Function, id: string, name: string) { +export function cloneServerReference(id: string) { const baseURL = import.meta.env.SERVER_BASE_URL; + + const fn = (...args: any[]) => { + return fetchServerFunction(`${baseURL}/_server`, id, {}, args); + }; + return new Proxy(fn, { get(target, prop, receiver) { if (prop === "url") { - return `${baseURL}/_server?id=${encodeURIComponent(id)}&name=${encodeURIComponent(name)}`; + return `${baseURL}/_server?id=${encodeURIComponent(id)}`; } if (prop === "GET") { return receiver.withOptions({ method: "GET" }); } if (prop === "withOptions") { - const url = `${baseURL}/_server/?id=${encodeURIComponent(id)}&name=${encodeURIComponent( - name, - )}`; + const url = `${baseURL}/_server/?id=${encodeURIComponent(id)}`; return (options: RequestInit) => { const fn = async (...args: any[]) => { const encodeArgs = @@ -121,7 +124,7 @@ export function createServerReference(fn: Function, id: string, name: string) { )}` : "") : `${baseURL}/_server`, - `${id}#${name}`, + id, options, encodeArgs ? [] : args, ); @@ -135,7 +138,7 @@ export function createServerReference(fn: Function, id: string, name: string) { apply(target, thisArg, args) { return fetchServerFunction( `${baseURL}/_server`, - `${id}#${name}`, + id, {}, args, ); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 7c8b18d22..9271e63f8 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -279,9 +279,15 @@ importers: packages/start: dependencies: - '@tanstack/server-functions-plugin': - specifier: 1.121.21 - version: 1.121.21(vite@6.3.6(@types/node@25.3.0)(jiti@2.6.0)(terser@5.46.0)(yaml@2.8.1)) + '@babel/core': + specifier: ^7.28.3 + version: 7.29.0 + '@babel/traverse': + specifier: ^7.28.3 + version: 7.29.0 + '@babel/types': + specifier: ^7.28.5 + version: 7.29.0 '@vinxi/plugin-directives': specifier: ^0.5.0 version: 0.5.1(vinxi@0.5.8(@types/node@25.3.0)(db0@0.3.2)(ioredis@5.7.0)(jiti@2.6.0)(terser@5.46.0)(yaml@2.8.1)) @@ -325,12 +331,21 @@ importers: specifier: ^2.11.10 version: 2.11.10(@testing-library/jest-dom@6.8.0)(solid-js@1.9.11)(vite@6.3.6(@types/node@25.3.0)(jiti@2.6.0)(terser@5.46.0)(yaml@2.8.1)) devDependencies: + '@types/babel__core': + specifier: ^7.20.5 + version: 7.20.5 + '@types/babel__traverse': + specifier: ^7.28.0 + version: 7.28.0 solid-js: specifier: ^1.9.11 version: 1.9.11 vinxi: specifier: ^0.5.7 version: 0.5.8(@types/node@25.3.0)(db0@0.3.2)(ioredis@5.7.0)(jiti@2.6.0)(terser@5.46.0)(yaml@2.8.1) + vite: + specifier: ^6.3.6 + version: 6.3.6(@types/node@25.3.0)(jiti@2.6.0)(terser@5.46.0)(yaml@2.8.1) vitest: specifier: 3.0.5 version: 3.0.5(@types/node@25.3.0)(@vitest/browser@3.2.4)(@vitest/ui@3.0.5)(jiti@2.6.0)(jsdom@25.0.1)(terser@5.46.0)(yaml@2.8.1) @@ -347,22 +362,10 @@ packages: '@asamuzakjp/css-color@3.2.0': resolution: {integrity: sha512-K1A6z8tS3XsmCMM86xoWdn7Fkdn9m6RSVtocUrJYIwZnFVkng/PvkEoWtOWmP+Scc6saYWHWZYbndEEXxl24jw==} - '@babel/code-frame@7.26.2': - resolution: {integrity: sha512-RJlIHRueQgwWitWgF8OdFYGZX328Ax5BCemNGlqHfplnRT9ESi8JkFlvaVYbS+UubVY6dpv87Fs2u5M29iNFVQ==} - engines: {node: '>=6.9.0'} - - '@babel/code-frame@7.27.1': - resolution: {integrity: sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==} - engines: {node: '>=6.9.0'} - '@babel/code-frame@7.29.0': resolution: {integrity: sha512-9NhCeYjq9+3uxgdtp20LSiJXJvN0FeCtNGpJxuMFZ1Kv3cWUNb6DOhJwUvcVCzKGR66cw4njwM6hrJLqgOwbcw==} engines: {node: '>=6.9.0'} - '@babel/compat-data@7.28.4': - resolution: {integrity: sha512-YsmSKC29MJwf0gF8Rjjrg5LQCmyh+j/nD8/eP7f+BeoQTKYqs9RoWbjGOdy0+1Ekr68RJZMUOPVQaQisnIo4Rw==} - engines: {node: '>=6.9.0'} - '@babel/compat-data@7.29.0': resolution: {integrity: sha512-T1NCJqT/j9+cn8fvkt7jtwbLBfLC/1y1c7NtCeXFRgzGTsafi68MRv8yzkYSapBnFA6L3U2VSc02ciDzoAJhJg==} engines: {node: '>=6.9.0'} @@ -375,10 +378,6 @@ packages: resolution: {integrity: sha512-CGOfOJqWjg2qW/Mb6zNsDm+u5vFQ8DxXfbM09z69p5Z6+mE1ikP2jUXw+j42Pf1XTYED2Rni5f95npYeuwMDQA==} engines: {node: '>=6.9.0'} - '@babel/generator@7.28.3': - resolution: {integrity: sha512-3lSpxGgvnmZznmBkCRnVREPUFJv2wrv9iAoFDvADJc0ypmdOxdUtcLeBgBJ6zE0PMeTKnxeQzyk0xTBq4Ep7zw==} - engines: {node: '>=6.9.0'} - '@babel/generator@7.29.1': resolution: {integrity: sha512-qsaF+9Qcm2Qv8SRIMMscAvG4O3lJ0F1GuMo5HR/Bp02LopNgnZBC/EkbevHFeGs4ls/oPz9v+Bsmzbkbe+0dUw==} engines: {node: '>=6.9.0'} @@ -387,20 +386,10 @@ packages: resolution: {integrity: sha512-fXSwMQqitTGeHLBC08Eq5yXz2m37E4pJX1qAU1+2cNedz/ifv/bVXft90VeSav5nFO61EcNgwr0aJxbyPaWBPg==} engines: {node: '>=6.9.0'} - '@babel/helper-compilation-targets@7.27.2': - resolution: {integrity: sha512-2+1thGUUWWjLTYTHZWK1n8Yga0ijBz1XAhUXcKy81rd5g6yh7hGqMp45v7cadSbEHc9G3OTv45SyneRN3ps4DQ==} - engines: {node: '>=6.9.0'} - '@babel/helper-compilation-targets@7.28.6': resolution: {integrity: sha512-JYtls3hqi15fcx5GaSNL7SCTJ2MNmjrkHXg4FSpOA/grxK8KwyZ5bubHsCq8FXCkua6xhuaaBit+3b7+VZRfcA==} engines: {node: '>=6.9.0'} - '@babel/helper-create-class-features-plugin@7.28.3': - resolution: {integrity: sha512-V9f6ZFIYSLNEbuGA/92uOvYsGCJNsuA8ESZ4ldc09bWk/j8H8TKiPw8Mk1eG6olpnO0ALHJmYfZvF4MEE4gajg==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0 - '@babel/helper-create-class-features-plugin@7.28.6': resolution: {integrity: sha512-dTOdvsjnG3xNT9Y0AUg1wAl38y+4Rl4sf9caSQZOXdNqVn+H+HbbJ4IyyHaIqNR6SW9oJpA/RuRjsjCw2IdIow==} engines: {node: '>=6.9.0'} @@ -422,10 +411,6 @@ packages: resolution: {integrity: sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw==} engines: {node: '>=6.9.0'} - '@babel/helper-member-expression-to-functions@7.27.1': - resolution: {integrity: sha512-E5chM8eWjTp/aNoVpcbfM7mLxu9XGLWYise2eBKGQomAk/Mb4XoxyqXTZbuTohbsl8EKqdlMhnDI2CCLfcs9wA==} - engines: {node: '>=6.9.0'} - '@babel/helper-member-expression-to-functions@7.28.5': resolution: {integrity: sha512-cwM7SBRZcPCLgl8a7cY0soT1SptSzAlMH39vwiRpOQkJlh53r5hdHwLSCZpQdVLT39sZt+CRpNwYG4Y2v77atg==} engines: {node: '>=6.9.0'} @@ -442,12 +427,6 @@ packages: resolution: {integrity: sha512-l5XkZK7r7wa9LucGw9LwZyyCUscb4x37JWTPz7swwFE/0FMQAGpiWUZn8u9DzkSBWEcK25jmvubfpw2dnAMdbw==} engines: {node: '>=6.9.0'} - '@babel/helper-module-transforms@7.28.3': - resolution: {integrity: sha512-gytXUbs8k2sXS9PnQptz5o0QnpLL51SwASIORY6XaBKF88nsOT0Zw9szLqlSGQDP/4TljBAD5y98p2U1fqkdsw==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0 - '@babel/helper-module-transforms@7.28.6': resolution: {integrity: sha512-67oXFAYr2cDLDVGLXTEABjdBJZ6drElUSI7WKp70NrpyISso3plG9SAGEF6y7zbha/wOzUByWWTJvEDVNIUGcA==} engines: {node: '>=6.9.0'} @@ -472,12 +451,6 @@ packages: peerDependencies: '@babel/core': ^7.0.0 - '@babel/helper-replace-supers@7.27.1': - resolution: {integrity: sha512-7EHz6qDZc8RYS5ElPoShMheWvEgERonFCs7IAonWLLUTXW59DP14bCZt89/GKyreYn8g3S83m21FelHKbeDCKA==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0 - '@babel/helper-replace-supers@7.28.6': resolution: {integrity: sha512-mq8e+laIk94/yFec3DxSjCRD2Z0TAjhVbEJY3UQrlwVo15Lmt7C2wAUbK4bjnTs4APkwsYLTahXRraQXhb1WCg==} engines: {node: '>=6.9.0'} @@ -492,10 +465,6 @@ packages: resolution: {integrity: sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==} engines: {node: '>=6.9.0'} - '@babel/helper-validator-identifier@7.27.1': - resolution: {integrity: sha512-D2hP9eA+Sqx1kBZgzxZh0y1trbuU+JoDkiEwqhQ36nodYqJwyEIhPSdMNd7lOm/4io72luTPWH20Yda0xOuUow==} - engines: {node: '>=6.9.0'} - '@babel/helper-validator-identifier@7.28.5': resolution: {integrity: sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==} engines: {node: '>=6.9.0'} @@ -508,10 +477,6 @@ packages: resolution: {integrity: sha512-z+PwLziMNBeSQJonizz2AGnndLsP2DeGHIxDAn+wdHOGuo4Fo1x1HBPPXeE9TAOPHNNWQKCSlA2VZyYyyibDnQ==} engines: {node: '>=6.9.0'} - '@babel/helpers@7.28.4': - resolution: {integrity: sha512-HFN59MmQXGHVyYadKLVumYsA9dBFun/ldYxipEjzA4196jpLZd8UjEEBLkbEkvfYreDqJhZxYAWFPtrfhNpj4w==} - engines: {node: '>=6.9.0'} - '@babel/helpers@7.28.6': resolution: {integrity: sha512-xOBvwq86HHdB7WUDTfKfT/Vuxh7gElQ+Sfti2Cy6yIWNW05P8iUslOVcZ4/sKbE+/jQaukQAdz/gf3724kYdqw==} engines: {node: '>=6.9.0'} @@ -742,12 +707,6 @@ packages: peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-modules-commonjs@7.27.1': - resolution: {integrity: sha512-OJguuwlTYlN0gBZFRPqwOGNWssZjfIUdS7HMYtN8c1KmwpwHFBwTeFZrg9XZa+DFTitWOW5iTAG7tyCUPsCCyw==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-modules-commonjs@7.28.6': resolution: {integrity: sha512-jppVbf8IV9iWWwWTQIxJMAJCWBuuKx71475wHwYytrRGQ2CWiDvYlADQno3tcYpS/T2UUWFQp3nVtYfK/YBQrA==} engines: {node: '>=6.9.0'} @@ -886,12 +845,6 @@ packages: peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-typescript@7.28.0': - resolution: {integrity: sha512-4AEiDEBPIZvLQaWlc9liCavE0xRM0dNca41WtBeM3jgFptfUOSG9z0uteLhq6+3rq+WB6jIvUwKDTpXEHPJ2Vg==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-unicode-escapes@7.27.1': resolution: {integrity: sha512-Ysg4v6AmF26k9vpfFuTZg8HRfVWzsh1kVfowA23y9j/Gu6dOuahdUVhkLqpObp3JIv27MLSii6noRnuKN8H0Mg==} engines: {node: '>=6.9.0'} @@ -927,36 +880,18 @@ packages: peerDependencies: '@babel/core': ^7.0.0-0 || ^8.0.0-0 <8.0.0 - '@babel/preset-typescript@7.27.1': - resolution: {integrity: sha512-l7WfQfX0WK4M0v2RudjuQK4u99BS6yLHYEmdtVPP7lKV013zr9DygFuWNlnbvQ9LR+LS0Egz/XAvGx5U9MX0fQ==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - '@babel/runtime@7.28.4': resolution: {integrity: sha512-Q/N6JNWvIvPnLDvjlE1OUBLPQHH6l3CltCEsHIujp45zQUSSh8K+gHnaEX45yAT1nyngnINhvWtzN+Nb9D8RAQ==} engines: {node: '>=6.9.0'} - '@babel/template@7.27.2': - resolution: {integrity: sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw==} - engines: {node: '>=6.9.0'} - '@babel/template@7.28.6': resolution: {integrity: sha512-YA6Ma2KsCdGb+WC6UpBVFJGXL58MDA6oyONbjyF/+5sBgxY/dwkhLogbMT2GXXyU84/IhRw/2D1Os1B/giz+BQ==} engines: {node: '>=6.9.0'} - '@babel/traverse@7.28.4': - resolution: {integrity: sha512-YEzuboP2qvQavAcjgQNVgsvHIDv6ZpwXvcvjmyySP2DIMuByS/6ioU5G9pYrWHM6T2YDfc7xga9iNzYOs12CFQ==} - engines: {node: '>=6.9.0'} - '@babel/traverse@7.29.0': resolution: {integrity: sha512-4HPiQr0X7+waHfyXPZpWPfWL/J7dcN1mx9gL6WdQVMbPnF3+ZhSMs8tCxN7oHddJE9fhNE7+lxdnlyemKfJRuA==} engines: {node: '>=6.9.0'} - '@babel/types@7.28.4': - resolution: {integrity: sha512-bkFqkLhh3pMBUQQkpVgWDWq/lqzc2678eUyDlTBhRqhCHFguYYGM0Efga7tYk4TogG/3x0EEl66/OQ+WGbWB/Q==} - engines: {node: '>=6.9.0'} - '@babel/types@7.29.0': resolution: {integrity: sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A==} engines: {node: '>=6.9.0'} @@ -1767,20 +1702,6 @@ packages: peerDependencies: tailwindcss: '>=3.0.0 || insiders || >=4.0.0-alpha.20 || >=4.0.0-beta.1' - '@tanstack/directive-functions-plugin@1.121.21': - resolution: {integrity: sha512-B9z/HbF7gJBaRHieyX7f2uQ4LpLLAVAEutBZipH6w+CYD6RHRJvSVPzECGHF7icFhNWTiJQL2QR6K07s59yzEw==} - engines: {node: '>=12'} - peerDependencies: - vite: '>=6.0.0' - - '@tanstack/router-utils@1.131.2': - resolution: {integrity: sha512-sr3x0d2sx9YIJoVth0QnfEcAcl+39sQYaNQxThtHmRpyeFYNyM2TTH+Ud3TNEnI3bbzmLYEUD+7YqB987GzhDA==} - engines: {node: '>=12'} - - '@tanstack/server-functions-plugin@1.121.21': - resolution: {integrity: sha512-a05fzK+jBGacsSAc1vE8an7lpBh4H0PyIEcivtEyHLomgSeElAJxm9E2It/0nYRZ5Lh23m0okbhzJNaYWZpAOg==} - engines: {node: '>=12'} - '@testing-library/dom@10.4.1': resolution: {integrity: sha512-o4PXJQidqJl82ckFaXUeoAW+XysPLauYI43Abki5hABd853iMhitooc6znOnczgbTYmEP6U6/y1ZyKAIsvMKGg==} engines: {node: '>=18'} @@ -2104,10 +2025,6 @@ packages: resolution: {integrity: sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==} engines: {node: '>=12'} - ansis@4.1.0: - resolution: {integrity: sha512-BGcItUBWSMRgOCe+SVZJ+S7yTRG0eGt9cXAHev72yuGcY23hnLA7Bky5L/xLyPINoSN95geovfBkqoTlNZYa7w==} - engines: {node: '>=14'} - any-promise@1.3.0: resolution: {integrity: sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==} @@ -2210,9 +2127,6 @@ packages: react-native-b4a: optional: true - babel-dead-code-elimination@1.0.10: - resolution: {integrity: sha512-DV5bdJZTzZ0zn0DC24v3jD7Mnidh6xhKa4GfKCbq3sfW8kaWhDdZjP3i81geA8T33tdYqWKw4D3fVv0CwEgKVA==} - babel-loader@10.0.0: resolution: {integrity: sha512-z8jt+EdS61AMw22nSfoNJAZ0vrtmhPRVi6ghL3rCeRZI8cdNYFiV5xeV3HbE7rlZZNmGH8BVccwWt8/ED0QOHA==} engines: {node: ^18.20.0 || ^20.10.0 || >=22.0.0} @@ -2779,10 +2693,6 @@ packages: didyoumean@1.2.2: resolution: {integrity: sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==} - diff@8.0.2: - resolution: {integrity: sha512-sSuxWU5j5SR9QQji/o2qMvqRNYRDOcBTgsJ/DeCf4iSN4gW+gNMXM7wFIP+fdXZxoNiAnHUTGjCr+TSWXdRDKg==} - engines: {node: '>=0.3.1'} - dir-glob@3.0.1: resolution: {integrity: sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==} engines: {node: '>=8'} @@ -5357,39 +5267,25 @@ snapshots: '@csstools/css-tokenizer': 3.0.4 lru-cache: 10.4.3 - '@babel/code-frame@7.26.2': - dependencies: - '@babel/helper-validator-identifier': 7.27.1 - js-tokens: 4.0.0 - picocolors: 1.1.1 - - '@babel/code-frame@7.27.1': - dependencies: - '@babel/helper-validator-identifier': 7.27.1 - js-tokens: 4.0.0 - picocolors: 1.1.1 - '@babel/code-frame@7.29.0': dependencies: '@babel/helper-validator-identifier': 7.28.5 js-tokens: 4.0.0 picocolors: 1.1.1 - '@babel/compat-data@7.28.4': {} - '@babel/compat-data@7.29.0': {} '@babel/core@7.28.4': dependencies: - '@babel/code-frame': 7.27.1 - '@babel/generator': 7.28.3 - '@babel/helper-compilation-targets': 7.27.2 - '@babel/helper-module-transforms': 7.28.3(@babel/core@7.28.4) - '@babel/helpers': 7.28.4 - '@babel/parser': 7.28.4 - '@babel/template': 7.27.2 - '@babel/traverse': 7.28.4 - '@babel/types': 7.28.4 + '@babel/code-frame': 7.29.0 + '@babel/generator': 7.29.1 + '@babel/helper-compilation-targets': 7.28.6 + '@babel/helper-module-transforms': 7.28.6(@babel/core@7.28.4) + '@babel/helpers': 7.28.6 + '@babel/parser': 7.29.0 + '@babel/template': 7.28.6 + '@babel/traverse': 7.29.0 + '@babel/types': 7.29.0 '@jridgewell/remapping': 2.3.5 convert-source-map: 2.0.0 debug: 4.4.3(supports-color@8.1.1) @@ -5419,14 +5315,6 @@ snapshots: transitivePeerDependencies: - supports-color - '@babel/generator@7.28.3': - dependencies: - '@babel/parser': 7.28.4 - '@babel/types': 7.28.4 - '@jridgewell/gen-mapping': 0.3.13 - '@jridgewell/trace-mapping': 0.3.31 - jsesc: 3.1.0 - '@babel/generator@7.29.1': dependencies: '@babel/parser': 7.29.0 @@ -5437,15 +5325,7 @@ snapshots: '@babel/helper-annotate-as-pure@7.27.3': dependencies: - '@babel/types': 7.28.4 - - '@babel/helper-compilation-targets@7.27.2': - dependencies: - '@babel/compat-data': 7.28.4 - '@babel/helper-validator-option': 7.27.1 - browserslist: 4.26.2 - lru-cache: 5.1.1 - semver: 6.3.1 + '@babel/types': 7.29.0 '@babel/helper-compilation-targets@7.28.6': dependencies: @@ -5455,19 +5335,6 @@ snapshots: lru-cache: 5.1.1 semver: 6.3.1 - '@babel/helper-create-class-features-plugin@7.28.3(@babel/core@7.28.4)': - dependencies: - '@babel/core': 7.28.4 - '@babel/helper-annotate-as-pure': 7.27.3 - '@babel/helper-member-expression-to-functions': 7.27.1 - '@babel/helper-optimise-call-expression': 7.27.1 - '@babel/helper-replace-supers': 7.27.1(@babel/core@7.28.4) - '@babel/helper-skip-transparent-expression-wrappers': 7.27.1 - '@babel/traverse': 7.28.4 - semver: 6.3.1 - transitivePeerDependencies: - - supports-color - '@babel/helper-create-class-features-plugin@7.28.6(@babel/core@7.28.4)': dependencies: '@babel/core': 7.28.4 @@ -5501,13 +5368,6 @@ snapshots: '@babel/helper-globals@7.28.0': {} - '@babel/helper-member-expression-to-functions@7.27.1': - dependencies: - '@babel/traverse': 7.28.4 - '@babel/types': 7.28.4 - transitivePeerDependencies: - - supports-color - '@babel/helper-member-expression-to-functions@7.28.5': dependencies: '@babel/traverse': 7.29.0 @@ -5517,12 +5377,12 @@ snapshots: '@babel/helper-module-imports@7.18.6': dependencies: - '@babel/types': 7.28.4 + '@babel/types': 7.29.0 '@babel/helper-module-imports@7.27.1': dependencies: - '@babel/traverse': 7.28.4 - '@babel/types': 7.28.4 + '@babel/traverse': 7.29.0 + '@babel/types': 7.29.0 transitivePeerDependencies: - supports-color @@ -5533,15 +5393,6 @@ snapshots: transitivePeerDependencies: - supports-color - '@babel/helper-module-transforms@7.28.3(@babel/core@7.28.4)': - dependencies: - '@babel/core': 7.28.4 - '@babel/helper-module-imports': 7.27.1 - '@babel/helper-validator-identifier': 7.27.1 - '@babel/traverse': 7.28.4 - transitivePeerDependencies: - - supports-color - '@babel/helper-module-transforms@7.28.6(@babel/core@7.28.4)': dependencies: '@babel/core': 7.28.4 @@ -5562,7 +5413,7 @@ snapshots: '@babel/helper-optimise-call-expression@7.27.1': dependencies: - '@babel/types': 7.28.4 + '@babel/types': 7.29.0 '@babel/helper-plugin-utils@7.27.1': {} @@ -5577,15 +5428,6 @@ snapshots: transitivePeerDependencies: - supports-color - '@babel/helper-replace-supers@7.27.1(@babel/core@7.28.4)': - dependencies: - '@babel/core': 7.28.4 - '@babel/helper-member-expression-to-functions': 7.27.1 - '@babel/helper-optimise-call-expression': 7.27.1 - '@babel/traverse': 7.28.4 - transitivePeerDependencies: - - supports-color - '@babel/helper-replace-supers@7.28.6(@babel/core@7.28.4)': dependencies: '@babel/core': 7.28.4 @@ -5597,15 +5439,13 @@ snapshots: '@babel/helper-skip-transparent-expression-wrappers@7.27.1': dependencies: - '@babel/traverse': 7.28.4 - '@babel/types': 7.28.4 + '@babel/traverse': 7.29.0 + '@babel/types': 7.29.0 transitivePeerDependencies: - supports-color '@babel/helper-string-parser@7.27.1': {} - '@babel/helper-validator-identifier@7.27.1': {} - '@babel/helper-validator-identifier@7.28.5': {} '@babel/helper-validator-option@7.27.1': {} @@ -5618,11 +5458,6 @@ snapshots: transitivePeerDependencies: - supports-color - '@babel/helpers@7.28.4': - dependencies: - '@babel/template': 7.27.2 - '@babel/types': 7.28.4 - '@babel/helpers@7.28.6': dependencies: '@babel/template': 7.28.6 @@ -5630,7 +5465,7 @@ snapshots: '@babel/parser@7.28.4': dependencies: - '@babel/types': 7.28.4 + '@babel/types': 7.29.0 '@babel/parser@7.29.0': dependencies: @@ -5866,14 +5701,6 @@ snapshots: transitivePeerDependencies: - supports-color - '@babel/plugin-transform-modules-commonjs@7.27.1(@babel/core@7.28.4)': - dependencies: - '@babel/core': 7.28.4 - '@babel/helper-module-transforms': 7.28.3(@babel/core@7.28.4) - '@babel/helper-plugin-utils': 7.27.1 - transitivePeerDependencies: - - supports-color - '@babel/plugin-transform-modules-commonjs@7.28.6(@babel/core@7.28.4)': dependencies: '@babel/core': 7.28.4 @@ -6024,17 +5851,6 @@ snapshots: '@babel/core': 7.28.4 '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-typescript@7.28.0(@babel/core@7.28.4)': - dependencies: - '@babel/core': 7.28.4 - '@babel/helper-annotate-as-pure': 7.27.3 - '@babel/helper-create-class-features-plugin': 7.28.3(@babel/core@7.28.4) - '@babel/helper-plugin-utils': 7.27.1 - '@babel/helper-skip-transparent-expression-wrappers': 7.27.1 - '@babel/plugin-syntax-typescript': 7.27.1(@babel/core@7.28.4) - transitivePeerDependencies: - - supports-color - '@babel/plugin-transform-unicode-escapes@7.27.1(@babel/core@7.28.4)': dependencies: '@babel/core': 7.28.4 @@ -6141,43 +5957,14 @@ snapshots: '@babel/types': 7.29.0 esutils: 2.0.3 - '@babel/preset-typescript@7.27.1(@babel/core@7.28.4)': - dependencies: - '@babel/core': 7.28.4 - '@babel/helper-plugin-utils': 7.27.1 - '@babel/helper-validator-option': 7.27.1 - '@babel/plugin-syntax-jsx': 7.27.1(@babel/core@7.28.4) - '@babel/plugin-transform-modules-commonjs': 7.27.1(@babel/core@7.28.4) - '@babel/plugin-transform-typescript': 7.28.0(@babel/core@7.28.4) - transitivePeerDependencies: - - supports-color - '@babel/runtime@7.28.4': {} - '@babel/template@7.27.2': - dependencies: - '@babel/code-frame': 7.27.1 - '@babel/parser': 7.28.4 - '@babel/types': 7.28.4 - '@babel/template@7.28.6': dependencies: '@babel/code-frame': 7.29.0 '@babel/parser': 7.29.0 '@babel/types': 7.29.0 - '@babel/traverse@7.28.4': - dependencies: - '@babel/code-frame': 7.27.1 - '@babel/generator': 7.28.3 - '@babel/helper-globals': 7.28.0 - '@babel/parser': 7.28.4 - '@babel/template': 7.27.2 - '@babel/types': 7.28.4 - debug: 4.4.3(supports-color@8.1.1) - transitivePeerDependencies: - - supports-color - '@babel/traverse@7.29.0': dependencies: '@babel/code-frame': 7.29.0 @@ -6190,11 +5977,6 @@ snapshots: transitivePeerDependencies: - supports-color - '@babel/types@7.28.4': - dependencies: - '@babel/helper-string-parser': 7.27.1 - '@babel/helper-validator-identifier': 7.27.1 - '@babel/types@7.29.0': dependencies: '@babel/helper-string-parser': 7.27.1 @@ -6419,7 +6201,7 @@ snapshots: '@babel/preset-env': 7.28.3(@babel/core@7.28.4) babel-loader: 10.0.0(@babel/core@7.28.4)(webpack@5.101.3) bluebird: 3.7.1 - debug: 4.4.0 + debug: 4.4.3(supports-color@8.1.1) lodash: 4.17.21 semver: 7.7.2 webpack: 5.101.3 @@ -7038,49 +6820,9 @@ snapshots: postcss-selector-parser: 6.0.10 tailwindcss: 3.4.17 - '@tanstack/directive-functions-plugin@1.121.21(vite@6.3.6(@types/node@25.3.0)(jiti@2.6.0)(terser@5.46.0)(yaml@2.8.1))': - dependencies: - '@babel/code-frame': 7.26.2 - '@babel/core': 7.28.4 - '@babel/traverse': 7.28.4 - '@babel/types': 7.28.4 - '@tanstack/router-utils': 1.131.2 - babel-dead-code-elimination: 1.0.10 - tiny-invariant: 1.3.3 - vite: 6.3.6(@types/node@25.3.0)(jiti@2.6.0)(terser@5.46.0)(yaml@2.8.1) - transitivePeerDependencies: - - supports-color - - '@tanstack/router-utils@1.131.2': - dependencies: - '@babel/core': 7.28.4 - '@babel/generator': 7.28.3 - '@babel/parser': 7.28.4 - '@babel/preset-typescript': 7.27.1(@babel/core@7.28.4) - ansis: 4.1.0 - diff: 8.0.2 - transitivePeerDependencies: - - supports-color - - '@tanstack/server-functions-plugin@1.121.21(vite@6.3.6(@types/node@25.3.0)(jiti@2.6.0)(terser@5.46.0)(yaml@2.8.1))': - dependencies: - '@babel/code-frame': 7.26.2 - '@babel/core': 7.28.4 - '@babel/plugin-syntax-jsx': 7.27.1(@babel/core@7.28.4) - '@babel/plugin-syntax-typescript': 7.27.1(@babel/core@7.28.4) - '@babel/template': 7.27.2 - '@babel/traverse': 7.28.4 - '@babel/types': 7.28.4 - '@tanstack/directive-functions-plugin': 1.121.21(vite@6.3.6(@types/node@25.3.0)(jiti@2.6.0)(terser@5.46.0)(yaml@2.8.1)) - babel-dead-code-elimination: 1.0.10 - tiny-invariant: 1.3.3 - transitivePeerDependencies: - - supports-color - - vite - '@testing-library/dom@10.4.1': dependencies: - '@babel/code-frame': 7.27.1 + '@babel/code-frame': 7.29.0 '@babel/runtime': 7.28.4 '@types/aria-query': 5.0.4 aria-query: 5.3.0 @@ -7494,8 +7236,6 @@ snapshots: ansi-styles@6.2.3: {} - ansis@4.1.0: {} - any-promise@1.3.0: {} anymatch@3.1.3: @@ -7589,15 +7329,6 @@ snapshots: b4a@1.7.1: {} - babel-dead-code-elimination@1.0.10: - dependencies: - '@babel/core': 7.28.4 - '@babel/parser': 7.28.4 - '@babel/traverse': 7.28.4 - '@babel/types': 7.28.4 - transitivePeerDependencies: - - supports-color - babel-loader@10.0.0(@babel/core@7.28.4)(webpack@5.101.3): dependencies: '@babel/core': 7.28.4 @@ -7609,7 +7340,7 @@ snapshots: '@babel/core': 7.28.4 '@babel/helper-module-imports': 7.18.6 '@babel/plugin-syntax-jsx': 7.27.1(@babel/core@7.28.4) - '@babel/types': 7.28.4 + '@babel/types': 7.29.0 html-entities: 2.3.3 parse5: 7.3.0 validate-html-nesting: 1.2.3 @@ -8135,8 +7866,6 @@ snapshots: didyoumean@1.2.2: {} - diff@8.0.2: {} - dir-glob@3.0.1: dependencies: path-type: 4.0.0 @@ -8819,7 +8548,7 @@ snapshots: istanbul-lib-instrument@4.0.3: dependencies: - '@babel/core': 7.28.4 + '@babel/core': 7.29.0 '@istanbuljs/schema': 0.1.3 istanbul-lib-coverage: 3.2.2 semver: 6.3.1 @@ -8843,7 +8572,7 @@ snapshots: istanbul-lib-source-maps@4.0.1: dependencies: - debug: 4.4.0 + debug: 4.4.3(supports-color@8.1.1) istanbul-lib-coverage: 3.2.2 source-map: 0.6.1 transitivePeerDependencies: @@ -9050,14 +8779,14 @@ snapshots: magicast@0.2.11: dependencies: - '@babel/parser': 7.28.4 - '@babel/types': 7.28.4 + '@babel/parser': 7.29.0 + '@babel/types': 7.29.0 recast: 0.23.11 magicast@0.3.5: dependencies: - '@babel/parser': 7.28.4 - '@babel/types': 7.28.4 + '@babel/parser': 7.29.0 + '@babel/types': 7.29.0 source-map-js: 1.2.1 make-dir@3.1.0: @@ -10016,18 +9745,18 @@ snapshots: solid-refresh@0.6.3(solid-js@1.9.11): dependencies: - '@babel/generator': 7.28.3 + '@babel/generator': 7.29.1 '@babel/helper-module-imports': 7.27.1 - '@babel/types': 7.28.4 + '@babel/types': 7.29.0 solid-js: 1.9.11 transitivePeerDependencies: - supports-color solid-refresh@0.6.3(solid-js@1.9.9): dependencies: - '@babel/generator': 7.28.3 + '@babel/generator': 7.29.1 '@babel/helper-module-imports': 7.27.1 - '@babel/types': 7.28.4 + '@babel/types': 7.29.0 solid-js: 1.9.9 transitivePeerDependencies: - supports-color