From 46c56c8ae1b20666f96e51546089e5e62a231fe9 Mon Sep 17 00:00:00 2001 From: Alem Tuzlak Date: Mon, 24 Aug 2026 16:25:22 +0200 Subject: [PATCH 1/8] feat(ai-client): hold UI snapshots in a TanStack Store atom Framework hooks read getSnapshot instead of copying fields through change callbacks. useChat return shape stays the same. --- .changeset/ai-client-store-snapshot.md | 14 ++ docs/api/ai-client.md | 28 +++ examples/ts-code-mode-web/package.json | 2 +- examples/ts-react-chat/package.json | 2 +- examples/ts-solid-chat/package.json | 2 +- packages/ai-angular/src/inject-chat.ts | 32 +-- .../ai-angular/src/inject-generate-video.ts | 35 ++-- packages/ai-angular/src/inject-generation.ts | 27 ++- packages/ai-client/package.json | 3 +- packages/ai-client/src/audio-recorder.ts | 32 +-- packages/ai-client/src/byok/client.ts | 20 +- packages/ai-client/src/chat-client.ts | 71 ++++++- packages/ai-client/src/generation-client.ts | 28 +++ packages/ai-client/src/generation-types.ts | 23 ++ packages/ai-client/src/index.ts | 3 + packages/ai-client/src/realtime-client.ts | 42 +++- packages/ai-client/src/snapshot-atom.ts | 41 ++++ packages/ai-client/src/types.ts | 21 ++ .../ai-client/src/video-generation-client.ts | 33 +++ packages/ai-client/tests/chat-client.test.ts | 30 +++ .../ai-client/tests/client-snapshots.test.ts | 94 +++++++++ .../ai-client/tests/snapshot-atom.test.ts | 31 +++ packages/ai-octane/src/use-chat.tsrx | 125 +++-------- .../ai-octane/src/use-generate-video.tsrx | 20 +- packages/ai-octane/src/use-generation.tsrx | 16 +- packages/ai-octane/src/use-realtime-chat.tsrx | 30 ++- packages/ai-preact/src/use-chat.ts | 194 +++-------------- packages/ai-react/src/use-chat.ts | 196 ++++-------------- packages/ai-react/src/use-generate-video.ts | 58 ++---- packages/ai-react/src/use-generation.ts | 46 ++-- packages/ai-react/src/use-realtime-chat.ts | 65 ++---- packages/ai-solid/src/use-chat.ts | 91 +++----- packages/ai-solid/src/use-generate-video.ts | 34 ++- packages/ai-solid/src/use-generation.ts | 26 +-- packages/ai-svelte/src/create-chat.svelte.ts | 75 ++----- .../src/create-generate-video.svelte.ts | 49 ++--- .../ai-svelte/src/create-generation.svelte.ts | 39 ++-- .../tests/create-generation-dispose.test.ts | 35 ++++ packages/ai-vue/src/use-chat.ts | 76 ++----- packages/ai-vue/src/use-generate-video.ts | 41 ++-- packages/ai-vue/src/use-generation.ts | 31 +-- pnpm-lock.yaml | 20 +- 42 files changed, 916 insertions(+), 965 deletions(-) create mode 100644 .changeset/ai-client-store-snapshot.md create mode 100644 packages/ai-client/src/snapshot-atom.ts create mode 100644 packages/ai-client/tests/client-snapshots.test.ts create mode 100644 packages/ai-client/tests/snapshot-atom.test.ts create mode 100644 packages/ai-svelte/tests/create-generation-dispose.test.ts diff --git a/.changeset/ai-client-store-snapshot.md b/.changeset/ai-client-store-snapshot.md new file mode 100644 index 0000000000..6115b3dad5 --- /dev/null +++ b/.changeset/ai-client-store-snapshot.md @@ -0,0 +1,14 @@ +--- +'@tanstack/ai-client': minor +'@tanstack/ai-react': patch +'@tanstack/ai-solid': patch +'@tanstack/ai-vue': patch +'@tanstack/ai-svelte': patch +'@tanstack/ai-angular': patch +'@tanstack/ai-preact': patch +'@tanstack/ai-octane': patch +--- + +Hold client UI state in a TanStack Store atom. Framework hooks read `getSnapshot()` instead of copying fields through change callbacks. `useChat()` return shape stays the same. + +`ChatClient` adds `subscribeSnapshot` / `getSnapshot`. The live connection method stays `subscribe()`. Generation, video, realtime, audio, and BYOK clients expose the same snapshot pair (`subscribe` / `getSnapshot`) where the name does not collide. diff --git a/docs/api/ai-client.md b/docs/api/ai-client.md index 2ae79139a1..903f6ef8c0 100644 --- a/docs/api/ai-client.md +++ b/docs/api/ai-client.md @@ -273,6 +273,34 @@ Stop tailing and drop the connection. Keeps messages, the run pointer and the ru id, so a later `attach()` continues where it left off. See [Lifecycle](#lifecycle-attach-and-detach). +#### `getSnapshot()` + +Returns the current UI snapshot: messages, status, loading, error, queue, run +id, subscription, connection, session generating, and interrupt state. + +`subscribeSnapshot(listener)` calls `listener` after that snapshot changes. It +does not fire with the current value. Read `getSnapshot()` first. This is not +`subscribe()`, which starts the live connection loop. + +```typescript +import { ChatClient, fetchServerSentEvents } from "@tanstack/ai-client"; + +const client = new ChatClient({ + connection: fetchServerSentEvents("/api/chat"), +}); + +const stop = client.subscribeSnapshot(() => { + render(client.getSnapshot()); +}); + +client.attach(); +client.sendMessage("Hello"); +``` + +`GenerationClient`, `VideoGenerationClient`, `RealtimeClient`, `AudioRecorder`, +and `ByokClient` use `subscribe(listener)` / `getSnapshot()` for the same job. +Their `subscribe` name does not collide with a live connection method. + #### `stop()` Stops the current response generation. It aborts the in-flight request. diff --git a/examples/ts-code-mode-web/package.json b/examples/ts-code-mode-web/package.json index 6ffbec8b6e..ed5a5978ee 100644 --- a/examples/ts-code-mode-web/package.json +++ b/examples/ts-code-mode-web/package.json @@ -35,7 +35,7 @@ "@tanstack/react-router": "^1.158.4", "@tanstack/react-start": "^1.159.0", "@tanstack/router-plugin": "^1.158.4", - "@tanstack/store": "^0.8.0", + "@tanstack/store": "^0.11.1", "framer-motion": "^11.15.0", "highlight.js": "^11.11.1", "isolated-vm": "^6.0.2", diff --git a/examples/ts-react-chat/package.json b/examples/ts-react-chat/package.json index c0502d9761..8afb8f862d 100644 --- a/examples/ts-react-chat/package.json +++ b/examples/ts-react-chat/package.json @@ -55,7 +55,7 @@ "@tanstack/react-start": "^1.159.0", "@tanstack/react-store": "^0.8.0", "@tanstack/router-plugin": "^1.158.4", - "@tanstack/store": "^0.8.0", + "@tanstack/store": "^0.11.1", "dockerode": "^4.0.2", "highlight.js": "^11.11.1", "lucide-react": "^0.561.0", diff --git a/examples/ts-solid-chat/package.json b/examples/ts-solid-chat/package.json index bccf27dce9..5ac6e3b16a 100644 --- a/examples/ts-solid-chat/package.json +++ b/examples/ts-solid-chat/package.json @@ -28,7 +28,7 @@ "@tanstack/solid-router-ssr-query": "^1.139.10", "@tanstack/solid-start": "^1.139.10", "@tanstack/solid-store": "^0.8.0", - "@tanstack/store": "^0.8.0", + "@tanstack/store": "^0.11.1", "highlight.js": "^11.11.1", "lucide-solid": "^0.554.0", "solid-js": "^1.9.10", diff --git a/packages/ai-angular/src/inject-chat.ts b/packages/ai-angular/src/inject-chat.ts index 58a4a13502..77847b3823 100644 --- a/packages/ai-angular/src/inject-chat.ts +++ b/packages/ai-angular/src/inject-chat.ts @@ -133,13 +133,7 @@ export function injectChat< onChunk: (chunk: StreamChunk) => options.onChunk?.(chunk), onFinish: (message) => options.onFinish?.(message), onError: (err) => options.onError?.(err), - onRunIdChange: (nextRunId) => runId.set(nextRunId), - // No `onResumeStateChange`: the run identity is surfaced as the `runId` - // signal (via `onRunIdChange`) and pending interrupts arrive through - // `onInterruptStateChange`, so there is nothing left for it to do — and it - // is not a public option here, matching the other framework packages. onInterruptStateChange: (nextInterruptState, context) => { - interruptState.set(nextInterruptState) options.onInterruptStateChange?.(nextInterruptState, context) }, tools: options.tools, @@ -151,19 +145,24 @@ export function injectChat< ...(options.streamProcessor !== undefined && { streamProcessor: options.streamProcessor, }), - onMessagesChange: (m: Array>) => messages.set(m), - onLoadingChange: (v: boolean) => isLoading.set(v), - onStatusChange: (v: ChatClientState) => status.set(v), - onErrorChange: (v: Error | undefined) => error.set(v), - onSubscriptionChange: (v: boolean) => isSubscribed.set(v), - onConnectionStatusChange: (v: ConnectionStatus) => connectionStatus.set(v), - onSessionGeneratingChange: (v: boolean) => sessionGenerating.set(v), ...(options.queue !== undefined && { queue: options.queue }), - onQueueChange: (nextQueue: Array) => queue.set(nextQueue), }) - messages.set(client.getMessages()) - interruptState.set(client.getInterruptState()) + const applySnapshot = () => { + const next = client.getSnapshot() + messages.set(next.messages) + isLoading.set(next.isLoading) + error.set(next.error) + status.set(next.status) + isSubscribed.set(next.isSubscribed) + connectionStatus.set(next.connectionStatus) + sessionGenerating.set(next.sessionGenerating) + queue.set(next.queue) + runId.set(next.runId) + interruptState.set(next.interruptState) + } + applySnapshot() + const unsubscribeSnapshot = client.subscribeSnapshot(applySnapshot) // START TAILING HERE, not in the constructor. A client is idle until something // attaches it, so a client that gets built and thrown away never opens a @@ -217,6 +216,7 @@ export function injectChat< ) destroyRef.onDestroy(() => { + unsubscribeSnapshot() // Release the connection first: the counterpart of the `attach` above. client.detach() if (liveSource?.()) { diff --git a/packages/ai-angular/src/inject-generate-video.ts b/packages/ai-angular/src/inject-generate-video.ts index 3287fbea29..43f19d7afb 100644 --- a/packages/ai-angular/src/inject-generate-video.ts +++ b/packages/ai-angular/src/inject-generate-video.ts @@ -181,27 +181,6 @@ export function injectGenerateVideo( onStatusUpdate: (s: VideoStatusInfo) => { if (!disposed) options.onStatusUpdate?.(s) }, - onResultChange: (r: TOutput | null) => { - if (!disposed) result.set(r) - }, - onLoadingChange: (l: boolean) => { - if (!disposed) isLoading.set(l) - }, - onErrorChange: (e: Error | undefined) => { - if (!disposed) error.set(e) - }, - onStatusChange: (s: GenerationClientState) => { - if (!disposed) status.set(s) - }, - onJobIdChange: (id: string | null) => { - if (!disposed) jobId.set(id) - }, - onVideoStatusChange: (s: VideoStatusInfo | null) => { - if (!disposed) videoStatus.set(s) - }, - onResumeStateChange: (rs: { runId: string } | null) => { - if (!disposed) runId.set(rs?.runId ?? null) - }, } let client: VideoGenerationClient @@ -221,6 +200,19 @@ export function injectGenerateVideo( ) } + const applySnapshot = () => { + const next = client.getSnapshot() + result.set(next.result) + isLoading.set(next.isLoading) + error.set(next.error) + status.set(next.status) + runId.set(next.runId) + jobId.set(next.jobId) + videoStatus.set(next.videoStatus) + } + applySnapshot() + const unsubscribeSnapshot = client.subscribe(applySnapshot) + if (bodySource) { effect( () => { @@ -242,6 +234,7 @@ export function injectGenerateVideo( ) destroyRef.onDestroy(() => { disposed = true + unsubscribeSnapshot() client.dispose() }) diff --git a/packages/ai-angular/src/inject-generation.ts b/packages/ai-angular/src/inject-generation.ts index dfd095e079..a103f38744 100644 --- a/packages/ai-angular/src/inject-generation.ts +++ b/packages/ai-angular/src/inject-generation.ts @@ -205,21 +205,6 @@ export function injectGeneration< onChunk: (c: StreamChunk) => { if (!disposed) options.onChunk?.(c) }, - onResultChange: (r: TOutput | null) => { - if (!disposed) result.set(r) - }, - onLoadingChange: (l: boolean) => { - if (!disposed) isLoading.set(l) - }, - onErrorChange: (e: Error | undefined) => { - if (!disposed) error.set(e) - }, - onStatusChange: (s: GenerationClientState) => { - if (!disposed) status.set(s) - }, - onResumeStateChange: (rs) => { - if (!disposed) runId.set(rs?.runId ?? null) - }, } const persistenceProps = @@ -253,6 +238,17 @@ export function injectGeneration< ) } + const applySnapshot = () => { + const next = client.getSnapshot() + result.set(next.result) + isLoading.set(next.isLoading) + error.set(next.error) + status.set(next.status) + runId.set(next.runId) + } + applySnapshot() + const unsubscribeSnapshot = client.subscribe(applySnapshot) + if (bodySource) { effect( () => { @@ -274,6 +270,7 @@ export function injectGeneration< ) destroyRef.onDestroy(() => { disposed = true + unsubscribeSnapshot() client.dispose() }) diff --git a/packages/ai-client/package.json b/packages/ai-client/package.json index 008f648567..aaec33c27d 100644 --- a/packages/ai-client/package.json +++ b/packages/ai-client/package.json @@ -71,7 +71,8 @@ "dependencies": { "@tanstack/ai": "workspace:^", "@tanstack/ai-event-client": "workspace:^", - "@tanstack/ai-utils": "workspace:^" + "@tanstack/ai-utils": "workspace:^", + "@tanstack/store": "^0.11.1" }, "devDependencies": { "@standard-schema/spec": "^1.1.0", diff --git a/packages/ai-client/src/audio-recorder.ts b/packages/ai-client/src/audio-recorder.ts index 0f2b79737f..7077a876ba 100644 --- a/packages/ai-client/src/audio-recorder.ts +++ b/packages/ai-client/src/audio-recorder.ts @@ -1,5 +1,7 @@ import { arrayBufferToBase64 } from '@tanstack/ai-utils' import type { AudioPart } from '@tanstack/ai/client' +import { createAtom } from './snapshot-atom' +import type { Atom } from './snapshot-atom' /** Lifecycle state of an {@link AudioRecorder}. */ export type AudioRecorderState = 'idle' | 'recording' | 'stopping' @@ -62,13 +64,13 @@ export class AudioRecorder { private stream: MediaStream | null = null private chunks: Array = [] private startedAt = 0 - private _state: AudioRecorderState = 'idle' + private readonly snapshotAtom: Atom = + createAtom('idle') // True while start() is awaiting getUserMedia (state is still 'idle' then). private starting = false // Set by cancel()/teardown during that window so start() releases the // freshly acquired stream instead of beginning a leaked recording. private pendingCancel = false - private readonly listeners = new Set<(state: AudioRecorderState) => void>() private stopResolve: ((recording: AudioRecording) => void) | null = null private stopReject: ((error: Error) => void) | null = null @@ -87,25 +89,25 @@ export class AudioRecorder { } get state(): AudioRecorderState { - return this._state + return this.snapshotAtom.get() } subscribe(cb: (state: AudioRecorderState) => void): () => void { - this.listeners.add(cb) - return () => { - this.listeners.delete(cb) - } + const { unsubscribe } = this.snapshotAtom.subscribe((next) => { + cb(next) + }) + return unsubscribe } + /** Current recorder lifecycle state. */ + getSnapshot = (): AudioRecorderState => this.snapshotAtom.get() + private setState(state: AudioRecorderState): void { - this._state = state - for (const cb of this.listeners) { - cb(state) - } + this.snapshotAtom.set(state) } async start(): Promise { - if (this._state !== 'idle' || this.starting) { + if (this.state !== 'idle' || this.starting) { return } this.starting = true @@ -168,7 +170,7 @@ export class AudioRecorder { } stop(): Promise { - if (this._state !== 'recording' || !this.recorder) { + if (this.state !== 'recording' || !this.recorder) { return Promise.reject( new Error('AudioRecorder.stop() called while not recording'), ) @@ -179,7 +181,7 @@ export class AudioRecorder { // Some browsers/codecs never fire onstop; this watchdog unwedges the // recorder instead of leaking this promise forever. const watchdog = setTimeout(() => { - if (this._state !== 'stopping') { + if (this.state !== 'stopping') { return } // Detach handlers so a late onstop/onerror from the stalled recorder @@ -215,7 +217,7 @@ export class AudioRecorder { this.pendingCancel = true return } - if (this._state === 'idle') { + if (this.state === 'idle') { return } const recorder = this.recorder diff --git a/packages/ai-client/src/byok/client.ts b/packages/ai-client/src/byok/client.ts index 5e2fde4522..eecddf457c 100644 --- a/packages/ai-client/src/byok/client.ts +++ b/packages/ai-client/src/byok/client.ts @@ -4,6 +4,8 @@ import { isProviderId, maskKey, } from '@tanstack/ai/byok' +import { createAtom, subscribeAtom } from '../snapshot-atom' +import type { Atom } from '../snapshot-atom' import { memoryStorage } from './storage' import type { ByokProvider, ProviderId } from '@tanstack/ai/byok' import type { Keyring, KeyringStorage } from './storage' @@ -91,9 +93,8 @@ export class ByokClient { #coverageAll = false #coverage: Record = {} readonly #companions: Record> = {} - readonly #listeners = new Set<() => void>() - #snapshot: ByokSnapshot #storageError: string | null = null + readonly #snapshotAtom: Atom readonly #ready: Promise constructor(options: DefineByokOptions = {}) { @@ -106,21 +107,17 @@ export class ByokClient { } } this.#locked = Boolean(this.storage.unlockable) - this.#snapshot = this.#buildSnapshot() + this.#snapshotAtom = createAtom(this.#buildSnapshot()) this.#ready = this.#hydrate() } /** Resolves when constructor hydration (peek/load) finishes. */ ready = (): Promise => this.#ready - subscribe = (listener: () => void): (() => void) => { - this.#listeners.add(listener) - return () => { - this.#listeners.delete(listener) - } - } + subscribe = (listener: () => void): (() => void) => + subscribeAtom(this.#snapshotAtom, listener) - getSnapshot = (): ByokSnapshot => this.#snapshot + getSnapshot = (): ByokSnapshot => this.#snapshotAtom.get() #buildSnapshot(): ByokSnapshot { return { @@ -371,8 +368,7 @@ export class ByokClient { } #emit(): void { - this.#snapshot = this.#buildSnapshot() - for (const listener of this.#listeners) listener() + this.#snapshotAtom.set(this.#buildSnapshot()) } } diff --git a/packages/ai-client/src/chat-client.ts b/packages/ai-client/src/chat-client.ts index 5c5f4cc5c8..6450b70ff8 100644 --- a/packages/ai-client/src/chat-client.ts +++ b/packages/ai-client/src/chat-client.ts @@ -52,9 +52,12 @@ import type { ChatDevtoolsBridge, ChatDevtoolsBridgeOptions, } from './devtools' +import { createAtom, patchAtom, subscribeAtom } from './snapshot-atom' +import type { Atom } from './snapshot-atom' import type { BoundInterrupts, ChatClientOptions, + ChatClientSnapshot, ChatClientState, ChatFetcher, ChatInterruptState, @@ -348,6 +351,24 @@ export class ChatClient< private readonly persistor?: ChatPersistor private readonly clearedStreamTracker = new ClearedStreamTracker() private currentRunId: string | null = null + private readonly snapshotAtom: Atom> = + createAtom>({ + messages: [], + status: 'ready', + isLoading: false, + error: undefined, + isSubscribed: false, + connectionStatus: 'disconnected', + sessionGenerating: false, + queue: [], + runId: null, + interruptState: { + interrupts: Object.freeze([]), + pendingInterrupts: Object.freeze([]), + interruptErrors: Object.freeze([]), + resuming: false, + } as ChatInterruptState, + }) // Interrupt-resume tracking: the run/thread of the most recent interrupted // run, so approvals/client-tool results can be sent back. Cleared when the // run terminates. This is STATE (interrupt) resume, not delivery/cursor. @@ -649,6 +670,9 @@ export class ChatClient< events: { onMessagesChange: (messages: Array) => { this.persistor?.notifyMessagesChanged(messages) + this.patchSnapshot({ + messages: messages as Array>, + }) this.callbacksRef.current.onMessagesChange(messages) }, onStreamStart: () => { @@ -866,6 +890,7 @@ export class ChatClient< }, }) + this.snapshotAtom.set(this.readSnapshot()) this.persistor?.hydrateAsync(persistedState) this.rejoinRunId = rejoinRunId @@ -1289,6 +1314,7 @@ export class ChatClient< private setCurrentRunId(runId: string | null): void { if (this.currentRunId === runId) return this.currentRunId = runId + this.patchSnapshot({ runId }) this.callbacksRef.current.onRunIdChange(runId) } @@ -1480,26 +1506,64 @@ export class ChatClient< return `${prefix}-${Date.now()}-${Math.random().toString(36).substring(7)}` } + private readSnapshot(): ChatClientSnapshot { + return { + messages: this.processor.getMessages() as Array>, + status: this.status, + isLoading: this.isLoading, + error: this.error, + isSubscribed: this.isSubscribed, + connectionStatus: this.connectionStatus, + sessionGenerating: this.sessionGenerating, + queue: this.getQueue(), + runId: this.currentRunId, + interruptState: this.interruptManager.getState(), + } + } + + private patchSnapshot( + patch: Partial>, + ): void { + patchAtom(this.snapshotAtom, patch) + } + + /** + * Subscribe to UI snapshot changes. Does not fire with the current value; + * read {@link getSnapshot} first. + * + * Named separately from {@link subscribe} (the live connection loop). + */ + subscribeSnapshot = (listener: () => void): (() => void) => + subscribeAtom(this.snapshotAtom, listener) + + /** Current UI snapshot. */ + getSnapshot = (): ChatClientSnapshot => + this.snapshotAtom.get() + private setIsLoading(isLoading: boolean): void { this.isLoading = isLoading + this.patchSnapshot({ isLoading }) this.callbacksRef.current.onLoadingChange(isLoading) this.events.loadingChanged(isLoading) } private setStatus(status: ChatClientState): void { this.status = status + this.patchSnapshot({ status }) this.callbacksRef.current.onStatusChange(status) this.devtoolsBridge.emitSnapshot() } private setIsSubscribed(isSubscribed: boolean): void { this.isSubscribed = isSubscribed + this.patchSnapshot({ isSubscribed }) this.callbacksRef.current.onSubscriptionChange(isSubscribed) this.devtoolsBridge.emitSnapshot() } private setConnectionStatus(status: ConnectionStatus): void { this.connectionStatus = status + this.patchSnapshot({ connectionStatus: status }) this.callbacksRef.current.onConnectionStatusChange(status) this.devtoolsBridge.emitSnapshot() } @@ -1507,6 +1571,7 @@ export class ChatClient< private setSessionGenerating(isGenerating: boolean): void { if (this.sessionGenerating === isGenerating) return this.sessionGenerating = isGenerating + this.patchSnapshot({ sessionGenerating: isGenerating }) this.callbacksRef.current.onSessionGeneratingChange(isGenerating) this.devtoolsBridge.emitSnapshot() } @@ -1516,6 +1581,7 @@ export class ChatClient< // Capture state before invoking callbacks so a synchronous nested change // cannot pair this publication's source with a later manager snapshot. const interruptState = this.interruptManager.getState() + this.patchSnapshot({ interruptState }) // Persist (or clear) the durable resume snapshot so a full page reload can // rehydrate pending interrupts and rejoin the run. Folded into the same // persistence adapter that stores messages (one record per chat). @@ -1558,6 +1624,7 @@ export class ChatClient< private setError(error: Error | undefined): void { this.error = error + this.patchSnapshot({ error }) this.callbacksRef.current.onErrorChange(error) this.events.errorChanged(error?.message || null) } @@ -2973,7 +3040,9 @@ export class ChatClient< } private emitQueueChange(): void { - this.callbacksRef.current.onQueueChange(this.getQueue()) + const queue = this.getQueue() + this.patchSnapshot({ queue }) + this.callbacksRef.current.onQueueChange(queue) this.devtoolsBridge.emitSnapshot() } diff --git a/packages/ai-client/src/generation-client.ts b/packages/ai-client/src/generation-client.ts index b61634bd9b..c7a36b0456 100644 --- a/packages/ai-client/src/generation-client.ts +++ b/packages/ai-client/src/generation-client.ts @@ -29,8 +29,11 @@ import type { GenerationDevtoolsBridge, GenerationDevtoolsBridgeOptions, } from './devtools' +import { createAtom, patchAtom, subscribeAtom } from './snapshot-atom' +import type { Atom } from './snapshot-atom' import type { GenerationClientOptions, + GenerationClientSnapshot, GenerationClientState, GenerationFetcher, GenerationPersistenceOptions, @@ -134,6 +137,14 @@ export class GenerationClient< private isLoading = false private error: Error | undefined = undefined private status: GenerationClientState = 'idle' + private readonly snapshotAtom: Atom> = + createAtom>({ + result: null, + isLoading: false, + error: undefined, + status: 'idle', + runId: null, + }) private resumeSnapshot: GenerationResumeSnapshot | undefined private lastEmittedResumeState: string | undefined private abortController: AbortController | null = null @@ -551,6 +562,16 @@ export class GenerationClient< // Getters // =========================== + /** + * Subscribe to UI snapshot changes. Does not fire with the current value; + * read {@link getSnapshot} first. + */ + subscribe = (listener: () => void): (() => void) => + subscribeAtom(this.snapshotAtom, listener) + + /** Current UI snapshot. */ + getSnapshot = (): GenerationClientSnapshot => this.snapshotAtom.get() + getResult(): TOutput | null { return this.result } @@ -601,6 +622,7 @@ export class GenerationClient< private setResult(rawResult: TResult | null): void { if (rawResult === null) { this.result = null + patchAtom(this.snapshotAtom, { result: null }) this.callbacksRef.onResultChange?.(null) this.devtoolsBridge.recordResultChange() return @@ -616,6 +638,7 @@ export class GenerationClient< if (transformed !== undefined) { // Non-null, non-undefined → use transformed value this.result = transformed + patchAtom(this.snapshotAtom, { result: this.result }) this.callbacksRef.onResultChange?.(this.result) this.devtoolsBridge.recordResultChange() return @@ -627,24 +650,28 @@ export class GenerationClient< // `TOutput` defaults to `TResult`, so the runtime cast is sound. // oxlint-disable-next-line eslint-js/no-restricted-syntax -- TOutput defaults to TResult when no onResult transform is supplied this.result = rawResult as unknown as TOutput + patchAtom(this.snapshotAtom, { result: this.result }) this.callbacksRef.onResultChange?.(this.result) this.devtoolsBridge.recordResultChange() } private setIsLoading(isLoading: boolean): void { this.isLoading = isLoading + patchAtom(this.snapshotAtom, { isLoading }) this.callbacksRef.onLoadingChange?.(isLoading) this.devtoolsBridge.recordLoadingChange() } private setError(error: Error | undefined): void { this.error = error + patchAtom(this.snapshotAtom, { error }) this.callbacksRef.onErrorChange?.(error) this.devtoolsBridge.recordErrorChange(error) } private setStatus(status: GenerationClientState): void { this.status = status + patchAtom(this.snapshotAtom, { status }) this.callbacksRef.onStatusChange?.(status) this.devtoolsBridge.recordStatusChange(status) } @@ -741,6 +768,7 @@ export class GenerationClient< return } this.lastEmittedResumeState = signature + patchAtom(this.snapshotAtom, { runId: resumeState?.runId ?? null }) this.callbacksRef.onResumeStateChange?.(resumeState) } diff --git a/packages/ai-client/src/generation-types.ts b/packages/ai-client/src/generation-types.ts index bee7670bb0..cb2cf82c01 100644 --- a/packages/ai-client/src/generation-types.ts +++ b/packages/ai-client/src/generation-types.ts @@ -64,6 +64,29 @@ export type InferGenerationOutput = TFn extends ( */ export type GenerationClientState = 'idle' | 'generating' | 'success' | 'error' +/** + * UI snapshot published by {@link GenerationClient.subscribe} / + * {@link GenerationClient.getSnapshot}. + */ +export interface GenerationClientSnapshot { + result: TOutput | null + isLoading: boolean + error: Error | undefined + status: GenerationClientState + runId: string | null +} + +/** + * UI snapshot published by {@link VideoGenerationClient.subscribe} / + * {@link VideoGenerationClient.getSnapshot}. + */ +export interface VideoGenerationClientSnapshot< + TOutput = unknown, +> extends GenerationClientSnapshot { + jobId: string | null + videoStatus: VideoStatusInfo | null +} + /** * Status of a persisted/restored generation run. * diff --git a/packages/ai-client/src/index.ts b/packages/ai-client/src/index.ts index a53e8bc742..b9e60ba966 100644 --- a/packages/ai-client/src/index.ts +++ b/packages/ai-client/src/index.ts @@ -57,6 +57,7 @@ export type { ChatRequestBody, InferChatMessages, InferredClientContext, + ChatClientSnapshot, ChatClientState, ConnectionStatus, ChatFetcher, @@ -77,7 +78,9 @@ export type { export type { InferGenerationOutput, InferGenerationOutputFromReturn, + GenerationClientSnapshot, GenerationClientState, + VideoGenerationClientSnapshot, GenerationPersistenceOptions, GenerationClientOptions, GenerationFetcher, diff --git a/packages/ai-client/src/realtime-client.ts b/packages/ai-client/src/realtime-client.ts index 7808818745..04b57d8088 100644 --- a/packages/ai-client/src/realtime-client.ts +++ b/packages/ai-client/src/realtime-client.ts @@ -1,4 +1,6 @@ import { convertSchemaToJsonSchema } from '@tanstack/ai/client' +import { createAtom, patchAtom, subscribeAtom } from './snapshot-atom' +import type { Atom } from './snapshot-atom' import type { AnyClientTool, AudioVisualization, @@ -49,13 +51,18 @@ export class RealtimeClient { new Set() private unsubscribers: Array<() => void> = [] - private state: RealtimeClientState = { - status: 'idle', - mode: 'idle', - messages: [], - pendingUserTranscript: null, - pendingAssistantTranscript: null, - error: null, + private readonly snapshotAtom: Atom = + createAtom({ + status: 'idle', + mode: 'idle', + messages: [], + pendingUserTranscript: null, + pendingAssistantTranscript: null, + error: null, + }) + + private get state(): RealtimeClientState { + return this.snapshotAtom.get() } constructor(options: RealtimeClientOptions) { @@ -88,7 +95,13 @@ export class RealtimeClient { return } - this.updateState({ status: 'connecting', error: null }) + this.updateState({ + status: 'connecting', + error: null, + messages: [], + pendingUserTranscript: null, + pendingAssistantTranscript: null, + }) try { // Fetch token from server @@ -195,6 +208,7 @@ export class RealtimeClient { return } this.connection.interrupt() + this.updateState({ pendingAssistantTranscript: null }) } // ============================================================================ @@ -331,6 +345,16 @@ export class RealtimeClient { } } + /** + * Subscribe to UI snapshot changes. Does not fire with the current value; + * read {@link getSnapshot} first. + */ + subscribe = (listener: () => void): (() => void) => + subscribeAtom(this.snapshotAtom, listener) + + /** Current UI snapshot. */ + getSnapshot = (): RealtimeClientState => this.snapshotAtom.get() + // ============================================================================ // Cleanup // ============================================================================ @@ -349,7 +373,7 @@ export class RealtimeClient { // ============================================================================ private updateState(updates: Partial): void { - this.state = { ...this.state, ...updates } + patchAtom(this.snapshotAtom, updates) // Notify callbacks for (const callback of this.stateChangeCallbacks) { diff --git a/packages/ai-client/src/snapshot-atom.ts b/packages/ai-client/src/snapshot-atom.ts new file mode 100644 index 0000000000..d1932dbed9 --- /dev/null +++ b/packages/ai-client/src/snapshot-atom.ts @@ -0,0 +1,41 @@ +import { createAtom } from '@tanstack/store' +import type { Atom } from '@tanstack/store' + +export { createAtom } +export type { Atom } + +/** + * Merge a partial update into an object atom. Skips notify when every + * provided field is `Object.is`-equal to the current value. + */ +export function patchAtom( + atom: Atom, + patch: Partial, +): void { + atom.set((prev) => { + let changed = false + const next = { ...prev } + for (const key of Object.keys(patch) as Array) { + if (Object.is(prev[key], patch[key])) continue + next[key] = patch[key] as T[keyof T] + changed = true + } + return changed ? next : prev + }) +} + +/** + * Adapt a Store atom's `{ unsubscribe }` subscription to the + * `() => void` unsubscribe that `useSyncExternalStore` expects. + */ +export function subscribeAtom( + atom: { + subscribe: (listener: (value: T) => void) => { unsubscribe: () => void } + }, + listener: () => void, +): () => void { + const { unsubscribe } = atom.subscribe(() => { + listener() + }) + return unsubscribe +} diff --git a/packages/ai-client/src/types.ts b/packages/ai-client/src/types.ts index 01373cef02..9c6868b837 100644 --- a/packages/ai-client/src/types.ts +++ b/packages/ai-client/src/types.ts @@ -364,6 +364,27 @@ export type ToolResultState = */ export type ChatClientState = 'ready' | 'submitted' | 'streaming' | 'error' +/** + * UI snapshot published by {@link ChatClient.subscribeSnapshot} / + * {@link ChatClient.getSnapshot}. + */ +export interface ChatClientSnapshot< + TTools extends ReadonlyArray = any, + TInterrupts extends ReadonlyArray> = + readonly [], +> { + messages: Array> + status: ChatClientState + isLoading: boolean + error: Error | undefined + isSubscribed: boolean + connectionStatus: ConnectionStatus + sessionGenerating: boolean + queue: Array + runId: string | null + interruptState: ChatInterruptState +} + /** * Connection lifecycle state for the subscription loop. */ diff --git a/packages/ai-client/src/video-generation-client.ts b/packages/ai-client/src/video-generation-client.ts index 7ae11c2fc1..fa9a2cb5f6 100644 --- a/packages/ai-client/src/video-generation-client.ts +++ b/packages/ai-client/src/video-generation-client.ts @@ -29,6 +29,8 @@ import type { VideoDevtoolsBridge, VideoDevtoolsBridgeOptions, } from './devtools' +import { createAtom, patchAtom, subscribeAtom } from './snapshot-atom' +import type { Atom } from './snapshot-atom' import type { GenerationClientState, GenerationFetcher, @@ -39,6 +41,7 @@ import type { VideoGenerateInput, VideoGenerateResult, VideoGenerationClientOptions, + VideoGenerationClientSnapshot, VideoStatusInfo, } from './generation-types' @@ -139,6 +142,16 @@ export class VideoGenerationClient { private isLoading = false private error: Error | undefined = undefined private status: GenerationClientState = 'idle' + private readonly snapshotAtom: Atom> = + createAtom>({ + result: null, + isLoading: false, + error: undefined, + status: 'idle', + runId: null, + jobId: null, + videoStatus: null, + }) private resumeSnapshot: GenerationResumeSnapshot | undefined private abortController: AbortController | null = null private rejoinedRunId: string | undefined @@ -558,6 +571,17 @@ export class VideoGenerationClient { // Getters // =========================== + /** + * Subscribe to UI snapshot changes. Does not fire with the current value; + * read {@link getSnapshot} first. + */ + subscribe = (listener: () => void): (() => void) => + subscribeAtom(this.snapshotAtom, listener) + + /** Current UI snapshot. */ + getSnapshot = (): VideoGenerationClientSnapshot => + this.snapshotAtom.get() + getResult(): TOutput | null { return this.result } @@ -616,6 +640,7 @@ export class VideoGenerationClient { private setResult(rawResult: VideoGenerateResult | null): void { if (rawResult === null) { this.result = null + patchAtom(this.snapshotAtom, { result: null }) this.callbacksRef.onResultChange?.(null) this.devtoolsBridge.recordResultChange() return @@ -638,6 +663,7 @@ export class VideoGenerationClient { if (transformed !== undefined) { // Non-null, non-undefined → use transformed value this.result = transformed + patchAtom(this.snapshotAtom, { result: this.result }) this.callbacksRef.onResultChange?.(this.result) this.devtoolsBridge.recordResultChange() return @@ -650,36 +676,42 @@ export class VideoGenerationClient { // sound. // oxlint-disable-next-line eslint-js/no-restricted-syntax -- TOutput defaults to VideoGenerateResult when no onResult transform is supplied this.result = rawResult as unknown as TOutput + patchAtom(this.snapshotAtom, { result: this.result }) this.callbacksRef.onResultChange?.(this.result) this.devtoolsBridge.recordResultChange() } private setJobId(jobId: string | null): void { this.jobId = jobId + patchAtom(this.snapshotAtom, { jobId }) this.callbacksRef.onJobIdChange?.(jobId) this.devtoolsBridge.recordJobIdChange() } private setVideoStatus(status: VideoStatusInfo | null): void { this.videoStatus = status + patchAtom(this.snapshotAtom, { videoStatus: status }) this.callbacksRef.onVideoStatusChange?.(status) this.devtoolsBridge.recordVideoStatusChange() } private setIsLoading(isLoading: boolean): void { this.isLoading = isLoading + patchAtom(this.snapshotAtom, { isLoading }) this.callbacksRef.onLoadingChange?.(isLoading) this.devtoolsBridge.recordLoadingChange() } private setError(error: Error | undefined): void { this.error = error + patchAtom(this.snapshotAtom, { error }) this.callbacksRef.onErrorChange?.(error) this.devtoolsBridge.recordErrorChange(error) } private setStatus(status: GenerationClientState): void { this.status = status + patchAtom(this.snapshotAtom, { status }) this.callbacksRef.onStatusChange?.(status) this.devtoolsBridge.recordStatusChange(status) } @@ -768,6 +800,7 @@ export class VideoGenerationClient { : {}), } : null + patchAtom(this.snapshotAtom, { runId: resumeState?.runId ?? null }) this.callbacksRef.onResumeStateChange?.(resumeState) } diff --git a/packages/ai-client/tests/chat-client.test.ts b/packages/ai-client/tests/chat-client.test.ts index 44a8ce4ce0..b8da70d6a0 100644 --- a/packages/ai-client/tests/chat-client.test.ts +++ b/packages/ai-client/tests/chat-client.test.ts @@ -68,6 +68,36 @@ describe('ChatClient', () => { expect(client.getError()).toBeUndefined() }) + it('exposes a UI snapshot that subscribeSnapshot notifies', () => { + const adapter = createMockConnectionAdapter() + const initialMessages: Array = [ + { + id: 'msg-1', + role: 'user', + parts: [{ type: 'text', content: 'Hello' }], + createdAt: new Date(), + }, + ] + const client = new ChatClient({ + connection: adapter, + initialMessages, + }) + + const snapshot = client.getSnapshot() + expect(snapshot.messages).toEqual(initialMessages) + expect(snapshot.status).toBe('ready') + expect(snapshot.isLoading).toBe(false) + expect(client.getSnapshot()).toBe(snapshot) + + const listener = vi.fn() + const stop = client.subscribeSnapshot(listener) + client.setMessagesManually([]) + expect(listener).toHaveBeenCalledTimes(1) + expect(client.getSnapshot().messages).toEqual([]) + expect(client.getSnapshot()).not.toBe(snapshot) + stop() + }) + it('should initialize with provided messages', () => { const adapter = createMockConnectionAdapter() const initialMessages: Array = [ diff --git a/packages/ai-client/tests/client-snapshots.test.ts b/packages/ai-client/tests/client-snapshots.test.ts new file mode 100644 index 0000000000..90efed3e5b --- /dev/null +++ b/packages/ai-client/tests/client-snapshots.test.ts @@ -0,0 +1,94 @@ +import { describe, expect, it, vi } from 'vitest' +import { + AudioRecorder, + GenerationClient, + RealtimeClient, + VideoGenerationClient, +} from '../src' +import type { RealtimeAdapter } from '../src' + +describe('client UI snapshots', () => { + it('GenerationClient notifies subscribe and keeps getSnapshot identity until a change', async () => { + const client = new GenerationClient({ + fetcher: async () => ({ id: '1' }), + }) + const snapshot = client.getSnapshot() + expect(snapshot).toEqual({ + result: null, + isLoading: false, + error: undefined, + status: 'idle', + runId: null, + }) + expect(client.getSnapshot()).toBe(snapshot) + + const listener = vi.fn() + const stop = client.subscribe(listener) + await client.generate({ prompt: 'test' }) + + expect(listener).toHaveBeenCalled() + expect(client.getSnapshot().status).toBe('success') + expect(client.getSnapshot().result).toEqual({ id: '1' }) + expect(client.getSnapshot()).not.toBe(snapshot) + stop() + }) + + it('VideoGenerationClient snapshot includes job fields', async () => { + const result = { + jobId: 'job-1', + status: 'completed' as const, + url: 'https://example.com/video.mp4', + } + const client = new VideoGenerationClient({ + fetcher: async () => result, + }) + const snapshot = client.getSnapshot() + expect(snapshot.jobId).toBeNull() + expect(snapshot.videoStatus).toBeNull() + expect(client.getSnapshot()).toBe(snapshot) + + const listener = vi.fn() + const stop = client.subscribe(listener) + await client.generate({ prompt: 'test video' }) + + expect(listener).toHaveBeenCalled() + expect(client.getSnapshot().status).toBe('success') + expect(client.getSnapshot().result).toEqual(result) + expect(client.getSnapshot()).not.toBe(snapshot) + stop() + }) + + it('AudioRecorder getSnapshot matches state', () => { + const recorder = new AudioRecorder() + expect(recorder.getSnapshot()).toBe('idle') + expect(recorder.getSnapshot()).toBe(recorder.state) + }) + + it('RealtimeClient subscribe fires when connect fails', async () => { + const adapter: RealtimeAdapter = { + provider: 'test', + connect: async () => { + throw new Error('unused') + }, + } + const client = new RealtimeClient({ + getToken: async () => { + throw new Error('no token') + }, + adapter, + }) + const snapshot = client.getSnapshot() + expect(snapshot.status).toBe('idle') + expect(client.getSnapshot()).toBe(snapshot) + + const listener = vi.fn() + const stop = client.subscribe(listener) + await expect(client.connect()).rejects.toThrow('no token') + + expect(listener).toHaveBeenCalled() + expect(client.getSnapshot().status).toBe('error') + expect(client.getSnapshot()).not.toBe(snapshot) + stop() + client.destroy() + }) +}) diff --git a/packages/ai-client/tests/snapshot-atom.test.ts b/packages/ai-client/tests/snapshot-atom.test.ts new file mode 100644 index 0000000000..74da6dbdc1 --- /dev/null +++ b/packages/ai-client/tests/snapshot-atom.test.ts @@ -0,0 +1,31 @@ +import { describe, expect, it, vi } from 'vitest' +import { createAtom, patchAtom, subscribeAtom } from '../src/snapshot-atom' + +describe('snapshot-atom', () => { + it('patchAtom skips notify when every field is unchanged', () => { + const atom = createAtom({ count: 1, label: 'a' }) + const listener = vi.fn() + const stop = subscribeAtom(atom, listener) + + patchAtom(atom, { count: 1, label: 'a' }) + expect(listener).not.toHaveBeenCalled() + expect(atom.get()).toEqual({ count: 1, label: 'a' }) + + patchAtom(atom, { count: 2 }) + expect(listener).toHaveBeenCalledTimes(1) + expect(atom.get()).toEqual({ count: 2, label: 'a' }) + stop() + }) + + it('subscribeAtom adapts { unsubscribe } to a plain cleanup', () => { + const atom = createAtom(0) + const listener = vi.fn() + const stop = subscribeAtom(atom, listener) + + atom.set(1) + expect(listener).toHaveBeenCalledTimes(1) + stop() + atom.set(2) + expect(listener).toHaveBeenCalledTimes(1) + }) +}) diff --git a/packages/ai-octane/src/use-chat.tsrx b/packages/ai-octane/src/use-chat.tsrx index f95f7f9fb8..d197d37ba9 100644 --- a/packages/ai-octane/src/use-chat.tsrx +++ b/packages/ai-octane/src/use-chat.tsrx @@ -90,12 +90,6 @@ export function useChat< useRef>(options) optionsRef.current = options - const syncResumeState = useCallback((target: ChatClient | null) => { - if (!target) return - setRunId(target.getCurrentRunId()) - setInterruptState(target.getInterruptState()) - }, []) - // Create ChatClient instance with callbacks to sync state const { client, initialization } = useMemo(() => { const messagesToUse = options.initialMessages || [] @@ -203,69 +197,11 @@ export function useChat< ...(options.streamProcessor !== undefined && { streamProcessor: options.streamProcessor, }), - onMessagesChange: (newMessages: Array>) => { - runOrQueueForActiveInstance(() => { - setMessages(newMessages) - }) - }, - onLoadingChange: (newIsLoading: boolean) => { - runOrQueueForActiveInstance(() => { - const currentInstance = getActiveInstance() - if (!currentInstance) return - setIsLoading(newIsLoading) - syncResumeState(currentInstance) - }) - }, - onErrorChange: (newError: Error | undefined) => { - runOrQueueForActiveInstance(() => { - setError(newError) - }) - }, - onStatusChange: (status: ChatClientState) => { - runOrQueueForActiveInstance(() => { - setStatus(status) - }) - }, - onSubscriptionChange: (nextIsSubscribed: boolean) => { - runOrQueueForActiveInstance(() => { - setIsSubscribed(nextIsSubscribed) - }) - }, - onConnectionStatusChange: (nextStatus: ConnectionStatus) => { - runOrQueueForActiveInstance(() => { - setConnectionStatus(nextStatus) - }) - }, - onSessionGeneratingChange: (isGenerating: boolean) => { - runOrQueueForActiveInstance(() => { - setSessionGenerating(isGenerating) - }) - }, ...(optionsRef.current.queue !== undefined && { queue: optionsRef.current.queue, }), - onQueueChange: (nextQueue: Array) => { - runOrQueueForActiveInstance(() => { - setQueue(nextQueue) - }) - }, - onRunIdChange: (nextRunId) => { - runOrQueueForActiveInstance(() => { - setRunId(nextRunId) - }) - }, - onResumeStateChange: (_nextResumeState, nextPendingInterrupts) => { - runOrQueueForActiveInstance(() => { - setInterruptState((current) => ({ - ...current, - interrupts: nextPendingInterrupts, - pendingInterrupts: nextPendingInterrupts, - })) - }) - }, onInterruptStateChange: (nextInterruptState, context) => { runOrQueueForActiveInstance(() => { - setInterruptState(nextInterruptState) optionsRef.current.onInterruptStateChange?.( nextInterruptState, context, @@ -275,7 +211,7 @@ export function useChat< }) instanceHolder.current = instance return { client: instance, initialization: initializationState } - }, [clientId, syncResumeState]) + }, [clientId]) useEffect(() => { activeClientRef.current = client @@ -296,10 +232,21 @@ export function useChat< }, [client, initialization]) useEffect(() => { - const clientMessages = client.getMessages() - if (clientMessages !== messagesRef.current) { - setMessages(clientMessages) + const applySnapshot = () => { + const next = client.getSnapshot() + setMessages(next.messages) + setIsLoading(next.isLoading) + setError(next.error) + setStatus(next.status) + setIsSubscribed(next.isSubscribed) + setConnectionStatus(next.connectionStatus) + setSessionGenerating(next.sessionGenerating) + setQueue(next.queue) + setRunId(next.runId) + setInterruptState(next.interruptState) } + applySnapshot() + return client.subscribeSnapshot(applySnapshot) }, [client]) // OCTANE DIVERGENCE: upstream captures the initial transport. ChatClient @@ -369,7 +316,6 @@ export function useChat< useEffect(() => { client.attach() client.mountDevtools() - syncResumeState(client) return () => { client.detach() if (optionsRef.current.live) { @@ -382,20 +328,16 @@ export function useChat< activeClientRef.current = null } } - }, [client, syncResumeState]) + }, [client]) const sendMessage = useCallback( async ( content: string | MultimodalContent, sendOptions?: SendMessageOptions, ) => { - try { - await client.sendMessage(content, undefined, sendOptions) - } finally { - syncResumeState(client) - } + await client.sendMessage(content, undefined, sendOptions) }, - [client, syncResumeState], + [client], ) const cancelQueued = useCallback( @@ -407,22 +349,14 @@ export function useChat< const append = useCallback( async (message: ModelMessage | UIMessage) => { - try { - await client.append(message) - } finally { - syncResumeState(client) - } + await client.append(message) }, - [client, syncResumeState], + [client], ) const reload = useCallback(async () => { - try { - await client.reload() - } finally { - syncResumeState(client) - } - }, [client, syncResumeState]) + await client.reload() + }, [client]) const stop = useCallback(() => { client.stop() @@ -430,8 +364,7 @@ export function useChat< const clear = useCallback(() => { client.clear() - syncResumeState(client) - }, [client, syncResumeState]) + }, [client]) const setMessagesManually = useCallback( (newMessages: Array>) => { @@ -456,21 +389,15 @@ export function useChat< const addToolApprovalResponse = useCallback( async (response: { id: string; approved: boolean }) => { await client.addToolApprovalResponse(response) - syncResumeState(client) }, - [client, syncResumeState], + [client], ) const resumeInterrupts = useCallback( async (resumeItems: Array, state?: ChatResumeState) => { - const result = await client.resumeInterrupts( - resumeItems, - state ?? undefined, - ) - syncResumeState(client) - return result + return await client.resumeInterrupts(resumeItems, state ?? undefined) }, - [client, syncResumeState], + [client], ) const resolveInterrupts = useCallback( diff --git a/packages/ai-octane/src/use-generate-video.tsrx b/packages/ai-octane/src/use-generate-video.tsrx index 5772a97326..c18dddc7bf 100644 --- a/packages/ai-octane/src/use-generate-video.tsrx +++ b/packages/ai-octane/src/use-generate-video.tsrx @@ -172,12 +172,6 @@ export function useGenerateVideo( onStatusUpdate: (s: VideoStatusInfo) => { optionsRef.current.onStatusUpdate?.(s) }, - onResultChange: setResult, - onLoadingChange: setIsLoading, - onErrorChange: setError, - onStatusChange: setStatus, - onJobIdChange: setJobId, - onVideoStatusChange: setVideoStatus, } if (opts.connection) { @@ -199,6 +193,20 @@ export function useGenerateVideo( ) }, [clientId]) + useEffect(() => { + const applySnapshot = () => { + const next = client.getSnapshot() + setResult(next.result) + setIsLoading(next.isLoading) + setError(next.error) + setStatus(next.status) + setJobId(next.jobId) + setVideoStatus(next.videoStatus) + } + applySnapshot() + return client.subscribe(applySnapshot) + }, [client]) + // Sync body changes without recreating client useEffect(() => { // Conditional spread: target uses strict-optional `body?: T`. diff --git a/packages/ai-octane/src/use-generation.tsrx b/packages/ai-octane/src/use-generation.tsrx index e3ca19c084..23eb3b0489 100644 --- a/packages/ai-octane/src/use-generation.tsrx +++ b/packages/ai-octane/src/use-generation.tsrx @@ -160,10 +160,6 @@ export function useGeneration< onChunk: (c: StreamChunk) => { optionsRef.current.onChunk?.(c) }, - onResultChange: setResult, - onLoadingChange: setIsLoading, - onErrorChange: setError, - onStatusChange: setStatus, } if (opts.connection) { @@ -185,6 +181,18 @@ export function useGeneration< ) }, [clientId]) + useEffect(() => { + const applySnapshot = () => { + const next = client.getSnapshot() + setResult(next.result) + setIsLoading(next.isLoading) + setError(next.error) + setStatus(next.status) + } + applySnapshot() + return client.subscribe(applySnapshot) + }, [client]) + // Sync body changes without recreating client useEffect(() => { // Conditional spread: target uses strict-optional `body?: T`. diff --git a/packages/ai-octane/src/use-realtime-chat.tsrx b/packages/ai-octane/src/use-realtime-chat.tsrx index b486b8cc12..4ed30a20ee 100644 --- a/packages/ai-octane/src/use-realtime-chat.tsrx +++ b/packages/ai-octane/src/use-realtime-chat.tsrx @@ -124,17 +124,14 @@ export function useRealtimeChat( semanticEagerness: initial.semanticEagerness, }), onStatusChange: (newStatus) => { - setStatus(newStatus) // OCTANE DIVERGENCE: upstream declares this callback but does not // forward status changes beyond its own hook state. optionsRef.current.onStatusChange?.(newStatus) }, onModeChange: (newMode) => { - setMode(newMode) optionsRef.current.onModeChange?.(newMode) }, onMessage: (message) => { - setMessages((prev) => [...prev, message]) optionsRef.current.onMessage?.(message) }, onUsage: (usage) => { @@ -144,31 +141,36 @@ export function useRealtimeChat( optionsRef.current.onGoAway?.(timeLeft) }, onError: (err) => { - setError(err) optionsRef.current.onError?.(err) }, onConnect: () => { - setError(null) optionsRef.current.onConnect?.() }, onDisconnect: () => { optionsRef.current.onDisconnect?.() }, onInterrupted: () => { - setPendingAssistantTranscript(null) optionsRef.current.onInterrupted?.() }, }) - - // Subscribe to state changes for transcripts - clientRef.current.onStateChange((state) => { - setPendingUserTranscript(state.pendingUserTranscript) - setPendingAssistantTranscript(state.pendingAssistantTranscript) - }) } const client = clientRef.current + useEffect(() => { + const applySnapshot = () => { + const next = client.getSnapshot() + setStatus(next.status) + setMode(next.mode) + setMessages(next.messages) + setPendingUserTranscript(next.pendingUserTranscript) + setPendingAssistantTranscript(next.pendingAssistantTranscript) + setError(next.error) + } + applySnapshot() + return client.subscribe(applySnapshot) + }, [client]) + // Audio level animation loop useEffect(() => { function updateLevels() { @@ -200,10 +202,6 @@ export function useRealtimeChat( // Connection methods const connect = useCallback(async () => { - setError(null) - setMessages([]) - setPendingUserTranscript(null) - setPendingAssistantTranscript(null) await client.connect() }, [client]) diff --git a/packages/ai-preact/src/use-chat.ts b/packages/ai-preact/src/use-chat.ts index f8376da1ee..2eaaeb7c62 100644 --- a/packages/ai-preact/src/use-chat.ts +++ b/packages/ai-preact/src/use-chat.ts @@ -1,21 +1,11 @@ import { ChatClient } from '@tanstack/ai-client' import { createChatDevtoolsBridge } from '@tanstack/ai-client/devtools' -import { - useCallback, - useEffect, - useId, - useMemo, - useRef, - useState, -} from 'preact/hooks' +import { useSyncExternalStore } from 'preact/compat' +import { useCallback, useEffect, useId, useMemo, useRef } from 'preact/hooks' import type { - ChatClientState, ResolvableChatInterrupt, - ChatInterruptState, ChatResumeState, - ConnectionStatus, InferredClientContext, - QueuedMessage, SendMessageOptions, } from '@tanstack/ai-client' import type { @@ -32,9 +22,6 @@ import type { UseChatReturn, } from './types' -const EMPTY_INTERRUPTS = Object.freeze([]) -const EMPTY_INTERRUPT_ERRORS = Object.freeze([]) - export function useChat< const TTools extends ReadonlyArray = any, TContext = InferredClientContext, @@ -50,32 +37,6 @@ export function useChat< const hookId = useId() const clientId = options.threadId ?? hookId - const [messages, setMessages] = useState>>( - options.initialMessages || [], - ) - const [isLoading, setIsLoading] = useState(false) - const [error, setError] = useState(undefined) - const [status, setStatus] = useState('ready') - const [isSubscribed, setIsSubscribed] = useState(false) - const [connectionStatus, setConnectionStatus] = - useState('disconnected') - const [sessionGenerating, setSessionGenerating] = useState(false) - const [queue, setQueue] = useState>([]) - const [runId, setRunId] = useState(null) - const [interruptState, setInterruptState] = useState< - ChatInterruptState - >(() => ({ - interrupts: EMPTY_INTERRUPTS, - pendingInterrupts: EMPTY_INTERRUPTS, - interruptErrors: EMPTY_INTERRUPT_ERRORS, - resuming: false, - })) - - // Track current messages in a ref to preserve them when client is recreated - const messagesRef = useRef>>( - options.initialMessages || [], - ) - const isFirstMountRef = useRef(true) const activeClientRef = useRef(null) const cleanupInvalidationRef = useRef | null>( null, @@ -89,19 +50,8 @@ export function useChat< optionsRef.current = options - const syncResumeState = useCallback((target: ChatClient | null) => { - if (!target) return - setRunId(target.getCurrentRunId()) - setInterruptState(target.getInterruptState()) - }, []) - - useEffect(() => { - messagesRef.current = messages - }, [messages]) - const { client, initialization } = useMemo(() => { const messagesToUse = options.initialMessages || [] - isFirstMountRef.current = false // Build options with conditional spreads for fields whose source // type is `T | undefined` but the ChatClient target uses a strict @@ -209,69 +159,11 @@ export function useChat< ...(options.streamProcessor !== undefined && { streamProcessor: options.streamProcessor, }), - onMessagesChange: (newMessages: Array>) => { - runOrQueueForActiveInstance(() => { - setMessages(newMessages) - }) - }, - onLoadingChange: (newIsLoading: boolean) => { - runOrQueueForActiveInstance(() => { - const currentInstance = getActiveInstance() - if (!currentInstance) return - setIsLoading(newIsLoading) - syncResumeState(currentInstance) - }) - }, - onStatusChange: (newStatus: ChatClientState) => { - runOrQueueForActiveInstance(() => { - setStatus(newStatus) - }) - }, - onErrorChange: (newError: Error | undefined) => { - runOrQueueForActiveInstance(() => { - setError(newError) - }) - }, - onSubscriptionChange: (nextIsSubscribed: boolean) => { - runOrQueueForActiveInstance(() => { - setIsSubscribed(nextIsSubscribed) - }) - }, - onConnectionStatusChange: (nextStatus: ConnectionStatus) => { - runOrQueueForActiveInstance(() => { - setConnectionStatus(nextStatus) - }) - }, - onSessionGeneratingChange: (isGenerating: boolean) => { - runOrQueueForActiveInstance(() => { - setSessionGenerating(isGenerating) - }) - }, ...(optionsRef.current.queue !== undefined && { queue: optionsRef.current.queue, }), - onQueueChange: (nextQueue: Array) => { - runOrQueueForActiveInstance(() => { - setQueue(nextQueue) - }) - }, - onRunIdChange: (nextRunId) => { - runOrQueueForActiveInstance(() => { - setRunId(nextRunId) - }) - }, - onResumeStateChange: (_nextResumeState, nextPendingInterrupts) => { - runOrQueueForActiveInstance(() => { - setInterruptState((current) => ({ - ...current, - interrupts: nextPendingInterrupts, - pendingInterrupts: nextPendingInterrupts, - })) - }) - }, onInterruptStateChange: (nextInterruptState, context) => { runOrQueueForActiveInstance(() => { - setInterruptState(nextInterruptState) optionsRef.current.onInterruptStateChange?.( nextInterruptState, context, @@ -281,7 +173,7 @@ export function useChat< }) instanceHolder.current = instance return { client: instance, initialization: initializationState } - }, [clientId, syncResumeState]) + }, [clientId]) useEffect(() => { activeClientRef.current = client @@ -301,12 +193,10 @@ export function useChat< } }, [client, initialization]) - useEffect(() => { - const clientMessages = client.getMessages() - if (clientMessages !== messagesRef.current) { - setMessages(clientMessages) - } - }, [client]) + const snapshot = useSyncExternalStore( + client.subscribeSnapshot, + client.getSnapshot, + ) // Sync body / forwardedProps changes to the client. // Both populate the same wire payload; `forwardedProps` is preferred @@ -368,10 +258,6 @@ export function useChat< cleanupInvalidationRef.current = null } client.mountDevtools() - // Delivery-durability resume is transparent: the resumable SSE connection - // adapter reattaches via the browser's native Last-Event-ID on reconnect. - // We only seed interrupt (state) resume from the client here. - syncResumeState(client) return () => { cleanupInvalidationRef.current = setTimeout(() => { @@ -400,7 +286,7 @@ export function useChat< } cleanupDisposalRef.current = disposal } - }, [client, syncResumeState]) + }, [client]) // All callback options are read through optionsRef at call time, so fresh // closures from each render are picked up without recreating the client. @@ -409,40 +295,28 @@ export function useChat< content: string | MultimodalContent, sendOptions?: SendMessageOptions, ) => { - try { - await client.sendMessage(content, undefined, sendOptions) - } finally { - syncResumeState(client) - } + await client.sendMessage(content, undefined, sendOptions) }, - [client, syncResumeState], + [client], ) const cancelQueued = useCallback( (id: string) => { client.cancelQueued(id) }, - [client, syncResumeState], + [client], ) const append = useCallback( async (message: ModelMessage | UIMessage) => { - try { - await client.append(message) - } finally { - syncResumeState(client) - } + await client.append(message) }, - [client, syncResumeState], + [client], ) const reload = useCallback(async () => { - try { - await client.reload() - } finally { - syncResumeState(client) - } - }, [client, syncResumeState]) + await client.reload() + }, [client]) const stop = useCallback(() => { client.stop() @@ -450,8 +324,7 @@ export function useChat< const clear = useCallback(() => { client.clear() - syncResumeState(client) - }, [client, syncResumeState]) + }, [client]) const setMessagesManually = useCallback( (newMessages: Array>) => { @@ -476,18 +349,15 @@ export function useChat< const addToolApprovalResponse = useCallback( async (response: { id: string; approved: boolean }) => { await client.addToolApprovalResponse(response) - syncResumeState(client) }, - [client, syncResumeState], + [client], ) const resumeInterrupts = useCallback( async (resumeItems: Array, state?: ChatResumeState) => { - const result = await client.resumeInterrupts(resumeItems, state) - syncResumeState(client) - return result + return await client.resumeInterrupts(resumeItems, state) }, - [client, syncResumeState], + [client], ) const resolveInterrupts = useCallback( @@ -521,7 +391,7 @@ export function useChat< [client], ) - const renderedMessages = client.getMessages() + const renderedMessages = snapshot.messages return { messages: renderedMessages, @@ -529,23 +399,23 @@ export function useChat< append, reload, stop, - isLoading, - error, - status, - isSubscribed, - connectionStatus, - sessionGenerating, + isLoading: snapshot.isLoading, + error: snapshot.error, + status: snapshot.status, + isSubscribed: snapshot.isSubscribed, + connectionStatus: snapshot.connectionStatus, + sessionGenerating: snapshot.sessionGenerating, setMessages: setMessagesManually, clear, addToolResult, addToolApprovalResponse, - queue, + queue: snapshot.queue, cancelQueued, - runId, - interrupts: interruptState.interrupts, - pendingInterrupts: interruptState.pendingInterrupts, - interruptErrors: interruptState.interruptErrors, - resuming: interruptState.resuming, + runId: snapshot.runId, + interrupts: snapshot.interruptState.interrupts, + pendingInterrupts: snapshot.interruptState.pendingInterrupts, + interruptErrors: snapshot.interruptState.interruptErrors, + resuming: snapshot.interruptState.resuming, resolveInterrupts, cancelInterrupts, retryInterrupts, diff --git a/packages/ai-react/src/use-chat.ts b/packages/ai-react/src/use-chat.ts index e5edb97d50..c567df72c2 100644 --- a/packages/ai-react/src/use-chat.ts +++ b/packages/ai-react/src/use-chat.ts @@ -1,6 +1,13 @@ import { ChatClient } from '@tanstack/ai-client' import { createChatDevtoolsBridge } from '@tanstack/ai-client/devtools' -import { useCallback, useEffect, useId, useMemo, useRef, useState } from 'react' +import { + useCallback, + useEffect, + useId, + useMemo, + useRef, + useSyncExternalStore, +} from 'react' import type { AnyClientTool, InferSchemaType, @@ -11,13 +18,9 @@ import type { StreamChunk, } from '@tanstack/ai/client' import type { - ChatClientState, ResolvableChatInterrupt, - ChatInterruptState, ChatResumeState, - ConnectionStatus, InferredClientContext, - QueuedMessage, SendMessageOptions, StructuredOutputPart, } from '@tanstack/ai-client' @@ -30,9 +33,6 @@ import type { UseChatReturn, } from './types' -const EMPTY_INTERRUPTS = Object.freeze([]) -const EMPTY_INTERRUPT_ERRORS = Object.freeze([]) - export function useChat< const TTools extends ReadonlyArray = any, TSchema extends SchemaInput | undefined = undefined, @@ -49,35 +49,9 @@ export function useChat< const hookId = useId() const clientId = options.threadId ?? hookId - const [messages, setMessages] = useState>>( - options.initialMessages || [], - ) - const [isLoading, setIsLoading] = useState(false) - const [error, setError] = useState(undefined) - const [status, setStatus] = useState('ready') - const [isSubscribed, setIsSubscribed] = useState(false) - const [connectionStatus, setConnectionStatus] = - useState('disconnected') - const [sessionGenerating, setSessionGenerating] = useState(false) - const [queue, setQueue] = useState>([]) - const [runId, setRunId] = useState(null) - const [interruptState, setInterruptState] = useState< - ChatInterruptState - >(() => ({ - interrupts: EMPTY_INTERRUPTS, - pendingInterrupts: EMPTY_INTERRUPTS, - interruptErrors: EMPTY_INTERRUPT_ERRORS, - resuming: false, - })) - type Partial = DeepPartial>> type Final = InferSchemaType> - // Track current messages in a ref to preserve them when client is recreated - const messagesRef = useRef>>( - options.initialMessages || [], - ) - const isFirstMountRef = useRef(true) const subscribedRef = useRef(false) const activeClientRef = useRef(null) const cleanupInvalidationRef = useRef | null>( @@ -88,24 +62,14 @@ export function useChat< timeout: ReturnType } | null>(null) - // Update ref synchronously during render so it's always current when useMemo runs. - messagesRef.current = messages - // Track current options in a ref to avoid recreating client when options change const optionsRef = useRef>(options) optionsRef.current = options - const syncResumeState = useCallback((target: ChatClient | null) => { - if (!target) return - setRunId(target.getCurrentRunId()) - setInterruptState(target.getInterruptState()) - }, []) - // Create ChatClient instance with callbacks to sync state const { client, initialization } = useMemo(() => { const messagesToUse = options.initialMessages || [] - isFirstMountRef.current = false // Build options with conditional spreads for fields whose source // type is `T | undefined` but the ChatClient target uses a strict @@ -211,69 +175,11 @@ export function useChat< ...(options.streamProcessor !== undefined && { streamProcessor: options.streamProcessor, }), - onMessagesChange: (newMessages: Array>) => { - runOrQueueForActiveInstance(() => { - setMessages(newMessages) - }) - }, - onLoadingChange: (newIsLoading: boolean) => { - runOrQueueForActiveInstance(() => { - const currentInstance = getActiveInstance() - if (!currentInstance) return - setIsLoading(newIsLoading) - syncResumeState(currentInstance) - }) - }, - onErrorChange: (newError: Error | undefined) => { - runOrQueueForActiveInstance(() => { - setError(newError) - }) - }, - onStatusChange: (status: ChatClientState) => { - runOrQueueForActiveInstance(() => { - setStatus(status) - }) - }, - onSubscriptionChange: (nextIsSubscribed: boolean) => { - runOrQueueForActiveInstance(() => { - setIsSubscribed(nextIsSubscribed) - }) - }, - onConnectionStatusChange: (nextStatus: ConnectionStatus) => { - runOrQueueForActiveInstance(() => { - setConnectionStatus(nextStatus) - }) - }, - onSessionGeneratingChange: (isGenerating: boolean) => { - runOrQueueForActiveInstance(() => { - setSessionGenerating(isGenerating) - }) - }, ...(optionsRef.current.queue !== undefined && { queue: optionsRef.current.queue, }), - onQueueChange: (nextQueue: Array) => { - runOrQueueForActiveInstance(() => { - setQueue(nextQueue) - }) - }, - onRunIdChange: (nextRunId) => { - runOrQueueForActiveInstance(() => { - setRunId(nextRunId) - }) - }, - onResumeStateChange: (_nextResumeState, nextPendingInterrupts) => { - runOrQueueForActiveInstance(() => { - setInterruptState((current) => ({ - ...current, - interrupts: nextPendingInterrupts, - pendingInterrupts: nextPendingInterrupts, - })) - }) - }, onInterruptStateChange: (nextInterruptState, context) => { runOrQueueForActiveInstance(() => { - setInterruptState(nextInterruptState) optionsRef.current.onInterruptStateChange?.( nextInterruptState, context, @@ -283,7 +189,7 @@ export function useChat< }) instanceHolder.current = instance return { client: instance, initialization: initializationState } - }, [clientId, syncResumeState]) + }, [clientId]) useEffect(() => { activeClientRef.current = client @@ -303,12 +209,11 @@ export function useChat< } }, [client, initialization]) - useEffect(() => { - const clientMessages = client.getMessages() - if (clientMessages !== messagesRef.current) { - setMessages(clientMessages) - } - }, [client]) + const snapshot = useSyncExternalStore( + client.subscribeSnapshot, + client.getSnapshot, + client.getSnapshot, + ) // Sync each wire-payload slot in its own effect so an unrelated option // changing doesn't re-run the others. `updateOptions` declares strict-optional @@ -387,10 +292,6 @@ export function useChat< cleanupInvalidationRef.current = null } client.mountDevtools() - // Delivery-durability resume is transparent: the resumable SSE connection - // adapter re-attaches via the browser's native Last-Event-ID on reconnect. - // We only seed interrupt (state) resume from the client here. - syncResumeState(client) return () => { cleanupInvalidationRef.current = setTimeout(() => { @@ -423,47 +324,35 @@ export function useChat< } cleanupDisposalRef.current = disposal } - }, [client, syncResumeState]) + }, [client]) const sendMessage = useCallback( async ( content: string | MultimodalContent, sendOptions?: SendMessageOptions, ) => { - try { - await client.sendMessage(content, undefined, sendOptions) - } finally { - syncResumeState(client) - } + await client.sendMessage(content, undefined, sendOptions) }, - [client, syncResumeState], + [client], ) const cancelQueued = useCallback( (id: string) => { client.cancelQueued(id) }, - [client, syncResumeState], + [client], ) const append = useCallback( async (message: ModelMessage | UIMessage) => { - try { - await client.append(message) - } finally { - syncResumeState(client) - } + await client.append(message) }, - [client, syncResumeState], + [client], ) const reload = useCallback(async () => { - try { - await client.reload() - } finally { - syncResumeState(client) - } - }, [client, syncResumeState]) + await client.reload() + }, [client]) const stop = useCallback(() => { client.stop() @@ -471,8 +360,7 @@ export function useChat< const clear = useCallback(() => { client.clear() - syncResumeState(client) - }, [client, syncResumeState]) + }, [client]) const setMessagesManually = useCallback( (newMessages: Array>) => { @@ -497,21 +385,15 @@ export function useChat< const addToolApprovalResponse = useCallback( async (response: { id: string; approved: boolean }) => { await client.addToolApprovalResponse(response) - syncResumeState(client) }, - [client, syncResumeState], + [client], ) const resumeInterrupts = useCallback( async (resumeItems: Array, state?: ChatResumeState) => { - const result = await client.resumeInterrupts( - resumeItems, - state ?? undefined, - ) - syncResumeState(client) - return result + return await client.resumeInterrupts(resumeItems, state ?? undefined) }, - [client, syncResumeState], + [client], ) const resolveInterrupts = useCallback( @@ -555,7 +437,7 @@ export function useChat< // a stale assistant turn or a system prompt) we deliberately return null // rather than scanning historical assistants — otherwise a `final` from a // previous session would leak into the hook value on first render. - const renderedMessages = client.getMessages() + const renderedMessages = snapshot.messages const activeStructuredPart = useMemo(() => { let lastUserIndex = -1 @@ -600,23 +482,23 @@ export function useChat< append, reload, stop, - isLoading, - error, - status, - isSubscribed, - connectionStatus, - sessionGenerating, + isLoading: snapshot.isLoading, + error: snapshot.error, + status: snapshot.status, + isSubscribed: snapshot.isSubscribed, + connectionStatus: snapshot.connectionStatus, + sessionGenerating: snapshot.sessionGenerating, setMessages: setMessagesManually, clear, addToolResult, addToolApprovalResponse, - queue, + queue: snapshot.queue, cancelQueued, - runId, - interrupts: interruptState.interrupts, - pendingInterrupts: interruptState.pendingInterrupts, - interruptErrors: interruptState.interruptErrors, - resuming: interruptState.resuming, + runId: snapshot.runId, + interrupts: snapshot.interruptState.interrupts, + pendingInterrupts: snapshot.interruptState.pendingInterrupts, + interruptErrors: snapshot.interruptState.interruptErrors, + resuming: snapshot.interruptState.resuming, resolveInterrupts, cancelInterrupts, retryInterrupts, diff --git a/packages/ai-react/src/use-generate-video.ts b/packages/ai-react/src/use-generate-video.ts index 708281fee2..393c17f1ab 100644 --- a/packages/ai-react/src/use-generate-video.ts +++ b/packages/ai-react/src/use-generate-video.ts @@ -1,6 +1,13 @@ import { VideoGenerationClient } from '@tanstack/ai-client' import { createVideoDevtoolsBridge } from '@tanstack/ai-client/devtools' -import { useCallback, useEffect, useId, useMemo, useRef, useState } from 'react' +import { + useCallback, + useEffect, + useId, + useMemo, + useRef, + useSyncExternalStore, +} from 'react' import type { StreamChunk } from '@tanstack/ai' import type { AIDevtoolsDisplayOptions, @@ -175,14 +182,6 @@ export function useGenerateVideo( // The hook identity is `threadId`. `hookId` is only a React recreation key. const clientIdentity = options.threadId ?? hookId - const [result, setResult] = useState(null) - const [jobId, setJobId] = useState(null) - const [videoStatus, setVideoStatus] = useState(null) - const [isLoading, setIsLoading] = useState(false) - const [error, setError] = useState(undefined) - const [status, setStatus] = useState('idle') - const [runId, setRunId] = useState(null) - const optionsRef = useRef(options) optionsRef.current = options const disposedRef = useRef(false) @@ -235,27 +234,6 @@ export function useGenerateVideo( onStatusUpdate: (s: VideoStatusInfo) => { if (!disposedRef.current) optionsRef.current.onStatusUpdate?.(s) }, - onResultChange: (r: TOutput | null) => { - if (!disposedRef.current) setResult(r) - }, - onLoadingChange: (l: boolean) => { - if (!disposedRef.current) setIsLoading(l) - }, - onErrorChange: (e: Error | undefined) => { - if (!disposedRef.current) setError(e) - }, - onStatusChange: (s: GenerationClientState) => { - if (!disposedRef.current) setStatus(s) - }, - onJobIdChange: (id: string | null) => { - if (!disposedRef.current) setJobId(id) - }, - onVideoStatusChange: (s: VideoStatusInfo | null) => { - if (!disposedRef.current) setVideoStatus(s) - }, - onResumeStateChange: (rs: { runId: string } | null) => { - if (!disposedRef.current) setRunId(rs?.runId ?? null) - }, } const persistenceProps = @@ -289,6 +267,12 @@ export function useGenerateVideo( ) }, [clientIdentity, hookId]) + const snapshot = useSyncExternalStore( + client.subscribe, + client.getSnapshot, + client.getSnapshot, + ) + // Sync body changes without recreating client useEffect(() => { // Conditional spread: target uses strict-optional `body?: T`. @@ -327,14 +311,14 @@ export function useGenerateVideo( return { generate, - result, - jobId, - videoStatus, - isLoading, - error, - status, + result: snapshot.result, + jobId: snapshot.jobId, + videoStatus: snapshot.videoStatus, + isLoading: snapshot.isLoading, + error: snapshot.error, + status: snapshot.status, stop, reset, - runId, + runId: snapshot.runId, } } diff --git a/packages/ai-react/src/use-generation.ts b/packages/ai-react/src/use-generation.ts index 8106f4cf90..6ebe77c942 100644 --- a/packages/ai-react/src/use-generation.ts +++ b/packages/ai-react/src/use-generation.ts @@ -1,6 +1,13 @@ import { GenerationClient } from '@tanstack/ai-client' import { createGenerationDevtoolsBridge } from '@tanstack/ai-client/devtools' -import { useCallback, useEffect, useId, useMemo, useRef, useState } from 'react' +import { + useCallback, + useEffect, + useId, + useMemo, + useRef, + useSyncExternalStore, +} from 'react' import type { StreamChunk } from '@tanstack/ai' import type { AIDevtoolsDisplayOptions, @@ -174,12 +181,6 @@ export function useGeneration< // The hook identity is `threadId`. `hookId` is only a React recreation key. const clientIdentity = options.threadId ?? hookId - const [result, setResult] = useState(null) - const [isLoading, setIsLoading] = useState(false) - const [error, setError] = useState(undefined) - const [status, setStatus] = useState('idle') - const [runId, setRunId] = useState(null) - const optionsRef = useRef(options) optionsRef.current = options const disposedRef = useRef(false) @@ -226,21 +227,6 @@ export function useGeneration< onChunk: (c: StreamChunk) => { if (!disposedRef.current) optionsRef.current.onChunk?.(c) }, - onResultChange: (r) => { - if (!disposedRef.current) setResult(r) - }, - onLoadingChange: (l) => { - if (!disposedRef.current) setIsLoading(l) - }, - onErrorChange: (e) => { - if (!disposedRef.current) setError(e) - }, - onStatusChange: (s) => { - if (!disposedRef.current) setStatus(s) - }, - onResumeStateChange: (rs) => { - if (!disposedRef.current) setRunId(rs?.runId ?? null) - }, } const persistenceProps = @@ -274,6 +260,12 @@ export function useGeneration< ) }, [clientIdentity, hookId]) + const snapshot = useSyncExternalStore( + client.subscribe, + client.getSnapshot, + client.getSnapshot, + ) + // Sync body changes without recreating client useEffect(() => { // Conditional spread: target uses strict-optional `body?: T`. @@ -312,12 +304,12 @@ export function useGeneration< return { generate, - result, - isLoading, - error, - status, + result: snapshot.result, + isLoading: snapshot.isLoading, + error: snapshot.error, + status: snapshot.status, stop, reset, - runId, + runId: snapshot.runId, } } diff --git a/packages/ai-react/src/use-realtime-chat.ts b/packages/ai-react/src/use-realtime-chat.ts index bddef502c6..9646765285 100644 --- a/packages/ai-react/src/use-realtime-chat.ts +++ b/packages/ai-react/src/use-realtime-chat.ts @@ -1,11 +1,12 @@ -import { useCallback, useEffect, useRef, useState } from 'react' +import { + useCallback, + useEffect, + useRef, + useState, + useSyncExternalStore, +} from 'react' import { RealtimeClient } from '@tanstack/ai-client' -import type { - RealtimeMessage, - RealtimeMode, - RealtimeSessionConfig, - RealtimeStatus, -} from '@tanstack/ai' +import type { RealtimeSessionConfig } from '@tanstack/ai' import type { UseRealtimeChatOptions, UseRealtimeChatReturn, @@ -58,17 +59,6 @@ const emptyTimeDomainData = new Uint8Array(128).fill(128) export function useRealtimeChat( options: UseRealtimeChatOptions, ): UseRealtimeChatReturn { - // State - const [status, setStatus] = useState('idle') - const [mode, setMode] = useState('idle') - const [messages, setMessages] = useState>([]) - const [pendingUserTranscript, setPendingUserTranscript] = useState< - string | null - >(null) - const [pendingAssistantTranscript, setPendingAssistantTranscript] = useState< - string | null - >(null) - const [error, setError] = useState(null) const [inputLevel, setInputLevel] = useState(0) const [outputLevel, setOutputLevel] = useState(0) @@ -113,15 +103,10 @@ export function useRealtimeChat( ...(initial.semanticEagerness !== undefined && { semanticEagerness: initial.semanticEagerness, }), - onStatusChange: (newStatus) => { - setStatus(newStatus) - }, onModeChange: (newMode) => { - setMode(newMode) optionsRef.current.onModeChange?.(newMode) }, onMessage: (message) => { - setMessages((prev) => [...prev, message]) optionsRef.current.onMessage?.(message) }, onUsage(usage) { @@ -131,30 +116,26 @@ export function useRealtimeChat( optionsRef.current.onGoAway?.(timeLeft) }, onError: (err) => { - setError(err) optionsRef.current.onError?.(err) }, onConnect: () => { - setError(null) optionsRef.current.onConnect?.() }, onDisconnect: () => { optionsRef.current.onDisconnect?.() }, onInterrupted: () => { - setPendingAssistantTranscript(null) optionsRef.current.onInterrupted?.() }, }) - - // Subscribe to state changes for transcripts - clientRef.current.onStateChange((state) => { - setPendingUserTranscript(state.pendingUserTranscript) - setPendingAssistantTranscript(state.pendingAssistantTranscript) - }) } const client = clientRef.current + const snapshot = useSyncExternalStore( + client.subscribe, + client.getSnapshot, + client.getSnapshot, + ) // Audio level animation loop useEffect(() => { @@ -166,7 +147,7 @@ export function useRealtimeChat( animationFrameRef.current = requestAnimationFrame(updateLevels) } - if (status === 'connected') { + if (snapshot.status === 'connected') { updateLevels() } @@ -176,7 +157,7 @@ export function useRealtimeChat( animationFrameRef.current = null } } - }, [status]) + }, [snapshot.status]) // Cleanup on unmount useEffect(() => { @@ -187,10 +168,6 @@ export function useRealtimeChat( // Connection methods const connect = useCallback(async () => { - setError(null) - setMessages([]) - setPendingUserTranscript(null) - setPendingAssistantTranscript(null) await client.connect() }, [client]) @@ -258,16 +235,16 @@ export function useRealtimeChat( return { // Connection state - status, - error, + status: snapshot.status, + error: snapshot.error, connect, disconnect, // Conversation state - mode, - messages, - pendingUserTranscript, - pendingAssistantTranscript, + mode: snapshot.mode, + messages: snapshot.messages, + pendingUserTranscript: snapshot.pendingUserTranscript, + pendingAssistantTranscript: snapshot.pendingAssistantTranscript, // Voice control startListening, diff --git a/packages/ai-solid/src/use-chat.ts b/packages/ai-solid/src/use-chat.ts index 6d5737b6b4..19ddf0f85b 100644 --- a/packages/ai-solid/src/use-chat.ts +++ b/packages/ai-solid/src/use-chat.ts @@ -82,11 +82,6 @@ export function useChat< resuming: false, }) - const syncResumeState = () => { - setRunId(client().getCurrentRunId()) - setInterruptState(client().getInterruptState()) - } - // Structured-output `partial` / `final` are derived from `messages` — // specifically from the structured-output part on the latest assistant // message (the one after the most recent user message). Per-turn parts @@ -159,44 +154,8 @@ export function useChat< ...(options.streamProcessor !== undefined && { streamProcessor: options.streamProcessor, }), - onMessagesChange: (newMessages: Array>) => { - setMessages(newMessages) - }, - onLoadingChange: (newIsLoading: boolean) => { - setIsLoading(newIsLoading) - syncResumeState() - }, - onStatusChange: (newStatus: ChatClientState) => { - setStatus(newStatus) - }, - onErrorChange: (newError: Error | undefined) => { - setError(newError) - }, - onSubscriptionChange: (nextIsSubscribed: boolean) => { - setIsSubscribed(nextIsSubscribed) - }, - onConnectionStatusChange: (nextStatus: ConnectionStatus) => { - setConnectionStatus(nextStatus) - }, - onSessionGeneratingChange: (isGenerating: boolean) => { - setSessionGenerating(isGenerating) - }, ...(options.queue !== undefined && { queue: options.queue }), - onQueueChange: (nextQueue: Array) => { - setQueue(nextQueue) - }, - onRunIdChange: (nextRunId) => { - setRunId(nextRunId) - }, - onResumeStateChange: (_nextResumeState, nextPendingInterrupts) => { - setInterruptState((current) => ({ - ...current, - interrupts: nextPendingInterrupts, - pendingInterrupts: nextPendingInterrupts, - })) - }, onInterruptStateChange: (nextInterruptState, context) => { - setInterruptState(nextInterruptState) options.onInterruptStateChange?.(nextInterruptState, context) }, }) @@ -204,8 +163,26 @@ export function useChat< // Connection and other options are captured at creation time }, [clientId]) - setMessages(client().getMessages()) - syncResumeState() + const applySnapshot = (target: ChatClient) => { + const next = target.getSnapshot() + setMessages(next.messages) + setIsLoading(next.isLoading) + setError(next.error) + setStatus(next.status) + setIsSubscribed(next.isSubscribed) + setConnectionStatus(next.connectionStatus) + setSessionGenerating(next.sessionGenerating) + setQueue(next.queue) + setRunId(next.runId) + setInterruptState(next.interruptState) + } + + createEffect(() => { + const target = client() + applySnapshot(target) + const unsubscribe = target.subscribeSnapshot(() => applySnapshot(target)) + onCleanup(unsubscribe) + }) // Sync body / forwardedProps changes to the client. // Both populate the same wire payload; `forwardedProps` is preferred @@ -245,10 +222,6 @@ export function useChat< // connections per origin until the page reloaded. client().attach() client().mountDevtools() - // Delivery-durability resume is transparent: the resumable SSE connection - // adapter reattaches via the browser's native Last-Event-ID on reconnect. - // We only seed interrupt (state) resume from the client here. - syncResumeState() }) // Cleanup on unmount: stop any in-flight requests. @@ -272,27 +245,15 @@ export function useChat< content: string | MultimodalContent, sendOptions?: SendMessageOptions, ) => { - try { - await client().sendMessage(content, undefined, sendOptions) - } finally { - syncResumeState() - } + await client().sendMessage(content, undefined, sendOptions) } const append = async (message: ModelMessage | UIMessage) => { - try { - await client().append(message) - } finally { - syncResumeState() - } + await client().append(message) } const reload = async () => { - try { - await client().reload() - } finally { - syncResumeState() - } + await client().reload() } const stop = () => { @@ -301,7 +262,6 @@ export function useChat< const clear = () => { client().clear() - syncResumeState() } const setMessagesManually = (newMessages: Array>) => { @@ -323,7 +283,6 @@ export function useChat< approved: boolean }) => { await client().addToolApprovalResponse(response) - syncResumeState() } const cancelQueued = (id: string) => client().cancelQueued(id) @@ -332,9 +291,7 @@ export function useChat< resumeItems: Array, state?: ChatResumeState, ) => { - const result = await client().resumeInterrupts(resumeItems, state) - syncResumeState() - return result + return await client().resumeInterrupts(resumeItems, state) } const resolveInterrupts = ( diff --git a/packages/ai-solid/src/use-generate-video.ts b/packages/ai-solid/src/use-generate-video.ts index 42acd27e53..ceba999c4f 100644 --- a/packages/ai-solid/src/use-generate-video.ts +++ b/packages/ai-solid/src/use-generate-video.ts @@ -244,27 +244,6 @@ export function useGenerateVideo( onStatusUpdate: (s: VideoStatusInfo) => { if (!disposed) options.onStatusUpdate?.(s) }, - onResultChange: (r: TOutput | null) => { - if (!disposed) setResult(() => r) - }, - onLoadingChange: (l: boolean) => { - if (!disposed) setIsLoading(l) - }, - onErrorChange: (e: Error | undefined) => { - if (!disposed) setError(e) - }, - onStatusChange: (s: GenerationClientState) => { - if (!disposed) setStatus(s) - }, - onJobIdChange: (id: string | null) => { - if (!disposed) setJobId(id) - }, - onVideoStatusChange: (s: VideoStatusInfo | null) => { - if (!disposed) setVideoStatus(s) - }, - onResumeStateChange: (rs: { runId: string } | null) => { - if (!disposed) setRunId(rs?.runId ?? null) - }, } if (options.connection) { @@ -286,6 +265,19 @@ export function useGenerateVideo( ) }) + const applySnapshot = () => { + const next = client.getSnapshot() + setResult(() => next.result) + setIsLoading(next.isLoading) + setError(next.error) + setStatus(next.status) + setRunId(next.runId) + setJobId(next.jobId) + setVideoStatus(next.videoStatus) + } + applySnapshot() + onCleanup(client.subscribe(applySnapshot)) + // Sync body changes without recreating client createEffect(() => { const currentBody = options.body diff --git a/packages/ai-solid/src/use-generation.ts b/packages/ai-solid/src/use-generation.ts index eedc8eb5c2..ee614f1d8c 100644 --- a/packages/ai-solid/src/use-generation.ts +++ b/packages/ai-solid/src/use-generation.ts @@ -230,21 +230,6 @@ export function useGeneration< onChunk: (c: StreamChunk) => { if (!disposed) options.onChunk?.(c) }, - onResultChange: (r) => { - if (!disposed) setResult(() => r) - }, - onLoadingChange: (l) => { - if (!disposed) setIsLoading(l) - }, - onErrorChange: (e) => { - if (!disposed) setError(e) - }, - onStatusChange: (s) => { - if (!disposed) setStatus(s) - }, - onResumeStateChange: (rs) => { - if (!disposed) setRunId(rs?.runId ?? null) - }, } const persistenceProps = @@ -280,6 +265,17 @@ export function useGeneration< ) }) + const applySnapshot = () => { + const next = client.getSnapshot() + setResult(() => next.result) + setIsLoading(next.isLoading) + setError(next.error) + setStatus(next.status) + setRunId(next.runId) + } + applySnapshot() + onCleanup(client.subscribe(applySnapshot)) + // Sync body changes without recreating client createEffect(() => { const currentBody = options.body diff --git a/packages/ai-svelte/src/create-chat.svelte.ts b/packages/ai-svelte/src/create-chat.svelte.ts index 9e72e21aeb..97cd334617 100644 --- a/packages/ai-svelte/src/create-chat.svelte.ts +++ b/packages/ai-svelte/src/create-chat.svelte.ts @@ -163,48 +163,28 @@ export function createChat< ...(options.streamProcessor !== undefined && { streamProcessor: options.streamProcessor, }), - onMessagesChange: (newMessages: Array>) => { - messages = newMessages - }, - onLoadingChange: (newIsLoading: boolean) => { - isLoading = newIsLoading - syncResumeState() - }, - onStatusChange: (newStatus: ChatClientState) => { - status = newStatus - }, - onErrorChange: (newError: Error | undefined) => { - error = newError - }, - onSubscriptionChange: (nextIsSubscribed: boolean) => { - isSubscribed = nextIsSubscribed - }, - onConnectionStatusChange: (nextStatus: ConnectionStatus) => { - connectionStatus = nextStatus - }, - onSessionGeneratingChange: (isGenerating: boolean) => { - sessionGenerating = isGenerating - }, ...(options.queue !== undefined && { queue: options.queue }), - onQueueChange: (nextQueue: Array) => { - queue = nextQueue - }, - onRunIdChange: (nextRunId) => { - runId = nextRunId - }, onInterruptStateChange: (nextInterruptState, context) => { - interruptState = nextInterruptState options.onInterruptStateChange?.(nextInterruptState, context) }, }) - function syncResumeState() { - runId = client.getCurrentRunId() - interruptState = client.getInterruptState() + function applySnapshot() { + const next = client.getSnapshot() + messages = next.messages + isLoading = next.isLoading + error = next.error + status = next.status + isSubscribed = next.isSubscribed + connectionStatus = next.connectionStatus + sessionGenerating = next.sessionGenerating + queue = next.queue + runId = next.runId + interruptState = next.interruptState } - messages = client.getMessages() - interruptState = client.getInterruptState() + applySnapshot() + const unsubscribeSnapshot = client.subscribeSnapshot(applySnapshot) if (options.live) { client.subscribe() @@ -218,7 +198,6 @@ export function createChat< // Delivery-durability resume is transparent: the resumable SSE // connection adapter reattaches via the browser's native // Last-Event-ID on reconnect. We only seed interrupt (state) resume. - syncResumeState() client.attach() // ONLY THE VIEW ON SCREEN HOLDS A STREAM. `onMount`'s returned function // runs when the component is destroyed, which is the one automatic @@ -230,6 +209,7 @@ export function createChat< // `detach` keeps the transcript and the resume pointer, so re-entering // the view picks the run back up from the durable log. return () => { + unsubscribeSnapshot() client.detach() } }) @@ -247,29 +227,17 @@ export function createChat< content: string | MultimodalContent, sendOptions?: SendMessageOptions, ) => { - try { - await client.sendMessage(content, undefined, sendOptions) - } finally { - syncResumeState() - } + await client.sendMessage(content, undefined, sendOptions) } const cancelQueued = (id: string) => client.cancelQueued(id) const append = async (message: ModelMessage | UIMessage) => { - try { - await client.append(message) - } finally { - syncResumeState() - } + await client.append(message) } const reload = async () => { - try { - await client.reload() - } finally { - syncResumeState() - } + await client.reload() } const stop = () => { @@ -277,12 +245,12 @@ export function createChat< } const dispose = () => { + unsubscribeSnapshot() client.dispose() } const clear = () => { client.clear() - syncResumeState() } const setMessages = (newMessages: Array>) => { @@ -304,16 +272,13 @@ export function createChat< approved: boolean }) => { await client.addToolApprovalResponse(response) - syncResumeState() } const resumeInterrupts = async ( resumeItems: Array, state?: ChatResumeState, ) => { - const result = await client.resumeInterrupts(resumeItems, state) - syncResumeState() - return result + return await client.resumeInterrupts(resumeItems, state) } const resolveInterrupts = ( diff --git a/packages/ai-svelte/src/create-generate-video.svelte.ts b/packages/ai-svelte/src/create-generate-video.svelte.ts index d8b8615bcf..4448245f8e 100644 --- a/packages/ai-svelte/src/create-generate-video.svelte.ts +++ b/packages/ai-svelte/src/create-generate-video.svelte.ts @@ -235,34 +235,6 @@ export function createGenerateVideo( onStatusUpdate: (s: VideoStatusInfo) => { if (!disposed) options.onStatusUpdate?.(s) }, - onResultChange: (r: TOutput | null) => { - if (disposed) return - result = r - }, - onLoadingChange: (l: boolean) => { - if (disposed) return - isLoading = l - }, - onErrorChange: (e: Error | undefined) => { - if (disposed) return - error = e - }, - onStatusChange: (s: GenerationClientState) => { - if (disposed) return - status = s - }, - onJobIdChange: (id: string | null) => { - if (disposed) return - jobId = id - }, - onVideoStatusChange: (s: VideoStatusInfo | null) => { - if (disposed) return - videoStatus = s - }, - onResumeStateChange: (rs: { runId: string } | null) => { - if (disposed) return - runId = rs?.runId ?? null - }, } let client: VideoGenerationClient @@ -283,6 +255,19 @@ export function createGenerateVideo( ) } + const applySnapshot = () => { + const next = client.getSnapshot() + result = next.result + isLoading = next.isLoading + error = next.error + status = next.status + runId = next.runId + jobId = next.jobId + videoStatus = next.videoStatus + } + applySnapshot() + let unsubscribeSnapshot = client.subscribe(applySnapshot) + // Mount devtools only. Generation runs are never auto-started on setup — // persisted state is read-only for display. client.mountDevtools() @@ -297,7 +282,11 @@ export function createGenerateVideo( // frameworks revive via mountDevtools() in their mount effects), so an // explicit generate() after dispose() is the Svelte revive path: bring // the client and the reactive bindings back together. - disposed = false + if (disposed) { + disposed = false + applySnapshot() + unsubscribeSnapshot = client.subscribe(applySnapshot) + } client.mountDevtools() await client.generate(input) } @@ -312,6 +301,8 @@ export function createGenerateVideo( const dispose = () => { disposed = true + unsubscribeSnapshot() + unsubscribeSnapshot = () => {} client.dispose() } diff --git a/packages/ai-svelte/src/create-generation.svelte.ts b/packages/ai-svelte/src/create-generation.svelte.ts index bf99c9dd3b..1c659dd2f8 100644 --- a/packages/ai-svelte/src/create-generation.svelte.ts +++ b/packages/ai-svelte/src/create-generation.svelte.ts @@ -233,26 +233,6 @@ export function createGeneration< onChunk: (c: StreamChunk) => { if (!disposed) options.onChunk?.(c) }, - onResultChange: (r: TOutput | null) => { - if (disposed) return - result = r - }, - onLoadingChange: (l: boolean) => { - if (disposed) return - isLoading = l - }, - onErrorChange: (e: Error | undefined) => { - if (disposed) return - error = e - }, - onStatusChange: (s: GenerationClientState) => { - if (disposed) return - status = s - }, - onResumeStateChange: (rs) => { - if (disposed) return - runId = rs?.runId ?? null - }, } const persistenceProps = @@ -287,6 +267,17 @@ export function createGeneration< ) } + const applySnapshot = () => { + const next = client.getSnapshot() + result = next.result + isLoading = next.isLoading + error = next.error + status = next.status + runId = next.runId + } + applySnapshot() + let unsubscribeSnapshot = client.subscribe(applySnapshot) + // Mount devtools only. Generation runs are never auto-started on setup — // persisted state is read-only for display. client.mountDevtools() @@ -301,7 +292,11 @@ export function createGeneration< // frameworks revive via mountDevtools() in their mount effects), so an // explicit generate() after dispose() is the Svelte revive path: bring // the client and the reactive bindings back together. - disposed = false + if (disposed) { + disposed = false + applySnapshot() + unsubscribeSnapshot = client.subscribe(applySnapshot) + } client.mountDevtools() await client.generate(input) } @@ -316,6 +311,8 @@ export function createGeneration< const dispose = () => { disposed = true + unsubscribeSnapshot() + unsubscribeSnapshot = () => {} client.dispose() } diff --git a/packages/ai-svelte/tests/create-generation-dispose.test.ts b/packages/ai-svelte/tests/create-generation-dispose.test.ts new file mode 100644 index 0000000000..e7ef6fc3d6 --- /dev/null +++ b/packages/ai-svelte/tests/create-generation-dispose.test.ts @@ -0,0 +1,35 @@ +import { describe, expect, it } from 'vitest' +import { createGeneration } from '../src/create-generation.svelte' +import { createGenerateVideo } from '../src/create-generate-video.svelte' + +describe('Svelte generate() after dispose() rebinds the snapshot', () => { + it('createGeneration updates result after dispose then generate', async () => { + const gen = createGeneration<{ prompt: string }, { id: string }>({ + fetcher: async (input) => ({ id: input.prompt }), + }) + + await gen.generate({ prompt: 'a' }) + expect(gen.result).toEqual({ id: 'a' }) + + gen.dispose() + await gen.generate({ prompt: 'b' }) + expect(gen.result).toEqual({ id: 'b' }) + }) + + it('createGenerateVideo updates result after dispose then generate', async () => { + const video = createGenerateVideo({ + fetcher: async (input) => ({ + jobId: input.prompt, + status: 'completed' as const, + url: `https://example.com/${input.prompt}.mp4`, + }), + }) + + await video.generate({ prompt: 'one' }) + expect(video.result?.jobId).toBe('one') + + video.dispose() + await video.generate({ prompt: 'two' }) + expect(video.result?.jobId).toBe('two') + }) +}) diff --git a/packages/ai-vue/src/use-chat.ts b/packages/ai-vue/src/use-chat.ts index 8e748f1a75..a51299cccd 100644 --- a/packages/ai-vue/src/use-chat.ts +++ b/packages/ai-vue/src/use-chat.ts @@ -149,48 +149,28 @@ export function useChat< ...(options.streamProcessor !== undefined && { streamProcessor: options.streamProcessor, }), - onMessagesChange: (newMessages: Array>) => { - messages.value = newMessages - }, - onLoadingChange: (newIsLoading: boolean) => { - isLoading.value = newIsLoading - syncResumeState() - }, - onStatusChange: (newStatus: ChatClientState) => { - status.value = newStatus - }, - onErrorChange: (newError: Error | undefined) => { - error.value = newError - }, - onSubscriptionChange: (nextIsSubscribed: boolean) => { - isSubscribed.value = nextIsSubscribed - }, - onConnectionStatusChange: (nextStatus: ConnectionStatus) => { - connectionStatus.value = nextStatus - }, - onSessionGeneratingChange: (isGenerating: boolean) => { - sessionGenerating.value = isGenerating - }, ...(options.queue !== undefined && { queue: options.queue }), - onQueueChange: (nextQueue: Array) => { - queue.value = nextQueue - }, - onRunIdChange: (nextRunId) => { - runId.value = nextRunId - }, onInterruptStateChange: (nextInterruptState, context) => { - interruptState.value = nextInterruptState options.onInterruptStateChange?.(nextInterruptState, context) }, }) - function syncResumeState() { - runId.value = client.getCurrentRunId() - interruptState.value = client.getInterruptState() + function applySnapshot() { + const next = client.getSnapshot() + messages.value = next.messages + isLoading.value = next.isLoading + error.value = next.error + status.value = next.status + isSubscribed.value = next.isSubscribed + connectionStatus.value = next.connectionStatus + sessionGenerating.value = next.sessionGenerating + queue.value = next.queue + runId.value = next.runId + interruptState.value = next.interruptState } - messages.value = client.getMessages() - interruptState.value = client.getInterruptState() + applySnapshot() + onScopeDispose(client.subscribeSnapshot(applySnapshot)) // Sync body / forwardedProps changes to the client. // Both populate the same wire payload; `forwardedProps` is preferred @@ -236,10 +216,6 @@ export function useChat< // connections per origin until the page reloaded. client.attach() client.mountDevtools() - // Delivery-durability resume is transparent: the resumable SSE connection - // adapter reattaches via the browser's native Last-Event-ID on reconnect. - // We only seed interrupt (state) resume from the client here. - syncResumeState() }) // Cleanup on unmount: stop any in-flight requests @@ -263,29 +239,17 @@ export function useChat< content: string | MultimodalContent, sendOptions?: SendMessageOptions, ) => { - try { - await client.sendMessage(content, undefined, sendOptions) - } finally { - syncResumeState() - } + await client.sendMessage(content, undefined, sendOptions) } const cancelQueued = (id: string) => client.cancelQueued(id) const append = async (message: ModelMessage | UIMessage) => { - try { - await client.append(message) - } finally { - syncResumeState() - } + await client.append(message) } const reload = async () => { - try { - await client.reload() - } finally { - syncResumeState() - } + await client.reload() } const stop = () => { @@ -294,7 +258,6 @@ export function useChat< const clear = () => { client.clear() - syncResumeState() } const setMessagesManually = (newMessages: Array>) => { @@ -316,16 +279,13 @@ export function useChat< approved: boolean }) => { await client.addToolApprovalResponse(response) - syncResumeState() } const resumeInterrupts = async ( resumeItems: Array, state?: ChatResumeState, ) => { - const result = await client.resumeInterrupts(resumeItems, state) - syncResumeState() - return result + return await client.resumeInterrupts(resumeItems, state) } const interrupts = computed(() => interruptState.value.interrupts) diff --git a/packages/ai-vue/src/use-generate-video.ts b/packages/ai-vue/src/use-generate-video.ts index fb2ac7a2a7..66ae22cd0a 100644 --- a/packages/ai-vue/src/use-generate-video.ts +++ b/packages/ai-vue/src/use-generate-video.ts @@ -231,34 +231,6 @@ export function useGenerateVideo( onStatusUpdate: (s: VideoStatusInfo) => { if (!disposed) options.onStatusUpdate?.(s) }, - onResultChange: (r: TOutput | null) => { - if (disposed) return - result.value = r - }, - onLoadingChange: (l: boolean) => { - if (disposed) return - isLoading.value = l - }, - onErrorChange: (e: Error | undefined) => { - if (disposed) return - error.value = e - }, - onStatusChange: (s: GenerationClientState) => { - if (disposed) return - status.value = s - }, - onJobIdChange: (id: string | null) => { - if (disposed) return - jobId.value = id - }, - onVideoStatusChange: (s: VideoStatusInfo | null) => { - if (disposed) return - videoStatus.value = s - }, - onResumeStateChange: (rs: { runId: string } | null) => { - if (disposed) return - runId.value = rs?.runId ?? null - }, } let client: VideoGenerationClient @@ -279,6 +251,19 @@ export function useGenerateVideo( ) } + const applySnapshot = () => { + const next = client.getSnapshot() + result.value = next.result + isLoading.value = next.isLoading + error.value = next.error + status.value = next.status + runId.value = next.runId + jobId.value = next.jobId + videoStatus.value = next.videoStatus + } + applySnapshot() + onScopeDispose(client.subscribe(applySnapshot)) + // Sync body changes to the client. // Conditional spread: `updateOptions` declares `body?: Record` // (strict optional) and rejects explicit `undefined` under EOPT. diff --git a/packages/ai-vue/src/use-generation.ts b/packages/ai-vue/src/use-generation.ts index cbec8f435f..2095da2d28 100644 --- a/packages/ai-vue/src/use-generation.ts +++ b/packages/ai-vue/src/use-generation.ts @@ -220,26 +220,6 @@ export function useGeneration< onChunk: (c: StreamChunk) => { if (!disposed) options.onChunk?.(c) }, - onResultChange: (r: TOutput | null) => { - if (disposed) return - result.value = r - }, - onLoadingChange: (l: boolean) => { - if (disposed) return - isLoading.value = l - }, - onErrorChange: (e: Error | undefined) => { - if (disposed) return - error.value = e - }, - onStatusChange: (s: GenerationClientState) => { - if (disposed) return - status.value = s - }, - onResumeStateChange: (rs) => { - if (disposed) return - runId.value = rs?.runId ?? null - }, } const persistenceProps = @@ -274,6 +254,17 @@ export function useGeneration< ) } + const applySnapshot = () => { + const next = client.getSnapshot() + result.value = next.result + isLoading.value = next.isLoading + error.value = next.error + status.value = next.status + runId.value = next.runId + } + applySnapshot() + onScopeDispose(client.subscribe(applySnapshot)) + // Sync body changes to the client. // Conditional spread: `updateOptions` declares `body?: Record` // (strict optional) and rejects explicit `undefined` under EOPT. diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index da0e7c0f37..b529405795 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -489,8 +489,8 @@ importers: specifier: ^1.158.4 version: 1.159.5(@tanstack/react-router@1.159.5(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(supports-color@7.2.0)(vite-plugin-solid@2.11.14(solid-js@1.9.10)(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)))(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)) '@tanstack/store': - specifier: ^0.8.0 - version: 0.8.0 + specifier: ^0.11.1 + version: 0.11.1 framer-motion: specifier: ^11.15.0 version: 11.18.2(react-dom@19.2.3(react@19.2.3))(react@19.2.3) @@ -791,8 +791,8 @@ importers: specifier: ^1.158.4 version: 1.159.5(@tanstack/react-router@1.159.5(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(supports-color@7.2.0)(vite-plugin-solid@2.11.14(solid-js@1.9.10)(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)))(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)) '@tanstack/store': - specifier: ^0.8.0 - version: 0.8.0 + specifier: ^0.11.1 + version: 0.11.1 dockerode: specifier: ^4.0.2 version: 4.0.12(supports-color@7.2.0) @@ -1362,8 +1362,8 @@ importers: specifier: ^0.8.0 version: 0.8.0(solid-js@1.9.10) '@tanstack/store': - specifier: ^0.8.0 - version: 0.8.0 + specifier: ^0.11.1 + version: 0.11.1 highlight.js: specifier: ^11.11.1 version: 11.11.1 @@ -1785,6 +1785,9 @@ importers: '@tanstack/ai-utils': specifier: workspace:^ version: link:../ai-utils + '@tanstack/store': + specifier: ^0.11.1 + version: 0.11.1 devDependencies: '@standard-schema/spec': specifier: ^1.1.0 @@ -10068,6 +10071,9 @@ packages: resolution: {integrity: sha512-fQO+O/5xJpli5KlV6pwDz6DtpbqO/0atdVSyVnkemzk0Mej9azm4HXtw+cKkIPtsSplWs4B1EbMtgGMb9ADhSA==} engines: {node: '>=12'} + '@tanstack/store@0.11.1': + resolution: {integrity: sha512-mzTOBhypOuDJAy/D8n2MfUZ1HFkXnmSETviRyhqEC8LUE7/IZQExOTxMANj3KjTofYTkFNpBY67qaVrT41YccA==} + '@tanstack/store@0.7.7': resolution: {integrity: sha512-xa6pTan1bcaqYDS9BDpSiS63qa6EoDkPN9RsRaxHuDdVDNntzq3xNwR5YKTU/V3SkSyC9T4YVOPh2zRQN0nhIQ==} @@ -26187,6 +26193,8 @@ snapshots: - xml2js - yaml + '@tanstack/store@0.11.1': {} + '@tanstack/store@0.7.7': {} '@tanstack/store@0.8.0': {} From af869e101567b76380b3401565f1ed7e11c6ebb3 Mon Sep 17 00:00:00 2001 From: Alem Tuzlak Date: Tue, 25 Aug 2026 16:29:53 +0200 Subject: [PATCH 2/8] fix(ai-client): harden observable snapshots --- .changeset/ai-client-store-snapshot.md | 2 +- docs/api/ai-client.md | 9 +- docs/persistence/client-persistence.md | 11 +- examples/sandbox-cloudflare/package.json | 6 +- examples/sandbox-web/package.json | 6 +- examples/sandbox-web/src/routeTree.gen.ts | 26 +- examples/ts-code-mode-web/package.json | 6 +- .../ts-code-mode-web/src/routeTree.gen.ts | 640 ++++---- .../routes/_banking-demo/api.banking-demo.ts | 2 +- .../routes/_banking-demo/api.banking-init.ts | 2 +- .../src/routes/_banking-demo/banking-demo.tsx | 2 +- .../_database-demo/api.database-demo.ts | 4 +- .../routes/_database-demo/api.db-snippets.ts | 2 +- .../src/routes/_database-demo/api.judge.ts | 2 +- .../routes/_database-demo/database-demo.tsx | 2 +- .../_execute-prompt/api.execute-prompt.ts | 4 +- .../_execute-prompt/api.realtime-token.ts | 4 +- .../routes/_execute-prompt/execute-prompt.tsx | 2 +- .../src/routes/_reporting/api.invalidate.ts | 2 +- .../src/routes/_reporting/api.report-demo.ts | 2 +- .../src/routes/_reporting/api.report-event.ts | 2 +- .../src/routes/_reporting/api.report-sse.ts | 2 +- .../src/routes/_reporting/api.reports.ts | 2 +- examples/ts-group-chat/package.json | 8 +- examples/ts-react-chat/package.json | 12 +- examples/ts-react-media/package.json | 6 +- examples/ts-react-media/src/routeTree.gen.ts | 26 +- examples/ts-react-rerank/package.json | 6 +- examples/ts-react-search/package.json | 10 +- examples/ts-react-search/src/routeTree.gen.ts | 152 +- examples/ts-solid-chat/package.json | 10 +- examples/ts-solid-chat/src/routeTree.gen.ts | 6 +- packages/ai-client/src/audio-recorder.ts | 8 +- packages/ai-client/src/byok/client.ts | 25 +- packages/ai-client/src/chat-client.ts | 84 +- packages/ai-client/src/generation-client.ts | 190 ++- packages/ai-client/src/realtime-client.ts | 60 +- packages/ai-client/src/snapshot-atom.ts | 23 +- .../ai-client/src/video-generation-client.ts | 246 +++- .../ai-client/tests/audio-recorder.test.ts | 15 + packages/ai-client/tests/byok-client.test.ts | 28 + .../tests/byok-generation-client.test.ts | 58 + .../byok-video-generation-client.test.ts | 58 + packages/ai-client/tests/chat-client.test.ts | 124 ++ .../ai-client/tests/client-snapshots.test.ts | 59 + .../ai-client/tests/generation-client.test.ts | 503 +++++++ .../tests/generation-devtools.test.ts | 178 +++ .../ai-client/tests/snapshot-atom.test.ts | 8 + .../tests/video-generation-client.test.ts | 627 ++++++++ packages/ai-react/src/use-chat.ts | 294 ++-- packages/ai-react/tests/use-chat.test.ts | 369 ++++- .../tests/create-generation-dispose.test.ts | 16 +- packages/ai-vertex/package.json | 1 - packages/ai-vertex/tests/factories.test.ts | 86 +- pnpm-lock.yaml | 1297 +++++++---------- testing/e2e/package.json | 4 +- testing/e2e/src/components/ImageGenUI.tsx | 14 +- testing/e2e/src/components/VideoGenUI.tsx | 14 +- testing/e2e/tests/chat.spec.ts | 21 + .../generic-middleware-interrupts.spec.ts | 18 + testing/e2e/tests/image-gen.spec.ts | 12 + .../e2e/tests/persistence-durability.spec.ts | 42 + testing/e2e/tests/video-gen.spec.ts | 12 + testing/panel/package.json | 4 +- 64 files changed, 3942 insertions(+), 1534 deletions(-) diff --git a/.changeset/ai-client-store-snapshot.md b/.changeset/ai-client-store-snapshot.md index 6115b3dad5..6a54bb2918 100644 --- a/.changeset/ai-client-store-snapshot.md +++ b/.changeset/ai-client-store-snapshot.md @@ -9,6 +9,6 @@ '@tanstack/ai-octane': patch --- -Hold client UI state in a TanStack Store atom. Framework hooks read `getSnapshot()` instead of copying fields through change callbacks. `useChat()` return shape stays the same. +Hold client UI state in a TanStack Store atom. Framework hooks read `getSnapshot()` instead of copying fields through change callbacks. React `useChat()` first commits `initialMessages` and `initialResumeSnapshot`, then applies browser persistence after attach. This timing applies to client-only rendering and keeps the server snapshot stable during SSR hydration. The `useChat()` return shape stays the same. `ChatClient` adds `subscribeSnapshot` / `getSnapshot`. The live connection method stays `subscribe()`. Generation, video, realtime, audio, and BYOK clients expose the same snapshot pair (`subscribe` / `getSnapshot`) where the name does not collide. diff --git a/docs/api/ai-client.md b/docs/api/ai-client.md index 903f6ef8c0..397919495d 100644 --- a/docs/api/ai-client.md +++ b/docs/api/ai-client.md @@ -289,8 +289,15 @@ const client = new ChatClient({ connection: fetchServerSentEvents("/api/chat"), }); +function logSnapshot() { + const snapshot = client.getSnapshot(); + console.log(snapshot.status, snapshot.messages.length); +} + +logSnapshot(); + const stop = client.subscribeSnapshot(() => { - render(client.getSnapshot()); + logSnapshot(); }); client.attach(); diff --git a/docs/persistence/client-persistence.md b/docs/persistence/client-persistence.md index b38673ea1c..e2d3e79366 100644 --- a/docs/persistence/client-persistence.md +++ b/docs/persistence/client-persistence.md @@ -56,10 +56,13 @@ to pick one and how it differs from the `runId` the hook reports. The client stores one record per `threadId`, the transcript plus a small resume pointer. On the next load `useChat` reads it and: -- **Repaints the transcript** from storage with no network. Sync adapters - (`localStorage` / `sessionStorage`) hydrate during construction; IndexedDB - hydrates asynchronously after the database opens (so the first paint may be - empty for a tick). +- **Repaints the transcript** from storage with no network. In React, the first + committed render uses `initialMessages` and `initialResumeSnapshot`. After the + hook attaches, it applies browser persistence from either a synchronous or an + asynchronous adapter. This timing also prevents SSR hydration mismatches. A + direct `ChatClient` and non-React framework wrappers still apply synchronous + stores during construction. IndexedDB always hydrates asynchronously after + the database opens. - **Rehydrates a pending interrupt**, so an approval prompt comes back exactly as it was. - **Rejoins an in-flight run**, if a reply was still streaming when the page diff --git a/examples/sandbox-cloudflare/package.json b/examples/sandbox-cloudflare/package.json index b6038d8cf8..1375ec6d77 100644 --- a/examples/sandbox-cloudflare/package.json +++ b/examples/sandbox-cloudflare/package.json @@ -22,8 +22,8 @@ "@tanstack/ai-sandbox": "workspace:*", "@tanstack/ai-sandbox-cloudflare": "workspace:*", "@tanstack/ai-sandbox-local-process": "workspace:*", - "@tanstack/react-router": "^1.158.4", - "@tanstack/react-start": "^1.159.0", + "@tanstack/react-router": "^1.170.32", + "@tanstack/react-start": "^1.168.49", "lucide-react": "^0.561.0", "react": "^19.2.3", "react-dom": "^19.2.3", @@ -37,7 +37,7 @@ "devDependencies": { "@cloudflare/vite-plugin": "^1.42.1", "@tailwindcss/vite": "^4.1.18", - "@tanstack/router-plugin": "^1.158.4", + "@tanstack/router-plugin": "^1.168.35", "@types/node": "^24.10.1", "@types/react": "^19.2.7", "@types/react-dom": "^19.2.3", diff --git a/examples/sandbox-web/package.json b/examples/sandbox-web/package.json index 75f96ab13e..941ff6df61 100644 --- a/examples/sandbox-web/package.json +++ b/examples/sandbox-web/package.json @@ -17,8 +17,8 @@ "@tanstack/ai-react": "workspace:*", "@tanstack/ai-sandbox": "workspace:*", "@tanstack/ai-sandbox-docker": "workspace:*", - "@tanstack/react-router": "^1.158.4", - "@tanstack/react-start": "^1.159.0", + "@tanstack/react-router": "^1.170.32", + "@tanstack/react-start": "^1.168.49", "lucide-react": "^0.561.0", "react": "^19.2.3", "react-dom": "^19.2.3", @@ -31,7 +31,7 @@ }, "devDependencies": { "@tailwindcss/vite": "^4.1.18", - "@tanstack/router-plugin": "^1.158.4", + "@tanstack/router-plugin": "^1.168.35", "@types/node": "^24.10.1", "@types/react": "^19.2.7", "@types/react-dom": "^19.2.3", diff --git a/examples/sandbox-web/src/routeTree.gen.ts b/examples/sandbox-web/src/routeTree.gen.ts index 5bc1e9dd01..1e6a913d7e 100644 --- a/examples/sandbox-web/src/routeTree.gen.ts +++ b/examples/sandbox-web/src/routeTree.gen.ts @@ -11,8 +11,8 @@ import { Route as rootRouteImport } from './routes/__root' import { Route as IndexRouteImport } from './routes/index' import { Route as ApiRunRouteImport } from './routes/api.run' -import { Route as ApiRunCancelRouteImport } from './routes/api.run.cancel' import { Route as ApiRunActiveRouteImport } from './routes/api.run.active' +import { Route as ApiRunCancelRouteImport } from './routes/api.run.cancel' const IndexRoute = IndexRouteImport.update({ id: '/', @@ -24,16 +24,16 @@ const ApiRunRoute = ApiRunRouteImport.update({ path: '/api/run', getParentRoute: () => rootRouteImport, } as any) -const ApiRunCancelRoute = ApiRunCancelRouteImport.update({ - id: '/cancel', - path: '/cancel', - getParentRoute: () => ApiRunRoute, -} as any) const ApiRunActiveRoute = ApiRunActiveRouteImport.update({ id: '/active', path: '/active', getParentRoute: () => ApiRunRoute, } as any) +const ApiRunCancelRoute = ApiRunCancelRouteImport.update({ + id: '/cancel', + path: '/cancel', + getParentRoute: () => ApiRunRoute, +} as any) export interface FileRoutesByFullPath { '/': typeof IndexRoute @@ -83,13 +83,6 @@ declare module '@tanstack/react-router' { preLoaderRoute: typeof ApiRunRouteImport parentRoute: typeof rootRouteImport } - '/api/run/cancel': { - id: '/api/run/cancel' - path: '/cancel' - fullPath: '/api/run/cancel' - preLoaderRoute: typeof ApiRunCancelRouteImport - parentRoute: typeof ApiRunRoute - } '/api/run/active': { id: '/api/run/active' path: '/active' @@ -97,6 +90,13 @@ declare module '@tanstack/react-router' { preLoaderRoute: typeof ApiRunActiveRouteImport parentRoute: typeof ApiRunRoute } + '/api/run/cancel': { + id: '/api/run/cancel' + path: '/cancel' + fullPath: '/api/run/cancel' + preLoaderRoute: typeof ApiRunCancelRouteImport + parentRoute: typeof ApiRunRoute + } } } diff --git a/examples/ts-code-mode-web/package.json b/examples/ts-code-mode-web/package.json index ed5a5978ee..c829b45cf6 100644 --- a/examples/ts-code-mode-web/package.json +++ b/examples/ts-code-mode-web/package.json @@ -32,9 +32,9 @@ "@tanstack/ai-ollama": "workspace:*", "@tanstack/ai-openai": "workspace:*", "@tanstack/ai-react": "workspace:*", - "@tanstack/react-router": "^1.158.4", - "@tanstack/react-start": "^1.159.0", - "@tanstack/router-plugin": "^1.158.4", + "@tanstack/react-router": "^1.170.32", + "@tanstack/react-start": "^1.168.49", + "@tanstack/router-plugin": "^1.168.35", "@tanstack/store": "^0.11.1", "framer-motion": "^11.15.0", "highlight.js": "^11.11.1", diff --git a/examples/ts-code-mode-web/src/routeTree.gen.ts b/examples/ts-code-mode-web/src/routeTree.gen.ts index e8255fd491..81c372c1ec 100644 --- a/examples/ts-code-mode-web/src/routeTree.gen.ts +++ b/examples/ts-code-mode-web/src/routeTree.gen.ts @@ -9,78 +9,101 @@ // Additionally, you should also exclude this file from your linter and/or formatter to prevent it from being checked or modified. import { Route as rootRouteImport } from './routes/__root' -import { Route as StructuredOutputRouteRouteImport } from './routes/_structured-output/route' -import { Route as ReportingRouteRouteImport } from './routes/_reporting/route' -import { Route as NpmGithubChatRouteRouteImport } from './routes/_npm-github-chat/route' -import { Route as HomeRouteRouteImport } from './routes/_home/route' -import { Route as ExecutePromptRouteRouteImport } from './routes/_execute-prompt/route' -import { Route as DatabaseDemoRouteRouteImport } from './routes/_database-demo/route' import { Route as BankingDemoRouteRouteImport } from './routes/_banking-demo/route' +import { Route as DatabaseDemoRouteRouteImport } from './routes/_database-demo/route' +import { Route as ExecutePromptRouteRouteImport } from './routes/_execute-prompt/route' +import { Route as HomeRouteRouteImport } from './routes/_home/route' +import { Route as NpmGithubChatRouteRouteImport } from './routes/_npm-github-chat/route' +import { Route as ReportingRouteRouteImport } from './routes/_reporting/route' +import { Route as StructuredOutputRouteRouteImport } from './routes/_structured-output/route' +import { Route as BankingDemoBankingDemoRouteImport } from './routes/_banking-demo/banking-demo' +import { Route as DatabaseDemoDatabaseDemoRouteImport } from './routes/_database-demo/database-demo' +import { Route as ExecutePromptExecutePromptRouteImport } from './routes/_execute-prompt/execute-prompt' import { Route as HomeIndexRouteImport } from './routes/_home/index' -import { Route as ApiRuntimeRouteImport } from './routes/api.runtime' -import { Route as StructuredOutputStructuredOutputRouteImport } from './routes/_structured-output/structured-output' -import { Route as ReportingReportingAgentRouteImport } from './routes/_reporting/reporting-agent' import { Route as NpmGithubChatNpmGithubChatRouteImport } from './routes/_npm-github-chat/npm-github-chat' -import { Route as ExecutePromptExecutePromptRouteImport } from './routes/_execute-prompt/execute-prompt' -import { Route as DatabaseDemoDatabaseDemoRouteImport } from './routes/_database-demo/database-demo' -import { Route as BankingDemoBankingDemoRouteImport } from './routes/_banking-demo/banking-demo' -import { Route as StructuredOutputApiStructuredOutputSnippetsRouteImport } from './routes/_structured-output/api.structured-output-snippets' -import { Route as StructuredOutputApiStructuredOutputRouteImport } from './routes/_structured-output/api.structured-output' -import { Route as ReportingApiReportsRouteImport } from './routes/_reporting/api.reports' -import { Route as ReportingApiReportSseRouteImport } from './routes/_reporting/api.report-sse' -import { Route as ReportingApiReportEventRouteImport } from './routes/_reporting/api.report-event' -import { Route as ReportingApiReportDemoRouteImport } from './routes/_reporting/api.report-demo' -import { Route as ReportingApiInvalidateRouteImport } from './routes/_reporting/api.invalidate' -import { Route as NpmGithubChatApiGeneratePdfRouteImport } from './routes/_npm-github-chat/api.generate-pdf' -import { Route as NpmGithubChatApiCodemodeRouteImport } from './routes/_npm-github-chat/api.codemode' -import { Route as HomeApiSnippetsRouteImport } from './routes/_home/api.snippets' -import { Route as HomeApiProductRegularRouteImport } from './routes/_home/api.product-regular' -import { Route as HomeApiProductCodemodeRouteImport } from './routes/_home/api.product-codemode' -import { Route as ExecutePromptApiRealtimeTokenRouteImport } from './routes/_execute-prompt/api.realtime-token' -import { Route as ExecutePromptApiExecutePromptRouteImport } from './routes/_execute-prompt/api.execute-prompt' -import { Route as DatabaseDemoApiJudgeRouteImport } from './routes/_database-demo/api.judge' -import { Route as DatabaseDemoApiDbSnippetsRouteImport } from './routes/_database-demo/api.db-snippets' -import { Route as DatabaseDemoApiDatabaseDemoRouteImport } from './routes/_database-demo/api.database-demo' -import { Route as BankingDemoApiBankingInitRouteImport } from './routes/_banking-demo/api.banking-init' +import { Route as ReportingReportingAgentRouteImport } from './routes/_reporting/reporting-agent' +import { Route as StructuredOutputStructuredOutputRouteImport } from './routes/_structured-output/structured-output' +import { Route as ApiRuntimeRouteImport } from './routes/api.runtime' import { Route as BankingDemoApiBankingDemoRouteImport } from './routes/_banking-demo/api.banking-demo' +import { Route as BankingDemoApiBankingInitRouteImport } from './routes/_banking-demo/api.banking-init' +import { Route as DatabaseDemoApiDatabaseDemoRouteImport } from './routes/_database-demo/api.database-demo' +import { Route as DatabaseDemoApiDbSnippetsRouteImport } from './routes/_database-demo/api.db-snippets' +import { Route as DatabaseDemoApiJudgeRouteImport } from './routes/_database-demo/api.judge' +import { Route as ExecutePromptApiExecutePromptRouteImport } from './routes/_execute-prompt/api.execute-prompt' +import { Route as ExecutePromptApiRealtimeTokenRouteImport } from './routes/_execute-prompt/api.realtime-token' +import { Route as HomeApiProductCodemodeRouteImport } from './routes/_home/api.product-codemode' +import { Route as HomeApiProductRegularRouteImport } from './routes/_home/api.product-regular' +import { Route as HomeApiSnippetsRouteImport } from './routes/_home/api.snippets' +import { Route as NpmGithubChatApiCodemodeRouteImport } from './routes/_npm-github-chat/api.codemode' +import { Route as NpmGithubChatApiGeneratePdfRouteImport } from './routes/_npm-github-chat/api.generate-pdf' +import { Route as ReportingApiInvalidateRouteImport } from './routes/_reporting/api.invalidate' +import { Route as ReportingApiReportDemoRouteImport } from './routes/_reporting/api.report-demo' +import { Route as ReportingApiReportEventRouteImport } from './routes/_reporting/api.report-event' +import { Route as ReportingApiReportSseRouteImport } from './routes/_reporting/api.report-sse' +import { Route as ReportingApiReportsRouteImport } from './routes/_reporting/api.reports' +import { Route as StructuredOutputApiStructuredOutputRouteImport } from './routes/_structured-output/api.structured-output' +import { Route as StructuredOutputApiStructuredOutputSnippetsRouteImport } from './routes/_structured-output/api.structured-output-snippets' -const StructuredOutputRouteRoute = StructuredOutputRouteRouteImport.update({ - id: '/_structured-output', +const BankingDemoRouteRoute = BankingDemoRouteRouteImport.update({ + id: '/_banking-demo', getParentRoute: () => rootRouteImport, } as any) -const ReportingRouteRoute = ReportingRouteRouteImport.update({ - id: '/_reporting', +const DatabaseDemoRouteRoute = DatabaseDemoRouteRouteImport.update({ + id: '/_database-demo', getParentRoute: () => rootRouteImport, } as any) -const NpmGithubChatRouteRoute = NpmGithubChatRouteRouteImport.update({ - id: '/_npm-github-chat', +const ExecutePromptRouteRoute = ExecutePromptRouteRouteImport.update({ + id: '/_execute-prompt', getParentRoute: () => rootRouteImport, } as any) const HomeRouteRoute = HomeRouteRouteImport.update({ id: '/_home', getParentRoute: () => rootRouteImport, } as any) -const ExecutePromptRouteRoute = ExecutePromptRouteRouteImport.update({ - id: '/_execute-prompt', +const NpmGithubChatRouteRoute = NpmGithubChatRouteRouteImport.update({ + id: '/_npm-github-chat', getParentRoute: () => rootRouteImport, } as any) -const DatabaseDemoRouteRoute = DatabaseDemoRouteRouteImport.update({ - id: '/_database-demo', +const ReportingRouteRoute = ReportingRouteRouteImport.update({ + id: '/_reporting', getParentRoute: () => rootRouteImport, } as any) -const BankingDemoRouteRoute = BankingDemoRouteRouteImport.update({ - id: '/_banking-demo', +const StructuredOutputRouteRoute = StructuredOutputRouteRouteImport.update({ + id: '/_structured-output', getParentRoute: () => rootRouteImport, } as any) +const BankingDemoBankingDemoRoute = BankingDemoBankingDemoRouteImport.update({ + id: '/banking-demo', + path: '/banking-demo', + getParentRoute: () => BankingDemoRouteRoute, +} as any) +const DatabaseDemoDatabaseDemoRoute = + DatabaseDemoDatabaseDemoRouteImport.update({ + id: '/database-demo', + path: '/database-demo', + getParentRoute: () => DatabaseDemoRouteRoute, + } as any) +const ExecutePromptExecutePromptRoute = + ExecutePromptExecutePromptRouteImport.update({ + id: '/execute-prompt', + path: '/execute-prompt', + getParentRoute: () => ExecutePromptRouteRoute, + } as any) const HomeIndexRoute = HomeIndexRouteImport.update({ id: '/', path: '/', getParentRoute: () => HomeRouteRoute, } as any) -const ApiRuntimeRoute = ApiRuntimeRouteImport.update({ - id: '/api/runtime', - path: '/api/runtime', - getParentRoute: () => rootRouteImport, +const NpmGithubChatNpmGithubChatRoute = + NpmGithubChatNpmGithubChatRouteImport.update({ + id: '/npm-github-chat', + path: '/npm-github-chat', + getParentRoute: () => NpmGithubChatRouteRoute, + } as any) +const ReportingReportingAgentRoute = ReportingReportingAgentRouteImport.update({ + id: '/reporting-agent', + path: '/reporting-agent', + getParentRoute: () => ReportingRouteRoute, } as any) const StructuredOutputStructuredOutputRoute = StructuredOutputStructuredOutputRouteImport.update({ @@ -88,54 +111,87 @@ const StructuredOutputStructuredOutputRoute = path: '/structured-output', getParentRoute: () => StructuredOutputRouteRoute, } as any) -const ReportingReportingAgentRoute = ReportingReportingAgentRouteImport.update({ - id: '/reporting-agent', - path: '/reporting-agent', - getParentRoute: () => ReportingRouteRoute, +const ApiRuntimeRoute = ApiRuntimeRouteImport.update({ + id: '/api/runtime', + path: '/api/runtime', + getParentRoute: () => rootRouteImport, } as any) -const NpmGithubChatNpmGithubChatRoute = - NpmGithubChatNpmGithubChatRouteImport.update({ - id: '/npm-github-chat', - path: '/npm-github-chat', - getParentRoute: () => NpmGithubChatRouteRoute, +const BankingDemoApiBankingDemoRoute = + BankingDemoApiBankingDemoRouteImport.update({ + id: '/api/banking-demo', + path: '/api/banking-demo', + getParentRoute: () => BankingDemoRouteRoute, } as any) -const ExecutePromptExecutePromptRoute = - ExecutePromptExecutePromptRouteImport.update({ - id: '/execute-prompt', - path: '/execute-prompt', - getParentRoute: () => ExecutePromptRouteRoute, +const BankingDemoApiBankingInitRoute = + BankingDemoApiBankingInitRouteImport.update({ + id: '/api/banking-init', + path: '/api/banking-init', + getParentRoute: () => BankingDemoRouteRoute, } as any) -const DatabaseDemoDatabaseDemoRoute = - DatabaseDemoDatabaseDemoRouteImport.update({ - id: '/database-demo', - path: '/database-demo', +const DatabaseDemoApiDatabaseDemoRoute = + DatabaseDemoApiDatabaseDemoRouteImport.update({ + id: '/api/database-demo', + path: '/api/database-demo', getParentRoute: () => DatabaseDemoRouteRoute, } as any) -const BankingDemoBankingDemoRoute = BankingDemoBankingDemoRouteImport.update({ - id: '/banking-demo', - path: '/banking-demo', - getParentRoute: () => BankingDemoRouteRoute, +const DatabaseDemoApiDbSnippetsRoute = + DatabaseDemoApiDbSnippetsRouteImport.update({ + id: '/api/db-snippets', + path: '/api/db-snippets', + getParentRoute: () => DatabaseDemoRouteRoute, + } as any) +const DatabaseDemoApiJudgeRoute = DatabaseDemoApiJudgeRouteImport.update({ + id: '/api/judge', + path: '/api/judge', + getParentRoute: () => DatabaseDemoRouteRoute, } as any) -const StructuredOutputApiStructuredOutputSnippetsRoute = - StructuredOutputApiStructuredOutputSnippetsRouteImport.update({ - id: '/api/structured-output-snippets', - path: '/api/structured-output-snippets', - getParentRoute: () => StructuredOutputRouteRoute, +const ExecutePromptApiExecutePromptRoute = + ExecutePromptApiExecutePromptRouteImport.update({ + id: '/api/execute-prompt', + path: '/api/execute-prompt', + getParentRoute: () => ExecutePromptRouteRoute, } as any) -const StructuredOutputApiStructuredOutputRoute = - StructuredOutputApiStructuredOutputRouteImport.update({ - id: '/api/structured-output', - path: '/api/structured-output', - getParentRoute: () => StructuredOutputRouteRoute, +const ExecutePromptApiRealtimeTokenRoute = + ExecutePromptApiRealtimeTokenRouteImport.update({ + id: '/api/realtime-token', + path: '/api/realtime-token', + getParentRoute: () => ExecutePromptRouteRoute, } as any) -const ReportingApiReportsRoute = ReportingApiReportsRouteImport.update({ - id: '/api/reports', - path: '/api/reports', +const HomeApiProductCodemodeRoute = HomeApiProductCodemodeRouteImport.update({ + id: '/api/product-codemode', + path: '/api/product-codemode', + getParentRoute: () => HomeRouteRoute, +} as any) +const HomeApiProductRegularRoute = HomeApiProductRegularRouteImport.update({ + id: '/api/product-regular', + path: '/api/product-regular', + getParentRoute: () => HomeRouteRoute, +} as any) +const HomeApiSnippetsRoute = HomeApiSnippetsRouteImport.update({ + id: '/api/snippets', + path: '/api/snippets', + getParentRoute: () => HomeRouteRoute, +} as any) +const NpmGithubChatApiCodemodeRoute = + NpmGithubChatApiCodemodeRouteImport.update({ + id: '/api/codemode', + path: '/api/codemode', + getParentRoute: () => NpmGithubChatRouteRoute, + } as any) +const NpmGithubChatApiGeneratePdfRoute = + NpmGithubChatApiGeneratePdfRouteImport.update({ + id: '/api/generate-pdf', + path: '/api/generate-pdf', + getParentRoute: () => NpmGithubChatRouteRoute, + } as any) +const ReportingApiInvalidateRoute = ReportingApiInvalidateRouteImport.update({ + id: '/api/invalidate', + path: '/api/invalidate', getParentRoute: () => ReportingRouteRoute, } as any) -const ReportingApiReportSseRoute = ReportingApiReportSseRouteImport.update({ - id: '/api/report-sse', - path: '/api/report-sse', +const ReportingApiReportDemoRoute = ReportingApiReportDemoRouteImport.update({ + id: '/api/report-demo', + path: '/api/report-demo', getParentRoute: () => ReportingRouteRoute, } as any) const ReportingApiReportEventRoute = ReportingApiReportEventRouteImport.update({ @@ -143,83 +199,27 @@ const ReportingApiReportEventRoute = ReportingApiReportEventRouteImport.update({ path: '/api/report-event', getParentRoute: () => ReportingRouteRoute, } as any) -const ReportingApiReportDemoRoute = ReportingApiReportDemoRouteImport.update({ - id: '/api/report-demo', - path: '/api/report-demo', +const ReportingApiReportSseRoute = ReportingApiReportSseRouteImport.update({ + id: '/api/report-sse', + path: '/api/report-sse', getParentRoute: () => ReportingRouteRoute, } as any) -const ReportingApiInvalidateRoute = ReportingApiInvalidateRouteImport.update({ - id: '/api/invalidate', - path: '/api/invalidate', +const ReportingApiReportsRoute = ReportingApiReportsRouteImport.update({ + id: '/api/reports', + path: '/api/reports', getParentRoute: () => ReportingRouteRoute, } as any) -const NpmGithubChatApiGeneratePdfRoute = - NpmGithubChatApiGeneratePdfRouteImport.update({ - id: '/api/generate-pdf', - path: '/api/generate-pdf', - getParentRoute: () => NpmGithubChatRouteRoute, +const StructuredOutputApiStructuredOutputRoute = + StructuredOutputApiStructuredOutputRouteImport.update({ + id: '/api/structured-output', + path: '/api/structured-output', + getParentRoute: () => StructuredOutputRouteRoute, } as any) -const NpmGithubChatApiCodemodeRoute = - NpmGithubChatApiCodemodeRouteImport.update({ - id: '/api/codemode', - path: '/api/codemode', - getParentRoute: () => NpmGithubChatRouteRoute, - } as any) -const HomeApiSnippetsRoute = HomeApiSnippetsRouteImport.update({ - id: '/api/snippets', - path: '/api/snippets', - getParentRoute: () => HomeRouteRoute, -} as any) -const HomeApiProductRegularRoute = HomeApiProductRegularRouteImport.update({ - id: '/api/product-regular', - path: '/api/product-regular', - getParentRoute: () => HomeRouteRoute, -} as any) -const HomeApiProductCodemodeRoute = HomeApiProductCodemodeRouteImport.update({ - id: '/api/product-codemode', - path: '/api/product-codemode', - getParentRoute: () => HomeRouteRoute, -} as any) -const ExecutePromptApiRealtimeTokenRoute = - ExecutePromptApiRealtimeTokenRouteImport.update({ - id: '/api/realtime-token', - path: '/api/realtime-token', - getParentRoute: () => ExecutePromptRouteRoute, - } as any) -const ExecutePromptApiExecutePromptRoute = - ExecutePromptApiExecutePromptRouteImport.update({ - id: '/api/execute-prompt', - path: '/api/execute-prompt', - getParentRoute: () => ExecutePromptRouteRoute, - } as any) -const DatabaseDemoApiJudgeRoute = DatabaseDemoApiJudgeRouteImport.update({ - id: '/api/judge', - path: '/api/judge', - getParentRoute: () => DatabaseDemoRouteRoute, -} as any) -const DatabaseDemoApiDbSnippetsRoute = - DatabaseDemoApiDbSnippetsRouteImport.update({ - id: '/api/db-snippets', - path: '/api/db-snippets', - getParentRoute: () => DatabaseDemoRouteRoute, - } as any) -const DatabaseDemoApiDatabaseDemoRoute = - DatabaseDemoApiDatabaseDemoRouteImport.update({ - id: '/api/database-demo', - path: '/api/database-demo', - getParentRoute: () => DatabaseDemoRouteRoute, - } as any) -const BankingDemoApiBankingInitRoute = - BankingDemoApiBankingInitRouteImport.update({ - id: '/api/banking-init', - path: '/api/banking-init', - getParentRoute: () => BankingDemoRouteRoute, - } as any) -const BankingDemoApiBankingDemoRoute = - BankingDemoApiBankingDemoRouteImport.update({ - id: '/api/banking-demo', - path: '/api/banking-demo', - getParentRoute: () => BankingDemoRouteRoute, +const StructuredOutputApiStructuredOutputSnippetsRoute = + StructuredOutputApiStructuredOutputSnippetsRouteImport.update({ + id: '/api/structured-output-snippets', + path: '/api/structured-output-snippets', + getParentRoute: () => StructuredOutputRouteRoute, } as any) export interface FileRoutesByFullPath { @@ -427,25 +427,25 @@ export interface RootRouteChildren { declare module '@tanstack/react-router' { interface FileRoutesByPath { - '/_structured-output': { - id: '/_structured-output' + '/_banking-demo': { + id: '/_banking-demo' path: '' fullPath: '/' - preLoaderRoute: typeof StructuredOutputRouteRouteImport + preLoaderRoute: typeof BankingDemoRouteRouteImport parentRoute: typeof rootRouteImport } - '/_reporting': { - id: '/_reporting' + '/_database-demo': { + id: '/_database-demo' path: '' fullPath: '/' - preLoaderRoute: typeof ReportingRouteRouteImport + preLoaderRoute: typeof DatabaseDemoRouteRouteImport parentRoute: typeof rootRouteImport } - '/_npm-github-chat': { - id: '/_npm-github-chat' + '/_execute-prompt': { + id: '/_execute-prompt' path: '' fullPath: '/' - preLoaderRoute: typeof NpmGithubChatRouteRouteImport + preLoaderRoute: typeof ExecutePromptRouteRouteImport parentRoute: typeof rootRouteImport } '/_home': { @@ -455,27 +455,48 @@ declare module '@tanstack/react-router' { preLoaderRoute: typeof HomeRouteRouteImport parentRoute: typeof rootRouteImport } - '/_execute-prompt': { - id: '/_execute-prompt' + '/_npm-github-chat': { + id: '/_npm-github-chat' path: '' fullPath: '/' - preLoaderRoute: typeof ExecutePromptRouteRouteImport + preLoaderRoute: typeof NpmGithubChatRouteRouteImport parentRoute: typeof rootRouteImport } - '/_database-demo': { - id: '/_database-demo' + '/_reporting': { + id: '/_reporting' path: '' fullPath: '/' - preLoaderRoute: typeof DatabaseDemoRouteRouteImport + preLoaderRoute: typeof ReportingRouteRouteImport parentRoute: typeof rootRouteImport } - '/_banking-demo': { - id: '/_banking-demo' + '/_structured-output': { + id: '/_structured-output' path: '' fullPath: '/' - preLoaderRoute: typeof BankingDemoRouteRouteImport + preLoaderRoute: typeof StructuredOutputRouteRouteImport parentRoute: typeof rootRouteImport } + '/_banking-demo/banking-demo': { + id: '/_banking-demo/banking-demo' + path: '/banking-demo' + fullPath: '/banking-demo' + preLoaderRoute: typeof BankingDemoBankingDemoRouteImport + parentRoute: typeof BankingDemoRouteRoute + } + '/_database-demo/database-demo': { + id: '/_database-demo/database-demo' + path: '/database-demo' + fullPath: '/database-demo' + preLoaderRoute: typeof DatabaseDemoDatabaseDemoRouteImport + parentRoute: typeof DatabaseDemoRouteRoute + } + '/_execute-prompt/execute-prompt': { + id: '/_execute-prompt/execute-prompt' + path: '/execute-prompt' + fullPath: '/execute-prompt' + preLoaderRoute: typeof ExecutePromptExecutePromptRouteImport + parentRoute: typeof ExecutePromptRouteRoute + } '/_home/': { id: '/_home/' path: '/' @@ -483,27 +504,6 @@ declare module '@tanstack/react-router' { preLoaderRoute: typeof HomeIndexRouteImport parentRoute: typeof HomeRouteRoute } - '/api/runtime': { - id: '/api/runtime' - path: '/api/runtime' - fullPath: '/api/runtime' - preLoaderRoute: typeof ApiRuntimeRouteImport - parentRoute: typeof rootRouteImport - } - '/_structured-output/structured-output': { - id: '/_structured-output/structured-output' - path: '/structured-output' - fullPath: '/structured-output' - preLoaderRoute: typeof StructuredOutputStructuredOutputRouteImport - parentRoute: typeof StructuredOutputRouteRoute - } - '/_reporting/reporting-agent': { - id: '/_reporting/reporting-agent' - path: '/reporting-agent' - fullPath: '/reporting-agent' - preLoaderRoute: typeof ReportingReportingAgentRouteImport - parentRoute: typeof ReportingRouteRoute - } '/_npm-github-chat/npm-github-chat': { id: '/_npm-github-chat/npm-github-chat' path: '/npm-github-chat' @@ -511,95 +511,81 @@ declare module '@tanstack/react-router' { preLoaderRoute: typeof NpmGithubChatNpmGithubChatRouteImport parentRoute: typeof NpmGithubChatRouteRoute } - '/_execute-prompt/execute-prompt': { - id: '/_execute-prompt/execute-prompt' - path: '/execute-prompt' - fullPath: '/execute-prompt' - preLoaderRoute: typeof ExecutePromptExecutePromptRouteImport - parentRoute: typeof ExecutePromptRouteRoute - } - '/_database-demo/database-demo': { - id: '/_database-demo/database-demo' - path: '/database-demo' - fullPath: '/database-demo' - preLoaderRoute: typeof DatabaseDemoDatabaseDemoRouteImport - parentRoute: typeof DatabaseDemoRouteRoute - } - '/_banking-demo/banking-demo': { - id: '/_banking-demo/banking-demo' - path: '/banking-demo' - fullPath: '/banking-demo' - preLoaderRoute: typeof BankingDemoBankingDemoRouteImport - parentRoute: typeof BankingDemoRouteRoute + '/_reporting/reporting-agent': { + id: '/_reporting/reporting-agent' + path: '/reporting-agent' + fullPath: '/reporting-agent' + preLoaderRoute: typeof ReportingReportingAgentRouteImport + parentRoute: typeof ReportingRouteRoute } - '/_structured-output/api/structured-output-snippets': { - id: '/_structured-output/api/structured-output-snippets' - path: '/api/structured-output-snippets' - fullPath: '/api/structured-output-snippets' - preLoaderRoute: typeof StructuredOutputApiStructuredOutputSnippetsRouteImport + '/_structured-output/structured-output': { + id: '/_structured-output/structured-output' + path: '/structured-output' + fullPath: '/structured-output' + preLoaderRoute: typeof StructuredOutputStructuredOutputRouteImport parentRoute: typeof StructuredOutputRouteRoute } - '/_structured-output/api/structured-output': { - id: '/_structured-output/api/structured-output' - path: '/api/structured-output' - fullPath: '/api/structured-output' - preLoaderRoute: typeof StructuredOutputApiStructuredOutputRouteImport - parentRoute: typeof StructuredOutputRouteRoute + '/api/runtime': { + id: '/api/runtime' + path: '/api/runtime' + fullPath: '/api/runtime' + preLoaderRoute: typeof ApiRuntimeRouteImport + parentRoute: typeof rootRouteImport } - '/_reporting/api/reports': { - id: '/_reporting/api/reports' - path: '/api/reports' - fullPath: '/api/reports' - preLoaderRoute: typeof ReportingApiReportsRouteImport - parentRoute: typeof ReportingRouteRoute + '/_banking-demo/api/banking-demo': { + id: '/_banking-demo/api/banking-demo' + path: '/api/banking-demo' + fullPath: '/api/banking-demo' + preLoaderRoute: typeof BankingDemoApiBankingDemoRouteImport + parentRoute: typeof BankingDemoRouteRoute } - '/_reporting/api/report-sse': { - id: '/_reporting/api/report-sse' - path: '/api/report-sse' - fullPath: '/api/report-sse' - preLoaderRoute: typeof ReportingApiReportSseRouteImport - parentRoute: typeof ReportingRouteRoute + '/_banking-demo/api/banking-init': { + id: '/_banking-demo/api/banking-init' + path: '/api/banking-init' + fullPath: '/api/banking-init' + preLoaderRoute: typeof BankingDemoApiBankingInitRouteImport + parentRoute: typeof BankingDemoRouteRoute } - '/_reporting/api/report-event': { - id: '/_reporting/api/report-event' - path: '/api/report-event' - fullPath: '/api/report-event' - preLoaderRoute: typeof ReportingApiReportEventRouteImport - parentRoute: typeof ReportingRouteRoute + '/_database-demo/api/database-demo': { + id: '/_database-demo/api/database-demo' + path: '/api/database-demo' + fullPath: '/api/database-demo' + preLoaderRoute: typeof DatabaseDemoApiDatabaseDemoRouteImport + parentRoute: typeof DatabaseDemoRouteRoute } - '/_reporting/api/report-demo': { - id: '/_reporting/api/report-demo' - path: '/api/report-demo' - fullPath: '/api/report-demo' - preLoaderRoute: typeof ReportingApiReportDemoRouteImport - parentRoute: typeof ReportingRouteRoute + '/_database-demo/api/db-snippets': { + id: '/_database-demo/api/db-snippets' + path: '/api/db-snippets' + fullPath: '/api/db-snippets' + preLoaderRoute: typeof DatabaseDemoApiDbSnippetsRouteImport + parentRoute: typeof DatabaseDemoRouteRoute } - '/_reporting/api/invalidate': { - id: '/_reporting/api/invalidate' - path: '/api/invalidate' - fullPath: '/api/invalidate' - preLoaderRoute: typeof ReportingApiInvalidateRouteImport - parentRoute: typeof ReportingRouteRoute + '/_database-demo/api/judge': { + id: '/_database-demo/api/judge' + path: '/api/judge' + fullPath: '/api/judge' + preLoaderRoute: typeof DatabaseDemoApiJudgeRouteImport + parentRoute: typeof DatabaseDemoRouteRoute } - '/_npm-github-chat/api/generate-pdf': { - id: '/_npm-github-chat/api/generate-pdf' - path: '/api/generate-pdf' - fullPath: '/api/generate-pdf' - preLoaderRoute: typeof NpmGithubChatApiGeneratePdfRouteImport - parentRoute: typeof NpmGithubChatRouteRoute + '/_execute-prompt/api/execute-prompt': { + id: '/_execute-prompt/api/execute-prompt' + path: '/api/execute-prompt' + fullPath: '/api/execute-prompt' + preLoaderRoute: typeof ExecutePromptApiExecutePromptRouteImport + parentRoute: typeof ExecutePromptRouteRoute } - '/_npm-github-chat/api/codemode': { - id: '/_npm-github-chat/api/codemode' - path: '/api/codemode' - fullPath: '/api/codemode' - preLoaderRoute: typeof NpmGithubChatApiCodemodeRouteImport - parentRoute: typeof NpmGithubChatRouteRoute + '/_execute-prompt/api/realtime-token': { + id: '/_execute-prompt/api/realtime-token' + path: '/api/realtime-token' + fullPath: '/api/realtime-token' + preLoaderRoute: typeof ExecutePromptApiRealtimeTokenRouteImport + parentRoute: typeof ExecutePromptRouteRoute } - '/_home/api/snippets': { - id: '/_home/api/snippets' - path: '/api/snippets' - fullPath: '/api/snippets' - preLoaderRoute: typeof HomeApiSnippetsRouteImport + '/_home/api/product-codemode': { + id: '/_home/api/product-codemode' + path: '/api/product-codemode' + fullPath: '/api/product-codemode' + preLoaderRoute: typeof HomeApiProductCodemodeRouteImport parentRoute: typeof HomeRouteRoute } '/_home/api/product-regular': { @@ -609,61 +595,75 @@ declare module '@tanstack/react-router' { preLoaderRoute: typeof HomeApiProductRegularRouteImport parentRoute: typeof HomeRouteRoute } - '/_home/api/product-codemode': { - id: '/_home/api/product-codemode' - path: '/api/product-codemode' - fullPath: '/api/product-codemode' - preLoaderRoute: typeof HomeApiProductCodemodeRouteImport + '/_home/api/snippets': { + id: '/_home/api/snippets' + path: '/api/snippets' + fullPath: '/api/snippets' + preLoaderRoute: typeof HomeApiSnippetsRouteImport parentRoute: typeof HomeRouteRoute } - '/_execute-prompt/api/realtime-token': { - id: '/_execute-prompt/api/realtime-token' - path: '/api/realtime-token' - fullPath: '/api/realtime-token' - preLoaderRoute: typeof ExecutePromptApiRealtimeTokenRouteImport - parentRoute: typeof ExecutePromptRouteRoute + '/_npm-github-chat/api/codemode': { + id: '/_npm-github-chat/api/codemode' + path: '/api/codemode' + fullPath: '/api/codemode' + preLoaderRoute: typeof NpmGithubChatApiCodemodeRouteImport + parentRoute: typeof NpmGithubChatRouteRoute } - '/_execute-prompt/api/execute-prompt': { - id: '/_execute-prompt/api/execute-prompt' - path: '/api/execute-prompt' - fullPath: '/api/execute-prompt' - preLoaderRoute: typeof ExecutePromptApiExecutePromptRouteImport - parentRoute: typeof ExecutePromptRouteRoute + '/_npm-github-chat/api/generate-pdf': { + id: '/_npm-github-chat/api/generate-pdf' + path: '/api/generate-pdf' + fullPath: '/api/generate-pdf' + preLoaderRoute: typeof NpmGithubChatApiGeneratePdfRouteImport + parentRoute: typeof NpmGithubChatRouteRoute } - '/_database-demo/api/judge': { - id: '/_database-demo/api/judge' - path: '/api/judge' - fullPath: '/api/judge' - preLoaderRoute: typeof DatabaseDemoApiJudgeRouteImport - parentRoute: typeof DatabaseDemoRouteRoute + '/_reporting/api/invalidate': { + id: '/_reporting/api/invalidate' + path: '/api/invalidate' + fullPath: '/api/invalidate' + preLoaderRoute: typeof ReportingApiInvalidateRouteImport + parentRoute: typeof ReportingRouteRoute } - '/_database-demo/api/db-snippets': { - id: '/_database-demo/api/db-snippets' - path: '/api/db-snippets' - fullPath: '/api/db-snippets' - preLoaderRoute: typeof DatabaseDemoApiDbSnippetsRouteImport - parentRoute: typeof DatabaseDemoRouteRoute + '/_reporting/api/report-demo': { + id: '/_reporting/api/report-demo' + path: '/api/report-demo' + fullPath: '/api/report-demo' + preLoaderRoute: typeof ReportingApiReportDemoRouteImport + parentRoute: typeof ReportingRouteRoute } - '/_database-demo/api/database-demo': { - id: '/_database-demo/api/database-demo' - path: '/api/database-demo' - fullPath: '/api/database-demo' - preLoaderRoute: typeof DatabaseDemoApiDatabaseDemoRouteImport - parentRoute: typeof DatabaseDemoRouteRoute + '/_reporting/api/report-event': { + id: '/_reporting/api/report-event' + path: '/api/report-event' + fullPath: '/api/report-event' + preLoaderRoute: typeof ReportingApiReportEventRouteImport + parentRoute: typeof ReportingRouteRoute } - '/_banking-demo/api/banking-init': { - id: '/_banking-demo/api/banking-init' - path: '/api/banking-init' - fullPath: '/api/banking-init' - preLoaderRoute: typeof BankingDemoApiBankingInitRouteImport - parentRoute: typeof BankingDemoRouteRoute + '/_reporting/api/report-sse': { + id: '/_reporting/api/report-sse' + path: '/api/report-sse' + fullPath: '/api/report-sse' + preLoaderRoute: typeof ReportingApiReportSseRouteImport + parentRoute: typeof ReportingRouteRoute } - '/_banking-demo/api/banking-demo': { - id: '/_banking-demo/api/banking-demo' - path: '/api/banking-demo' - fullPath: '/api/banking-demo' - preLoaderRoute: typeof BankingDemoApiBankingDemoRouteImport - parentRoute: typeof BankingDemoRouteRoute + '/_reporting/api/reports': { + id: '/_reporting/api/reports' + path: '/api/reports' + fullPath: '/api/reports' + preLoaderRoute: typeof ReportingApiReportsRouteImport + parentRoute: typeof ReportingRouteRoute + } + '/_structured-output/api/structured-output': { + id: '/_structured-output/api/structured-output' + path: '/api/structured-output' + fullPath: '/api/structured-output' + preLoaderRoute: typeof StructuredOutputApiStructuredOutputRouteImport + parentRoute: typeof StructuredOutputRouteRoute + } + '/_structured-output/api/structured-output-snippets': { + id: '/_structured-output/api/structured-output-snippets' + path: '/api/structured-output-snippets' + fullPath: '/api/structured-output-snippets' + preLoaderRoute: typeof StructuredOutputApiStructuredOutputSnippetsRouteImport + parentRoute: typeof StructuredOutputRouteRoute } } } diff --git a/examples/ts-code-mode-web/src/routes/_banking-demo/api.banking-demo.ts b/examples/ts-code-mode-web/src/routes/_banking-demo/api.banking-demo.ts index ff14d96999..335115b4be 100644 --- a/examples/ts-code-mode-web/src/routes/_banking-demo/api.banking-demo.ts +++ b/examples/ts-code-mode-web/src/routes/_banking-demo/api.banking-demo.ts @@ -199,7 +199,7 @@ async function getCodeModeTools() { return codeModeCache } -export const Route = createFileRoute('/_banking-demo/api/banking-demo' as any)({ +export const Route = createFileRoute('/_banking-demo/api/banking-demo')({ server: { handlers: { POST: async ({ request }) => { diff --git a/examples/ts-code-mode-web/src/routes/_banking-demo/api.banking-init.ts b/examples/ts-code-mode-web/src/routes/_banking-demo/api.banking-init.ts index 30630aaa38..1275b6aca7 100644 --- a/examples/ts-code-mode-web/src/routes/_banking-demo/api.banking-init.ts +++ b/examples/ts-code-mode-web/src/routes/_banking-demo/api.banking-init.ts @@ -10,7 +10,7 @@ import { getMockBalances } from '@/lib/reports/create-handler-bindings' const DASHBOARD_ID = 'dashboard' -export const Route = createFileRoute('/_banking-demo/api/banking-init' as any)({ +export const Route = createFileRoute('/_banking-demo/api/banking-init')({ server: { handlers: { POST: async () => { diff --git a/examples/ts-code-mode-web/src/routes/_banking-demo/banking-demo.tsx b/examples/ts-code-mode-web/src/routes/_banking-demo/banking-demo.tsx index d0ab65e1db..6dd38976e6 100644 --- a/examples/ts-code-mode-web/src/routes/_banking-demo/banking-demo.tsx +++ b/examples/ts-code-mode-web/src/routes/_banking-demo/banking-demo.tsx @@ -28,7 +28,7 @@ import type { UIUpdate, } from '@/lib/reports/types' -export const Route = createFileRoute('/_banking-demo/banking-demo' as any)({ +export const Route = createFileRoute('/_banking-demo/banking-demo')({ component: BankingDemoPage, }) diff --git a/examples/ts-code-mode-web/src/routes/_database-demo/api.database-demo.ts b/examples/ts-code-mode-web/src/routes/_database-demo/api.database-demo.ts index 10d7a12a85..4258f9ceb3 100644 --- a/examples/ts-code-mode-web/src/routes/_database-demo/api.database-demo.ts +++ b/examples/ts-code-mode-web/src/routes/_database-demo/api.database-demo.ts @@ -226,9 +226,7 @@ function wrapWithTimingEvents( })() } -export const Route = createFileRoute( - '/_database-demo/api/database-demo' as any, -)({ +export const Route = createFileRoute('/_database-demo/api/database-demo')({ server: { handlers: { POST: async ({ request }) => { diff --git a/examples/ts-code-mode-web/src/routes/_database-demo/api.db-snippets.ts b/examples/ts-code-mode-web/src/routes/_database-demo/api.db-snippets.ts index a7f0cdcac0..a04274deb9 100644 --- a/examples/ts-code-mode-web/src/routes/_database-demo/api.db-snippets.ts +++ b/examples/ts-code-mode-web/src/routes/_database-demo/api.db-snippets.ts @@ -14,7 +14,7 @@ const snippetStorage = createFileSnippetStorage({ trustStrategy, }) -export const Route = createFileRoute('/_database-demo/api/db-snippets' as any)({ +export const Route = createFileRoute('/_database-demo/api/db-snippets')({ server: { handlers: { GET: async () => { diff --git a/examples/ts-code-mode-web/src/routes/_database-demo/api.judge.ts b/examples/ts-code-mode-web/src/routes/_database-demo/api.judge.ts index 3b31b0a3e3..b231857928 100644 --- a/examples/ts-code-mode-web/src/routes/_database-demo/api.judge.ts +++ b/examples/ts-code-mode-web/src/routes/_database-demo/api.judge.ts @@ -29,7 +29,7 @@ Rate the candidate on two dimensions, each on a scale from 1 to 10 (10 = best): Provide a two sentence summary of your evaluation.` -export const Route = createFileRoute('/_database-demo/api/judge' as any)({ +export const Route = createFileRoute('/_database-demo/api/judge')({ server: { handlers: { POST: async ({ request }) => { diff --git a/examples/ts-code-mode-web/src/routes/_database-demo/database-demo.tsx b/examples/ts-code-mode-web/src/routes/_database-demo/database-demo.tsx index c4a05fab1e..d4d9c966e2 100644 --- a/examples/ts-code-mode-web/src/routes/_database-demo/database-demo.tsx +++ b/examples/ts-code-mode-web/src/routes/_database-demo/database-demo.tsx @@ -25,7 +25,7 @@ import ChatInput from '@/components/ChatInput' import { formatDuration } from '@/lib/efficiency' import { toolResultContentToString } from '@/lib/tool-result-content' -export const Route = createFileRoute('/_database-demo/database-demo' as any)({ +export const Route = createFileRoute('/_database-demo/database-demo')({ component: DatabaseDemoPage, }) diff --git a/examples/ts-code-mode-web/src/routes/_execute-prompt/api.execute-prompt.ts b/examples/ts-code-mode-web/src/routes/_execute-prompt/api.execute-prompt.ts index f5c83f3f42..f49ecf5a4f 100644 --- a/examples/ts-code-mode-web/src/routes/_execute-prompt/api.execute-prompt.ts +++ b/examples/ts-code-mode-web/src/routes/_execute-prompt/api.execute-prompt.ts @@ -33,9 +33,7 @@ async function getDriver(): Promise { return cachedDriver } -export const Route = createFileRoute( - '/_execute-prompt/api/execute-prompt' as any, -)({ +export const Route = createFileRoute('/_execute-prompt/api/execute-prompt')({ server: { handlers: { POST: async ({ request }) => { diff --git a/examples/ts-code-mode-web/src/routes/_execute-prompt/api.realtime-token.ts b/examples/ts-code-mode-web/src/routes/_execute-prompt/api.realtime-token.ts index 9b4b38cafe..5b7ab96876 100644 --- a/examples/ts-code-mode-web/src/routes/_execute-prompt/api.realtime-token.ts +++ b/examples/ts-code-mode-web/src/routes/_execute-prompt/api.realtime-token.ts @@ -2,9 +2,7 @@ import { createFileRoute } from '@tanstack/react-router' import { realtimeToken } from '@tanstack/ai' import { openaiRealtimeToken } from '@tanstack/ai-openai' -export const Route = createFileRoute( - '/_execute-prompt/api/realtime-token' as any, -)({ +export const Route = createFileRoute('/_execute-prompt/api/realtime-token')({ server: { handlers: { POST: async () => { diff --git a/examples/ts-code-mode-web/src/routes/_execute-prompt/execute-prompt.tsx b/examples/ts-code-mode-web/src/routes/_execute-prompt/execute-prompt.tsx index e44c07563d..d42bebb877 100644 --- a/examples/ts-code-mode-web/src/routes/_execute-prompt/execute-prompt.tsx +++ b/examples/ts-code-mode-web/src/routes/_execute-prompt/execute-prompt.tsx @@ -29,7 +29,7 @@ import type { CodeExecution, } from '@/lib/execute-prompt-realtime-tools' -export const Route = createFileRoute('/_execute-prompt/execute-prompt' as any)({ +export const Route = createFileRoute('/_execute-prompt/execute-prompt')({ component: DashboardDemoPage, }) diff --git a/examples/ts-code-mode-web/src/routes/_reporting/api.invalidate.ts b/examples/ts-code-mode-web/src/routes/_reporting/api.invalidate.ts index f7100859e5..f473ebd017 100644 --- a/examples/ts-code-mode-web/src/routes/_reporting/api.invalidate.ts +++ b/examples/ts-code-mode-web/src/routes/_reporting/api.invalidate.ts @@ -4,7 +4,7 @@ import { getReportState, getSSEController } from '@/lib/reports/report-storage' import { refreshComponent } from '@/lib/reports/refresh-component' import { evaluateWatchersForSignals } from '@/lib/reports/evaluate-watchers' -export const Route = createFileRoute('/_reporting/api/invalidate' as any)({ +export const Route = createFileRoute('/_reporting/api/invalidate')({ server: { handlers: { POST: async ({ request }) => { diff --git a/examples/ts-code-mode-web/src/routes/_reporting/api.report-demo.ts b/examples/ts-code-mode-web/src/routes/_reporting/api.report-demo.ts index dcf599641b..2ef92fdd4d 100644 --- a/examples/ts-code-mode-web/src/routes/_reporting/api.report-demo.ts +++ b/examples/ts-code-mode-web/src/routes/_reporting/api.report-demo.ts @@ -4,7 +4,7 @@ import { simulateDeposit, } from '@/lib/reports/create-handler-bindings' -export const Route = createFileRoute('/_reporting/api/report-demo' as any)({ +export const Route = createFileRoute('/_reporting/api/report-demo')({ server: { handlers: { POST: async ({ request }) => { diff --git a/examples/ts-code-mode-web/src/routes/_reporting/api.report-event.ts b/examples/ts-code-mode-web/src/routes/_reporting/api.report-event.ts index 90bf68b2f5..11d97742ee 100644 --- a/examples/ts-code-mode-web/src/routes/_reporting/api.report-event.ts +++ b/examples/ts-code-mode-web/src/routes/_reporting/api.report-event.ts @@ -16,7 +16,7 @@ import { import { refreshComponent } from '@/lib/reports/refresh-component' import { evaluateWatchersForSignals } from '@/lib/reports/evaluate-watchers' -export const Route = createFileRoute('/_reporting/api/report-event' as any)({ +export const Route = createFileRoute('/_reporting/api/report-event')({ server: { handlers: { POST: async ({ request }) => { diff --git a/examples/ts-code-mode-web/src/routes/_reporting/api.report-sse.ts b/examples/ts-code-mode-web/src/routes/_reporting/api.report-sse.ts index d53bf55080..97a429b400 100644 --- a/examples/ts-code-mode-web/src/routes/_reporting/api.report-sse.ts +++ b/examples/ts-code-mode-web/src/routes/_reporting/api.report-sse.ts @@ -5,7 +5,7 @@ import { getSSEController, } from '@/lib/reports/report-storage' -export const Route = createFileRoute('/_reporting/api/report-sse' as any)({ +export const Route = createFileRoute('/_reporting/api/report-sse')({ server: { handlers: { GET: async ({ request }) => { diff --git a/examples/ts-code-mode-web/src/routes/_reporting/api.reports.ts b/examples/ts-code-mode-web/src/routes/_reporting/api.reports.ts index 4ff06ad390..4a64e80fa1 100644 --- a/examples/ts-code-mode-web/src/routes/_reporting/api.reports.ts +++ b/examples/ts-code-mode-web/src/routes/_reporting/api.reports.ts @@ -49,7 +49,7 @@ async function getCodeModeTools() { return codeModeCache } -export const Route = createFileRoute('/_reporting/api/reports' as any)({ +export const Route = createFileRoute('/_reporting/api/reports')({ server: { handlers: { POST: async ({ request }) => { diff --git a/examples/ts-group-chat/package.json b/examples/ts-group-chat/package.json index 8b0e844330..66edb51124 100644 --- a/examples/ts-group-chat/package.json +++ b/examples/ts-group-chat/package.json @@ -14,10 +14,10 @@ "@tanstack/ai": "workspace:*", "@tanstack/ai-anthropic": "workspace:*", "@tanstack/react-devtools": "^0.9.10", - "@tanstack/react-router": "^1.158.4", - "@tanstack/react-router-devtools": "^1.158.4", - "@tanstack/react-start": "^1.159.0", - "@tanstack/router-plugin": "^1.158.4", + "@tanstack/react-router": "^1.170.32", + "@tanstack/react-router-devtools": "^1.167.1", + "@tanstack/react-start": "^1.168.49", + "@tanstack/router-plugin": "^1.168.35", "capnweb": "^0.10.0", "nitro": "3.0.260610-beta", "react": "^19.2.3", diff --git a/examples/ts-react-chat/package.json b/examples/ts-react-chat/package.json index 8afb8f862d..a9c642f6a9 100644 --- a/examples/ts-react-chat/package.json +++ b/examples/ts-react-chat/package.json @@ -49,12 +49,12 @@ "@tanstack/ai-sandbox-local-process": "workspace:*", "@tanstack/ai-sandbox-vercel": "workspace:*", "@tanstack/react-devtools": "^0.9.10", - "@tanstack/react-router": "^1.158.4", - "@tanstack/react-router-devtools": "^1.158.4", - "@tanstack/react-router-ssr-query": "^1.158.4", - "@tanstack/react-start": "^1.159.0", - "@tanstack/react-store": "^0.8.0", - "@tanstack/router-plugin": "^1.158.4", + "@tanstack/react-router": "^1.170.32", + "@tanstack/react-router-devtools": "^1.167.1", + "@tanstack/react-router-ssr-query": "^1.167.1", + "@tanstack/react-start": "^1.168.49", + "@tanstack/react-store": "^0.11.1", + "@tanstack/router-plugin": "^1.168.35", "@tanstack/store": "^0.11.1", "dockerode": "^4.0.2", "highlight.js": "^11.11.1", diff --git a/examples/ts-react-media/package.json b/examples/ts-react-media/package.json index 89f5d0b74f..1f832eb91c 100644 --- a/examples/ts-react-media/package.json +++ b/examples/ts-react-media/package.json @@ -18,9 +18,9 @@ "@tanstack/ai-grok": "workspace:*", "@tanstack/ai-openrouter": "workspace:*", "@tanstack/ai-react": "workspace:*", - "@tanstack/react-router": "^1.158.4", - "@tanstack/react-start": "^1.159.0", - "@tanstack/router-plugin": "^1.158.4", + "@tanstack/react-router": "^1.170.32", + "@tanstack/react-start": "^1.168.49", + "@tanstack/router-plugin": "^1.168.35", "lucide-react": "^0.561.0", "nitro": "3.0.260610-beta", "react": "^19.2.3", diff --git a/examples/ts-react-media/src/routeTree.gen.ts b/examples/ts-react-media/src/routeTree.gen.ts index cfbe5387c9..3182bcf153 100644 --- a/examples/ts-react-media/src/routeTree.gen.ts +++ b/examples/ts-react-media/src/routeTree.gen.ts @@ -9,19 +9,19 @@ // Additionally, you should also exclude this file from your linter and/or formatter to prevent it from being checked or modified. import { Route as rootRouteImport } from './routes/__root' -import { Route as SeedanceRouteImport } from './routes/seedance' import { Route as IndexRouteImport } from './routes/index' +import { Route as SeedanceRouteImport } from './routes/seedance' -const SeedanceRoute = SeedanceRouteImport.update({ - id: '/seedance', - path: '/seedance', - getParentRoute: () => rootRouteImport, -} as any) const IndexRoute = IndexRouteImport.update({ id: '/', path: '/', getParentRoute: () => rootRouteImport, } as any) +const SeedanceRoute = SeedanceRouteImport.update({ + id: '/seedance', + path: '/seedance', + getParentRoute: () => rootRouteImport, +} as any) export interface FileRoutesByFullPath { '/': typeof IndexRoute @@ -51,13 +51,6 @@ export interface RootRouteChildren { declare module '@tanstack/react-router' { interface FileRoutesByPath { - '/seedance': { - id: '/seedance' - path: '/seedance' - fullPath: '/seedance' - preLoaderRoute: typeof SeedanceRouteImport - parentRoute: typeof rootRouteImport - } '/': { id: '/' path: '/' @@ -65,6 +58,13 @@ declare module '@tanstack/react-router' { preLoaderRoute: typeof IndexRouteImport parentRoute: typeof rootRouteImport } + '/seedance': { + id: '/seedance' + path: '/seedance' + fullPath: '/seedance' + preLoaderRoute: typeof SeedanceRouteImport + parentRoute: typeof rootRouteImport + } } } diff --git a/examples/ts-react-rerank/package.json b/examples/ts-react-rerank/package.json index 83785b9b13..045fd110d7 100644 --- a/examples/ts-react-rerank/package.json +++ b/examples/ts-react-rerank/package.json @@ -14,9 +14,9 @@ "@tanstack/ai": "workspace:*", "@tanstack/ai-cohere": "workspace:*", "@tanstack/ai-openrouter": "workspace:*", - "@tanstack/react-router": "^1.158.4", - "@tanstack/react-start": "^1.159.0", - "@tanstack/router-plugin": "^1.158.4", + "@tanstack/react-router": "^1.170.32", + "@tanstack/react-start": "^1.168.49", + "@tanstack/router-plugin": "^1.168.35", "lucide-react": "^0.561.0", "nitro": "3.0.260610-beta", "react": "^19.2.3", diff --git a/examples/ts-react-search/package.json b/examples/ts-react-search/package.json index 26b915c7df..3ffaa70b71 100644 --- a/examples/ts-react-search/package.json +++ b/examples/ts-react-search/package.json @@ -19,11 +19,11 @@ "@tanstack/react-db": "^0.1.55", "@tanstack/react-devtools": "^0.9.10", "@tanstack/react-query": "^5.90.12", - "@tanstack/react-router": "^1.158.4", - "@tanstack/react-router-devtools": "^1.158.4", - "@tanstack/react-router-ssr-query": "^1.158.4", - "@tanstack/react-start": "^1.159.0", - "@tanstack/router-plugin": "^1.158.4", + "@tanstack/react-router": "^1.170.32", + "@tanstack/react-router-devtools": "^1.167.1", + "@tanstack/react-router-ssr-query": "^1.167.1", + "@tanstack/react-start": "^1.168.49", + "@tanstack/router-plugin": "^1.168.35", "@tanstack/zod-adapter": "^1.140.1", "class-variance-authority": "^0.7.1", "clsx": "^2.1.1", diff --git a/examples/ts-react-search/src/routeTree.gen.ts b/examples/ts-react-search/src/routeTree.gen.ts index 1ef02fbb58..3fa520b194 100644 --- a/examples/ts-react-search/src/routeTree.gen.ts +++ b/examples/ts-react-search/src/routeTree.gen.ts @@ -9,59 +9,59 @@ // Additionally, you should also exclude this file from your linter and/or formatter to prevent it from being checked or modified. import { Route as rootRouteImport } from './routes/__root' -import { Route as LayoutRouteRouteImport } from './routes/_layout/route' import { Route as IndexRouteImport } from './routes/index' -import { Route as ApiSettlementsRouteImport } from './routes/api/settlements' -import { Route as ApiSearchRouteImport } from './routes/api/search' -import { Route as ApiOrdersRouteImport } from './routes/api/orders' -import { Route as ApiDisputesRouteImport } from './routes/api/disputes' -import { Route as LayoutSettlementsRouteImport } from './routes/_layout/settlements' -import { Route as LayoutOrdersRouteImport } from './routes/_layout/orders' +import { Route as LayoutRouteRouteImport } from './routes/_layout/route' import { Route as LayoutDisputesRouteImport } from './routes/_layout/disputes' +import { Route as LayoutOrdersRouteImport } from './routes/_layout/orders' +import { Route as LayoutSettlementsRouteImport } from './routes/_layout/settlements' +import { Route as ApiDisputesRouteImport } from './routes/api/disputes' +import { Route as ApiOrdersRouteImport } from './routes/api/orders' +import { Route as ApiSearchRouteImport } from './routes/api/search' +import { Route as ApiSettlementsRouteImport } from './routes/api/settlements' -const LayoutRouteRoute = LayoutRouteRouteImport.update({ - id: '/_layout', - getParentRoute: () => rootRouteImport, -} as any) const IndexRoute = IndexRouteImport.update({ id: '/', path: '/', getParentRoute: () => rootRouteImport, } as any) -const ApiSettlementsRoute = ApiSettlementsRouteImport.update({ - id: '/api/settlements', - path: '/api/settlements', +const LayoutRouteRoute = LayoutRouteRouteImport.update({ + id: '/_layout', getParentRoute: () => rootRouteImport, } as any) -const ApiSearchRoute = ApiSearchRouteImport.update({ - id: '/api/search', - path: '/api/search', - getParentRoute: () => rootRouteImport, +const LayoutDisputesRoute = LayoutDisputesRouteImport.update({ + id: '/disputes', + path: '/disputes', + getParentRoute: () => LayoutRouteRoute, } as any) -const ApiOrdersRoute = ApiOrdersRouteImport.update({ - id: '/api/orders', - path: '/api/orders', - getParentRoute: () => rootRouteImport, +const LayoutOrdersRoute = LayoutOrdersRouteImport.update({ + id: '/orders', + path: '/orders', + getParentRoute: () => LayoutRouteRoute, +} as any) +const LayoutSettlementsRoute = LayoutSettlementsRouteImport.update({ + id: '/settlements', + path: '/settlements', + getParentRoute: () => LayoutRouteRoute, } as any) const ApiDisputesRoute = ApiDisputesRouteImport.update({ id: '/api/disputes', path: '/api/disputes', getParentRoute: () => rootRouteImport, } as any) -const LayoutSettlementsRoute = LayoutSettlementsRouteImport.update({ - id: '/settlements', - path: '/settlements', - getParentRoute: () => LayoutRouteRoute, +const ApiOrdersRoute = ApiOrdersRouteImport.update({ + id: '/api/orders', + path: '/api/orders', + getParentRoute: () => rootRouteImport, } as any) -const LayoutOrdersRoute = LayoutOrdersRouteImport.update({ - id: '/orders', - path: '/orders', - getParentRoute: () => LayoutRouteRoute, +const ApiSearchRoute = ApiSearchRouteImport.update({ + id: '/api/search', + path: '/api/search', + getParentRoute: () => rootRouteImport, } as any) -const LayoutDisputesRoute = LayoutDisputesRouteImport.update({ - id: '/disputes', - path: '/disputes', - getParentRoute: () => LayoutRouteRoute, +const ApiSettlementsRoute = ApiSettlementsRouteImport.update({ + id: '/api/settlements', + path: '/api/settlements', + getParentRoute: () => rootRouteImport, } as any) export interface FileRoutesByFullPath { @@ -141,13 +141,6 @@ export interface RootRouteChildren { declare module '@tanstack/react-router' { interface FileRoutesByPath { - '/_layout': { - id: '/_layout' - path: '' - fullPath: '/' - preLoaderRoute: typeof LayoutRouteRouteImport - parentRoute: typeof rootRouteImport - } '/': { id: '/' path: '/' @@ -155,26 +148,33 @@ declare module '@tanstack/react-router' { preLoaderRoute: typeof IndexRouteImport parentRoute: typeof rootRouteImport } - '/api/settlements': { - id: '/api/settlements' - path: '/api/settlements' - fullPath: '/api/settlements' - preLoaderRoute: typeof ApiSettlementsRouteImport + '/_layout': { + id: '/_layout' + path: '' + fullPath: '/' + preLoaderRoute: typeof LayoutRouteRouteImport parentRoute: typeof rootRouteImport } - '/api/search': { - id: '/api/search' - path: '/api/search' - fullPath: '/api/search' - preLoaderRoute: typeof ApiSearchRouteImport - parentRoute: typeof rootRouteImport + '/_layout/disputes': { + id: '/_layout/disputes' + path: '/disputes' + fullPath: '/disputes' + preLoaderRoute: typeof LayoutDisputesRouteImport + parentRoute: typeof LayoutRouteRoute } - '/api/orders': { - id: '/api/orders' - path: '/api/orders' - fullPath: '/api/orders' - preLoaderRoute: typeof ApiOrdersRouteImport - parentRoute: typeof rootRouteImport + '/_layout/orders': { + id: '/_layout/orders' + path: '/orders' + fullPath: '/orders' + preLoaderRoute: typeof LayoutOrdersRouteImport + parentRoute: typeof LayoutRouteRoute + } + '/_layout/settlements': { + id: '/_layout/settlements' + path: '/settlements' + fullPath: '/settlements' + preLoaderRoute: typeof LayoutSettlementsRouteImport + parentRoute: typeof LayoutRouteRoute } '/api/disputes': { id: '/api/disputes' @@ -183,26 +183,26 @@ declare module '@tanstack/react-router' { preLoaderRoute: typeof ApiDisputesRouteImport parentRoute: typeof rootRouteImport } - '/_layout/settlements': { - id: '/_layout/settlements' - path: '/settlements' - fullPath: '/settlements' - preLoaderRoute: typeof LayoutSettlementsRouteImport - parentRoute: typeof LayoutRouteRoute + '/api/orders': { + id: '/api/orders' + path: '/api/orders' + fullPath: '/api/orders' + preLoaderRoute: typeof ApiOrdersRouteImport + parentRoute: typeof rootRouteImport } - '/_layout/orders': { - id: '/_layout/orders' - path: '/orders' - fullPath: '/orders' - preLoaderRoute: typeof LayoutOrdersRouteImport - parentRoute: typeof LayoutRouteRoute + '/api/search': { + id: '/api/search' + path: '/api/search' + fullPath: '/api/search' + preLoaderRoute: typeof ApiSearchRouteImport + parentRoute: typeof rootRouteImport } - '/_layout/disputes': { - id: '/_layout/disputes' - path: '/disputes' - fullPath: '/disputes' - preLoaderRoute: typeof LayoutDisputesRouteImport - parentRoute: typeof LayoutRouteRoute + '/api/settlements': { + id: '/api/settlements' + path: '/api/settlements' + fullPath: '/api/settlements' + preLoaderRoute: typeof ApiSettlementsRouteImport + parentRoute: typeof rootRouteImport } } } diff --git a/examples/ts-solid-chat/package.json b/examples/ts-solid-chat/package.json index 5ac6e3b16a..d67411add8 100644 --- a/examples/ts-solid-chat/package.json +++ b/examples/ts-solid-chat/package.json @@ -20,13 +20,13 @@ "@tanstack/ai-openai": "workspace:*", "@tanstack/ai-solid": "workspace:*", "@tanstack/nitro-v2-vite-plugin": "^1.155.0", - "@tanstack/router-plugin": "^1.158.4", + "@tanstack/router-plugin": "^1.168.35", "@tanstack/solid-ai-devtools": "workspace:*", "@tanstack/solid-devtools": "^0.7.15", - "@tanstack/solid-router": "^1.139.10", - "@tanstack/solid-router-devtools": "^1.139.10", - "@tanstack/solid-router-ssr-query": "^1.139.10", - "@tanstack/solid-start": "^1.139.10", + "@tanstack/solid-router": "^1.170.30", + "@tanstack/solid-router-devtools": "^1.167.1", + "@tanstack/solid-router-ssr-query": "^1.167.1", + "@tanstack/solid-start": "^1.168.47", "@tanstack/solid-store": "^0.8.0", "@tanstack/store": "^0.11.1", "highlight.js": "^11.11.1", diff --git a/examples/ts-solid-chat/src/routeTree.gen.ts b/examples/ts-solid-chat/src/routeTree.gen.ts index 09f7e9514c..80d094ec75 100644 --- a/examples/ts-solid-chat/src/routeTree.gen.ts +++ b/examples/ts-solid-chat/src/routeTree.gen.ts @@ -46,7 +46,7 @@ export interface FileRoutesByFullPath { '/solid-ui': typeof SolidUiRoute '/api/chat': typeof ApiChatRoute '/example/guitars/$guitarId': typeof ExampleGuitarsGuitarIdRoute - '/example/guitars': typeof ExampleGuitarsIndexRoute + '/example/guitars/': typeof ExampleGuitarsIndexRoute } export interface FileRoutesByTo { '/': typeof IndexRoute @@ -70,7 +70,7 @@ export interface FileRouteTypes { | '/solid-ui' | '/api/chat' | '/example/guitars/$guitarId' - | '/example/guitars' + | '/example/guitars/' fileRoutesByTo: FileRoutesByTo to: | '/' @@ -121,7 +121,7 @@ declare module '@tanstack/solid-router' { '/example/guitars/': { id: '/example/guitars/' path: '/example/guitars' - fullPath: '/example/guitars' + fullPath: '/example/guitars/' preLoaderRoute: typeof ExampleGuitarsIndexRouteImport parentRoute: typeof rootRouteImport } diff --git a/packages/ai-client/src/audio-recorder.ts b/packages/ai-client/src/audio-recorder.ts index 7077a876ba..070ff95f58 100644 --- a/packages/ai-client/src/audio-recorder.ts +++ b/packages/ai-client/src/audio-recorder.ts @@ -66,6 +66,7 @@ export class AudioRecorder { private startedAt = 0 private readonly snapshotAtom: Atom = createAtom('idle') + private readonly listeners = new Set<(state: AudioRecorderState) => void>() // True while start() is awaiting getUserMedia (state is still 'idle' then). private starting = false // Set by cancel()/teardown during that window so start() releases the @@ -93,10 +94,8 @@ export class AudioRecorder { } subscribe(cb: (state: AudioRecorderState) => void): () => void { - const { unsubscribe } = this.snapshotAtom.subscribe((next) => { - cb(next) - }) - return unsubscribe + this.listeners.add(cb) + return () => this.listeners.delete(cb) } /** Current recorder lifecycle state. */ @@ -104,6 +103,7 @@ export class AudioRecorder { private setState(state: AudioRecorderState): void { this.snapshotAtom.set(state) + for (const listener of this.listeners) listener(state) } async start(): Promise { diff --git a/packages/ai-client/src/byok/client.ts b/packages/ai-client/src/byok/client.ts index eecddf457c..d1012936e6 100644 --- a/packages/ai-client/src/byok/client.ts +++ b/packages/ai-client/src/byok/client.ts @@ -4,7 +4,7 @@ import { isProviderId, maskKey, } from '@tanstack/ai/byok' -import { createAtom, subscribeAtom } from '../snapshot-atom' +import { createAtom } from '../snapshot-atom' import type { Atom } from '../snapshot-atom' import { memoryStorage } from './storage' import type { ByokProvider, ProviderId } from '@tanstack/ai/byok' @@ -95,6 +95,7 @@ export class ByokClient { readonly #companions: Record> = {} #storageError: string | null = null readonly #snapshotAtom: Atom + readonly #listeners = new Set<() => void>() readonly #ready: Promise constructor(options: DefineByokOptions = {}) { @@ -114,18 +115,27 @@ export class ByokClient { /** Resolves when constructor hydration (peek/load) finishes. */ ready = (): Promise => this.#ready - subscribe = (listener: () => void): (() => void) => - subscribeAtom(this.#snapshotAtom, listener) + subscribe = (listener: () => void): (() => void) => { + this.#listeners.add(listener) + return () => this.#listeners.delete(listener) + } getSnapshot = (): ByokSnapshot => this.#snapshotAtom.get() #buildSnapshot(): ByokSnapshot { - return { - status: { ...this.#statuses }, + return Object.freeze({ + status: Object.freeze( + Object.fromEntries( + Object.entries(this.#statuses).map(([key, value]) => [ + key, + value ? Object.freeze({ ...value }) : value, + ]), + ), + ), locked: this.#locked, - prompt: this.#prompt, + prompt: this.#prompt ? Object.freeze({ ...this.#prompt }) : null, storageError: this.#storageError, - } + }) } keys(): Keyring { @@ -369,6 +379,7 @@ export class ByokClient { #emit(): void { this.#snapshotAtom.set(this.#buildSnapshot()) + for (const listener of this.#listeners) listener() } } diff --git a/packages/ai-client/src/chat-client.ts b/packages/ai-client/src/chat-client.ts index 6450b70ff8..f3eb2ba289 100644 --- a/packages/ai-client/src/chat-client.ts +++ b/packages/ai-client/src/chat-client.ts @@ -671,7 +671,9 @@ export class ChatClient< onMessagesChange: (messages: Array) => { this.persistor?.notifyMessagesChanged(messages) this.patchSnapshot({ - messages: messages as Array>, + messages: this.freezeSnapshotMessages( + messages as Array>, + ), }) this.callbacksRef.current.onMessagesChange(messages) }, @@ -1506,19 +1508,89 @@ export class ChatClient< return `${prefix}-${Date.now()}-${Math.random().toString(36).substring(7)}` } + private freezeSnapshotPart>( + part: TPart, + ): TPart { + return Object.freeze({ + ...part, + ...('source' in part && + typeof part.source === 'object' && + part.source !== null + ? { source: Object.freeze({ ...part.source }) } + : {}), + ...(part.type === 'tool-call' && 'approval' in part && part.approval + ? { approval: Object.freeze({ ...part.approval }) } + : {}), + ...(part.type === 'tool-result' && Array.isArray(part.content) + ? { + content: Object.freeze( + part.content.map((contentPart) => + this.freezeSnapshotPart(contentPart), + ), + ), + } + : {}), + }) as TPart + } + + private freezeSnapshotMessages( + messages: Array>, + ): Array> { + return Object.freeze( + messages.map((message) => + Object.freeze({ + ...message, + parts: Object.freeze( + message.parts.map((part) => this.freezeSnapshotPart(part)), + ), + }), + ), + ) as Array> + } + + private freezeSnapshotQueue( + queue: Array, + ): Array { + return Object.freeze( + queue.map((item) => + Object.freeze({ + ...item, + ...(typeof item.content === 'object' + ? { + content: Object.freeze({ + ...item.content, + ...(Array.isArray(item.content.content) + ? { + content: Object.freeze( + item.content.content.map((part) => + this.freezeSnapshotPart(part), + ), + ), + } + : {}), + }), + } + : {}), + }), + ), + ) as Array + } + private readSnapshot(): ChatClientSnapshot { - return { - messages: this.processor.getMessages() as Array>, + return Object.freeze({ + messages: this.freezeSnapshotMessages( + this.processor.getMessages() as Array>, + ), status: this.status, isLoading: this.isLoading, error: this.error, isSubscribed: this.isSubscribed, connectionStatus: this.connectionStatus, sessionGenerating: this.sessionGenerating, - queue: this.getQueue(), + queue: this.freezeSnapshotQueue(this.getQueue()), runId: this.currentRunId, interruptState: this.interruptManager.getState(), - } + }) } private patchSnapshot( @@ -3041,7 +3113,7 @@ export class ChatClient< private emitQueueChange(): void { const queue = this.getQueue() - this.patchSnapshot({ queue }) + this.patchSnapshot({ queue: this.freezeSnapshotQueue(queue) }) this.callbacksRef.current.onQueueChange(queue) this.devtoolsBridge.emitSnapshot() } diff --git a/packages/ai-client/src/generation-client.ts b/packages/ai-client/src/generation-client.ts index c7a36b0456..a6fed26e1c 100644 --- a/packages/ai-client/src/generation-client.ts +++ b/packages/ai-client/src/generation-client.ts @@ -276,14 +276,19 @@ export class GenerationClient< this.input = input this.progress = null - const runId = this.devtoolsBridge.beginRun(input) - this.setIsLoading(true) - this.setStatus('generating') - this.setError(undefined) - const abortController = new AbortController() this.abortController = abortController const { signal } = abortController + const runId = this.devtoolsBridge.beginRun(input) + patchAtom(this.snapshotAtom, { runId }) + if (!this.ownsRun(abortController)) return + + this.setIsLoading(true, abortController) + if (!this.ownsRun(abortController)) return + this.setStatus('generating', abortController) + if (!this.ownsRun(abortController)) return + this.setError(undefined, abortController) + if (!this.ownsRun(abortController)) return try { let headers: Record | undefined @@ -293,6 +298,7 @@ export class GenerationClient< this.body.provider, ) headers = await prepareResolvedByokHeaders(this.byok, provider) + if (!this.ownsRun(abortController)) return } if (this.fetcher) { @@ -301,19 +307,21 @@ export class GenerationClient< input, headers === undefined ? { signal } : { signal, headers }, ) - if (signal.aborted) return + if (!this.ownsRun(abortController)) return if (result instanceof Response) { // Server function returned SSE Response — parse stream await this.processStream( parseSSEResponse(result, signal), runId, - signal, + abortController, ) } else { this.devtoolsBridge.ensureRunStarted(runId) - this.setResult(result) - this.setStatus('success') - this.completePlainFetcherResumeSnapshot(result) + this.setResult(result, abortController) + if (!this.ownsRun(abortController)) return + this.setStatus('success', abortController) + if (!this.ownsRun(abortController)) return + this.completePlainFetcherResumeSnapshot(result, abortController) } } else if (this.connection) { // Streaming adapter path @@ -324,13 +332,13 @@ export class GenerationClient< signal, this.createRunContext(runId, headers), ) - await this.processStream(stream, runId, signal) + await this.processStream(stream, runId, abortController) } else { throw new Error( 'GenerationClient requires either a connection or fetcher option', ) } - if (!signal.aborted && this.status === 'success') { + if (this.ownsRun(abortController) && this.status === 'success') { // Bump progress to 100 on successful completion so devtools // snapshots reflect the final state. The bridge mirrors this in // the run's recorded progress, but the snapshot reads `progress` @@ -343,17 +351,22 @@ export class GenerationClient< ) } } catch (err: unknown) { - if (signal.aborted) return + if (!this.ownsRun(abortController)) return const error = err instanceof Error ? err : new Error(String(err)) if (error instanceof ByokMissingError) { this.byok?.request(error.provider, 'missing') + if (!this.ownsRun(abortController)) return } if (error instanceof ByokBlockedError && error.reason === 'locked') { this.byok?.request(error.provider, 'locked') + if (!this.ownsRun(abortController)) return } - this.setError(error) - this.setStatus('error') - this.recordResumeSnapshotError(error) + this.setError(error, abortController) + if (!this.ownsRun(abortController)) return + this.setStatus('error', abortController) + if (!this.ownsRun(abortController)) return + this.recordResumeSnapshotError(error, abortController) + if (!this.ownsRun(abortController)) return this.devtoolsBridge.finishRun( this.devtoolsBridge.getActiveRunId() ?? runId, 'run:errored', @@ -363,8 +376,11 @@ export class GenerationClient< this.callbacksRef.onError?.(error) } finally { if (this.abortController === abortController) { - this.abortController = null - this.setIsLoading(false) + patchAtom(this.snapshotAtom, { runId: null }) + if (this.ownsRun(abortController)) { + this.setIsLoading(false, abortController) + if (this.ownsRun(abortController)) this.abortController = null + } } } } @@ -384,8 +400,9 @@ export class GenerationClient< private async processStream( source: AsyncIterable, fallbackRunId: string, - signal: AbortSignal, + abortController: AbortController, ): Promise { + const { signal } = abortController let streamRunId: string | undefined let sawTerminalChunk = false @@ -394,7 +411,9 @@ export class GenerationClient< const chunk = restoreInboundChunk(raw) this.callbacksRef.onChunk?.(chunk) - this.observeResumeSnapshot(chunk) + if (!this.ownsRun(abortController)) return + this.observeResumeSnapshot(chunk, abortController) + if (!this.ownsRun(abortController)) return const chunkRunId = 'runId' in chunk && typeof chunk.runId === 'string' ? chunk.runId @@ -404,19 +423,23 @@ export class GenerationClient< switch (chunk.type) { case 'RUN_STARTED': { streamRunId = chunk.runId + patchAtom(this.snapshotAtom, { runId: chunk.runId }) + if (!this.ownsRun(abortController)) return this.devtoolsBridge.ensureRunStarted(chunk.runId) break } case 'CUSTOM': { this.devtoolsBridge.ensureRunStarted(streamRunId ?? fallbackRunId) if (chunk.name === GENERATION_EVENTS.RESULT) { - this.setResult(chunk.value as TResult) + this.setResult(chunk.value as TResult, abortController) + if (!this.ownsRun(abortController)) return } else if (chunk.name === GENERATION_EVENTS.PROGRESS) { const { progress, message } = chunk.value as { progress: number message?: string } - this.setProgress(progress, message) + this.setProgress(progress, message, abortController) + if (!this.ownsRun(abortController)) return } break } @@ -424,7 +447,8 @@ export class GenerationClient< streamRunId = chunk.runId sawTerminalChunk = true this.devtoolsBridge.ensureRunStarted(chunk.runId) - this.setStatus('success') + this.setStatus('success', abortController) + if (!this.ownsRun(abortController)) return break } case 'RUN_ERROR': { @@ -452,17 +476,29 @@ export class GenerationClient< */ stop(): void { const runId = this.devtoolsBridge.getActiveRunId() + const stoppedStatus = this.status if (this.abortController) { this.abortController.abort() this.abortController = null } - this.setIsLoading(false) - if (this.status === 'generating') { - this.setStatus('idle') - if (runId) { + if (runId) { + if (stoppedStatus === 'success') { + this.devtoolsBridge.finishRun(runId, 'run:completed', 'completed') + } else if (stoppedStatus === 'error') { + this.devtoolsBridge.finishRun( + runId, + 'run:errored', + 'errored', + this.error?.message, + ) + } else { this.devtoolsBridge.finishRun(runId, 'run:cancelled', 'cancelled') } } + patchAtom(this.snapshotAtom, { runId: null }) + if (stoppedStatus === 'generating') { + this.setStatus('idle') + } // A stopped run is no longer resumable. Without this the in-memory // snapshot stays `running`, and a remount's `maybeResumeInFlight` would // rejoin a run the user just cancelled. @@ -474,6 +510,7 @@ export class GenerationClient< } this.notifyResumeSnapshotChanged() } + this.setIsLoading(false) } /** @@ -484,6 +521,7 @@ export class GenerationClient< */ reset(): void { this.stop() + if (this.abortController || this.isLoading) return this.setResult(null) this.input = null this.progress = null @@ -548,7 +586,9 @@ export class GenerationClient< this.abortController.abort() this.abortController = null } - this.setIsLoading(false) + if (this.resumeSnapshot?.status !== 'running') { + patchAtom(this.snapshotAtom, { runId: null }) + } this.devtoolsBridge.dispose() this.devtoolsMounted = false // Re-arm mount hydration + rejoin so a remount resumes from the (preserved) @@ -556,6 +596,7 @@ export class GenerationClient< // `maybeResumeInFlight`, both individually guarded. this.serverHydrationStarted = false this.rejoinedRunId = undefined + this.setIsLoading(false) } // =========================== @@ -619,17 +660,23 @@ export class GenerationClient< // Private state setters // =========================== - private setResult(rawResult: TResult | null): void { + private setResult( + rawResult: TResult | null, + controller?: AbortController, + ): void { if (rawResult === null) { this.result = null patchAtom(this.snapshotAtom, { result: null }) + if (controller && !this.ownsRun(controller)) return this.callbacksRef.onResultChange?.(null) + if (controller && !this.ownsRun(controller)) return this.devtoolsBridge.recordResultChange() return } if (this.callbacksRef.onResult) { const transformed = this.callbacksRef.onResult(rawResult) + if (controller && !this.ownsRun(controller)) return if (transformed === null) { // null return → keep previous result unchanged, just re-emit this.devtoolsBridge.emitState() @@ -639,7 +686,9 @@ export class GenerationClient< // Non-null, non-undefined → use transformed value this.result = transformed patchAtom(this.snapshotAtom, { result: this.result }) + if (controller && !this.ownsRun(controller)) return this.callbacksRef.onResultChange?.(this.result) + if (controller && !this.ownsRun(controller)) return this.devtoolsBridge.recordResultChange() return } @@ -651,32 +700,50 @@ export class GenerationClient< // oxlint-disable-next-line eslint-js/no-restricted-syntax -- TOutput defaults to TResult when no onResult transform is supplied this.result = rawResult as unknown as TOutput patchAtom(this.snapshotAtom, { result: this.result }) + if (controller && !this.ownsRun(controller)) return this.callbacksRef.onResultChange?.(this.result) + if (controller && !this.ownsRun(controller)) return this.devtoolsBridge.recordResultChange() } - private setIsLoading(isLoading: boolean): void { + private setIsLoading(isLoading: boolean, controller?: AbortController): void { this.isLoading = isLoading patchAtom(this.snapshotAtom, { isLoading }) + if (controller && !this.ownsRun(controller)) return this.callbacksRef.onLoadingChange?.(isLoading) + if (controller && !this.ownsRun(controller)) return this.devtoolsBridge.recordLoadingChange() } - private setError(error: Error | undefined): void { + private setError( + error: Error | undefined, + controller?: AbortController, + ): void { this.error = error patchAtom(this.snapshotAtom, { error }) + if (controller && !this.ownsRun(controller)) return this.callbacksRef.onErrorChange?.(error) + if (controller && !this.ownsRun(controller)) return this.devtoolsBridge.recordErrorChange(error) } - private setStatus(status: GenerationClientState): void { + private setStatus( + status: GenerationClientState, + controller?: AbortController, + ): void { this.status = status patchAtom(this.snapshotAtom, { status }) + if (controller && !this.ownsRun(controller)) return this.callbacksRef.onStatusChange?.(status) + if (controller && !this.ownsRun(controller)) return this.devtoolsBridge.recordStatusChange(status) } - private setProgress(value: number, message?: string): void { + private setProgress( + value: number, + message?: string, + controller?: AbortController, + ): void { this.progress = { value, ...(message ? { message } : {}), @@ -686,6 +753,7 @@ export class GenerationClient< } else { this.callbacksRef.onProgress?.(value, message) } + if (controller && !this.ownsRun(controller)) return this.devtoolsBridge.recordProgressChange() } @@ -712,6 +780,10 @@ export class GenerationClient< return `${prefix}-${Date.now()}-${Math.random().toString(36).substring(7)}` } + private ownsRun(controller: AbortController): boolean { + return !controller.signal.aborted && this.abortController === controller + } + private createRunContext( runId: string, headers?: Record, @@ -723,12 +795,15 @@ export class GenerationClient< } } - private observeResumeSnapshot(chunk: StreamChunk): void { + private observeResumeSnapshot( + chunk: StreamChunk, + controller: AbortController, + ): void { this.resumeSnapshot = updateGenerationResumeSnapshot( this.resumeSnapshot, chunk, ) - this.notifyResumeSnapshotChanged() + this.notifyResumeSnapshotChanged(controller) } /** @@ -736,9 +811,10 @@ export class GenerationClient< * The snapshot stays internal (persistence + devtools); the hook consumes * `resumeState`, mirroring the chat client. */ - private notifyResumeSnapshotChanged(): void { + private notifyResumeSnapshotChanged(controller?: AbortController): void { this.callbacksRef.onResumeSnapshotChange?.(this.resumeSnapshot) - this.emitResumeState() + if (controller && !this.ownsRun(controller)) return + this.emitResumeState(controller) } /** @@ -752,7 +828,7 @@ export class GenerationClient< * boundaries and when artifacts land, so skip the notification unless it * materially changed — same gate the persistence writes use. */ - private emitResumeState(): void { + private emitResumeState(controller?: AbortController): void { const snapshot = this.resumeSnapshot const state = snapshot?.resumeState const resumeState: GenerationResumeState | null = state @@ -769,6 +845,7 @@ export class GenerationClient< } this.lastEmittedResumeState = signature patchAtom(this.snapshotAtom, { runId: resumeState?.runId ?? null }) + if (controller && !this.ownsRun(controller)) return this.callbacksRef.onResumeStateChange?.(resumeState) } @@ -897,7 +974,10 @@ export class GenerationClient< * stale `error` from a previous run is intentionally dropped — this run * succeeded. */ - private completePlainFetcherResumeSnapshot(rawResult: unknown): void { + private completePlainFetcherResumeSnapshot( + rawResult: unknown, + controller: AbortController, + ): void { const previous = this.resumeSnapshot const result = createGenerationResultSnapshot(rawResult) this.resumeSnapshot = { @@ -914,7 +994,7 @@ export class GenerationClient< ? { result: { ...previous.result } } : {}), } - this.notifyResumeSnapshotChanged() + this.notifyResumeSnapshotChanged(controller) } /** @@ -923,15 +1003,20 @@ export class GenerationClient< * mark the snapshot `error`, leaving a persisted record that claims the * run is still in flight. */ - private recordResumeSnapshotError(error: Error): void { + private recordResumeSnapshotError( + error: Error, + controller?: AbortController, + ): void { // Surface the failure on the OBSERVABLE fields FIRST: a rejoin (or live // stream) that emits RUN_ERROR has already flipped the snapshot to `error` // via `observeResumeSnapshot`, so the early-return below would otherwise // skip this and leave `status` stuck on `generating` — the run would look // like it is still going forever. The guard avoids a duplicate `error` // emission on the live `generate()` path, which sets the status itself. - if (this.status !== 'error') this.setStatus('error') - this.setError(error) + if (this.status !== 'error') this.setStatus('error', controller) + if (controller && !this.ownsRun(controller)) return + this.setError(error, controller) + if (controller && !this.ownsRun(controller)) return if (this.resumeSnapshot?.status === 'error') return if (!this.resumeSnapshot && !this.serverDriven) return const previous = this.resumeSnapshot @@ -946,7 +1031,7 @@ export class GenerationClient< ...(previous?.result ? { result: { ...previous.result } } : {}), error: { message: error.message }, } - this.notifyResumeSnapshotChanged() + this.notifyResumeSnapshotChanged(controller) } /** @@ -1070,23 +1155,26 @@ export class GenerationClient< this.rejoinedRunId = runId const controller = new AbortController() this.abortController = controller - this.setIsLoading(true) - this.setStatus('generating') + this.setIsLoading(true, controller) + if (!this.ownsRun(controller)) return + this.setStatus('generating', controller) + if (!this.ownsRun(controller)) return void (async () => { try { await this.processStream( joinRun(runId, controller.signal), runId, - controller.signal, + controller, ) } catch (error) { - if (!controller.signal.aborted) { + if (this.ownsRun(controller)) { const failure = error instanceof Error ? error : new Error(String(error)) // Settles `status`/`error` AND rewrites the snapshot to a terminal // `error` with a null `resumeState`, so the next mount does not // rejoin this run again. - this.recordResumeSnapshotError(failure) + this.recordResumeSnapshotError(failure, controller) + if (!this.ownsRun(controller)) return this.callbacksRef.onError?.(failure) } } finally { @@ -1094,8 +1182,8 @@ export class GenerationClient< // fresh `generate()` may have replaced the controller while the tail // was settling, and that live run owns `isLoading` now. if (this.abortController === controller) { - this.abortController = null - this.setIsLoading(false) + this.setIsLoading(false, controller) + if (this.ownsRun(controller)) this.abortController = null } } })() diff --git a/packages/ai-client/src/realtime-client.ts b/packages/ai-client/src/realtime-client.ts index 04b57d8088..a97f420d99 100644 --- a/packages/ai-client/src/realtime-client.ts +++ b/packages/ai-client/src/realtime-client.ts @@ -1,5 +1,5 @@ import { convertSchemaToJsonSchema } from '@tanstack/ai/client' -import { createAtom, patchAtom, subscribeAtom } from './snapshot-atom' +import { createAtom, subscribeAtom } from './snapshot-atom' import type { Atom } from './snapshot-atom' import type { AnyClientTool, @@ -51,19 +51,17 @@ export class RealtimeClient { new Set() private unsubscribers: Array<() => void> = [] - private readonly snapshotAtom: Atom = - createAtom({ - status: 'idle', - mode: 'idle', - messages: [], - pendingUserTranscript: null, - pendingAssistantTranscript: null, - error: null, - }) - - private get state(): RealtimeClientState { - return this.snapshotAtom.get() + private state: RealtimeClientState = { + status: 'idle', + mode: 'idle', + messages: [], + pendingUserTranscript: null, + pendingAssistantTranscript: null, + error: null, } + private readonly snapshotAtom: Atom = createAtom( + this.buildSnapshot(), + ) constructor(options: RealtimeClientOptions) { this.options = { @@ -373,11 +371,18 @@ export class RealtimeClient { // ============================================================================ private updateState(updates: Partial): void { - patchAtom(this.snapshotAtom, updates) + const changed = Object.keys(updates).some((key) => { + const stateKey = key as keyof RealtimeClientState + return !Object.is(this.state[stateKey], updates[stateKey]) + }) + if (!changed) return + this.state = { ...this.state, ...updates } + this.snapshotAtom.set(this.buildSnapshot()) + const snapshot = this.snapshotAtom.get() // Notify callbacks for (const callback of this.stateChangeCallbacks) { - callback(this.state) + callback(snapshot) } // Notify specific callbacks @@ -389,6 +394,31 @@ export class RealtimeClient { } } + private buildSnapshot(): RealtimeClientState { + return { + ...this.state, + messages: Object.freeze( + this.state.messages.map((message) => + Object.freeze({ + ...message, + parts: Object.freeze( + message.parts.map((part) => + Object.freeze({ + ...part, + ...('source' in part && + typeof part.source === 'object' && + part.source !== null + ? { source: Object.freeze({ ...part.source }) } + : {}), + }), + ), + ), + }), + ), + ) as Array, + } + } + private addMessage(message: RealtimeMessage): void { this.updateState({ messages: [...this.state.messages, message], diff --git a/packages/ai-client/src/snapshot-atom.ts b/packages/ai-client/src/snapshot-atom.ts index d1932dbed9..b05b7ff9d2 100644 --- a/packages/ai-client/src/snapshot-atom.ts +++ b/packages/ai-client/src/snapshot-atom.ts @@ -1,9 +1,28 @@ -import { createAtom } from '@tanstack/store' +import { createAtom as createStoreAtom } from '@tanstack/store' import type { Atom } from '@tanstack/store' -export { createAtom } export type { Atom } +function freezeSnapshot(value: T): T { + return typeof value === 'object' && value !== null + ? Object.freeze(value) + : value +} + +export function createAtom(initialValue: T): Atom { + const atom = createStoreAtom(freezeSnapshot(initialValue)) + const set = atom.set.bind(atom) + atom.set = (updater) => + set((previous) => + freezeSnapshot( + typeof updater === 'function' + ? (updater as (value: T) => T)(previous) + : updater, + ), + ) + return atom +} + /** * Merge a partial update into an object atom. Skips notify when every * provided field is `Object.is`-equal to the current value. diff --git a/packages/ai-client/src/video-generation-client.ts b/packages/ai-client/src/video-generation-client.ts index fa9a2cb5f6..eceddf9595 100644 --- a/packages/ai-client/src/video-generation-client.ts +++ b/packages/ai-client/src/video-generation-client.ts @@ -269,16 +269,23 @@ export class VideoGenerationClient { this.input = input this.progress = null - const runId = this.devtoolsBridge.beginRun(input) - this.setIsLoading(true) - this.setStatus('generating') - this.setError(undefined) - this.setJobId(null) - this.setVideoStatus(null) - const abortController = new AbortController() this.abortController = abortController const { signal } = abortController + const runId = this.devtoolsBridge.beginRun(input) + patchAtom(this.snapshotAtom, { runId }) + if (!this.ownsRun(abortController)) return + + this.setIsLoading(true, abortController) + if (!this.ownsRun(abortController)) return + this.setStatus('generating', abortController) + if (!this.ownsRun(abortController)) return + this.setError(undefined, abortController) + if (!this.ownsRun(abortController)) return + this.setJobId(null, abortController) + if (!this.ownsRun(abortController)) return + this.setVideoStatus(null, abortController) + if (!this.ownsRun(abortController)) return try { let headers: Record | undefined @@ -288,10 +295,11 @@ export class VideoGenerationClient { this.body.provider, ) headers = await prepareResolvedByokHeaders(this.byok, provider) + if (!this.ownsRun(abortController)) return } if (this.fetcher) { - await this.generateWithFetcher(input, signal, runId, headers) + await this.generateWithFetcher(input, abortController, runId, headers) } else if (this.connection) { const mergedData = { ...this.body, ...input } const stream = this.connection.connect( @@ -300,13 +308,13 @@ export class VideoGenerationClient { signal, this.createRunContext(runId, headers), ) - await this.processStream(stream, runId, signal) + await this.processStream(stream, runId, abortController) } else { throw new Error( 'VideoGenerationClient requires either a connection or fetcher option', ) } - if (!signal.aborted && this.status === 'success') { + if (this.ownsRun(abortController) && this.status === 'success') { this.devtoolsBridge.finishRun( this.devtoolsBridge.getActiveRunId() ?? runId, 'run:completed', @@ -314,17 +322,22 @@ export class VideoGenerationClient { ) } } catch (err: unknown) { - if (signal.aborted) return + if (!this.ownsRun(abortController)) return const error = err instanceof Error ? err : new Error(String(err)) if (error instanceof ByokMissingError) { this.byok?.request(error.provider, 'missing') + if (!this.ownsRun(abortController)) return } if (error instanceof ByokBlockedError && error.reason === 'locked') { this.byok?.request(error.provider, 'locked') + if (!this.ownsRun(abortController)) return } - this.setError(error) - this.setStatus('error') - this.recordResumeSnapshotError(error) + this.setError(error, abortController) + if (!this.ownsRun(abortController)) return + this.setStatus('error', abortController) + if (!this.ownsRun(abortController)) return + this.recordResumeSnapshotError(error, abortController) + if (!this.ownsRun(abortController)) return this.devtoolsBridge.finishRun( this.devtoolsBridge.getActiveRunId() ?? runId, 'run:errored', @@ -334,8 +347,11 @@ export class VideoGenerationClient { this.callbacksRef.onError?.(error) } finally { if (this.abortController === abortController) { - this.abortController = null - this.setIsLoading(false) + patchAtom(this.snapshotAtom, { runId: null }) + if (this.ownsRun(abortController)) { + this.setIsLoading(false, abortController) + if (this.ownsRun(abortController)) this.abortController = null + } } } } @@ -345,27 +361,34 @@ export class VideoGenerationClient { */ private async generateWithFetcher( input: VideoGenerateInput, - signal: AbortSignal, + abortController: AbortController, runId: string, headers?: Record, ): Promise { if (!this.fetcher) return + const { signal } = abortController // Fetcher returns a completed result directly, or a Response with SSE body const result = await this.fetcher( input, headers === undefined ? { signal } : { signal, headers }, ) - if (signal.aborted) return + if (!this.ownsRun(abortController)) return if (result instanceof Response) { // Server function returned SSE Response — parse stream - await this.processStream(parseSSEResponse(result, signal), runId, signal) + await this.processStream( + parseSSEResponse(result, signal), + runId, + abortController, + ) } else { this.devtoolsBridge.ensureRunStarted(runId) - this.setResult(result) - this.setStatus('success') - this.completePlainFetcherResumeSnapshot(result) + this.setResult(result, abortController) + if (!this.ownsRun(abortController)) return + this.setStatus('success', abortController) + if (!this.ownsRun(abortController)) return + this.completePlainFetcherResumeSnapshot(result, abortController) } } @@ -381,8 +404,9 @@ export class VideoGenerationClient { private async processStream( source: AsyncIterable, fallbackRunId: string, - signal: AbortSignal, + abortController: AbortController, ): Promise { + const { signal } = abortController let streamRunId: string | undefined let sawTerminalChunk = false @@ -391,7 +415,9 @@ export class VideoGenerationClient { const chunk = restoreInboundChunk(raw) this.callbacksRef.onChunk?.(chunk) - this.observeResumeSnapshot(chunk) + if (!this.ownsRun(abortController)) return + this.observeResumeSnapshot(chunk, abortController) + if (!this.ownsRun(abortController)) return const chunkRunId = 'runId' in chunk && typeof chunk.runId === 'string' ? chunk.runId @@ -401,6 +427,8 @@ export class VideoGenerationClient { switch (chunk.type) { case 'RUN_STARTED': { streamRunId = chunk.runId + patchAtom(this.snapshotAtom, { runId: chunk.runId }) + if (!this.ownsRun(abortController)) return this.devtoolsBridge.ensureRunStarted(chunk.runId) break } @@ -408,23 +436,30 @@ export class VideoGenerationClient { this.devtoolsBridge.ensureRunStarted(streamRunId ?? fallbackRunId) if (chunk.name === GENERATION_EVENTS.VIDEO_JOB_CREATED) { const { jobId } = chunk.value as { jobId: string } - this.setJobId(jobId) + this.setJobId(jobId, abortController) + if (!this.ownsRun(abortController)) return this.callbacksRef.onJobCreated?.(jobId) + if (!this.ownsRun(abortController)) return } else if (chunk.name === GENERATION_EVENTS.VIDEO_STATUS) { const statusInfo = chunk.value as VideoStatusInfo - this.setVideoStatus(statusInfo) + this.setVideoStatus(statusInfo, abortController) + if (!this.ownsRun(abortController)) return this.callbacksRef.onStatusUpdate?.(statusInfo) + if (!this.ownsRun(abortController)) return if (statusInfo.progress !== undefined) { - this.setProgress(statusInfo.progress) + this.setProgress(statusInfo.progress, undefined, abortController) + if (!this.ownsRun(abortController)) return } } else if (chunk.name === GENERATION_EVENTS.RESULT) { - this.setResult(chunk.value as VideoGenerateResult) + this.setResult(chunk.value as VideoGenerateResult, abortController) + if (!this.ownsRun(abortController)) return } else if (chunk.name === GENERATION_EVENTS.PROGRESS) { const { progress, message } = chunk.value as { progress: number message?: string } - this.setProgress(progress, message) + this.setProgress(progress, message, abortController) + if (!this.ownsRun(abortController)) return } break } @@ -432,7 +467,8 @@ export class VideoGenerationClient { streamRunId = chunk.runId sawTerminalChunk = true this.devtoolsBridge.ensureRunStarted(chunk.runId) - this.setStatus('success') + this.setStatus('success', abortController) + if (!this.ownsRun(abortController)) return break } case 'RUN_ERROR': { @@ -460,17 +496,29 @@ export class VideoGenerationClient { */ stop(): void { const runId = this.devtoolsBridge.getActiveRunId() + const stoppedStatus = this.status if (this.abortController) { this.abortController.abort() this.abortController = null } - this.setIsLoading(false) - if (this.status === 'generating') { - this.setStatus('idle') - if (runId) { + if (runId) { + if (stoppedStatus === 'success') { + this.devtoolsBridge.finishRun(runId, 'run:completed', 'completed') + } else if (stoppedStatus === 'error') { + this.devtoolsBridge.finishRun( + runId, + 'run:errored', + 'errored', + this.error?.message, + ) + } else { this.devtoolsBridge.finishRun(runId, 'run:cancelled', 'cancelled') } } + patchAtom(this.snapshotAtom, { runId: null }) + if (stoppedStatus === 'generating') { + this.setStatus('idle') + } // A stopped run is no longer resumable. Without this the in-memory // snapshot stays `running`, and a remount's `maybeResumeInFlight` would // rejoin a run the user just cancelled. @@ -482,6 +530,7 @@ export class VideoGenerationClient { } this.notifyResumeSnapshotChanged() } + this.setIsLoading(false) } /** @@ -492,6 +541,7 @@ export class VideoGenerationClient { */ reset(): void { this.stop() + if (this.abortController || this.isLoading) return this.setResult(null) this.input = null this.progress = null @@ -560,11 +610,14 @@ export class VideoGenerationClient { this.abortController.abort() this.abortController = null } - this.setIsLoading(false) + if (this.resumeSnapshot?.status !== 'running') { + patchAtom(this.snapshotAtom, { runId: null }) + } this.devtoolsBridge.dispose() this.devtoolsMounted = false this.serverHydrationStarted = false this.rejoinedRunId = undefined + this.setIsLoading(false) } // =========================== @@ -637,24 +690,33 @@ export class VideoGenerationClient { // Private state setters // =========================== - private setResult(rawResult: VideoGenerateResult | null): void { + private setResult( + rawResult: VideoGenerateResult | null, + controller?: AbortController, + ): void { if (rawResult === null) { this.result = null patchAtom(this.snapshotAtom, { result: null }) + if (controller && !this.ownsRun(controller)) return this.callbacksRef.onResultChange?.(null) + if (controller && !this.ownsRun(controller)) return this.devtoolsBridge.recordResultChange() return } const completedStatus = this.createCompletedVideoStatus(rawResult) if (this.progress?.value !== 100) { - this.setProgress(100, this.progress?.message) + this.setProgress(100, this.progress?.message, controller) + if (controller && !this.ownsRun(controller)) return } - this.setJobId(rawResult.jobId) - this.setVideoStatus(completedStatus) + this.setJobId(rawResult.jobId, controller) + if (controller && !this.ownsRun(controller)) return + this.setVideoStatus(completedStatus, controller) + if (controller && !this.ownsRun(controller)) return if (this.callbacksRef.onResult) { const transformed = this.callbacksRef.onResult(rawResult) + if (controller && !this.ownsRun(controller)) return if (transformed === null) { // null return → keep previous result unchanged, just re-emit this.devtoolsBridge.emitState() @@ -664,7 +726,9 @@ export class VideoGenerationClient { // Non-null, non-undefined → use transformed value this.result = transformed patchAtom(this.snapshotAtom, { result: this.result }) + if (controller && !this.ownsRun(controller)) return this.callbacksRef.onResultChange?.(this.result) + if (controller && !this.ownsRun(controller)) return this.devtoolsBridge.recordResultChange() return } @@ -677,46 +741,75 @@ export class VideoGenerationClient { // oxlint-disable-next-line eslint-js/no-restricted-syntax -- TOutput defaults to VideoGenerateResult when no onResult transform is supplied this.result = rawResult as unknown as TOutput patchAtom(this.snapshotAtom, { result: this.result }) + if (controller && !this.ownsRun(controller)) return this.callbacksRef.onResultChange?.(this.result) + if (controller && !this.ownsRun(controller)) return this.devtoolsBridge.recordResultChange() } - private setJobId(jobId: string | null): void { + private setJobId(jobId: string | null, controller?: AbortController): void { this.jobId = jobId patchAtom(this.snapshotAtom, { jobId }) + if (controller && !this.ownsRun(controller)) return this.callbacksRef.onJobIdChange?.(jobId) + if (controller && !this.ownsRun(controller)) return this.devtoolsBridge.recordJobIdChange() } - private setVideoStatus(status: VideoStatusInfo | null): void { - this.videoStatus = status - patchAtom(this.snapshotAtom, { videoStatus: status }) - this.callbacksRef.onVideoStatusChange?.(status) + private setVideoStatus( + status: VideoStatusInfo | null, + controller?: AbortController, + ): void { + this.videoStatus = status ? { ...status } : null + patchAtom(this.snapshotAtom, { + videoStatus: this.videoStatus + ? Object.freeze({ ...this.videoStatus }) + : null, + }) + if (controller && !this.ownsRun(controller)) return + this.callbacksRef.onVideoStatusChange?.(this.videoStatus) + if (controller && !this.ownsRun(controller)) return this.devtoolsBridge.recordVideoStatusChange() } - private setIsLoading(isLoading: boolean): void { + private setIsLoading(isLoading: boolean, controller?: AbortController): void { this.isLoading = isLoading patchAtom(this.snapshotAtom, { isLoading }) + if (controller && !this.ownsRun(controller)) return this.callbacksRef.onLoadingChange?.(isLoading) + if (controller && !this.ownsRun(controller)) return this.devtoolsBridge.recordLoadingChange() } - private setError(error: Error | undefined): void { + private setError( + error: Error | undefined, + controller?: AbortController, + ): void { this.error = error patchAtom(this.snapshotAtom, { error }) + if (controller && !this.ownsRun(controller)) return this.callbacksRef.onErrorChange?.(error) + if (controller && !this.ownsRun(controller)) return this.devtoolsBridge.recordErrorChange(error) } - private setStatus(status: GenerationClientState): void { + private setStatus( + status: GenerationClientState, + controller?: AbortController, + ): void { this.status = status patchAtom(this.snapshotAtom, { status }) + if (controller && !this.ownsRun(controller)) return this.callbacksRef.onStatusChange?.(status) + if (controller && !this.ownsRun(controller)) return this.devtoolsBridge.recordStatusChange(status) } - private setProgress(value: number, message?: string): void { + private setProgress( + value: number, + message?: string, + controller?: AbortController, + ): void { this.progress = { value, ...(message ? { message } : {}), @@ -726,6 +819,7 @@ export class VideoGenerationClient { } else { this.callbacksRef.onProgress?.(value, message) } + if (controller && !this.ownsRun(controller)) return this.devtoolsBridge.recordProgressChange() } @@ -763,6 +857,10 @@ export class VideoGenerationClient { return `${prefix}-${Date.now()}-${Math.random().toString(36).substring(7)}` } + private ownsRun(controller: AbortController): boolean { + return !controller.signal.aborted && this.abortController === controller + } + private createRunContext( runId: string, headers?: Record, @@ -774,22 +872,26 @@ export class VideoGenerationClient { } } - private observeResumeSnapshot(chunk: StreamChunk): void { + private observeResumeSnapshot( + chunk: StreamChunk, + controller: AbortController, + ): void { this.resumeSnapshot = updateGenerationResumeSnapshot( this.resumeSnapshot, chunk, ) - this.notifyResumeSnapshotChanged() + this.notifyResumeSnapshotChanged(controller) } /** Notify the internal snapshot listener AND emit the public resume state. */ - private notifyResumeSnapshotChanged(): void { + private notifyResumeSnapshotChanged(controller?: AbortController): void { this.callbacksRef.onResumeSnapshotChange?.(this.resumeSnapshot) - this.emitResumeState() + if (controller && !this.ownsRun(controller)) return + this.emitResumeState(controller) } /** Derive the public `resumeState` from the internal snapshot. */ - private emitResumeState(): void { + private emitResumeState(controller?: AbortController): void { const snapshot = this.resumeSnapshot const state = snapshot?.resumeState const resumeState: GenerationResumeState | null = state @@ -801,6 +903,7 @@ export class VideoGenerationClient { } : null patchAtom(this.snapshotAtom, { runId: resumeState?.runId ?? null }) + if (controller && !this.ownsRun(controller)) return this.callbacksRef.onResumeStateChange?.(resumeState) } @@ -914,7 +1017,10 @@ export class VideoGenerationClient { * stale `error` from a previous run is intentionally dropped — this run * succeeded. */ - private completePlainFetcherResumeSnapshot(rawResult: unknown): void { + private completePlainFetcherResumeSnapshot( + rawResult: unknown, + controller: AbortController, + ): void { const previous = this.resumeSnapshot const result = createGenerationResultSnapshot(rawResult) this.resumeSnapshot = { @@ -931,7 +1037,7 @@ export class VideoGenerationClient { ? { result: { ...previous.result } } : {}), } - this.notifyResumeSnapshotChanged() + this.notifyResumeSnapshotChanged(controller) } /** @@ -940,14 +1046,19 @@ export class VideoGenerationClient { * mark the snapshot `error`, leaving a persisted record that claims the * run is still in flight. */ - private recordResumeSnapshotError(error: Error): void { + private recordResumeSnapshotError( + error: Error, + controller?: AbortController, + ): void { // Surface the failure on the observable fields FIRST, unconditionally (see // the note in GenerationClient.recordResumeSnapshotError): a RUN_ERROR // already flipped the snapshot to `error`, so the early-return would else // skip this and leave `status` stuck on `generating`. The guard avoids a // duplicate `error` emission on the live `generate()` path. - if (this.status !== 'error') this.setStatus('error') - this.setError(error) + if (this.status !== 'error') this.setStatus('error', controller) + if (controller && !this.ownsRun(controller)) return + this.setError(error, controller) + if (controller && !this.ownsRun(controller)) return if (this.resumeSnapshot?.status === 'error') return if (!this.resumeSnapshot && !this.serverDriven) return const previous = this.resumeSnapshot @@ -962,7 +1073,7 @@ export class VideoGenerationClient { ...(previous?.result ? { result: { ...previous.result } } : {}), error: { message: error.message }, } - this.notifyResumeSnapshotChanged() + this.notifyResumeSnapshotChanged(controller) } /** @@ -1079,23 +1190,26 @@ export class VideoGenerationClient { this.rejoinedRunId = runId const controller = new AbortController() this.abortController = controller - this.setIsLoading(true) - this.setStatus('generating') + this.setIsLoading(true, controller) + if (!this.ownsRun(controller)) return + this.setStatus('generating', controller) + if (!this.ownsRun(controller)) return void (async () => { try { await this.processStream( joinRun(runId, controller.signal), runId, - controller.signal, + controller, ) } catch (error) { - if (!controller.signal.aborted) { + if (this.ownsRun(controller)) { const failure = error instanceof Error ? error : new Error(String(error)) // Settles `status`/`error` AND rewrites the snapshot to a terminal // `error` with a null `resumeState`, so the next mount does not // rejoin this run again. - this.recordResumeSnapshotError(failure) + this.recordResumeSnapshotError(failure, controller) + if (!this.ownsRun(controller)) return this.callbacksRef.onError?.(failure) } } finally { @@ -1103,8 +1217,8 @@ export class VideoGenerationClient { // fresh `generate()` may have replaced the controller while the tail // was settling, and that live run owns `isLoading` now. if (this.abortController === controller) { - this.abortController = null - this.setIsLoading(false) + this.setIsLoading(false, controller) + if (this.ownsRun(controller)) this.abortController = null } } })() diff --git a/packages/ai-client/tests/audio-recorder.test.ts b/packages/ai-client/tests/audio-recorder.test.ts index 49c773b0cd..387308fb8b 100644 --- a/packages/ai-client/tests/audio-recorder.test.ts +++ b/packages/ai-client/tests/audio-recorder.test.ts @@ -75,6 +75,21 @@ afterEach(() => { }) describe('AudioRecorder', () => { + it('uses Set subscription behavior and reports repeated states', async () => { + const recorder = new AudioRecorder() + const listener = vi.fn() + const first = recorder.subscribe(listener) + recorder.subscribe(listener) + + getUserMedia.mockRejectedValueOnce(new Error('denied')) + await expect(recorder.start()).rejects.toThrow('denied') + expect(listener).toHaveBeenCalledTimes(1) + first() + getUserMedia.mockRejectedValueOnce(new Error('denied')) + await expect(recorder.start()).rejects.toThrow('denied') + expect(listener).toHaveBeenCalledTimes(1) + }) + it('isSupported() is true when media APIs exist', () => { expect(AudioRecorder.isSupported()).toBe(true) }) diff --git a/packages/ai-client/tests/byok-client.test.ts b/packages/ai-client/tests/byok-client.test.ts index 6754240720..8832f82151 100644 --- a/packages/ai-client/tests/byok-client.test.ts +++ b/packages/ai-client/tests/byok-client.test.ts @@ -8,6 +8,34 @@ describe('defineByok memory', () => { vi.unstubAllGlobals() }) + it('isolates and freezes nested snapshot state', async () => { + const byok = defineByok() + await byok.update('openai', 'sk-abcdefghij') + const snapshot = byok.getSnapshot() + + expect(Object.isFrozen(snapshot)).toBe(true) + expect(Object.isFrozen(snapshot.status)).toBe(true) + expect(Object.isFrozen(snapshot.status.openai)).toBe(true) + Reflect.set(snapshot.status.openai!, 'masked', 'leak') + expect(byok.getSnapshot().status.openai).toEqual({ + state: 'set', + masked: 'ghij', + }) + }) + + it('uses Set subscription behavior', () => { + const byok = defineByok() + const listener = vi.fn() + const first = byok.subscribe(listener) + byok.subscribe(listener) + + byok.request('openai', 'missing') + expect(listener).toHaveBeenCalledTimes(1) + first() + byok.request('openai', 'missing') + expect(listener).toHaveBeenCalledTimes(1) + }) + it('updates and snapshots without exposing the raw key', async () => { const byok = defineByok({ storage: memoryStorage() }) await byok.update('openai', 'sk-abcdefghij') diff --git a/packages/ai-client/tests/byok-generation-client.test.ts b/packages/ai-client/tests/byok-generation-client.test.ts index 948635c5b2..eeceb405e9 100644 --- a/packages/ai-client/tests/byok-generation-client.test.ts +++ b/packages/ai-client/tests/byok-generation-client.test.ts @@ -87,6 +87,64 @@ describe('GenerationClient byok', () => { expect(client.getError()).toBeInstanceOf(ByokMissingError) }) + it('stops the failed run when the BYOK request subscriber stops', async () => { + const byok = defineByok({ storage: memoryStorage() }) + await byok.update('elevenlabs', ELEVENLABS_KEY) + const onErrorChange = vi.fn() + let client!: GenerationClient<{ prompt: string }, { id: string }> + client = new GenerationClient({ + fetcher: async (): Promise<{ id: string }> => { + throw new ByokMissingError('elevenlabs') + }, + byok, + byokProvider: () => 'elevenlabs', + onErrorChange, + }) + byok.subscribe(() => { + if (byok.getSnapshot().prompt) client.stop() + }) + + await client.generate({ prompt: 'first' }) + + expect(client.getStatus()).toBe('idle') + expect(client.getError()).toBeUndefined() + expect(onErrorChange).not.toHaveBeenCalledWith(expect.any(Error)) + }) + + it('does not let a failed BYOK run overwrite a replacement', async () => { + const byok = defineByok({ storage: memoryStorage() }) + await byok.update('elevenlabs', ELEVENLABS_KEY) + let releaseSecond!: (value: { id: string }) => void + const secondResult = new Promise<{ id: string }>((resolve) => { + releaseSecond = resolve + }) + let secondGenerate: Promise | undefined + let replaced = false + const client = new GenerationClient({ + fetcher: async (input) => { + if (input.prompt === 'first') { + throw new ByokMissingError('elevenlabs') + } + return secondResult + }, + byok, + byokProvider: () => 'elevenlabs', + }) + byok.subscribe(() => { + if (!byok.getSnapshot().prompt || replaced) return + replaced = true + client.stop() + secondGenerate = client.generate({ prompt: 'second' }) + }) + + await client.generate({ prompt: 'first' }) + + expect(client.getStatus()).toBe('generating') + expect(client.getError()).toBeUndefined() + releaseSecond({ id: 'second' }) + await secondGenerate + }) + it('requests a missing key when the fetcher returns a byokMissing Response', async () => { const byok = defineByok({ storage: memoryStorage() }) await byok.update('elevenlabs', ELEVENLABS_KEY) diff --git a/packages/ai-client/tests/byok-video-generation-client.test.ts b/packages/ai-client/tests/byok-video-generation-client.test.ts index 166b3eb4d4..2b7633c385 100644 --- a/packages/ai-client/tests/byok-video-generation-client.test.ts +++ b/packages/ai-client/tests/byok-video-generation-client.test.ts @@ -92,6 +92,64 @@ describe('VideoGenerationClient byok', () => { expect(client.getError()).toBeInstanceOf(ByokMissingError) }) + it('stops the failed run when the BYOK request subscriber stops', async () => { + const byok = defineByok({ storage: memoryStorage() }) + await byok.update('elevenlabs', ELEVENLABS_KEY) + const onErrorChange = vi.fn() + let client!: VideoGenerationClient + client = new VideoGenerationClient({ + fetcher: async () => { + throw new ByokMissingError('elevenlabs') + }, + byok, + byokProvider: () => 'elevenlabs', + onErrorChange, + }) + byok.subscribe(() => { + if (byok.getSnapshot().prompt) client.stop() + }) + + await client.generate({ prompt: 'first' }) + + expect(client.getStatus()).toBe('idle') + expect(client.getError()).toBeUndefined() + expect(onErrorChange).not.toHaveBeenCalledWith(expect.any(Error)) + }) + + it('does not let a failed BYOK run overwrite a replacement', async () => { + const byok = defineByok({ storage: memoryStorage() }) + await byok.update('elevenlabs', ELEVENLABS_KEY) + let releaseSecond!: (value: typeof VIDEO_RESULT) => void + const secondResult = new Promise((resolve) => { + releaseSecond = resolve + }) + let secondGenerate: Promise | undefined + let replaced = false + const client = new VideoGenerationClient({ + fetcher: async (input) => { + if (input.prompt === 'first') { + throw new ByokMissingError('elevenlabs') + } + return secondResult + }, + byok, + byokProvider: () => 'elevenlabs', + }) + byok.subscribe(() => { + if (!byok.getSnapshot().prompt || replaced) return + replaced = true + client.stop() + secondGenerate = client.generate({ prompt: 'second' }) + }) + + await client.generate({ prompt: 'first' }) + + expect(client.getStatus()).toBe('generating') + expect(client.getError()).toBeUndefined() + releaseSecond(VIDEO_RESULT) + await secondGenerate + }) + it('requests a missing key when the fetcher returns a byokMissing Response', async () => { const byok = defineByok({ storage: memoryStorage() }) await byok.update('elevenlabs', ELEVENLABS_KEY) diff --git a/packages/ai-client/tests/chat-client.test.ts b/packages/ai-client/tests/chat-client.test.ts index b8da70d6a0..dc01508989 100644 --- a/packages/ai-client/tests/chat-client.test.ts +++ b/packages/ai-client/tests/chat-client.test.ts @@ -98,6 +98,75 @@ describe('ChatClient', () => { stop() }) + it('isolates nested message parts from callers and old snapshots', () => { + const adapter = createMockConnectionAdapter() + const source = { + type: 'url' as const, + value: 'https://example.com/a.png', + } + const client = new ChatClient({ + connection: adapter, + initialMessages: [ + { + id: 'msg-1', + role: 'user', + parts: [{ type: 'image', source }], + createdAt: new Date(), + }, + ], + }) + const oldSnapshot = client.getSnapshot() + + source.value = 'https://example.com/changed.png' + expect(oldSnapshot.messages[0]?.parts[0]).toMatchObject({ + source: { value: 'https://example.com/a.png' }, + }) + const publishedPart = oldSnapshot.messages[0]?.parts[0] + expect(Object.isFrozen(publishedPart)).toBe(true) + if (!publishedPart || !('source' in publishedPart)) { + throw new Error('Expected a message part with a source') + } + expect(Object.isFrozen(publishedPart.source)).toBe(true) + }) + + it('isolates messages published by normal updates', () => { + const client = new ChatClient({ + connection: createMockConnectionAdapter(), + }) + const oldSnapshot = client.getSnapshot() + const source = { + type: 'url' as const, + value: 'https://example.com/updated.png', + } + + client.setMessagesManually([ + { + id: 'updated-1', + role: 'user', + parts: [{ type: 'image', source }], + }, + ]) + + const snapshot = client.getSnapshot() + const part = snapshot.messages[0]?.parts[0] + expect(snapshot).not.toBe(oldSnapshot) + expect(oldSnapshot.messages).toEqual([]) + expect(Object.isFrozen(snapshot.messages)).toBe(true) + expect(Object.isFrozen(snapshot.messages[0])).toBe(true) + expect(Object.isFrozen(snapshot.messages[0]?.parts)).toBe(true) + expect(Object.isFrozen(part)).toBe(true) + expect(part).toMatchObject({ source }) + + if (!part || !('source' in part)) { + throw new Error('Expected a message part with a source') + } + const publishedSource = part.source + expect(Object.isFrozen(publishedSource)).toBe(true) + expect(Reflect.set(publishedSource, 'value', 'changed')).toBe(false) + expect(client.getMessages()[0]?.parts[0]).toMatchObject({ source }) + expect(client.getSnapshot()).toBe(snapshot) + }) + it('should initialize with provided messages', () => { const adapter = createMockConnectionAdapter() const initialMessages: Array = [ @@ -2278,6 +2347,61 @@ describe('ChatClient', () => { { type: 'text', content: 'Second' }, ]) }) + + it('isolates queue entries published by normal updates', async () => { + const client = new ChatClient({ + connection: createMockConnectionAdapter({ + chunks: createTextChunks('Response'), + chunkDelay: 100, + }), + }) + const firstSend = client.sendMessage('First') + const oldSnapshot = client.getSnapshot() + + await client.sendMessage({ + content: [ + { + type: 'image', + source: { + type: 'url', + value: 'https://example.com/queued.png', + }, + }, + ], + }) + + const snapshot = client.getSnapshot() + const queuedContent = snapshot.queue[0]?.content + expect(snapshot).not.toBe(oldSnapshot) + expect(oldSnapshot.queue).toEqual([]) + expect(Object.isFrozen(snapshot.queue)).toBe(true) + expect(Object.isFrozen(snapshot.queue[0])).toBe(true) + expect(typeof queuedContent).toBe('object') + if (typeof queuedContent === 'object') { + expect(Object.isFrozen(queuedContent)).toBe(true) + expect(Object.isFrozen(queuedContent.content)).toBe(true) + const queuedPart = Array.isArray(queuedContent.content) + ? queuedContent.content[0] + : undefined + expect(Object.isFrozen(queuedPart)).toBe(true) + if (!queuedPart || !('source' in queuedPart)) { + throw new Error('Expected a queued content part with a source') + } + const publishedSource = queuedPart.source + expect(Object.isFrozen(publishedSource)).toBe(true) + expect(Reflect.set(publishedSource, 'value', 'changed')).toBe(false) + } + expect(client.getQueue()[0]?.content).toMatchObject({ + content: [ + { + source: { value: 'https://example.com/queued.png' }, + }, + ], + }) + expect(client.getSnapshot()).toBe(snapshot) + + await firstSend + }) }) describe('append', () => { diff --git a/packages/ai-client/tests/client-snapshots.test.ts b/packages/ai-client/tests/client-snapshots.test.ts index 90efed3e5b..bcbf6b8636 100644 --- a/packages/ai-client/tests/client-snapshots.test.ts +++ b/packages/ai-client/tests/client-snapshots.test.ts @@ -8,6 +8,22 @@ import { import type { RealtimeAdapter } from '../src' describe('client UI snapshots', () => { + it('publishes and clears the active generation run id', async () => { + let resolve!: (value: { id: string }) => void + const pending = new Promise<{ id: string }>((done) => { + resolve = done + }) + const client = new GenerationClient({ fetcher: async () => pending }) + + const generating = client.generate({ prompt: 'test' }) + expect(client.getSnapshot().runId).toEqual(expect.any(String)) + expect(client.getSnapshot().runId).not.toBe('') + + resolve({ id: '1' }) + await generating + expect(client.getSnapshot().runId).toBeNull() + }) + it('GenerationClient notifies subscribe and keeps getSnapshot identity until a change', async () => { const client = new GenerationClient({ fetcher: async () => ({ id: '1' }), @@ -55,6 +71,10 @@ describe('client UI snapshots', () => { expect(client.getSnapshot().status).toBe('success') expect(client.getSnapshot().result).toEqual(result) expect(client.getSnapshot()).not.toBe(snapshot) + const completed = client.getSnapshot() + expect(Object.isFrozen(completed.videoStatus)).toBe(true) + Reflect.set(completed.videoStatus!, 'status', 'failed') + expect(client.getVideoStatus()?.status).toBe('completed') stop() }) @@ -91,4 +111,43 @@ describe('client UI snapshots', () => { stop() client.destroy() }) + + it('RealtimeClient does not read connection control from its public snapshot', async () => { + const getToken = vi.fn(async () => { + throw new Error('token attempted') + }) + const client = new RealtimeClient({ + getToken, + adapter: { provider: 'test', connect: vi.fn() }, + }) + + Reflect.set(client.getSnapshot(), 'status', 'connected') + await expect(client.connect()).rejects.toThrow('token attempted') + expect(getToken).toHaveBeenCalledOnce() + }) + + it('RealtimeClient isolates connection control from state change callbacks', async () => { + const getToken = vi.fn(async () => ({ + provider: 'test', + token: 'token', + expiresAt: Date.now() + 120_000, + config: {}, + })) + const connect = vi.fn(async () => { + throw new Error('connect attempted') + }) + const client = new RealtimeClient({ + getToken, + adapter: { provider: 'test', connect }, + }) + client.onStateChange((state) => { + Reflect.set(state, 'status', 'connected') + }) + + await expect(client.connect()).rejects.toThrow('connect attempted') + await expect(client.connect()).rejects.toThrow('connect attempted') + + expect(getToken).toHaveBeenCalledTimes(2) + expect(connect).toHaveBeenCalledTimes(2) + }) }) diff --git a/packages/ai-client/tests/generation-client.test.ts b/packages/ai-client/tests/generation-client.test.ts index 8b941689dd..cf93a55495 100644 --- a/packages/ai-client/tests/generation-client.test.ts +++ b/packages/ai-client/tests/generation-client.test.ts @@ -115,6 +115,7 @@ describe('GenerationClient', () => { expect(onResultChange).toHaveBeenCalledWith(mockResult) expect(client.getResult()).toEqual(mockResult) expect(client.getStatus()).toBe('success') + expect(client.getSnapshot().runId).toBeNull() expect(client.getIsLoading()).toBe(false) }) @@ -274,6 +275,7 @@ describe('GenerationClient', () => { expect(onError).toHaveBeenCalledWith(expect.any(Error)) expect(client.getStatus()).toBe('error') expect(client.getError()?.message).toBe('Generation failed') + expect(client.getSnapshot().runId).toBeNull() }) it('should report progress from CUSTOM progress events', async () => { @@ -408,14 +410,366 @@ describe('GenerationClient', () => { const generatePromise = client.generate({ prompt: 'test' }) expect(client.getIsLoading()).toBe(true) + expect(client.getSnapshot().runId).toEqual(expect.any(String)) client.stop() expect(client.getIsLoading()).toBe(false) expect(client.getStatus()).toBe('idle') + expect(client.getSnapshot().runId).toBeNull() resolvePromise!({ id: '1' }) await generatePromise }) + + it('should not overwrite a run started by the stopped loading callback', async () => { + let releaseFirst!: (value: { id: string }) => void + let releaseSecond!: (value: { id: string }) => void + const firstResult = new Promise<{ id: string }>((resolve) => { + releaseFirst = resolve + }) + const secondResult = new Promise<{ id: string }>((resolve) => { + releaseSecond = resolve + }) + let secondGenerate: Promise | undefined + let secondRunId: string | null = null + let replaced = false + let client!: GenerationClient<{ prompt: string }, { id: string }> + client = new GenerationClient({ + fetcher: async (input) => + input.prompt === 'first' ? firstResult : secondResult, + onLoadingChange: (isLoading) => { + if (isLoading || replaced) return + replaced = true + secondGenerate = client.generate({ prompt: 'second' }) + secondRunId = client.getSnapshot().runId + }, + }) + + const firstGenerate = client.generate({ prompt: 'first' }) + client.stop() + + expect(secondRunId).not.toBeNull() + expect(client.getSnapshot().runId).toBe(secondRunId) + expect(client.getIsLoading()).toBe(true) + expect(client.getStatus()).toBe('generating') + releaseFirst({ id: 'first' }) + releaseSecond({ id: 'second' }) + await Promise.all([firstGenerate, secondGenerate]) + }) + + it('should stop before transport work when loading callback stops', async () => { + const fetcher = vi.fn(async () => ({ id: 'unexpected' })) + let client!: GenerationClient<{ prompt: string }, { id: string }> + client = new GenerationClient({ + fetcher, + onLoadingChange: (isLoading) => { + if (isLoading) client.stop() + }, + }) + + await client.generate({ prompt: 'test' }) + + expect(fetcher).not.toHaveBeenCalled() + expect(client.getStatus()).toBe('idle') + expect(client.getSnapshot().runId).toBeNull() + }) + + it('should not complete resume state after success callback stops', async () => { + let client!: GenerationClient<{ prompt: string }, { id: string }> + client = new GenerationClient({ + fetcher: async () => ({ id: 'result' }), + onStatusChange: (status) => { + if (status === 'success') client.stop() + }, + }) + + await client.generate({ prompt: 'test' }) + + expect(client.getStatus()).toBe('success') + expect(client.getSnapshot().runId).toBeNull() + expect(client.getResumeSnapshot()).toBeUndefined() + }) + + it('should not let initialization continue after loading callback starts a replacement', async () => { + let releaseSecond!: (value: { id: string }) => void + const secondResult = new Promise<{ id: string }>((resolve) => { + releaseSecond = resolve + }) + const prompts: Array = [] + let client!: GenerationClient<{ prompt: string }, { id: string }> + let replaced = false + let secondGenerate: Promise | undefined + client = new GenerationClient({ + fetcher: async (input) => { + prompts.push(input.prompt) + return input.prompt === 'second' ? secondResult : { id: 'first' } + }, + onLoadingChange: (isLoading) => { + if (!isLoading || replaced) return + replaced = true + client.stop() + secondGenerate = client.generate({ prompt: 'second' }) + }, + }) + + await client.generate({ prompt: 'first' }) + + expect(prompts).toEqual(['second']) + expect(client.getStatus()).toBe('generating') + releaseSecond({ id: 'second' }) + await secondGenerate + }) + + it('should not let an old result callback complete a replacement run', async () => { + let releaseSecond!: (value: { id: string }) => void + const secondResult = new Promise<{ id: string }>((resolve) => { + releaseSecond = resolve + }) + let client!: GenerationClient<{ prompt: string }, { id: string }> + let secondGenerate: Promise | undefined + let secondRunId: string | null = null + client = new GenerationClient({ + fetcher: async (input) => + input.prompt === 'first' ? { id: 'first' } : secondResult, + onResultChange: (result) => { + if (result?.id !== 'first') return + client.stop() + secondGenerate = client.generate({ prompt: 'second' }) + secondRunId = client.getSnapshot().runId + }, + }) + + await client.generate({ prompt: 'first' }) + + expect(secondRunId).not.toBeNull() + expect(client.getSnapshot().runId).toBe(secondRunId) + expect(client.getStatus()).toBe('generating') + expect(client.getResumeSnapshot()).toBeUndefined() + releaseSecond({ id: 'second' }) + await secondGenerate + }) + + it('should not let an old error callback overwrite a replacement run', async () => { + let releaseSecond!: (value: { id: string }) => void + const secondResult = new Promise<{ id: string }>((resolve) => { + releaseSecond = resolve + }) + let client!: GenerationClient<{ prompt: string }, { id: string }> + let secondGenerate: Promise | undefined + let secondRunId: string | null = null + client = new GenerationClient({ + fetcher: async (input) => { + if (input.prompt === 'first') throw new Error('first failed') + return secondResult + }, + onErrorChange: (error) => { + if (error?.message !== 'first failed') return + client.stop() + secondGenerate = client.generate({ prompt: 'second' }) + secondRunId = client.getSnapshot().runId + }, + }) + + await client.generate({ prompt: 'first' }) + + expect(secondRunId).not.toBeNull() + expect(client.getSnapshot().runId).toBe(secondRunId) + expect(client.getStatus()).toBe('generating') + releaseSecond({ id: 'second' }) + await secondGenerate + }) + + it('should remain stopped when the error callback stops', async () => { + let client!: GenerationClient<{ prompt: string }, { id: string }> + client = new GenerationClient({ + fetcher: async (): Promise<{ id: string }> => { + throw new Error('failed') + }, + onErrorChange: (error) => { + if (error) client.stop() + }, + }) + + await client.generate({ prompt: 'test' }) + + expect(client.getStatus()).toBe('idle') + expect(client.getSnapshot().runId).toBeNull() + }) + + it('should not let an old error status callback overwrite a replacement run', async () => { + let releaseSecond!: (value: { id: string }) => void + const secondResult = new Promise<{ id: string }>((resolve) => { + releaseSecond = resolve + }) + let client!: GenerationClient<{ prompt: string }, { id: string }> + let secondGenerate: Promise | undefined + let replaced = false + client = new GenerationClient({ + fetcher: async (input) => { + if (input.prompt === 'first') throw new Error('first failed') + return secondResult + }, + onStatusChange: (status) => { + if (status !== 'error' || replaced) return + replaced = true + client.stop() + secondGenerate = client.generate({ prompt: 'second' }) + }, + }) + + await client.generate({ prompt: 'first' }) + + expect(client.getStatus()).toBe('generating') + expect(client.getError()).toBeUndefined() + releaseSecond({ id: 'second' }) + await secondGenerate + }) + + it('should stop before transport when the run id subscriber stops', async () => { + const fetcher = vi.fn(async () => ({ id: 'unexpected' })) + const onLoadingChange = vi.fn() + const client = new GenerationClient({ fetcher, onLoadingChange }) + client.subscribe(() => { + if (client.getSnapshot().runId) client.stop() + }) + + await client.generate({ prompt: 'test' }) + + expect(fetcher).not.toHaveBeenCalled() + expect(onLoadingChange).not.toHaveBeenCalledWith(true) + expect(client.getSnapshot().runId).toBeNull() + }) + + it('should not continue an old run after the run id subscriber starts a replacement', async () => { + let releaseSecond!: (value: { id: string }) => void + const secondResult = new Promise<{ id: string }>((resolve) => { + releaseSecond = resolve + }) + const prompts: Array = [] + let secondGenerate: Promise | undefined + let replaced = false + const client = new GenerationClient({ + fetcher: async (input) => { + prompts.push(input.prompt) + return input.prompt === 'second' ? secondResult : { id: 'first' } + }, + }) + client.subscribe(() => { + if (!client.getSnapshot().runId || replaced) return + replaced = true + client.stop() + secondGenerate = client.generate({ prompt: 'second' }) + }) + + await client.generate({ prompt: 'first' }) + + expect(prompts).toEqual(['second']) + expect(client.getStatus()).toBe('generating') + releaseSecond({ id: 'second' }) + await secondGenerate + }) + + it('should not call the loading callback after its snapshot subscriber stops', async () => { + const fetcher = vi.fn(async () => ({ id: 'unexpected' })) + const onLoadingChange = vi.fn() + const client = new GenerationClient({ fetcher, onLoadingChange }) + client.subscribe(() => { + if (client.getSnapshot().isLoading) client.stop() + }) + + await client.generate({ prompt: 'test' }) + + expect(fetcher).not.toHaveBeenCalled() + expect(onLoadingChange).not.toHaveBeenCalledWith(true) + }) + + it('should not call the old status callback after its subscriber starts a replacement', async () => { + let releaseSecond!: (value: { id: string }) => void + const secondResult = new Promise<{ id: string }>((resolve) => { + releaseSecond = resolve + }) + const generatingStatuses: Array = [] + let secondGenerate: Promise | undefined + let replaced = false + const client = new GenerationClient({ + fetcher: async (input) => + input.prompt === 'second' ? secondResult : { id: 'first' }, + onStatusChange: (status) => { + if (status === 'generating') generatingStatuses.push(status) + }, + }) + client.subscribe(() => { + if (client.getSnapshot().status !== 'generating' || replaced) return + replaced = true + client.stop() + secondGenerate = client.generate({ prompt: 'second' }) + }) + + await client.generate({ prompt: 'first' }) + + expect(generatingStatuses).toEqual(['generating']) + expect(client.getStatus()).toBe('generating') + releaseSecond({ id: 'second' }) + await secondGenerate + }) + + it('should not call the old result callback after its subscriber starts a replacement', async () => { + let releaseSecond!: (value: { id: string }) => void + const secondResult = new Promise<{ id: string }>((resolve) => { + releaseSecond = resolve + }) + const onResultChange = vi.fn() + let secondGenerate: Promise | undefined + let replaced = false + const client = new GenerationClient({ + fetcher: async (input) => + input.prompt === 'second' ? secondResult : { id: 'first' }, + onResultChange, + }) + client.subscribe(() => { + if (client.getResult()?.id !== 'first' || replaced) return + replaced = true + client.stop() + secondGenerate = client.generate({ prompt: 'second' }) + }) + + await client.generate({ prompt: 'first' }) + + expect(onResultChange).not.toHaveBeenCalledWith({ id: 'first' }) + expect(client.getStatus()).toBe('generating') + releaseSecond({ id: 'second' }) + await secondGenerate + }) + + it('should not call the old error callback after its subscriber starts a replacement', async () => { + let releaseSecond!: (value: { id: string }) => void + const secondResult = new Promise<{ id: string }>((resolve) => { + releaseSecond = resolve + }) + const onErrorChange = vi.fn() + let secondGenerate: Promise | undefined + let replaced = false + const client = new GenerationClient({ + fetcher: async (input) => { + if (input.prompt === 'first') throw new Error('first failed') + return secondResult + }, + onErrorChange, + }) + client.subscribe(() => { + if (client.getError()?.message !== 'first failed' || replaced) return + replaced = true + client.stop() + secondGenerate = client.generate({ prompt: 'second' }) + }) + + await client.generate({ prompt: 'first' }) + + expect(onErrorChange).not.toHaveBeenCalledWith(expect.any(Error)) + expect(client.getStatus()).toBe('generating') + releaseSecond({ id: 'second' }) + await secondGenerate + }) }) describe('reset()', () => { @@ -432,6 +786,82 @@ describe('GenerationClient', () => { expect(client.getResult()).toBeNull() expect(client.getError()).toBeUndefined() expect(client.getStatus()).toBe('idle') + expect(client.getSnapshot().runId).toBeNull() + }) + + it('should not overwrite a run started by the reset loading callback', async () => { + let releaseFirst!: (value: { id: string }) => void + let releaseSecond!: (value: { id: string }) => void + const firstResult = new Promise<{ id: string }>((resolve) => { + releaseFirst = resolve + }) + const secondResult = new Promise<{ id: string }>((resolve) => { + releaseSecond = resolve + }) + let replaceOnStop = false + let secondGenerate: Promise | undefined + let secondRunId: string | null = null + let client!: GenerationClient<{ prompt: string }, { id: string }> + client = new GenerationClient({ + fetcher: async (input) => { + if (input.prompt === 'seed') return { id: 'seed' } + return input.prompt === 'first' ? firstResult : secondResult + }, + onLoadingChange: (isLoading) => { + if (isLoading || !replaceOnStop) return + replaceOnStop = false + secondGenerate = client.generate({ prompt: 'second' }) + secondRunId = client.getSnapshot().runId + }, + }) + await client.generate({ prompt: 'seed' }) + const firstGenerate = client.generate({ prompt: 'first' }) + replaceOnStop = true + + client.reset() + + expect(secondRunId).not.toBeNull() + expect(client.getSnapshot().runId).toBe(secondRunId) + expect(client.getStatus()).toBe('generating') + expect(client.getIsLoading()).toBe(true) + expect(client.getResult()).toEqual({ id: 'seed' }) + releaseFirst({ id: 'first' }) + releaseSecond({ id: 'second' }) + await Promise.all([firstGenerate, secondGenerate]) + }) + }) + + describe('dispose()', () => { + it('should not overwrite a run started by the dispose loading callback', async () => { + const first = createDeferred<{ id: string }>() + const second = createDeferred<{ id: string }>() + let replaceOnDispose = false + let secondGenerate: Promise | undefined + let secondRunId: string | null = null + let client!: GenerationClient<{ prompt: string }, { id: string }> + client = new GenerationClient({ + fetcher: (input) => + input.prompt === 'first' ? first.promise : second.promise, + onLoadingChange: (isLoading) => { + if (isLoading || !replaceOnDispose) return + replaceOnDispose = false + client.mountDevtools() + secondGenerate = client.generate({ prompt: 'second' }) + secondRunId = client.getSnapshot().runId + }, + }) + const firstGenerate = client.generate({ prompt: 'first' }) + replaceOnDispose = true + + client.dispose() + + expect(secondRunId).not.toBeNull() + expect(client.getSnapshot().runId).toBe(secondRunId) + expect(client.getStatus()).toBe('generating') + expect(client.getIsLoading()).toBe(true) + first.resolve({ id: 'first' }) + second.resolve({ id: 'second' }) + await Promise.all([firstGenerate, secondGenerate]) }) }) @@ -560,6 +990,75 @@ describe('GenerationClient', () => { expect(client.getStatus()).toBe('idle') }) + it('should not publish a run id after onChunk stops the run', async () => { + const connection: ConnectConnectionAdapter = { + async *connect() { + yield { + type: EventType.RUN_STARTED as const, + runId: 'run-1', + threadId: 'thread-1', + timestamp: Date.now(), + } + }, + } + let client!: GenerationClient<{ prompt: string }, { id: string }> + client = new GenerationClient({ + connection, + onChunk: (chunk) => { + if (chunk.type === EventType.RUN_STARTED) client.stop() + }, + }) + + await client.generate({ prompt: 'test' }) + + expect(client.getSnapshot().runId).toBeNull() + expect(client.getStatus()).toBe('idle') + }) + + it('should not let an old onChunk continuation overwrite a newer run', async () => { + let connectionCount = 0 + let releaseSecond!: () => void + const secondBlocked = new Promise((resolve) => { + releaseSecond = resolve + }) + const connection: ConnectConnectionAdapter = { + async *connect() { + connectionCount++ + if (connectionCount === 1) { + yield { + type: EventType.RUN_STARTED as const, + runId: 'run-1', + threadId: 'thread-1', + timestamp: Date.now(), + } + return + } + await secondBlocked + }, + } + let client!: GenerationClient<{ prompt: string }, { id: string }> + let secondGenerate: Promise | undefined + let secondLocalRunId: string | null = null + client = new GenerationClient({ + connection, + onChunk: (chunk) => { + if (chunk.type !== EventType.RUN_STARTED) return + client.stop() + secondGenerate = client.generate({ prompt: 'second' }) + secondLocalRunId = client.getSnapshot().runId + }, + }) + + await client.generate({ prompt: 'first' }) + + expect(secondLocalRunId).not.toBeNull() + expect(client.getSnapshot().runId).toBe(secondLocalRunId) + expect(client.getIsLoading()).toBe(true) + client.stop() + releaseSecond() + await secondGenerate + }) + it('should not let a stopped run clear the controller for a newer generation', async () => { const firstAborted = createDeferred() const firstCanFinish = createDeferred() @@ -621,12 +1120,14 @@ describe('GenerationClient', () => { await waitForCondition(() => { expect(signals).toHaveLength(2) expect(client.getIsLoading()).toBe(true) + expect(client.getSnapshot().runId).toBe('run-2') }) firstCanFinish.resolve(undefined) await firstGenerate expect(client.getIsLoading()).toBe(true) + expect(client.getSnapshot().runId).toBe('run-2') client.stop() expect(signals[1]?.aborted).toBe(true) @@ -758,12 +1259,14 @@ describe('GenerationClient', () => { await waitForCondition(() => { expect(signals).toHaveLength(2) expect(client.getIsLoading()).toBe(true) + expect(client.getSnapshot().runId).toBe('run-2') }) firstCanFinish.resolve(undefined) await firstGenerate expect(client.getIsLoading()).toBe(true) + expect(client.getSnapshot().runId).toBe('run-2') client.stop() expect(signals[1]?.aborted).toBe(true) diff --git a/packages/ai-client/tests/generation-devtools.test.ts b/packages/ai-client/tests/generation-devtools.test.ts index 133519a42d..ce967ca388 100644 --- a/packages/ai-client/tests/generation-devtools.test.ts +++ b/packages/ai-client/tests/generation-devtools.test.ts @@ -289,6 +289,184 @@ describe('generation client devtools bridge', () => { client.dispose() }) + it('finishes a generation devtools run when a runId subscriber stops it', async () => { + const fetcher = vi.fn(async () => ({ text: 'done' })) + const client = new GenerationClient({ + threadId: 'generation-run-id-stop', + fetcher, + devtools: { hookName: 'useGenerationRunIdStop' }, + }) + const unsubscribe = client.subscribe(() => { + if (client.getSnapshot().runId) client.stop() + }) + + await client.generate({ prompt: 'stop early' }) + + expect(fetcher).not.toHaveBeenCalled() + expect(latestSnapshotState().activeRunId).toBeNull() + unsubscribe() + client.dispose() + }) + + it('finishes a generation devtools run when loading callback stops it', async () => { + const fetcher = vi.fn(async () => ({ text: 'done' })) + let client: GenerationClient<{ prompt: string }, { text: string }> + client = new GenerationClient({ + threadId: 'generation-loading-stop', + fetcher, + devtools: { hookName: 'useGenerationLoadingStop' }, + onLoadingChange: (isLoading) => { + if (isLoading) client.stop() + }, + }) + + await client.generate({ prompt: 'stop while loading' }) + + expect(fetcher).not.toHaveBeenCalled() + expect(latestSnapshotState().activeRunId).toBeNull() + client.dispose() + }) + + it('finishes a completed generation devtools run when success callback stops it', async () => { + let client: GenerationClient<{ prompt: string }, { text: string }> + client = new GenerationClient({ + threadId: 'generation-success-stop', + fetcher: async () => ({ text: 'done' }), + devtools: { hookName: 'useGenerationSuccessStop' }, + onStatusChange: (status) => { + if (status === 'success') client.stop() + }, + }) + + await client.generate({ prompt: 'finish then stop' }) + + expect(latestSnapshotState().activeRunId).toBeNull() + expect(latestGenerationRuns().at(-1)).toEqual( + expect.objectContaining({ status: 'success', result: { text: 'done' } }), + ) + client.dispose() + }) + + it('finishes an errored generation devtools run when error callback stops it', async () => { + let client: GenerationClient<{ prompt: string }, { text: string }> + client = new GenerationClient<{ prompt: string }, { text: string }>({ + threadId: 'generation-error-stop', + devtools: { hookName: 'useGenerationErrorStop' }, + fetcher: async (): Promise<{ text: string }> => { + throw new Error('generation failed') + }, + onStatusChange: (status) => { + if (status === 'error') client.stop() + }, + }) + + await client.generate({ prompt: 'fail then stop' }) + + expect(latestSnapshotState().activeRunId).toBeNull() + expect(latestGenerationRuns().at(-1)).toEqual( + expect.objectContaining({ + status: 'error', + error: 'generation failed', + }), + ) + client.dispose() + }) + + it('finishes a video devtools run when a runId subscriber stops it', async () => { + const fetcher = vi.fn(async () => ({ + jobId: 'video-1', + status: 'completed' as const, + url: 'https://example.com/video-1.mp4', + })) + const client = new VideoGenerationClient({ + threadId: 'video-run-id-stop', + fetcher, + devtools: { hookName: 'useVideoRunIdStop' }, + }) + const unsubscribe = client.subscribe(() => { + if (client.getSnapshot().runId) client.stop() + }) + + await client.generate({ prompt: 'stop early' }) + + expect(fetcher).not.toHaveBeenCalled() + expect(latestSnapshotState().activeRunId).toBeNull() + unsubscribe() + client.dispose() + }) + + it('finishes a video devtools run when loading callback stops it', async () => { + const fetcher = vi.fn(async () => ({ + jobId: 'video-1', + status: 'completed' as const, + url: 'https://example.com/video-1.mp4', + })) + let client: VideoGenerationClient + client = new VideoGenerationClient({ + threadId: 'video-loading-stop', + fetcher, + devtools: { hookName: 'useVideoLoadingStop' }, + onLoadingChange: (isLoading) => { + if (isLoading) client.stop() + }, + }) + + await client.generate({ prompt: 'stop while loading' }) + + expect(fetcher).not.toHaveBeenCalled() + expect(latestSnapshotState().activeRunId).toBeNull() + client.dispose() + }) + + it('finishes a completed video devtools run when success callback stops it', async () => { + let client: VideoGenerationClient + client = new VideoGenerationClient({ + threadId: 'video-success-stop', + fetcher: async () => ({ + jobId: 'video-1', + status: 'completed' as const, + url: 'https://example.com/video-1.mp4', + }), + devtools: { hookName: 'useVideoSuccessStop' }, + onStatusChange: (status) => { + if (status === 'success') client.stop() + }, + }) + + await client.generate({ prompt: 'finish then stop' }) + + expect(latestSnapshotState().activeRunId).toBeNull() + expect(latestGenerationRuns().at(-1)).toEqual( + expect.objectContaining({ + status: 'success', + result: expect.objectContaining({ jobId: 'video-1' }), + }), + ) + client.dispose() + }) + + it('finishes an errored video devtools run when error callback stops it', async () => { + let client: VideoGenerationClient + client = new VideoGenerationClient({ + threadId: 'video-error-stop', + devtools: { hookName: 'useVideoErrorStop' }, + fetcher: async () => { + throw new Error('video failed') + }, + onStatusChange: (status) => { + if (status === 'error') client.stop() + }, + }) + + await client.generate({ prompt: 'fail then stop' }) + + expect(latestSnapshotState().activeRunId).toBeNull() + expect(latestGenerationRuns().at(-1)).toEqual( + expect.objectContaining({ status: 'error', error: 'video failed' }), + ) + client.dispose() + }) + it('includes input, progress, and renderable previews in generation snapshots', async () => { const client = new GenerationClient({ threadId: 'image-hook', diff --git a/packages/ai-client/tests/snapshot-atom.test.ts b/packages/ai-client/tests/snapshot-atom.test.ts index 74da6dbdc1..dbd0742190 100644 --- a/packages/ai-client/tests/snapshot-atom.test.ts +++ b/packages/ai-client/tests/snapshot-atom.test.ts @@ -2,6 +2,14 @@ import { describe, expect, it, vi } from 'vitest' import { createAtom, patchAtom, subscribeAtom } from '../src/snapshot-atom' describe('snapshot-atom', () => { + it('freezes object snapshots and keeps identity without a change', () => { + const atom = createAtom({ count: 1 }) + const snapshot = atom.get() + + expect(Object.isFrozen(snapshot)).toBe(true) + expect(atom.get()).toBe(snapshot) + }) + it('patchAtom skips notify when every field is unchanged', () => { const atom = createAtom({ count: 1, label: 'a' }) const listener = vi.fn() diff --git a/packages/ai-client/tests/video-generation-client.test.ts b/packages/ai-client/tests/video-generation-client.test.ts index be788e4d57..7e8ad13be0 100644 --- a/packages/ai-client/tests/video-generation-client.test.ts +++ b/packages/ai-client/tests/video-generation-client.test.ts @@ -224,6 +224,7 @@ describe('VideoGenerationClient', () => { ) expect(client.getStatus()).toBe('success') expect(client.getJobId()).toBe('job-123') + expect(client.getSnapshot().runId).toBeNull() }) it('should track video status updates', async () => { @@ -314,6 +315,7 @@ describe('VideoGenerationClient', () => { expect(onError).toHaveBeenCalledWith(expect.any(Error)) expect(client.getStatus()).toBe('error') expect(client.getError()?.message).toBe('Video generation failed') + expect(client.getSnapshot().runId).toBeNull() }) it('should report progress from video:status events', async () => { @@ -483,10 +485,12 @@ describe('VideoGenerationClient', () => { const generatePromise = client.generate({ prompt: 'test' }) expect(client.getIsLoading()).toBe(true) + expect(client.getSnapshot().runId).toEqual(expect.any(String)) client.stop() expect(client.getIsLoading()).toBe(false) expect(client.getStatus()).toBe('idle') + expect(client.getSnapshot().runId).toBeNull() resolvePromise!({ jobId: 'job-1', @@ -495,6 +499,454 @@ describe('VideoGenerationClient', () => { }) await generatePromise }) + + it('should not overwrite a run started by the stopped loading callback', async () => { + const firstVideo = { + jobId: 'job-1', + status: 'completed' as const, + url: 'https://example.com/first.mp4', + } + const secondVideo = { + jobId: 'job-2', + status: 'completed' as const, + url: 'https://example.com/second.mp4', + } + let releaseFirst!: (value: typeof firstVideo) => void + let releaseSecond!: (value: typeof secondVideo) => void + const firstResult = new Promise((resolve) => { + releaseFirst = resolve + }) + const secondResult = new Promise((resolve) => { + releaseSecond = resolve + }) + let secondGenerate: Promise | undefined + let secondRunId: string | null = null + let replaced = false + let client!: VideoGenerationClient + client = new VideoGenerationClient({ + fetcher: async (input) => + input.prompt === 'first' ? firstResult : secondResult, + onLoadingChange: (isLoading) => { + if (isLoading || replaced) return + replaced = true + secondGenerate = client.generate({ prompt: 'second' }) + secondRunId = client.getSnapshot().runId + }, + }) + + const firstGenerate = client.generate({ prompt: 'first' }) + client.stop() + + expect(secondRunId).not.toBeNull() + expect(client.getSnapshot().runId).toBe(secondRunId) + expect(client.getIsLoading()).toBe(true) + expect(client.getStatus()).toBe('generating') + releaseFirst(firstVideo) + releaseSecond(secondVideo) + await Promise.all([firstGenerate, secondGenerate]) + }) + + it('should clear the run id when the success status callback stops', async () => { + let client!: VideoGenerationClient + client = new VideoGenerationClient({ + fetcher: async () => ({ + jobId: 'job-1', + status: 'completed', + url: 'https://example.com/video.mp4', + }), + onStatusChange: (status) => { + if (status === 'success') client.stop() + }, + }) + + await client.generate({ prompt: 'test' }) + + expect(client.getStatus()).toBe('success') + expect(client.getSnapshot().runId).toBeNull() + expect(client.getResumeSnapshot()).toBeUndefined() + }) + + it('should remain stopped when the error callback stops', async () => { + let client!: VideoGenerationClient + client = new VideoGenerationClient({ + fetcher: async () => { + throw new Error('failed') + }, + onErrorChange: (error) => { + if (error) client.stop() + }, + }) + + await client.generate({ prompt: 'test' }) + + expect(client.getStatus()).toBe('idle') + expect(client.getSnapshot().runId).toBeNull() + }) + + it('should stop before transport work when loading callback stops', async () => { + const fetcher = vi.fn(async () => ({ + jobId: 'unexpected', + status: 'completed' as const, + url: 'https://example.com/unexpected.mp4', + })) + let client!: VideoGenerationClient + client = new VideoGenerationClient({ + fetcher, + onLoadingChange: (isLoading) => { + if (isLoading) client.stop() + }, + }) + + await client.generate({ prompt: 'test' }) + + expect(fetcher).not.toHaveBeenCalled() + expect(client.getStatus()).toBe('idle') + expect(client.getSnapshot().runId).toBeNull() + }) + + it('should not let initialization continue after loading callback starts a replacement', async () => { + const secondVideo = { + jobId: 'job-2', + status: 'completed' as const, + url: 'https://example.com/second.mp4', + } + let releaseSecond!: (value: typeof secondVideo) => void + const secondResult = new Promise((resolve) => { + releaseSecond = resolve + }) + const prompts: Array = [] + let client!: VideoGenerationClient + let replaced = false + let secondGenerate: Promise | undefined + client = new VideoGenerationClient({ + fetcher: async (input) => { + if (typeof input.prompt === 'string') prompts.push(input.prompt) + return input.prompt === 'second' + ? secondResult + : { + jobId: 'job-1', + status: 'completed', + url: 'https://example.com/first.mp4', + } + }, + onLoadingChange: (isLoading) => { + if (!isLoading || replaced) return + replaced = true + client.stop() + secondGenerate = client.generate({ prompt: 'second' }) + }, + }) + + await client.generate({ prompt: 'first' }) + + expect(prompts).toEqual(['second']) + expect(client.getStatus()).toBe('generating') + releaseSecond(secondVideo) + await secondGenerate + }) + + it('should not let an old result callback complete a replacement run', async () => { + const secondVideo = { + jobId: 'job-2', + status: 'completed' as const, + url: 'https://example.com/second.mp4', + } + let releaseSecond!: (value: typeof secondVideo) => void + const secondResult = new Promise((resolve) => { + releaseSecond = resolve + }) + let client!: VideoGenerationClient + let secondGenerate: Promise | undefined + let secondRunId: string | null = null + client = new VideoGenerationClient({ + fetcher: async (input) => + input.prompt === 'first' + ? { + jobId: 'job-1', + status: 'completed', + url: 'https://example.com/first.mp4', + } + : secondResult, + onResultChange: (result) => { + if (result?.jobId !== 'job-1') return + client.stop() + secondGenerate = client.generate({ prompt: 'second' }) + secondRunId = client.getSnapshot().runId + }, + }) + + await client.generate({ prompt: 'first' }) + + expect(secondRunId).not.toBeNull() + expect(client.getSnapshot().runId).toBe(secondRunId) + expect(client.getStatus()).toBe('generating') + expect(client.getResumeSnapshot()).toBeUndefined() + releaseSecond(secondVideo) + await secondGenerate + }) + + it('should not let an old error callback overwrite a replacement run', async () => { + const secondVideo = { + jobId: 'job-2', + status: 'completed' as const, + url: 'https://example.com/second.mp4', + } + let releaseSecond!: (value: typeof secondVideo) => void + const secondResult = new Promise((resolve) => { + releaseSecond = resolve + }) + let client!: VideoGenerationClient + let secondGenerate: Promise | undefined + let secondRunId: string | null = null + client = new VideoGenerationClient({ + fetcher: async (input) => { + if (input.prompt === 'first') throw new Error('first failed') + return secondResult + }, + onErrorChange: (error) => { + if (error?.message !== 'first failed') return + client.stop() + secondGenerate = client.generate({ prompt: 'second' }) + secondRunId = client.getSnapshot().runId + }, + }) + + await client.generate({ prompt: 'first' }) + + expect(secondRunId).not.toBeNull() + expect(client.getSnapshot().runId).toBe(secondRunId) + expect(client.getStatus()).toBe('generating') + releaseSecond(secondVideo) + await secondGenerate + }) + + it('should not let an old error status callback overwrite a replacement run', async () => { + const secondVideo = { + jobId: 'job-2', + status: 'completed' as const, + url: 'https://example.com/second.mp4', + } + let releaseSecond!: (value: typeof secondVideo) => void + const secondResult = new Promise((resolve) => { + releaseSecond = resolve + }) + let client!: VideoGenerationClient + let secondGenerate: Promise | undefined + let replaced = false + client = new VideoGenerationClient({ + fetcher: async (input) => { + if (input.prompt === 'first') throw new Error('first failed') + return secondResult + }, + onStatusChange: (status) => { + if (status !== 'error' || replaced) return + replaced = true + client.stop() + secondGenerate = client.generate({ prompt: 'second' }) + }, + }) + + await client.generate({ prompt: 'first' }) + + expect(client.getStatus()).toBe('generating') + expect(client.getError()).toBeUndefined() + releaseSecond(secondVideo) + await secondGenerate + }) + + it('should stop before transport when the run id subscriber stops', async () => { + const fetcher = vi.fn(async () => ({ + jobId: 'unexpected', + status: 'completed' as const, + url: 'https://example.com/unexpected.mp4', + })) + const onLoadingChange = vi.fn() + const client = new VideoGenerationClient({ fetcher, onLoadingChange }) + client.subscribe(() => { + if (client.getSnapshot().runId) client.stop() + }) + + await client.generate({ prompt: 'test' }) + + expect(fetcher).not.toHaveBeenCalled() + expect(onLoadingChange).not.toHaveBeenCalledWith(true) + expect(client.getSnapshot().runId).toBeNull() + }) + + it('should not continue an old run after the run id subscriber starts a replacement', async () => { + const secondVideo = { + jobId: 'job-2', + status: 'completed' as const, + url: 'https://example.com/second.mp4', + } + let releaseSecond!: (value: typeof secondVideo) => void + const secondResult = new Promise((resolve) => { + releaseSecond = resolve + }) + const prompts: Array = [] + let secondGenerate: Promise | undefined + let replaced = false + const client = new VideoGenerationClient({ + fetcher: async (input) => { + if (typeof input.prompt === 'string') prompts.push(input.prompt) + return input.prompt === 'second' + ? secondResult + : { + jobId: 'job-1', + status: 'completed', + url: 'https://example.com/first.mp4', + } + }, + }) + client.subscribe(() => { + if (!client.getSnapshot().runId || replaced) return + replaced = true + client.stop() + secondGenerate = client.generate({ prompt: 'second' }) + }) + + await client.generate({ prompt: 'first' }) + + expect(prompts).toEqual(['second']) + expect(client.getStatus()).toBe('generating') + releaseSecond(secondVideo) + await secondGenerate + }) + + it('should not call the loading callback after its snapshot subscriber stops', async () => { + const fetcher = vi.fn(async () => ({ + jobId: 'unexpected', + status: 'completed' as const, + url: 'https://example.com/unexpected.mp4', + })) + const onLoadingChange = vi.fn() + const client = new VideoGenerationClient({ fetcher, onLoadingChange }) + client.subscribe(() => { + if (client.getSnapshot().isLoading) client.stop() + }) + + await client.generate({ prompt: 'test' }) + + expect(fetcher).not.toHaveBeenCalled() + expect(onLoadingChange).not.toHaveBeenCalledWith(true) + }) + + it('should not call the old status callback after its subscriber starts a replacement', async () => { + const secondVideo = { + jobId: 'job-2', + status: 'completed' as const, + url: 'https://example.com/second.mp4', + } + let releaseSecond!: (value: typeof secondVideo) => void + const secondResult = new Promise((resolve) => { + releaseSecond = resolve + }) + const generatingStatuses: Array = [] + let secondGenerate: Promise | undefined + let replaced = false + const client = new VideoGenerationClient({ + fetcher: async (input) => + input.prompt === 'second' + ? secondResult + : { + jobId: 'job-1', + status: 'completed', + url: 'https://example.com/first.mp4', + }, + onStatusChange: (status) => { + if (status === 'generating') generatingStatuses.push(status) + }, + }) + client.subscribe(() => { + if (client.getSnapshot().status !== 'generating' || replaced) return + replaced = true + client.stop() + secondGenerate = client.generate({ prompt: 'second' }) + }) + + await client.generate({ prompt: 'first' }) + + expect(generatingStatuses).toEqual(['generating']) + expect(client.getStatus()).toBe('generating') + releaseSecond(secondVideo) + await secondGenerate + }) + + it('should not call the old result callback after its subscriber starts a replacement', async () => { + const secondVideo = { + jobId: 'job-2', + status: 'completed' as const, + url: 'https://example.com/second.mp4', + } + let releaseSecond!: (value: typeof secondVideo) => void + const secondResult = new Promise((resolve) => { + releaseSecond = resolve + }) + const onResultChange = vi.fn() + let secondGenerate: Promise | undefined + let replaced = false + const client = new VideoGenerationClient({ + fetcher: async (input) => + input.prompt === 'second' + ? secondResult + : { + jobId: 'job-1', + status: 'completed', + url: 'https://example.com/first.mp4', + }, + onResultChange, + }) + client.subscribe(() => { + if (client.getResult()?.jobId !== 'job-1' || replaced) return + replaced = true + client.stop() + secondGenerate = client.generate({ prompt: 'second' }) + }) + + await client.generate({ prompt: 'first' }) + + expect(onResultChange).not.toHaveBeenCalledWith( + expect.objectContaining({ jobId: 'job-1' }), + ) + expect(client.getStatus()).toBe('generating') + releaseSecond(secondVideo) + await secondGenerate + }) + + it('should not call the old error callback after its subscriber starts a replacement', async () => { + const secondVideo = { + jobId: 'job-2', + status: 'completed' as const, + url: 'https://example.com/second.mp4', + } + let releaseSecond!: (value: typeof secondVideo) => void + const secondResult = new Promise((resolve) => { + releaseSecond = resolve + }) + const onErrorChange = vi.fn() + let secondGenerate: Promise | undefined + let replaced = false + const client = new VideoGenerationClient({ + fetcher: async (input) => { + if (input.prompt === 'first') throw new Error('first failed') + return secondResult + }, + onErrorChange, + }) + client.subscribe(() => { + if (client.getError()?.message !== 'first failed' || replaced) return + replaced = true + client.stop() + secondGenerate = client.generate({ prompt: 'second' }) + }) + + await client.generate({ prompt: 'first' }) + + expect(onErrorChange).not.toHaveBeenCalledWith(expect.any(Error)) + expect(client.getStatus()).toBe('generating') + releaseSecond(secondVideo) + await secondGenerate + }) }) describe('reset()', () => { @@ -561,6 +1013,112 @@ describe('VideoGenerationClient', () => { expect(client.getVideoStatus()).toBeNull() expect(client.getError()).toBeUndefined() expect(client.getStatus()).toBe('idle') + expect(client.getSnapshot().runId).toBeNull() + }) + + it('should not overwrite a run started by the reset loading callback', async () => { + const seedVideo = { + jobId: 'seed', + status: 'completed' as const, + url: 'https://example.com/seed.mp4', + } + const firstVideo = { + jobId: 'job-1', + status: 'completed' as const, + url: 'https://example.com/first.mp4', + } + const secondVideo = { + jobId: 'job-2', + status: 'completed' as const, + url: 'https://example.com/second.mp4', + } + let releaseFirst!: (value: typeof firstVideo) => void + let releaseSecond!: (value: typeof secondVideo) => void + const firstResult = new Promise((resolve) => { + releaseFirst = resolve + }) + const secondResult = new Promise((resolve) => { + releaseSecond = resolve + }) + let replaceOnStop = false + let secondGenerate: Promise | undefined + let secondRunId: string | null = null + let client!: VideoGenerationClient + client = new VideoGenerationClient({ + fetcher: async (input) => { + if (input.prompt === 'seed') return seedVideo + return input.prompt === 'first' ? firstResult : secondResult + }, + onLoadingChange: (isLoading) => { + if (isLoading || !replaceOnStop) return + replaceOnStop = false + secondGenerate = client.generate({ prompt: 'second' }) + secondRunId = client.getSnapshot().runId + }, + }) + await client.generate({ prompt: 'seed' }) + const firstGenerate = client.generate({ prompt: 'first' }) + replaceOnStop = true + + client.reset() + + expect(secondRunId).not.toBeNull() + expect(client.getSnapshot().runId).toBe(secondRunId) + expect(client.getStatus()).toBe('generating') + expect(client.getIsLoading()).toBe(true) + expect(client.getResult()).toEqual(seedVideo) + releaseFirst(firstVideo) + releaseSecond(secondVideo) + await Promise.all([firstGenerate, secondGenerate]) + }) + }) + + describe('dispose()', () => { + it('should not overwrite a run started by the dispose loading callback', async () => { + const firstVideo = { + jobId: 'job-1', + status: 'completed' as const, + url: 'https://example.com/first.mp4', + } + const secondVideo = { + jobId: 'job-2', + status: 'completed' as const, + url: 'https://example.com/second.mp4', + } + let releaseFirst!: (value: typeof firstVideo) => void + let releaseSecond!: (value: typeof secondVideo) => void + const first = new Promise((resolve) => { + releaseFirst = resolve + }) + const second = new Promise((resolve) => { + releaseSecond = resolve + }) + let replaceOnDispose = false + let secondGenerate: Promise | undefined + let secondRunId: string | null = null + let client!: VideoGenerationClient + client = new VideoGenerationClient({ + fetcher: (input) => (input.prompt === 'first' ? first : second), + onLoadingChange: (isLoading) => { + if (isLoading || !replaceOnDispose) return + replaceOnDispose = false + client.mountDevtools() + secondGenerate = client.generate({ prompt: 'second' }) + secondRunId = client.getSnapshot().runId + }, + }) + const firstGenerate = client.generate({ prompt: 'first' }) + replaceOnDispose = true + + client.dispose() + + expect(secondRunId).not.toBeNull() + expect(client.getSnapshot().runId).toBe(secondRunId) + expect(client.getStatus()).toBe('generating') + expect(client.getIsLoading()).toBe(true) + releaseFirst(firstVideo) + releaseSecond(secondVideo) + await Promise.all([firstGenerate, secondGenerate]) }) }) @@ -652,6 +1210,75 @@ describe('VideoGenerationClient', () => { expect(client.getResult()).toBeNull() expect(client.getStatus()).toBe('idle') }) + + it('should not publish a run id after onChunk stops the run', async () => { + const connection: ConnectConnectionAdapter = { + async *connect() { + yield { + type: EventType.RUN_STARTED as const, + runId: 'run-1', + threadId: 'thread-1', + timestamp: Date.now(), + } + }, + } + let client!: VideoGenerationClient + client = new VideoGenerationClient({ + connection, + onChunk: (chunk) => { + if (chunk.type === EventType.RUN_STARTED) client.stop() + }, + }) + + await client.generate({ prompt: 'test' }) + + expect(client.getSnapshot().runId).toBeNull() + expect(client.getStatus()).toBe('idle') + }) + + it('should not let an old onChunk continuation overwrite a newer run', async () => { + let connectionCount = 0 + let releaseSecond!: () => void + const secondBlocked = new Promise((resolve) => { + releaseSecond = resolve + }) + const connection: ConnectConnectionAdapter = { + async *connect() { + connectionCount++ + if (connectionCount === 1) { + yield { + type: EventType.RUN_STARTED as const, + runId: 'run-1', + threadId: 'thread-1', + timestamp: Date.now(), + } + return + } + await secondBlocked + }, + } + let client!: VideoGenerationClient + let secondGenerate: Promise | undefined + let secondLocalRunId: string | null = null + client = new VideoGenerationClient({ + connection, + onChunk: (chunk) => { + if (chunk.type !== EventType.RUN_STARTED) return + client.stop() + secondGenerate = client.generate({ prompt: 'second' }) + secondLocalRunId = client.getSnapshot().runId + }, + }) + + await client.generate({ prompt: 'first' }) + + expect(secondLocalRunId).not.toBeNull() + expect(client.getSnapshot().runId).toBe(secondLocalRunId) + expect(client.getIsLoading()).toBe(true) + client.stop() + releaseSecond() + await secondGenerate + }) }) describe('error wrapping', () => { diff --git a/packages/ai-react/src/use-chat.ts b/packages/ai-react/src/use-chat.ts index c567df72c2..e1cdf0e004 100644 --- a/packages/ai-react/src/use-chat.ts +++ b/packages/ai-react/src/use-chat.ts @@ -18,6 +18,7 @@ import type { StreamChunk, } from '@tanstack/ai/client' import type { + ChatClientPersistence, ResolvableChatInterrupt, ChatResumeState, InferredClientContext, @@ -68,128 +69,180 @@ export function useChat< optionsRef.current = options // Create ChatClient instance with callbacks to sync state - const { client, initialization } = useMemo(() => { - const messagesToUse = options.initialMessages || [] - - // Build options with conditional spreads for fields whose source - // type is `T | undefined` but the ChatClient target uses a strict - // optional (`field?: T`) — `exactOptionalPropertyTypes` rejects - // assigning `undefined` to those, so we omit the key when absent. - const initialOptions = optionsRef.current - const transport = initialOptions.connection - ? { connection: initialOptions.connection } - : { fetcher: initialOptions.fetcher } - - const instanceHolder: { - current: ChatClient | undefined - } = { current: undefined } - const getActiveInstance = () => { - const currentInstance = instanceHolder.current - if (!currentInstance || activeClientRef.current !== currentInstance) { - return undefined + const { client, initialization, serverSnapshot, startPersistenceHydration } = + useMemo(() => { + const messagesToUse = options.initialMessages || [] + + // Build options with conditional spreads for fields whose source + // type is `T | undefined` but the ChatClient target uses a strict + // optional (`field?: T`) — `exactOptionalPropertyTypes` rejects + // assigning `undefined` to those, so we omit the key when absent. + const initialOptions = optionsRef.current + let persistence = initialOptions.persistence + let releasePersistenceHydration = () => {} + if (persistence && typeof persistence === 'object') { + const source = persistence + let hydrationStarted = false + let releaseRead: (() => void) | undefined + let hydrationPromise: + | Promise< + Awaited['getItem']>> + > + | undefined + const gatedPersistence: ChatClientPersistence = { + getItem(id) { + if (!hydrationPromise) { + hydrationPromise = new Promise((resolve, reject) => { + let readStarted = false + releaseRead = () => { + if (readStarted) return + readStarted = true + try { + resolve(source.getItem.call(source, id)) + } catch (error) { + reject(error) + } + } + }) + } + if (hydrationStarted) releaseRead?.() + return hydrationPromise + }, + setItem(id, state) { + return source.setItem.call(source, id, state) + }, + removeItem(id) { + return source.removeItem.call(source, id) + }, + } + persistence = gatedPersistence + releasePersistenceHydration = () => { + if (hydrationStarted) return + hydrationStarted = true + releaseRead?.() + } } - return currentInstance - } - // ChatClient may publish while its constructor is running or while async - // persistence resolves before commit. Preserve those exact notifications - // until this render commits; invoking them here would run state setters and - // user callbacks for a client React may abandon. - const initializationState = { - ready: false, - callbacks: [] as Array<() => void>, - } - const runOrQueueForActiveInstance = (callback: () => void) => { - if (!initializationState.ready) { - initializationState.callbacks.push(callback) - return + const transport = initialOptions.connection + ? { connection: initialOptions.connection } + : { fetcher: initialOptions.fetcher } + + const instanceHolder: { + current: ChatClient | undefined + } = { current: undefined } + const getActiveInstance = () => { + const currentInstance = instanceHolder.current + if (!currentInstance || activeClientRef.current !== currentInstance) { + return undefined + } + return currentInstance } - const currentInstance = instanceHolder.current - if (!currentInstance || activeClientRef.current !== currentInstance) - return - callback() - } - const instance = new ChatClient({ - devtoolsBridgeFactory: createChatDevtoolsBridge, - ...transport, - initialMessages: messagesToUse, - ...(typeof initialOptions.threadId === 'string' && - initialOptions.persistence - ? { - persistence: initialOptions.persistence, - threadId: initialOptions.threadId, - } - : { - ...(initialOptions.threadId !== undefined && { + // ChatClient may publish while its constructor is running or while async + // persistence resolves before commit. Preserve those exact notifications + // until this render commits; invoking them here would run state setters and + // user callbacks for a client React may abandon. + const initializationState = { + ready: false, + callbacks: [] as Array<() => void>, + } + const runOrQueueForActiveInstance = (callback: () => void) => { + if (!initializationState.ready) { + initializationState.callbacks.push(callback) + return + } + const currentInstance = instanceHolder.current + if (!currentInstance || activeClientRef.current !== currentInstance) + return + callback() + } + const instance = new ChatClient({ + devtoolsBridgeFactory: createChatDevtoolsBridge, + ...transport, + initialMessages: messagesToUse, + ...(typeof initialOptions.threadId === 'string' && persistence + ? { + persistence, threadId: initialOptions.threadId, + } + : { + ...(initialOptions.threadId !== undefined && { + threadId: initialOptions.threadId, + }), }), - }), - ...(initialOptions.body !== undefined && { body: initialOptions.body }), - ...(initialOptions.forwardedProps !== undefined && { - forwardedProps: initialOptions.forwardedProps, - }), - ...(initialOptions.byok !== undefined && { byok: initialOptions.byok }), - byokProvider: () => optionsRef.current.byokProvider?.(), - ...(initialOptions.initialResumeSnapshot !== undefined && { - initialResumeSnapshot: initialOptions.initialResumeSnapshot, - }), - ...(initialOptions.context !== undefined && { - context: initialOptions.context, - }), - devtools: { - ...initialOptions.devtools, - framework: 'react', - hookName: 'useChat', - outputKind: initialOptions.outputSchema ? 'structured' : 'chat', - }, - onResponse: (response) => { - // ChatClient awaits this return value. Queuing would drop the promise. - if (!getActiveInstance()) return - return optionsRef.current.onResponse?.(response) - }, - onChunk: (chunk: StreamChunk) => { - runOrQueueForActiveInstance(() => { - optionsRef.current.onChunk?.(chunk) - }) - }, - onFinish: (message: UIMessage) => { - runOrQueueForActiveInstance(() => { - optionsRef.current.onFinish?.(message) - }) - }, - onError: (error: Error) => { - runOrQueueForActiveInstance(() => { - optionsRef.current.onError?.(error) - }) - }, - ...(initialOptions.tools !== undefined && { - tools: initialOptions.tools, - }), - ...(initialOptions.interrupts !== undefined && { - interrupts: initialOptions.interrupts, - }), - onCustomEvent: (eventType, data, context) => { - runOrQueueForActiveInstance(() => { - optionsRef.current.onCustomEvent?.(eventType, data, context) - }) - }, - ...(options.streamProcessor !== undefined && { - streamProcessor: options.streamProcessor, - }), - ...(optionsRef.current.queue !== undefined && { - queue: optionsRef.current.queue, - }), - onInterruptStateChange: (nextInterruptState, context) => { - runOrQueueForActiveInstance(() => { - optionsRef.current.onInterruptStateChange?.( - nextInterruptState, - context, - ) - }) - }, - }) - instanceHolder.current = instance - return { client: instance, initialization: initializationState } - }, [clientId]) + ...(initialOptions.body !== undefined && { body: initialOptions.body }), + ...(initialOptions.forwardedProps !== undefined && { + forwardedProps: initialOptions.forwardedProps, + }), + ...(initialOptions.byok !== undefined && { byok: initialOptions.byok }), + byokProvider: () => optionsRef.current.byokProvider?.(), + ...(initialOptions.initialResumeSnapshot !== undefined && { + initialResumeSnapshot: initialOptions.initialResumeSnapshot, + }), + ...(initialOptions.context !== undefined && { + context: initialOptions.context, + }), + devtools: { + ...initialOptions.devtools, + framework: 'react', + hookName: 'useChat', + outputKind: initialOptions.outputSchema ? 'structured' : 'chat', + }, + onResponse: (response) => { + // ChatClient awaits this return value. Queuing would drop the promise. + if (!getActiveInstance()) return + return optionsRef.current.onResponse?.(response) + }, + onChunk: (chunk: StreamChunk) => { + runOrQueueForActiveInstance(() => { + optionsRef.current.onChunk?.(chunk) + }) + }, + onFinish: (message: UIMessage) => { + runOrQueueForActiveInstance(() => { + optionsRef.current.onFinish?.(message) + }) + }, + onError: (error: Error) => { + runOrQueueForActiveInstance(() => { + optionsRef.current.onError?.(error) + }) + }, + ...(initialOptions.tools !== undefined && { + tools: initialOptions.tools, + }), + ...(initialOptions.interrupts !== undefined && { + interrupts: initialOptions.interrupts, + }), + onCustomEvent: (eventType, data, context) => { + runOrQueueForActiveInstance(() => { + optionsRef.current.onCustomEvent?.(eventType, data, context) + }) + }, + ...(options.streamProcessor !== undefined && { + streamProcessor: options.streamProcessor, + }), + ...(optionsRef.current.queue !== undefined && { + queue: optionsRef.current.queue, + }), + onInterruptStateChange: (nextInterruptState, context) => { + runOrQueueForActiveInstance(() => { + optionsRef.current.onInterruptStateChange?.( + nextInterruptState, + context, + ) + }) + }, + }) + instanceHolder.current = instance + const capturedServerSnapshot = instance.getSnapshot() + return { + client: instance, + initialization: initializationState, + serverSnapshot: capturedServerSnapshot, + startPersistenceHydration: releasePersistenceHydration, + } + }, [clientId]) + + const getServerSnapshot = useCallback(() => serverSnapshot, [serverSnapshot]) useEffect(() => { activeClientRef.current = client @@ -212,7 +265,7 @@ export function useChat< const snapshot = useSyncExternalStore( client.subscribeSnapshot, client.getSnapshot, - client.getSnapshot, + getServerSnapshot, ) // Sync each wire-payload slot in its own effect so an unrelated option @@ -277,10 +330,11 @@ export function useChat< // run is picked straight back up from the durable log. useEffect(() => { client.attach() + startPersistenceHydration() return () => { client.detach() } - }, [client]) + }, [client, startPersistenceHydration]) useEffect(() => { if (cleanupDisposalRef.current?.client === client) { diff --git a/packages/ai-react/tests/use-chat.test.ts b/packages/ai-react/tests/use-chat.test.ts index 3f6d6593f8..04f2fe9f01 100644 --- a/packages/ai-react/tests/use-chat.test.ts +++ b/packages/ai-react/tests/use-chat.test.ts @@ -1,7 +1,13 @@ import { EventType } from '@tanstack/ai' import { ChatClient } from '@tanstack/ai-client' import { act, render, renderHook, waitFor } from '@testing-library/react' -import { StrictMode, Suspense, createElement, useState } from 'react' +import { + StrictMode, + Suspense, + createElement, + useLayoutEffect, + useState, +} from 'react' import { afterEach, describe, expect, it, vi } from 'vitest' import { useChat } from '../src/use-chat' import { @@ -232,7 +238,7 @@ describe('useChat', () => { expect(persistence.getItem).toHaveBeenCalledWith('persisted-chat') }) - it('should forward synchronous persisted interrupt hydration', () => { + it('forwards persisted interrupt hydration from a synchronous store', async () => { const onInterruptStateChange = vi.fn() const persistence = { getItem: vi.fn(() => ({ @@ -254,7 +260,9 @@ describe('useChat', () => { { wrapper: StrictMode }, ) - expect(result.current.interrupts).toHaveLength(2) + await waitFor(() => { + expect(result.current.interrupts).toHaveLength(2) + }) expect(onInterruptStateChange).toHaveBeenCalledOnce() expect(onInterruptStateChange).toHaveBeenCalledWith( expect.objectContaining({ interrupts: result.current.interrupts }), @@ -262,6 +270,360 @@ describe('useChat', () => { ) }) + it('keeps the server message count for the first hydration render', async () => { + const initialMessages: Array = [ + { + id: 'server-message', + role: 'user', + parts: [{ type: 'text', content: 'Server message' }], + createdAt: new Date(), + }, + ] + const persistedMessages: Array = [ + ...initialMessages, + { + id: 'persisted-message', + role: 'assistant', + parts: [{ type: 'text', content: 'Persisted message' }], + createdAt: new Date(), + }, + ] + const persistence = { + getItem: vi.fn(() => persistedMessages), + setItem: vi.fn(), + removeItem: vi.fn(), + } + const renderCounts: Array = [] + const onRecoverableError = vi.fn() + const container = document.createElement('div') + container.innerHTML = '
1
' + document.body.append(container) + + function HydratedChat() { + const chat = useChat({ + connection: createMockConnectionAdapter(), + threadId: 'hydrated-message-chat', + initialMessages, + persistence, + }) + renderCounts.push(chat.messages.length) + return createElement( + 'div', + { 'data-testid': 'message-count' }, + chat.messages.length, + ) + } + + const view = render( + createElement(StrictMode, null, createElement(HydratedChat)), + { container, hydrate: true, onRecoverableError }, + ) + + expect(renderCounts[0]).toBe(1) + await waitFor(() => { + expect(view.getByTestId('message-count').textContent).toBe('2') + }) + expect(persistence.getItem).toHaveBeenCalledOnce() + expect(onRecoverableError).not.toHaveBeenCalled() + }) + + it('keeps server interrupts empty until persistence hydration starts after commit', async () => { + const persistence = { + getItem: vi.fn(() => ({ + messages: [], + resume: createInterruptResumeSnapshot(), + })), + setItem: vi.fn(), + removeItem: vi.fn(), + } + const renderCounts: Array = [] + const hydrationCommitStates: Array = [] + const onRecoverableError = vi.fn() + const container = document.createElement('div') + container.innerHTML = '
0
' + document.body.append(container) + + function HydratedInterrupts() { + let committed = false + useLayoutEffect(() => { + committed = true + }, []) + const chat = useChat({ + connection: createMockConnectionAdapter(), + threadId: 'hydrated-interrupt-chat', + persistence, + onInterruptStateChange: (_state, context) => { + if (context.source === 'hydrate') { + hydrationCommitStates.push(committed) + } + }, + }) + renderCounts.push(chat.interrupts.length) + return createElement( + 'div', + { 'data-testid': 'interrupt-count' }, + chat.interrupts.length, + ) + } + + const view = render( + createElement(StrictMode, null, createElement(HydratedInterrupts)), + { container, hydrate: true, onRecoverableError }, + ) + + expect(renderCounts[0]).toBe(0) + await waitFor(() => { + expect(view.getByTestId('interrupt-count').textContent).toBe('2') + }) + expect(hydrationCommitStates).toEqual([true]) + expect(persistence.getItem).toHaveBeenCalledOnce() + expect(onRecoverableError).not.toHaveBeenCalled() + }) + + it('keeps the initial resume snapshot through hydration before rejoining the stored run', async () => { + const initialResumeSnapshot = createInterruptResumeSnapshot() + const persistence = { + getItem: vi.fn(() => ({ + messages: [], + resume: { + schemaVersion: 2, + resumeState: { + threadId: 'hydrated-resume-chat', + runId: 'stored-run', + }, + }, + })), + setItem: vi.fn(), + removeItem: vi.fn(), + } + const joinRun = vi.fn(async function* (_runId: string) {}) + const connection: ResumableConnectConnectionAdapter = { + connect: async function* () {}, + joinRun, + } + const renderCounts: Array = [] + const onRecoverableError = vi.fn() + const container = document.createElement('div') + container.innerHTML = '
2
' + document.body.append(container) + + function HydratedResume() { + const chat = useChat({ + connection, + threadId: 'hydrated-resume-chat', + initialResumeSnapshot, + persistence, + }) + renderCounts.push(chat.interrupts.length) + return createElement( + 'div', + { 'data-testid': 'interrupt-count' }, + chat.interrupts.length, + ) + } + + const view = render(createElement(HydratedResume), { + container, + hydrate: true, + onRecoverableError, + }) + + expect(renderCounts[0]).toBe(2) + expect(joinRun).not.toHaveBeenCalled() + await waitFor(() => { + expect(view.getByTestId('interrupt-count').textContent).toBe('0') + expect(joinRun).toHaveBeenCalledOnce() + }) + expect(joinRun).toHaveBeenCalledWith('stored-run', expect.anything()) + expect(persistence.getItem).toHaveBeenCalledOnce() + expect(onRecoverableError).not.toHaveBeenCalled() + }) + + it('preserves the persistence adapter receiver for reads, writes, and removal', async () => { + class ReceiverSensitivePersistence implements ChatClientPersistence { + calls: Array = [] + + getItem(id: string) { + this.calls.push(`get:${id}`) + return [] + } + + setItem(id: string) { + this.calls.push(`set:${id}`) + } + + removeItem(id: string) { + this.calls.push(`remove:${id}`) + } + } + + const persistence = new ReceiverSensitivePersistence() + const { result } = renderUseChat({ + connection: createMockConnectionAdapter({ + chunks: createTextChunks('Persisted reply'), + }), + threadId: 'receiver-chat', + persistence, + }) + + await waitFor(() => { + expect(persistence.calls).toContain('get:receiver-chat') + }) + await act(async () => { + await result.current.sendMessage('Persist me') + }) + await waitFor(() => { + expect(persistence.calls).toContain('set:receiver-chat') + }) + const removalsBeforeClear = persistence.calls.filter( + (call) => call === 'remove:receiver-chat', + ).length + act(() => result.current.clear()) + await waitFor(() => { + const removalsAfterClear = persistence.calls.filter( + (call) => call === 'remove:receiver-chat', + ).length + expect(removalsAfterClear).toBeGreaterThan(removalsBeforeClear) + }) + }) + + it('keeps initial state when a synchronous persistence read throws during hydration', async () => { + const initialMessages: Array = [ + { + id: 'initial-message', + role: 'user', + parts: [{ type: 'text', content: 'Initial' }], + createdAt: new Date(), + }, + ] + const persistence = { + getItem: vi.fn(() => { + throw new Error('storage unavailable') + }), + setItem: vi.fn(), + removeItem: vi.fn(), + } + const onInterruptStateChange = vi.fn() + const onRecoverableError = vi.fn() + const container = document.createElement('div') + container.innerHTML = '
1
' + document.body.append(container) + + function HydratedChat() { + const chat = useChat({ + connection: createMockConnectionAdapter(), + threadId: 'throwing-sync-chat', + initialMessages, + persistence, + onInterruptStateChange, + }) + return createElement( + 'div', + { 'data-testid': 'message-count' }, + chat.messages.length, + ) + } + + const view = render(createElement(HydratedChat), { + container, + hydrate: true, + onRecoverableError, + }) + + await waitFor(() => { + expect(persistence.getItem).toHaveBeenCalledOnce() + }) + expect(view.getByTestId('message-count').textContent).toBe('1') + expect(onInterruptStateChange).not.toHaveBeenCalled() + expect(onRecoverableError).not.toHaveBeenCalled() + }) + + it('keeps initial state when an asynchronous persistence read rejects', async () => { + const initialMessages: Array = [ + { + id: 'initial-message', + role: 'user', + parts: [{ type: 'text', content: 'Initial' }], + createdAt: new Date(), + }, + ] + const persistence = { + getItem: vi.fn(async () => { + throw new Error('storage unavailable') + }), + setItem: vi.fn(), + removeItem: vi.fn(), + } + const onInterruptStateChange = vi.fn() + const { result } = renderUseChat({ + connection: createMockConnectionAdapter(), + threadId: 'throwing-async-chat', + initialMessages, + persistence, + onInterruptStateChange, + }) + + await waitFor(() => { + expect(persistence.getItem).toHaveBeenCalledOnce() + }) + expect(result.current.messages).toEqual(initialMessages) + expect(onInterruptStateChange).not.toHaveBeenCalled() + }) + + it('applies asynchronous persistence only after attach and commit', async () => { + const hydration = createDeferred<{ + messages: Array + resume: ReturnType + }>() + let committed = false + const readCommitStates: Array = [] + const hydrationCommitStates: Array = [] + const persistence = { + getItem: vi.fn(() => { + readCommitStates.push(committed) + return hydration.promise + }), + setItem: vi.fn(), + removeItem: vi.fn(), + } + + function useHydratedChat() { + useLayoutEffect(() => { + committed = true + }, []) + const chat = useChat({ + connection: createMockConnectionAdapter(), + threadId: 'async-hydration-chat', + persistence, + onInterruptStateChange: (_state, context) => { + if (context.source === 'hydrate') { + hydrationCommitStates.push(committed) + } + }, + }) + return chat.interrupts.length + } + + const { result } = renderHook(() => useHydratedChat()) + + expect(result.current).toBe(0) + await waitFor(() => { + expect(persistence.getItem).toHaveBeenCalledOnce() + }) + expect(readCommitStates).toEqual([true]) + await act(async () => { + hydration.resolve({ + messages: [], + resume: createInterruptResumeSnapshot(), + }) + await hydration.promise + }) + await waitFor(() => { + expect(result.current).toBe(2) + }) + expect(hydrationCommitStates).toEqual([true]) + }) + it('does not publish async hydration from an abandoned render', async () => { const hydration = createDeferred<{ messages: Array @@ -302,6 +664,7 @@ describe('useChat', () => { await hydration.promise }) + expect(persistence.getItem).not.toHaveBeenCalled() expect(onInterruptStateChange).not.toHaveBeenCalled() }) diff --git a/packages/ai-svelte/tests/create-generation-dispose.test.ts b/packages/ai-svelte/tests/create-generation-dispose.test.ts index e7ef6fc3d6..31920ea009 100644 --- a/packages/ai-svelte/tests/create-generation-dispose.test.ts +++ b/packages/ai-svelte/tests/create-generation-dispose.test.ts @@ -18,11 +18,17 @@ describe('Svelte generate() after dispose() rebinds the snapshot', () => { it('createGenerateVideo updates result after dispose then generate', async () => { const video = createGenerateVideo({ - fetcher: async (input) => ({ - jobId: input.prompt, - status: 'completed' as const, - url: `https://example.com/${input.prompt}.mp4`, - }), + fetcher: async (input) => { + if (typeof input.prompt !== 'string') { + throw new Error('Expected a text prompt') + } + + return { + jobId: input.prompt, + status: 'completed' as const, + url: `https://example.com/${input.prompt}.mp4`, + } + }, }) await video.generate({ prompt: 'one' }) diff --git a/packages/ai-vertex/package.json b/packages/ai-vertex/package.json index 0fead1cade..f5d635271c 100644 --- a/packages/ai-vertex/package.json +++ b/packages/ai-vertex/package.json @@ -58,7 +58,6 @@ "@tanstack/ai": "workspace:^" }, "devDependencies": { - "@google/genai": "^2.10.0", "@tanstack/ai": "workspace:*", "@vitest/coverage-v8": "4.1.10", "vite": "^8.2.1" diff --git a/packages/ai-vertex/tests/factories.test.ts b/packages/ai-vertex/tests/factories.test.ts index 54c9c86b84..c21f6c0d5e 100644 --- a/packages/ai-vertex/tests/factories.test.ts +++ b/packages/ai-vertex/tests/factories.test.ts @@ -11,22 +11,35 @@ import { const mocks = vi.hoisted(() => { return { - constructorSpy: vi.fn<(options: Record) => void>(), + constructorSpy: + vi.fn< + (kind: string, options: Record, model: string) => void + >(), } }) -vi.mock('@google/genai', async (importOriginal) => { - const actual = await importOriginal() +vi.mock('@tanstack/ai-gemini', async (importOriginal) => { + const actual = await importOriginal() + const adapterClass = (kind: string) => { + return class { + readonly name = 'gemini' + readonly model: string - class MockGoogleGenAI { - constructor(options: Record) { - mocks.constructorSpy(options) + constructor(options: Record, model: string) { + this.model = model + mocks.constructorSpy(kind, options, model) + } } } return { ...actual, - GoogleGenAI: MockGoogleGenAI, + GeminiTextAdapter: adapterClass('text'), + GeminiImageAdapter: adapterClass('image'), + GeminiEmbeddingAdapter: adapterClass('embedding'), + GeminiTTSAdapter: adapterClass('speech'), + GeminiAudioAdapter: adapterClass('audio'), + GeminiVideoAdapter: adapterClass('video'), } }) @@ -49,11 +62,15 @@ describe('vertex factories', () => { expect(adapter.name).toBe('gemini') expect(adapter.model).toBe('gemini-3.7-flash') - expect(mocks.constructorSpy).toHaveBeenCalledExactlyOnceWith({ - project: 'my-project', - location: 'europe-west1', - vertexai: true, - }) + expect(mocks.constructorSpy).toHaveBeenCalledExactlyOnceWith( + 'text', + { + project: 'my-project', + location: 'europe-west1', + vertexai: true, + }, + 'gemini-3.7-flash', + ) }) it('builds summarize, image, embedding, speech, audio, and video adapters', () => { @@ -66,13 +83,42 @@ describe('vertex factories', () => { expect(vertexAudio('lyria-3-pro-preview', auth).name).toBe('gemini') expect(vertexVideo('veo-3.1-generate-preview', auth).name).toBe('gemini') - expect(mocks.constructorSpy).toHaveBeenCalledTimes(6) - for (const call of mocks.constructorSpy.mock.calls) { - expect(call[0]).toMatchObject({ - project: 'my-project', - location: 'europe-west1', - vertexai: true, - }) - } + expect(mocks.constructorSpy.mock.calls).toEqual([ + [ + 'text', + { project: 'my-project', location: 'europe-west1', vertexai: true }, + 'gemini-3.7-flash', + ], + [ + 'image', + { project: 'my-project', location: 'europe-west1', vertexai: true }, + 'gemini-3.1-flash-image', + ], + [ + 'embedding', + { project: 'my-project', location: 'europe-west1', vertexai: true }, + 'gemini-embedding-001', + ], + [ + 'speech', + { project: 'my-project', location: 'europe-west1', vertexai: true }, + 'gemini-3.1-flash-tts-preview', + ], + [ + 'audio', + { project: 'my-project', location: 'europe-west1', vertexai: true }, + 'lyria-3-pro-preview', + ], + [ + 'video', + { + project: 'my-project', + location: 'europe-west1', + vertexai: true, + allowUrlFetch: undefined, + }, + 'veo-3.1-generate-preview', + ], + ]) }) }) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index b529405795..3a0b698ac8 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -204,11 +204,11 @@ importers: specifier: workspace:* version: link:../../packages/ai-sandbox-local-process '@tanstack/react-router': - specifier: ^1.158.4 - version: 1.159.5(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + specifier: ^1.170.32 + version: 1.170.32(react-dom@19.2.3(react@19.2.3))(react@19.2.3) '@tanstack/react-start': - specifier: ^1.159.0 - version: 1.159.5(crossws@0.4.6(srvx@0.11.17))(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(vite-plugin-solid@2.11.14(solid-js@1.9.10)(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)))(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)) + specifier: ^1.168.49 + version: 1.168.49(crossws@0.4.6(srvx@0.11.17))(esbuild@0.28.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(rolldown@1.2.4)(rollup@4.60.1)(vite-plugin-solid@2.11.14(solid-js@1.9.10)(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)))(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)) lucide-react: specifier: ^0.561.0 version: 0.561.0(react@19.2.3) @@ -244,8 +244,8 @@ importers: specifier: ^4.1.18 version: 4.1.18(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)) '@tanstack/router-plugin': - specifier: ^1.158.4 - version: 1.159.5(@tanstack/react-router@1.159.5(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(supports-color@7.2.0)(vite-plugin-solid@2.11.14(solid-js@1.9.10)(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)))(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)) + specifier: ^1.168.35 + version: 1.168.35(@tanstack/react-router@1.170.32(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(esbuild@0.28.1)(rolldown@1.2.4)(rollup@4.60.1)(vite-plugin-solid@2.11.14(solid-js@1.9.10)(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)))(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)) '@types/node': specifier: ^24.10.1 version: 24.10.3 @@ -292,11 +292,11 @@ importers: specifier: workspace:* version: link:../../packages/ai-sandbox-docker '@tanstack/react-router': - specifier: ^1.158.4 - version: 1.159.5(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + specifier: ^1.170.32 + version: 1.170.32(react-dom@19.2.3(react@19.2.3))(react@19.2.3) '@tanstack/react-start': - specifier: ^1.159.0 - version: 1.159.5(crossws@0.4.6(srvx@0.11.17))(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(vite-plugin-solid@2.11.14(solid-js@1.9.10)(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)))(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)) + specifier: ^1.168.49 + version: 1.168.49(crossws@0.4.6(srvx@0.11.17))(esbuild@0.28.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(rolldown@1.2.4)(rollup@4.60.1)(vite-plugin-solid@2.11.14(solid-js@1.9.10)(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)))(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)) lucide-react: specifier: ^0.561.0 version: 0.561.0(react@19.2.3) @@ -329,8 +329,8 @@ importers: specifier: ^4.1.18 version: 4.1.18(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)) '@tanstack/router-plugin': - specifier: ^1.158.4 - version: 1.159.5(@tanstack/react-router@1.159.5(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(supports-color@7.2.0)(vite-plugin-solid@2.11.14(solid-js@1.9.10)(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)))(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)) + specifier: ^1.168.35 + version: 1.168.35(@tanstack/react-router@1.170.32(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(esbuild@0.28.1)(rolldown@1.2.4)(rollup@4.60.1)(vite-plugin-solid@2.11.14(solid-js@1.9.10)(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)))(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)) '@types/node': specifier: ^24.10.1 version: 24.10.3 @@ -480,14 +480,14 @@ importers: specifier: workspace:* version: link:../../packages/ai-react '@tanstack/react-router': - specifier: ^1.158.4 - version: 1.159.5(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + specifier: ^1.170.32 + version: 1.170.32(react-dom@19.2.3(react@19.2.3))(react@19.2.3) '@tanstack/react-start': - specifier: ^1.159.0 - version: 1.159.5(crossws@0.4.6(srvx@0.11.17))(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(vite-plugin-solid@2.11.14(solid-js@1.9.10)(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)))(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)) + specifier: ^1.168.49 + version: 1.168.49(crossws@0.4.6(srvx@0.11.17))(esbuild@0.28.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(rolldown@1.2.4)(rollup@4.60.1)(vite-plugin-solid@2.11.14(solid-js@1.9.10)(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)))(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)) '@tanstack/router-plugin': - specifier: ^1.158.4 - version: 1.159.5(@tanstack/react-router@1.159.5(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(supports-color@7.2.0)(vite-plugin-solid@2.11.14(solid-js@1.9.10)(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)))(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)) + specifier: ^1.168.35 + version: 1.168.35(@tanstack/react-router@1.170.32(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(esbuild@0.28.1)(rolldown@1.2.4)(rollup@4.60.1)(vite-plugin-solid@2.11.14(solid-js@1.9.10)(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)))(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)) '@tanstack/store': specifier: ^0.11.1 version: 0.11.1 @@ -589,17 +589,17 @@ importers: specifier: ^0.9.10 version: 0.9.10(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(csstype@3.2.3)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(solid-js@1.9.10) '@tanstack/react-router': - specifier: ^1.158.4 - version: 1.159.5(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + specifier: ^1.170.32 + version: 1.170.32(react-dom@19.2.3(react@19.2.3))(react@19.2.3) '@tanstack/react-router-devtools': - specifier: ^1.158.4 - version: 1.159.5(@tanstack/react-router@1.159.5(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(@tanstack/router-core@1.159.4)(csstype@3.2.3)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + specifier: ^1.167.1 + version: 1.167.1(@tanstack/react-router@1.170.32(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(@tanstack/router-core@1.171.27)(csstype@3.2.3)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) '@tanstack/react-start': - specifier: ^1.159.0 - version: 1.159.5(crossws@0.4.6(srvx@0.11.17))(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(vite-plugin-solid@2.11.14(solid-js@1.9.10)(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)))(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)) + specifier: ^1.168.49 + version: 1.168.49(crossws@0.4.6(srvx@0.11.17))(esbuild@0.28.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(rolldown@1.2.4)(rollup@4.60.1)(vite-plugin-solid@2.11.14(solid-js@1.9.10)(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)))(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)) '@tanstack/router-plugin': - specifier: ^1.158.4 - version: 1.159.5(@tanstack/react-router@1.159.5(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(supports-color@7.2.0)(vite-plugin-solid@2.11.14(solid-js@1.9.10)(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)))(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)) + specifier: ^1.168.35 + version: 1.168.35(@tanstack/react-router@1.170.32(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(esbuild@0.28.1)(rolldown@1.2.4)(rollup@4.60.1)(vite-plugin-solid@2.11.14(solid-js@1.9.10)(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)))(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)) capnweb: specifier: ^0.10.0 version: 0.10.0 @@ -773,23 +773,23 @@ importers: specifier: ^0.9.10 version: 0.9.10(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(csstype@3.2.3)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(solid-js@1.9.10) '@tanstack/react-router': - specifier: ^1.158.4 - version: 1.159.5(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + specifier: ^1.170.32 + version: 1.170.32(react-dom@19.2.3(react@19.2.3))(react@19.2.3) '@tanstack/react-router-devtools': - specifier: ^1.158.4 - version: 1.159.5(@tanstack/react-router@1.159.5(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(@tanstack/router-core@1.159.4)(csstype@3.2.3)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + specifier: ^1.167.1 + version: 1.167.1(@tanstack/react-router@1.170.32(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(@tanstack/router-core@1.171.27)(csstype@3.2.3)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) '@tanstack/react-router-ssr-query': - specifier: ^1.158.4 - version: 1.159.5(@tanstack/query-core@5.90.12)(@tanstack/react-query@5.90.12(react@19.2.3))(@tanstack/react-router@1.159.5(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(@tanstack/router-core@1.159.4)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + specifier: ^1.167.1 + version: 1.167.1(@tanstack/query-core@5.90.12)(@tanstack/react-query@5.90.12(react@19.2.3))(@tanstack/react-router@1.170.32(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(@tanstack/router-core@1.171.27)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) '@tanstack/react-start': - specifier: ^1.159.0 - version: 1.159.5(crossws@0.4.6(srvx@0.11.17))(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(vite-plugin-solid@2.11.14(solid-js@1.9.10)(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)))(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)) + specifier: ^1.168.49 + version: 1.168.49(crossws@0.4.6(srvx@0.11.17))(esbuild@0.28.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(rolldown@1.2.4)(rollup@4.60.1)(vite-plugin-solid@2.11.14(solid-js@1.9.10)(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)))(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)) '@tanstack/react-store': - specifier: ^0.8.0 - version: 0.8.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + specifier: ^0.11.1 + version: 0.11.1(react-dom@19.2.3(react@19.2.3))(react@19.2.3) '@tanstack/router-plugin': - specifier: ^1.158.4 - version: 1.159.5(@tanstack/react-router@1.159.5(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(supports-color@7.2.0)(vite-plugin-solid@2.11.14(solid-js@1.9.10)(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)))(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)) + specifier: ^1.168.35 + version: 1.168.35(@tanstack/react-router@1.170.32(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(esbuild@0.28.1)(rolldown@1.2.4)(rollup@4.60.1)(vite-plugin-solid@2.11.14(solid-js@1.9.10)(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)))(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)) '@tanstack/store': specifier: ^0.11.1 version: 0.11.1 @@ -909,14 +909,14 @@ importers: specifier: workspace:* version: link:../../packages/ai-react '@tanstack/react-router': - specifier: ^1.158.4 - version: 1.159.5(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + specifier: ^1.170.32 + version: 1.170.32(react-dom@19.2.3(react@19.2.3))(react@19.2.3) '@tanstack/react-start': - specifier: ^1.159.0 - version: 1.159.5(crossws@0.4.6(srvx@0.11.17))(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(vite-plugin-solid@2.11.14(solid-js@1.9.10)(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)))(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)) + specifier: ^1.168.49 + version: 1.168.49(crossws@0.4.6(srvx@0.11.17))(esbuild@0.28.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(rolldown@1.2.4)(rollup@4.60.1)(vite-plugin-solid@2.11.14(solid-js@1.9.10)(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)))(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)) '@tanstack/router-plugin': - specifier: ^1.158.4 - version: 1.159.5(@tanstack/react-router@1.159.5(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(supports-color@7.2.0)(vite-plugin-solid@2.11.14(solid-js@1.9.10)(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)))(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)) + specifier: ^1.168.35 + version: 1.168.35(@tanstack/react-router@1.170.32(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(esbuild@0.28.1)(rolldown@1.2.4)(rollup@4.60.1)(vite-plugin-solid@2.11.14(solid-js@1.9.10)(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)))(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)) lucide-react: specifier: ^0.561.0 version: 0.561.0(react@19.2.3) @@ -1013,14 +1013,14 @@ importers: specifier: workspace:* version: link:../../packages/ai-openrouter '@tanstack/react-router': - specifier: ^1.158.4 - version: 1.159.5(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + specifier: ^1.170.32 + version: 1.170.32(react-dom@19.2.3(react@19.2.3))(react@19.2.3) '@tanstack/react-start': - specifier: ^1.159.0 - version: 1.159.5(crossws@0.4.6(srvx@0.11.17))(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(vite-plugin-solid@2.11.14(solid-js@1.9.10)(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)))(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)) + specifier: ^1.168.49 + version: 1.168.49(crossws@0.4.6(srvx@0.11.17))(esbuild@0.28.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(rolldown@1.2.4)(rollup@4.60.1)(vite-plugin-solid@2.11.14(solid-js@1.9.10)(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)))(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)) '@tanstack/router-plugin': - specifier: ^1.158.4 - version: 1.159.5(@tanstack/react-router@1.159.5(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(supports-color@7.2.0)(vite-plugin-solid@2.11.14(solid-js@1.9.10)(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)))(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)) + specifier: ^1.168.35 + version: 1.168.35(@tanstack/react-router@1.170.32(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(esbuild@0.28.1)(rolldown@1.2.4)(rollup@4.60.1)(vite-plugin-solid@2.11.14(solid-js@1.9.10)(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)))(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)) lucide-react: specifier: ^0.561.0 version: 0.561.0(react@19.2.3) @@ -1086,23 +1086,23 @@ importers: specifier: ^5.90.12 version: 5.90.12(react@19.2.3) '@tanstack/react-router': - specifier: ^1.158.4 - version: 1.159.5(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + specifier: ^1.170.32 + version: 1.170.32(react-dom@19.2.3(react@19.2.3))(react@19.2.3) '@tanstack/react-router-devtools': - specifier: ^1.158.4 - version: 1.159.5(@tanstack/react-router@1.159.5(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(@tanstack/router-core@1.159.4)(csstype@3.2.3)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + specifier: ^1.167.1 + version: 1.167.1(@tanstack/react-router@1.170.32(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(@tanstack/router-core@1.171.27)(csstype@3.2.3)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) '@tanstack/react-router-ssr-query': - specifier: ^1.158.4 - version: 1.159.5(@tanstack/query-core@5.90.12)(@tanstack/react-query@5.90.12(react@19.2.3))(@tanstack/react-router@1.159.5(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(@tanstack/router-core@1.159.4)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + specifier: ^1.167.1 + version: 1.167.1(@tanstack/query-core@5.90.12)(@tanstack/react-query@5.90.12(react@19.2.3))(@tanstack/react-router@1.170.32(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(@tanstack/router-core@1.171.27)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) '@tanstack/react-start': - specifier: ^1.159.0 - version: 1.159.5(crossws@0.4.6(srvx@0.11.17))(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(vite-plugin-solid@2.11.14(solid-js@1.9.10)(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)))(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)) + specifier: ^1.168.49 + version: 1.168.49(crossws@0.4.6(srvx@0.11.17))(esbuild@0.28.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(rolldown@1.2.4)(rollup@4.60.1)(vite-plugin-solid@2.11.14(solid-js@1.9.10)(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)))(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)) '@tanstack/router-plugin': - specifier: ^1.158.4 - version: 1.159.5(@tanstack/react-router@1.159.5(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(supports-color@7.2.0)(vite-plugin-solid@2.11.14(solid-js@1.9.10)(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)))(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)) + specifier: ^1.168.35 + version: 1.168.35(@tanstack/react-router@1.170.32(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(esbuild@0.28.1)(rolldown@1.2.4)(rollup@4.60.1)(vite-plugin-solid@2.11.14(solid-js@1.9.10)(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)))(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)) '@tanstack/zod-adapter': specifier: ^1.140.1 - version: 1.166.9(@tanstack/react-router@1.159.5(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(zod@4.3.6) + version: 1.166.9(@tanstack/react-router@1.170.32(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(zod@4.3.6) class-variance-authority: specifier: ^0.7.1 version: 0.7.1 @@ -1338,8 +1338,8 @@ importers: specifier: ^1.155.0 version: 1.155.0(@electric-sql/pglite@0.4.3)(aws4fetch@1.0.20)(better-sqlite3@12.11.1)(drizzle-orm@0.45.2(@cloudflare/workers-types@4.20260317.1)(@electric-sql/pglite@0.4.3)(@opentelemetry/api@1.9.1)(@prisma/client@7.9.0(prisma@7.9.0(@types/react@19.2.18)(better-sqlite3@12.11.1)(magicast@0.5.2)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(typescript@5.9.3))(typescript@5.9.3))(better-sqlite3@12.11.1)(bun-types@1.3.14)(mysql2@3.15.3)(postgres@3.4.7)(prisma@7.9.0(@types/react@19.2.18)(better-sqlite3@12.11.1)(magicast@0.5.2)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(typescript@5.9.3)))(mysql2@3.15.3)(rolldown@1.1.5)(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)) '@tanstack/router-plugin': - specifier: ^1.158.4 - version: 1.159.5(@tanstack/react-router@1.159.5(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(supports-color@7.2.0)(vite-plugin-solid@2.11.14(solid-js@1.9.10)(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)))(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)) + specifier: ^1.168.35 + version: 1.168.35(@tanstack/react-router@1.170.32(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(esbuild@0.28.1)(rolldown@1.2.4)(rollup@4.60.1)(vite-plugin-solid@2.11.14(solid-js@1.9.10)(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)))(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)) '@tanstack/solid-ai-devtools': specifier: workspace:* version: link:../../packages/solid-ai-devtools @@ -1347,17 +1347,17 @@ importers: specifier: ^0.7.15 version: 0.7.17(csstype@3.2.3)(solid-js@1.9.10) '@tanstack/solid-router': - specifier: ^1.139.10 - version: 1.141.1(solid-js@1.9.10) + specifier: ^1.170.30 + version: 1.170.30(solid-js@1.9.10) '@tanstack/solid-router-devtools': - specifier: ^1.139.10 - version: 1.141.1(@tanstack/router-core@1.159.4)(@tanstack/solid-router@1.141.1(solid-js@1.9.10))(csstype@3.2.3)(solid-js@1.9.10) + specifier: ^1.167.1 + version: 1.167.1(@tanstack/router-core@1.171.27)(@tanstack/solid-router@1.170.30(solid-js@1.9.10))(csstype@3.2.3)(solid-js@1.9.10) '@tanstack/solid-router-ssr-query': - specifier: ^1.139.10 - version: 1.141.1(@tanstack/query-core@5.90.12)(@tanstack/router-core@1.159.4)(@tanstack/solid-query@5.90.15(solid-js@1.9.10))(@tanstack/solid-router@1.141.1(solid-js@1.9.10))(eslint@9.39.4(jiti@2.7.0))(solid-js@1.9.10)(supports-color@7.2.0)(typescript@5.9.3) + specifier: ^1.167.1 + version: 1.167.1(@tanstack/query-core@5.90.12)(@tanstack/router-core@1.171.27)(@tanstack/solid-query@5.90.15(solid-js@1.9.10))(@tanstack/solid-router@1.170.30(solid-js@1.9.10))(solid-js@1.9.10) '@tanstack/solid-start': - specifier: ^1.139.10 - version: 1.141.1(@tanstack/react-router@1.159.5(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(crossws@0.4.6(srvx@0.11.17))(solid-js@1.9.10)(vite-plugin-solid@2.11.14(solid-js@1.9.10)(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)))(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)) + specifier: ^1.168.47 + version: 1.168.47(@tanstack/react-router@1.170.32(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(crossws@0.4.6(srvx@0.11.17))(esbuild@0.28.1)(rolldown@1.2.4)(rollup@4.60.1)(solid-js@1.9.10)(vite-plugin-solid@2.11.14(solid-js@1.9.10)(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)))(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)) '@tanstack/solid-store': specifier: ^0.8.0 version: 0.8.0(solid-js@1.9.10) @@ -2913,9 +2913,6 @@ importers: specifier: workspace:^ version: link:../ai-gemini devDependencies: - '@google/genai': - specifier: ^2.10.0 - version: 2.10.0(@modelcontextprotocol/sdk@1.29.0(zod@4.3.6)) '@tanstack/ai': specifier: workspace:* version: link:../ai @@ -3206,11 +3203,11 @@ importers: specifier: workspace:* version: link:../../packages/react-ai-devtools '@tanstack/react-router': - specifier: ^1.158.4 - version: 1.159.5(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + specifier: ^1.170.32 + version: 1.170.32(react-dom@19.2.3(react@19.2.3))(react@19.2.3) '@tanstack/react-start': - specifier: ^1.159.0 - version: 1.159.5(crossws@0.4.6(srvx@0.11.17))(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(vite-plugin-solid@2.11.14(solid-js@1.9.10)(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)))(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)) + specifier: ^1.168.49 + version: 1.168.49(crossws@0.4.6(srvx@0.11.17))(esbuild@0.28.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(rolldown@1.2.4)(rollup@4.60.1)(vite-plugin-solid@2.11.14(solid-js@1.9.10)(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)))(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)) arktype: specifier: ^2.1.28 version: 2.2.0 @@ -3330,11 +3327,11 @@ importers: specifier: ^0.9.10 version: 0.9.10(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(csstype@3.2.3)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(solid-js@1.9.10) '@tanstack/react-router': - specifier: ^1.158.4 - version: 1.159.5(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + specifier: ^1.170.32 + version: 1.170.32(react-dom@19.2.3(react@19.2.3))(react@19.2.3) '@tanstack/react-start': - specifier: ^1.159.0 - version: 1.159.5(crossws@0.4.6(srvx@0.11.17))(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(vite-plugin-solid@2.11.14(solid-js@1.9.10)(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)))(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)) + specifier: ^1.168.49 + version: 1.168.49(crossws@0.4.6(srvx@0.11.17))(esbuild@0.28.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(rolldown@1.2.4)(rollup@4.60.1)(vite-plugin-solid@2.11.14(solid-js@1.9.10)(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)))(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)) '@tanstack/start': specifier: ^1.120.20 version: 1.120.20(340eefabdbae5b0c948fd6f8943277d1) @@ -4264,10 +4261,6 @@ packages: resolution: {integrity: sha512-JiDShH45zKHWyGe4ZNVRrCjBz8Nh9TMmZG1kh4QTK8hCBTWBi8Da+i7s1fJw7/lYpM4ccepSNfqzZ/QvABBi5g==} engines: {node: '>=6.9.0'} - '@babel/template@7.27.2': - resolution: {integrity: sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw==} - engines: {node: '>=6.9.0'} - '@babel/template@7.29.7': resolution: {integrity: sha512-puq+Gf35oI24FeN11LkoUQFqv9uwNeWpxXZi/Ji3rRIoKAzKnxRaZ+Gkj0vKS9ZCiTESfng1N9LyOyXvo+m+Gg==} engines: {node: '>=6.9.0'} @@ -4284,10 +4277,6 @@ packages: resolution: {integrity: sha512-EhlfNQtZ+NK22w5BM61ciuiq1m58ed33Wr1Xan//ZRTy6hgjnwyCffRYwzsGXdASJSUJ1guZILsErh1eQcl+zw==} engines: {node: '>=6.9.0'} - '@babel/types@7.28.5': - resolution: {integrity: sha512-qQ5m48eI/MFLQ5PxQj4PFaprjyCTLI37ElWMmNs0K8Lk3dVeOdNpB3ks8jc7yM5CDmVC73eMVk/trk3fgmrUpA==} - engines: {node: '>=6.9.0'} - '@babel/types@7.29.0': resolution: {integrity: sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A==} engines: {node: '>=6.9.0'} @@ -6114,9 +6103,6 @@ packages: resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} engines: {node: '>= 8'} - '@nothing-but/utils@0.17.0': - resolution: {integrity: sha512-TuCHcHLOqDL0SnaAxACfuRHBNRgNJcNn9X0GiH5H3YSDBVquCr3qEIG3FOQAuMyZCbu9w8nk2CHhOsn7IvhIwQ==} - '@nx/nx-darwin-arm64@23.1.1': resolution: {integrity: sha512-Rq/RXLX5uIvJQfb6kuUgEirquT5ARaAgQyNaMZVnOPAL5wuxaDvQag8WX/WUCIgbUKZuGkclJwM7Vlnvtn3bdg==} cpu: [arm64] @@ -8839,9 +8825,6 @@ packages: '@rolldown/pluginutils@1.0.0-beta.27': resolution: {integrity: sha512-+d0F4MKMCbeVUJwG96uQ4SgAznZNSq93I3V+9NHA4OpvqG8mRCpGdKmK8l/dl02h2CCDHwW2FqilnTyDcAnqjA==} - '@rolldown/pluginutils@1.0.0-beta.40': - resolution: {integrity: sha512-s3GeJKSQOwBlzdUrj4ISjJj5SfSh+aqn0wjOar4Bx95iV1ETI7F6S/5hLcfAxZ9kXDcyrAkxPlqmd1ZITttf+w==} - '@rolldown/pluginutils@1.0.0-beta.53': resolution: {integrity: sha512-vENRlFU4YbrwVqNDZ7fLvy+JR1CRkyr01jhSiDpE1u6py3OMzQfztQU2jxykW3ALNxO4kSlqIDeYyD0Y9RcQeQ==} @@ -9291,26 +9274,6 @@ packages: resolution: {integrity: sha512-R8Rdn8Hy72KKcebgLiv8jQcQkXoLMOGGv5uI1/k0l+snqkOzQ1R0ChUBCxWMlBsFMekWjq0wRudIweFs7sKT5A==} engines: {node: '>=14.0.0'} - '@solid-devtools/debugger@0.28.1': - resolution: {integrity: sha512-6qIUI6VYkXoRnL8oF5bvh2KgH71qlJ18hNw/mwSyY6v48eb80ZR48/5PDXufUa3q+MBSuYa1uqTMwLewpay9eg==} - peerDependencies: - solid-js: ^1.9.0 - - '@solid-devtools/logger@0.9.11': - resolution: {integrity: sha512-THbiY1iQlieL6vdgJc4FIsLe7V8a57hod/Thm8zdKrTkWL88UPZjkBBfM+mVNGusd4OCnAN20tIFBhNnuT1Dew==} - peerDependencies: - solid-js: ^1.9.0 - - '@solid-devtools/shared@0.20.0': - resolution: {integrity: sha512-o5TACmUOQsxpzpOKCjbQqGk8wL8PMi+frXG9WNu4Lh3PQVUB6hs95Kl/S8xc++zwcMguUKZJn8h5URUiMOca6Q==} - peerDependencies: - solid-js: ^1.9.0 - - '@solid-primitives/bounds@0.1.3': - resolution: {integrity: sha512-UbiyKMdSPmtijcEDnYLQL3zzaejpwWDAJJ4Gt5P0hgVs6A72piov0GyNw7V2SroH7NZFwxlYS22YmOr8A5xc1Q==} - peerDependencies: - solid-js: ^1.6.12 - '@solid-primitives/event-listener@2.4.3': resolution: {integrity: sha512-h4VqkYFv6Gf+L7SQj+Y6puigL/5DIi7x5q07VZET7AWcS+9/G3WfIE9WheniHWJs51OEkRB43w6lDys5YeFceg==} peerDependencies: @@ -9321,11 +9284,6 @@ packages: peerDependencies: solid-js: ^1.6.12 - '@solid-primitives/media@2.3.3': - resolution: {integrity: sha512-hQ4hLOGvfbugQi5Eu1BFWAIJGIAzztq9x0h02xgBGl2l0Jaa3h7tg6bz5tV1NSuNYVGio4rPoa7zVQQLkkx9dA==} - peerDependencies: - solid-js: ^1.6.12 - '@solid-primitives/refs@1.1.2': resolution: {integrity: sha512-K7tf2thy7L+YJjdqXspXOg5xvNEOH8tgEWsp0+1mQk3obHBRD6hEjYZk7p7FlJphSZImS35je3UfmWuD7MhDfg==} peerDependencies: @@ -9341,21 +9299,11 @@ packages: peerDependencies: solid-js: ^1.6.12 - '@solid-primitives/scheduled@1.5.2': - resolution: {integrity: sha512-/j2igE0xyNaHhj6kMfcUQn5rAVSTLbAX+CDEBm25hSNBmNiHLu2lM7Usj2kJJ5j36D67bE8wR1hBNA8hjtvsQA==} - peerDependencies: - solid-js: ^1.6.12 - '@solid-primitives/static-store@0.1.2': resolution: {integrity: sha512-ReK+5O38lJ7fT+L6mUFvUr6igFwHBESZF+2Ug842s7fvlVeBdIVEdTCErygff6w7uR6+jrr7J8jQo+cYrEq4Iw==} peerDependencies: solid-js: ^1.6.12 - '@solid-primitives/styles@0.1.2': - resolution: {integrity: sha512-7iX5K+J5b1PRrbgw3Ki92uvU2LgQ0Kd/QMsrAZxDg5dpUBwMyTijZkA3bbs1ikZsT1oQhS41bTyKbjrXeU0Awg==} - peerDependencies: - solid-js: ^1.6.12 - '@solid-primitives/utils@6.3.2': resolution: {integrity: sha512-hZ/M/qr25QOCcwDPOHtGjxTD8w2mNyVAYvcfgwzBHq2RwNqHNdDNsMZYap20+ruRwW4A3Cdkczyoz0TSxLCAPQ==} peerDependencies: @@ -9647,6 +9595,10 @@ packages: resolution: {integrity: sha512-xyIfof8eHBuub1CkBnbKNKQXeRZC4dClhmzePHVOEel4G7lk/dW+TQ16da7CFdeNLv6u6Owf5VoBQxoo6DFTSA==} engines: {node: '>=12'} + '@tanstack/history@1.162.1': + resolution: {integrity: sha512-DR9t6lfLVdrjgCwpglrR9DR7Ok8/HlXjcOE+goWXF3zyuLUO/ug7vMbSFxTqrQTtbRghJfyhmIZ0S6LhPIy44w==} + engines: {node: '>=20.19'} + '@tanstack/nitro-v2-vite-plugin@1.155.0': resolution: {integrity: sha512-iW9S2c4QxlT+WgKVT+Mw8hzvLqyVSg4UefzX74LX5dfUxbGDahxZItp+07JSD5Ok8ZdTlUHzwLnIsncXh/MNAQ==} engines: {node: '>=22.12'} @@ -9685,21 +9637,21 @@ packages: peerDependencies: react: ^18 || ^19 - '@tanstack/react-router-devtools@1.159.5': - resolution: {integrity: sha512-IIyomu+ypWTxyoYT32mxamVmdTs7ZCGcTbdj7HVvtD3xp1lvo/bwRXj9oERENmb+OAPOaWF2doRYC/pmKjK5vg==} - engines: {node: '>=12'} + '@tanstack/react-router-devtools@1.167.1': + resolution: {integrity: sha512-pjfGrmjj4d7naEPM7oshqFfwBoxDPNo/UxltlHH5ePbHsJ+plBhd+JaAewm1ueYOjZ0js9hckjWWDYXpCrSfKw==} + engines: {node: '>=20.19'} peerDependencies: - '@tanstack/react-router': ^1.159.5 - '@tanstack/router-core': ^1.159.4 + '@tanstack/react-router': ^1.170.19 + '@tanstack/router-core': ^1.171.16 react: '>=18.0.0 || >=19.0.0' react-dom: '>=18.0.0 || >=19.0.0' peerDependenciesMeta: '@tanstack/router-core': optional: true - '@tanstack/react-router-ssr-query@1.159.5': - resolution: {integrity: sha512-r/Um9DASjmaTdiyXA3cpooGLrSD1BlcXUNsRz4zAlvD38m0gIFvaykOM2Naztqm9H+2CJkocRZp2/kR69Xcmyg==} - engines: {node: '>=12'} + '@tanstack/react-router-ssr-query@1.167.1': + resolution: {integrity: sha512-W9j5JPnBikyafvuUfykFfHIWod58OAbAAa5leNkXBcoDoocghMmu6w9uZOmUZvAWT7CSvgj5tBUtF7CM2OoHXQ==} + engines: {node: '>=20.19'} peerDependencies: '@tanstack/query-core': '>=5.90.0' '@tanstack/react-query': '>=5.90.0' @@ -9714,9 +9666,9 @@ packages: react: '>=18.0.0 || >=19.0.0' react-dom: '>=18.0.0 || >=19.0.0' - '@tanstack/react-router@1.159.5': - resolution: {integrity: sha512-rVb0MtKzP5c0BkWIoFgWBiRAJHYSU3bhsEHbT0cRdRLmlJiw21Awb6VEjgYq3hJiEhowcKKm6J8AdRD/8oZ5dQ==} - engines: {node: '>=12'} + '@tanstack/react-router@1.170.32': + resolution: {integrity: sha512-SIpxvaTKco100a5ZR3ePmArbhtm3XOx+w1dpGYY9gxHDta4iXSKDdQuhLonwJbIMkVJsU1rwXf0UDHMrF/1snw==} + engines: {node: '>=20.19'} peerDependencies: react: '>=18.0.0 || >=19.0.0' react-dom: '>=18.0.0 || >=19.0.0' @@ -9728,8 +9680,8 @@ packages: react: '>=18.0.0 || >=19.0.0' react-dom: '>=18.0.0 || >=19.0.0' - '@tanstack/react-start-client@1.159.5': - resolution: {integrity: sha512-Qynx7XWHI1rhVpSUx6P40zazcQVJRhl2fnAcSH0I6vaAxSuZm8lvI37YacXPRu8flvI/ZGlF095arxiyps+A0w==} + '@tanstack/react-start-client@1.168.30': + resolution: {integrity: sha512-qsZuykUl1EF0/rc1bin1RtjFzz07YMOTBzhOstSDzbOVm/WKf1QKFTN+qAZi74xlbXSWNuT2MiFRyg4RKwj8iw==} engines: {node: '>=22.12.0'} peerDependencies: react: '>=18.0.0 || >=19.0.0' @@ -9746,6 +9698,23 @@ packages: resolution: {integrity: sha512-z+4YL6shTtsHjk32yaIemQwgkx6FcqwPBYfeNt7Co2eOpWrvsoo/Fe9869/oIY2sPyhiWDs1rDb3e0qnAy8Cag==} engines: {node: '>=12'} + '@tanstack/react-start-rsc@0.1.48': + resolution: {integrity: sha512-UglRdTMuF3c4dvzL/gh4dMVbMWHsPy8ZgTQdT2qpTlyt1b/3m+R40tBFdsfTgw76VTXivW+qV/ih0PN9000XTw==} + engines: {node: '>=22.12.0'} + peerDependencies: + '@rspack/core': '>=2.0.0-0' + '@vitejs/plugin-rsc': '>=0.5.30' + react: '>=18.0.0 || >=19.0.0' + react-dom: '>=18.0.0 || >=19.0.0' + react-server-dom-rspack: '>=0.0.2' + peerDependenciesMeta: + '@rspack/core': + optional: true + '@vitejs/plugin-rsc': + optional: true + react-server-dom-rspack: + optional: true + '@tanstack/react-start-server@1.141.1': resolution: {integrity: sha512-GsZ7De5CCDkKcrimvwJiYJHMFGw7LQRu8IuLvqyzYgQvJPcbkfY5UIQd2IZfgRNFegzb2aYzkAXwv5lxfdu1VQ==} engines: {node: '>=22.12.0'} @@ -9753,20 +9722,35 @@ packages: react: '>=18.0.0 || >=19.0.0' react-dom: '>=18.0.0 || >=19.0.0' - '@tanstack/react-start-server@1.159.5': - resolution: {integrity: sha512-X4/SunwDTEbGkYTfM0gR+79amfk6phAM+2+NlC2s7TX2cD51xE8bUz2a//RxfOh9xg8f0f2CRIO34xTEDHGTfQ==} + '@tanstack/react-start-server@1.167.37': + resolution: {integrity: sha512-cODHpFU8vIm7AdHii9W3NEuwyruNmT5wLDZjRsJLT9Jp+7FACnfJrRbvxnp1ldSv/9mxcHKi/OgwbdHQeMZcAQ==} engines: {node: '>=22.12.0'} peerDependencies: react: '>=18.0.0 || >=19.0.0' react-dom: '>=18.0.0 || >=19.0.0' - '@tanstack/react-start@1.159.5': - resolution: {integrity: sha512-vfnF7eYswAK54ru6Ay08nb0TXVzTBaVRsbbRW7hx2M0chgwtSx+YScYzoixqkccRARQBN8a/CeVq7vNFW8525w==} + '@tanstack/react-start@1.168.49': + resolution: {integrity: sha512-iQb1ZoEHqvZMGLR4G7v3tTtgL06yv/bwxvGP3waVHxVn7bRpyopM44YbOluaGkcJzc13ZTvdLKWYNAN3bxMX/Q==} engines: {node: '>=22.12.0'} peerDependencies: + '@rsbuild/core': ^2.0.0 + '@vitejs/plugin-rsc': '*' react: '>=18.0.0 || >=19.0.0' react-dom: '>=18.0.0 || >=19.0.0' vite: '>=7.0.0' + peerDependenciesMeta: + '@rsbuild/core': + optional: true + '@vitejs/plugin-rsc': + optional: true + vite: + optional: true + + '@tanstack/react-store@0.11.1': + resolution: {integrity: sha512-HaIGKI3YLmjBYIvy5DFDY23oNaYZIsTZfngey07Uh5iLVJgM3bIGCnZeOFOqzjFld9JHWcaHJnasD/bKoGKwJQ==} + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 '@tanstack/react-store@0.8.0': resolution: {integrity: sha512-1vG9beLIuB7q69skxK9r5xiLN3ztzIPfSQSs0GfeqWGO2tGIyInZx0x1COhpx97RKaONSoAb8C3dxacWksm1ow==} @@ -9774,6 +9758,12 @@ packages: react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + '@tanstack/react-store@0.9.3': + resolution: {integrity: sha512-y2iHd/N9OkoQbFJLUX1T9vbc2O9tjH0pQRgTcx1/Nz4IlwLvkgpuglXUx+mXt0g5ZDFrEeDnONPqkbfxXJKwRg==} + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + '@tanstack/router-core@1.131.50': resolution: {integrity: sha512-eojd4JZ5ziUhGEmXZ4CaVX5mQdiTMiz56Sp8ZQ6r7deb55Q+5G4JQDkeuXpI7HMAvzr+4qlsFeLaDRXXjXyOqQ==} engines: {node: '>=12'} @@ -9786,22 +9776,15 @@ packages: resolution: {integrity: sha512-MFzPH39ijNO83qJN3pe7x4iAlhZyqgao3sJIzv3SJ4Pnk12xMnzuDzIAQT/1WV6JolPQEcw0Wr4L5agF8yxoeg==} engines: {node: '>=12'} - '@tanstack/router-devtools-core@1.141.1': - resolution: {integrity: sha512-wD9yRvOk6FI+thiNBplhkGutPIPBlXvWu9ttU/obdFY5oXQj9WYgNS+IO9BEe8Pz5rNEu8zE/oLn4RUGIVdtnw==} - engines: {node: '>=12'} - peerDependencies: - '@tanstack/router-core': ^1.141.1 - csstype: ^3.0.10 - solid-js: '>=1.9.5' - peerDependenciesMeta: - csstype: - optional: true + '@tanstack/router-core@1.171.27': + resolution: {integrity: sha512-wDwSLvoLwIaNcnx9UNcN9Mb7Y8QwCYq1U1RQZwyN186gnkIoIYI2SOxy8VqH1vFigbkHkk4FmwMAQlghPgDK2g==} + engines: {node: '>=20.19'} - '@tanstack/router-devtools-core@1.159.4': - resolution: {integrity: sha512-qMUeIv+6n1mZOcO2raCIbdOeDeMpJEmgm6oMs/nWEG61lYrzJYaCcpBTviAX0nRhSiQSUCX9cHiosUEA0e2HAw==} - engines: {node: '>=12'} + '@tanstack/router-devtools-core@1.168.1': + resolution: {integrity: sha512-qr4voa4cpSMwQvS3867xkU3AB3MtJbTuovKIy+btjJ/Faju6er9w0nDylmD+005Mk/3YKw9/iueZJl2JAB7JOA==} + engines: {node: '>=20.19'} peerDependencies: - '@tanstack/router-core': ^1.159.4 + '@tanstack/router-core': ^1.171.16 csstype: ^3.0.10 peerDependenciesMeta: csstype: @@ -9811,14 +9794,14 @@ packages: resolution: {integrity: sha512-zlMBw5l88GIg3v+378JsfDYq3ejEaJmD3P1R+m0yEPxh0N//Id1FjKNSS7yJbejlK2WGVm9DUG46iBdTDMQM+Q==} engines: {node: '>=12'} - '@tanstack/router-generator@1.141.1': - resolution: {integrity: sha512-21RbVAoIDn7s/n/PKMN6U60d5hCeVADrBH/uN6B/poMT4MVYtJXqISVzkc2RAboVRw6eRdYFeF+YlwA3nF6y3Q==} - engines: {node: '>=12'} - '@tanstack/router-generator@1.159.4': resolution: {integrity: sha512-O8tICQoSuvK6vs3mvBdI3zVLFmYfj/AYDCX0a5msSADP/2S0GsgDDTB5ah731TqYCtjeNriaWz9iqst38cjF/Q==} engines: {node: '>=12'} + '@tanstack/router-generator@1.167.33': + resolution: {integrity: sha512-Z3lCWIPuRUMPmuI8Mm48x/s49TxmHOaFVZ52j1W1QKYrsFHyT6U/h9bqfHJDxfQ8kz7y9q+W1YPKZ15Ee7yuCA==} + engines: {node: '>=20.19'} + '@tanstack/router-plugin@1.131.50': resolution: {integrity: sha512-gdEBPGzx7llQNRnaqfPJ1iaPS3oqB8SlvKRG5l7Fxp4q4yINgkeowFYSKEhPOc9bjoNhGrIHOlvPTPXEzAQXzQ==} engines: {node: '>=12'} @@ -9840,12 +9823,12 @@ packages: webpack: optional: true - '@tanstack/router-plugin@1.141.1': - resolution: {integrity: sha512-SoNXm8QK8cqX1Q4y1AfLU0tZLOt4mB4wkdpBI/Mi3ZEezF8tIrmaenyJ3987cjT9jedTy3VDBab1wN0g8MoOXg==} + '@tanstack/router-plugin@1.159.5': + resolution: {integrity: sha512-i2LR3WRaBOAZ1Uab5QBG9UxZIRJ3V56JVu890NysbuX15rgzRiL5yLAbfenOHdhaHy2+4joX35VICAHuVWy7Og==} engines: {node: '>=12'} peerDependencies: '@rsbuild/core': '>=1.0.2' - '@tanstack/react-router': ^1.141.1 + '@tanstack/react-router': ^1.159.5 vite: '>=5.0.0 || >=6.0.0 || >=7.0.0' vite-plugin-solid: ^2.11.10 webpack: '>=5.92.0' @@ -9861,14 +9844,14 @@ packages: webpack: optional: true - '@tanstack/router-plugin@1.159.5': - resolution: {integrity: sha512-i2LR3WRaBOAZ1Uab5QBG9UxZIRJ3V56JVu890NysbuX15rgzRiL5yLAbfenOHdhaHy2+4joX35VICAHuVWy7Og==} - engines: {node: '>=12'} + '@tanstack/router-plugin@1.168.35': + resolution: {integrity: sha512-foDAZKFqHXae+oFbIgcsSvy2QCVRn7XdS3nhwcRvD+ed6JrKPUP/1lQMsZLJqWycgR1vkZF7gs955KGa0NZQ0w==} + engines: {node: '>=20.19'} peerDependencies: - '@rsbuild/core': '>=1.0.2' - '@tanstack/react-router': ^1.159.5 - vite: '>=5.0.0 || >=6.0.0 || >=7.0.0' - vite-plugin-solid: ^2.11.10 + '@rsbuild/core': '>=1.0.2 || ^2.0.0' + '@tanstack/react-router': ^1.170.32 + vite: '>=5.0.0 || >=6.0.0 || >=7.0.0 || >=8.0.0' + vite-plugin-solid: ^2.11.10 || ^3.0.0-0 webpack: '>=5.92.0' peerDependenciesMeta: '@rsbuild/core': @@ -9882,16 +9865,9 @@ packages: webpack: optional: true - '@tanstack/router-ssr-query-core@1.141.1': - resolution: {integrity: sha512-bkRXUhktifxBewnnphH59E0sGcsUI1NmNqxzCAmXIb93xYgafhjUGGYwfK6FqFBOmCB5isr32exGO3+UMHJr/A==} - engines: {node: '>=12'} - peerDependencies: - '@tanstack/query-core': '>=5.90.0' - '@tanstack/router-core': '>=1.127.0' - - '@tanstack/router-ssr-query-core@1.159.4': - resolution: {integrity: sha512-zqgJaf8iTk2ugrJqvU+b8NnFf3MKcnFaurtlp5tP38lNHQGW4En9UaOBOou/6zYZMlKQBcvqxSGJiwaLIyTK2g==} - engines: {node: '>=12'} + '@tanstack/router-ssr-query-core@1.169.1': + resolution: {integrity: sha512-rngux8s/3mPQzcjLYDLkNU31coYVyCgrVTfpdwqUdY5jIEHqGTXrO73DTkPR1PppwYUeVhmNCgl8TctRcnupjg==} + engines: {node: '>=20.19'} peerDependencies: '@tanstack/query-core': '>=5.90.0' '@tanstack/router-core': '>=1.127.0' @@ -9908,6 +9884,10 @@ packages: resolution: {integrity: sha512-qZ76eaLKU6Ae9iI/mc5zizBX149DXXZkBVVO3/QRIll79uKLJZHQlMKR++2ba7JsciBWz1pgpIBcCJPE9S0LVg==} engines: {node: '>=12'} + '@tanstack/router-utils@1.162.2': + resolution: {integrity: sha512-hTWqJtqIFFdvuCl8WXNyrodp2L9zo2G37xKRrcVmVRWpAB2h+U1LuRAfS4tsFTiWOIoE/B+WDVFB8JpoEdw6jQ==} + engines: {node: '>=20.19'} + '@tanstack/server-functions-plugin@1.131.2': resolution: {integrity: sha512-hWsaSgEZAVyzHg8+IcJWCEtfI9ZSlNELErfLiGHG9XCHEXMegFWsrESsKHlASzJqef9RsuOLDl+1IMPIskwdDw==} engines: {node: '>=12'} @@ -9927,50 +9907,56 @@ packages: peerDependencies: solid-js: ^1.6.0 - '@tanstack/solid-router-devtools@1.141.1': - resolution: {integrity: sha512-ezm8V1UR47kY/xquIobascexHkbWOcH1YXc8BRvYDKV33NEdeUhMVUqkZmwuojlRYXhF7LEfj2aSwZr0uBfH8A==} - engines: {node: '>=12'} + '@tanstack/solid-router-devtools@1.167.1': + resolution: {integrity: sha512-GZiRbHx7E1vbuv1zGjPl1EmCKbwKZKoCU0TjycBjU6SW0rMt/24SON0MbtMbPlLs3XE28jFi7C5odwE2hryh/Q==} + engines: {node: '>=20.19'} peerDependencies: - '@tanstack/router-core': ^1.141.1 - '@tanstack/solid-router': ^1.141.1 + '@tanstack/router-core': ^1.171.16 + '@tanstack/solid-router': ^1.170.19 solid-js: ^1.9.10 peerDependenciesMeta: '@tanstack/router-core': optional: true - '@tanstack/solid-router-ssr-query@1.141.1': - resolution: {integrity: sha512-jM2RKblxWbrMV2nmZ+L+Y2HvfBZ448tZHXYBP/NrQa2YAHVXCZfVE5ojjB5vyDZHc7ueFAF8+yIvMGnIQQE99g==} - engines: {node: '>=12'} + '@tanstack/solid-router-ssr-query@1.167.1': + resolution: {integrity: sha512-N76V3oz1ZQlTveBTRpLGOTlUtXU5GKOD++IkMnLBtuHEsge9ReluB94QBgVA+ElpQgdeso9uKUs/JsPluAynUA==} + engines: {node: '>=20.19'} peerDependencies: '@tanstack/query-core': '>=5.90.0' '@tanstack/solid-query': '>=5.90.0' '@tanstack/solid-router': '>=1.127.0' solid-js: ^1.9.10 - '@tanstack/solid-router@1.141.1': - resolution: {integrity: sha512-xcWkYdwvTXzQwLd4gI0efq7dUzXlcTyent/UDrGf1K5dDBqlFSAj9c11vNwP0+YvCaPt4U1r8czyMD1Qr3aNGA==} - engines: {node: '>=12'} + '@tanstack/solid-router@1.170.30': + resolution: {integrity: sha512-FozWeln6hx6o2T45gFFdkGQJxvq/LN0EUlzx7+eENy9HJH/thEBSb89KTkQahULzs9bsMOufzeXJJVgB6H9/wA==} + engines: {node: '>=20.19'} peerDependencies: solid-js: ^1.9.10 - '@tanstack/solid-start-client@1.141.1': - resolution: {integrity: sha512-NGc70Jj9DoWFieFX9iQG70fmuTvX7nfTUG5vlboxBzvTuPrIdyeddrQVnBX/kXUdFzLGzez7QlxqyOrm3zouuQ==} + '@tanstack/solid-start-client@1.168.29': + resolution: {integrity: sha512-+F3Z/J1SVxPj2Hs53Wvos2DhIe7cGvlHpwZD9x0+aIWofIlkRSnrGm2wehWZzun1tzgZNnK2L2thkQlXVtuVaw==} engines: {node: '>=22.12.0'} peerDependencies: solid-js: '>=1.0.0' - '@tanstack/solid-start-server@1.141.1': - resolution: {integrity: sha512-vIuw74+6cgBmh1zAqc27dKHd5rU2K4V6nHt+u7vBKUUu/9QIF7PoQD0fj2dWnrjnz7EJKb1W7Gr9rAtOdglgGw==} + '@tanstack/solid-start-server@1.167.36': + resolution: {integrity: sha512-7WMqLxe1Yr+9Q+Ze2dsYrPnousiPmA5LndJtg1MnaIRNecL1NInd5jsiIwNB42qOWTwcGr8aD8LnHH4dcVh/wA==} engines: {node: '>=22.12.0'} peerDependencies: solid-js: ^1.0.0 - '@tanstack/solid-start@1.141.1': - resolution: {integrity: sha512-b7B7UUPn3GANvnvTusiryTr+CUEs+lMMFRRiDiBZXx+Yb1cqtp/UYilEDHdqnx2xUoAhR0FBd4kRcieCV69DVg==} + '@tanstack/solid-start@1.168.47': + resolution: {integrity: sha512-yqXrj5Q1wGh/9Gb/wGp117AavC48tFk29LP/2oGHBJKq4ZATYes8s3yPBRSWlSkqQG9N2yQzjmF+sutXZSZVzw==} engines: {node: '>=22.12.0'} peerDependencies: + '@rsbuild/core': ^2.0.0 solid-js: '>=1.0.0' vite: '>=7.0.0' + peerDependenciesMeta: + '@rsbuild/core': + optional: true + vite: + optional: true '@tanstack/solid-store@0.8.0': resolution: {integrity: sha512-JwqTedbxyOGw7mfmdGkB0RGgefRCw/tNauc8tlMcaS1mV5wTFT8c1KIB3LgttuHaanMJEBeqQJ7bc/R0WTP1fA==} @@ -9993,6 +9979,10 @@ packages: resolution: {integrity: sha512-9j2i1PRTIGcYAD+509znve0ngK81ZUfbX4XCpoNFMaUUpRHoEPPK5I9+PzLFvL9sNOto67x+WULCUggzX+lEKQ==} engines: {node: '>=22.12.0'} + '@tanstack/start-client-core@1.170.27': + resolution: {integrity: sha512-Ro6ZSM0NgYKDMxM0e8qyU4mBfnld2Zb74BA/9f4i35C0Y3IAA8Zxs/DIPfOo9VRYWp5c5n5Q8dRBn2qn0vtPhQ==} + engines: {node: '>=22.12.0'} + '@tanstack/start-config@1.120.20': resolution: {integrity: sha512-oH/mfTSHV8Qbil74tWicPLW6+kKmT3esXCnDzvrkhi3+N8ZuVUDr01Qpil0Wxf9lLPfM5L6VX03nF4hSU8vljg==} engines: {node: '>=12'} @@ -10005,23 +9995,27 @@ packages: resolution: {integrity: sha512-D69B78L6pcFN5X5PHaydv7CScQcKLzJeEYqs7jpuyyqGQHSUIZUjS955j+Sir8cHhuDIovCe2LmsYHeZfWf3dQ==} engines: {node: '>=22.12.0'} + '@tanstack/start-fn-stubs@1.162.0': + resolution: {integrity: sha512-QWfUZ3Yo923tdQn38LyKMU8rcTw69zc+T4dAvgTWV4O56SqFRsGfS0lSWIMhJRwXIx/bvdi7nTUBDdZtTHtpTQ==} + engines: {node: '>=22.12.0'} + '@tanstack/start-plugin-core@1.131.50': resolution: {integrity: sha512-eFvMA0chqLtHbq+8ojp1fXN7AQjhmeoOpQaZaU1d51wb7ugetrn0k3OuHblxtE/O0L4HEC9s4X5zmFJt0vLh0w==} engines: {node: '>=12'} peerDependencies: vite: '>=6.0.0' - '@tanstack/start-plugin-core@1.141.1': - resolution: {integrity: sha512-jXfgKeM4XX7aoP7WF/cJZH52N0ewIYRdP028ItXaSwUMcDyBO+PPTNbSEqTu3zbzLsmTOOyuJEpIrVA0/lmbjA==} - engines: {node: '>=22.12.0'} - peerDependencies: - vite: '>=7.0.0' - - '@tanstack/start-plugin-core@1.159.5': - resolution: {integrity: sha512-QGiBw+L3qu2sUY0Tg9KovxjDSi5kevoANEcq9RLX7iIhLkTjrILN6hnAlXZUzqk5Egaf0aN2yWhwI4HWucMprw==} + '@tanstack/start-plugin-core@1.171.39': + resolution: {integrity: sha512-Zyj6G4MDFLXcHYhPavhewCBo8dsxi3qvPk31zl/QtTzYzOY9rJHDDBGarKsJq20ziChmkGn/sttYqb4vGCxJDA==} engines: {node: '>=22.12.0'} peerDependencies: + '@rsbuild/core': ^2.0.0 vite: '>=7.0.0' + peerDependenciesMeta: + '@rsbuild/core': + optional: true + vite: + optional: true '@tanstack/start-server-core@1.131.50': resolution: {integrity: sha512-3SWwwhW2GKMhPSaqWRal6Jj1Y9ObfdWEXKFQid1LBuk5xk/Es4bmW68o++MbVgs/GxUxyeZ3TRVqb0c7RG1sog==} @@ -10035,6 +10029,10 @@ packages: resolution: {integrity: sha512-sGpr+iil+pcY3Gglvbnxaj7fCEPTQJv4oF7YA24SVv8YvayLXtBXpF26miJLA+KR9P31dQdPYe1gTjv5zRyvHg==} engines: {node: '>=22.12.0'} + '@tanstack/start-server-core@1.169.31': + resolution: {integrity: sha512-56w8l+Fao01YCrmv0hzNxL3b3FRmqLRGdE11izZNQsW+1CcSYuehAM5khWKABuI1DI/UIBLGV7BwL4Dlg0eHCw==} + engines: {node: '>=22.12.0'} + '@tanstack/start-server-functions-client@1.131.50': resolution: {integrity: sha512-4aM17fFdVAFH6uLPswKJxzrhhIjcCwKqzfTcgY3OnhUKnaZBTQwJA+nUHQCI6IWvEvrcrNVtFTtv13TkDk3YMw==} engines: {node: '>=12'} @@ -10067,6 +10065,10 @@ packages: resolution: {integrity: sha512-iGkmuCIq3PLI4GKOGwgUNHQKZ13YV8LGq62o2hVnyXE64Jm2SP7c5z6D1ndydpk4JwdRzQKlcOFT/1agvS6Nsg==} engines: {node: '>=22.12.0'} + '@tanstack/start-storage-context@1.167.29': + resolution: {integrity: sha512-8qfprC5774XMRDQlMogkfiGpFLiBf0xDG4bMFUbfkSzpCAQwpLbgGY4Zwft22O9rKYq2vUXusKAdVjvJTUEquQ==} + engines: {node: '>=22.12.0'} + '@tanstack/start@1.120.20': resolution: {integrity: sha512-fQO+O/5xJpli5KlV6pwDz6DtpbqO/0atdVSyVnkemzk0Mej9azm4HXtw+cKkIPtsSplWs4B1EbMtgGMb9ADhSA==} engines: {node: '>=12'} @@ -10080,6 +10082,9 @@ packages: '@tanstack/store@0.8.0': resolution: {integrity: sha512-Om+BO0YfMZe//X2z0uLF2j+75nQga6TpTJgLJQBiq85aOyZNIhkCgleNcud2KQg4k4v9Y9l+Uhru3qWMPGTOzQ==} + '@tanstack/store@0.9.3': + resolution: {integrity: sha512-8reSzl/qGWGGVKhBoxXPMWzATSbZLZFWhwBAFO9NAyp0TxzfBP0mIrGb8CP8KrQTmvzXlR/vFPPUrHTLBGyFyw==} + '@tanstack/typedoc-config@0.3.4': resolution: {integrity: sha512-WXJavpiNqumNwdBQTM3wBqbHaULgoZ3cIri7xJinKqX/mOGXgc6ZghfAardD2PydP8tOcPf+xhrd1Qk/am9DMg==} engines: {node: '>=18'} @@ -10088,14 +10093,14 @@ packages: resolution: {integrity: sha512-VEEOxc4mvyu67O+Bl0APtYjwcNRcL9it9B4HKbNgcBTIOEalhk+ufBl4kiqc8WP1sx1+NAaiS+3CcJBhrqaSRg==} engines: {node: '>=12'} - '@tanstack/virtual-file-routes@1.141.0': - resolution: {integrity: sha512-CJrWtr6L9TVzEImm9S7dQINx+xJcYP/aDkIi6gnaWtIgbZs1pnzsE0yJc2noqXZ+yAOqLx3TBGpBEs9tS0P9/A==} - engines: {node: '>=12'} - '@tanstack/virtual-file-routes@1.154.7': resolution: {integrity: sha512-cHHDnewHozgjpI+MIVp9tcib6lYEQK5MyUr0ChHpHFGBl8Xei55rohFK0I0ve/GKoHeioaK42Smd8OixPp6CTg==} engines: {node: '>=12'} + '@tanstack/virtual-file-routes@1.162.0': + resolution: {integrity: sha512-uhOeFyxLcU41HzvrxsGpiWdcMbScY1EDgbZ5K7DVRMYInbLYWAC0EA/kx9wXAoSM8q82bUG2hRl8+EAjE6XAbA==} + engines: {node: '>=20.19'} + '@tanstack/vite-config@0.6.0': resolution: {integrity: sha512-TtcetFc7aBm9BBclG3/8pM8ZlyzS8yNwi+eScN4gqsB9xnxyOPCbuvvkk//ybfQj8MVEZavQ03EOQxmOJdW8Rw==} engines: {node: '>=18'} @@ -10379,32 +10384,16 @@ packages: eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 typescript: '>=4.8.4 <6.1.0' - '@typescript-eslint/project-service@8.49.0': - resolution: {integrity: sha512-/wJN0/DKkmRUMXjZUXYZpD1NEQzQAAn9QWfGwo+Ai8gnzqH7tvqS7oNVdTjKqOcPyVIdZdyCMoqN66Ia789e7g==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - peerDependencies: - typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/project-service@8.59.4': resolution: {integrity: sha512-Ly00Vu4oAacfDeHp2Zg85ioNG6l8HG+tN1D7J+xTHSxu9y0awYKJ2zH1rFBn8ZSfuGK+7FxK3Cgl3uAz0aZZLg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: typescript: '>=4.8.4 <6.1.0' - '@typescript-eslint/scope-manager@8.49.0': - resolution: {integrity: sha512-npgS3zi+/30KSOkXNs0LQXtsg9ekZ8OISAOLGWA/ZOEn0ZH74Ginfl7foziV8DT+D98WfQ5Kopwqb/PZOaIJGg==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@typescript-eslint/scope-manager@8.59.4': resolution: {integrity: sha512-mUeR/3H1WrTAddJrwut8OoPjfauaztMQmRwV5fQTUyNVJCLiUXXe4lGEyYIL2oFDpP7UtgbGJXCt72wT0z2S3Q==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@typescript-eslint/tsconfig-utils@8.49.0': - resolution: {integrity: sha512-8prixNi1/6nawsRYxet4YOhnbW+W9FK/bQPxsGB1D3ZrDzbJ5FXw5XmzxZv82X3B+ZccuSxo/X8q9nQ+mFecWA==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - peerDependencies: - typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/tsconfig-utils@8.59.4': resolution: {integrity: sha512-DLCpnKgD4alVxTBSKulK+gU1KCqOgUXfDRDXh2mZgzokQKa/70ax93I2uVO3m/LLvIAtWZIFoiifudmIqAxpMA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} @@ -10418,33 +10407,16 @@ packages: eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 typescript: '>=4.8.4 <6.1.0' - '@typescript-eslint/types@8.49.0': - resolution: {integrity: sha512-e9k/fneezorUo6WShlQpMxXh8/8wfyc+biu6tnAqA81oWrEic0k21RHzP9uqqpyBBeBKu4T+Bsjy9/b8u7obXQ==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@typescript-eslint/types@8.59.4': resolution: {integrity: sha512-F1o7WJcCq+bc8dwcO/YsSEOudAH8RDtaOhM6wcAQhcUsFhnWQl81JKy48q1hoxAU0qrzM89+31GYh1515Zde3Q==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@typescript-eslint/typescript-estree@8.49.0': - resolution: {integrity: sha512-jrLdRuAbPfPIdYNppHJ/D0wN+wwNfJ32YTAm10eJVsFmrVpXQnDWBn8niCSMlWjvml8jsce5E/O+86IQtTbJWA==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - peerDependencies: - typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/typescript-estree@8.59.4': resolution: {integrity: sha512-F+RuOmcDXo4+TPdfd/TCLS3m2nw8gE9XXyZLrA3JBfaA5tz9TtdkyD3YJFmPxulyc2cKbEok/CvFE3MgSLWnag==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: typescript: '>=4.8.4 <6.1.0' - '@typescript-eslint/utils@8.49.0': - resolution: {integrity: sha512-N3W7rJw7Rw+z1tRsHZbK395TWSYvufBXumYtEGzypgMUthlg0/hmCImeA8hgO2d2G4pd7ftpxxul2J8OdtdaFA==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - peerDependencies: - eslint: ^8.57.0 || ^9.0.0 - typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/utils@8.59.4': resolution: {integrity: sha512-cYXeNAUsG4lJo5dbc1FcKm+JwIWrj1/UpTORsC6tGMjEZ81DYcvIr9/ueikhMa/Y/gDQYGp+YX9/xQrXje5BJw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} @@ -10452,10 +10424,6 @@ packages: eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 typescript: '>=4.8.4 <6.1.0' - '@typescript-eslint/visitor-keys@8.49.0': - resolution: {integrity: sha512-LlKaciDe3GmZFphXIc79THF/YYBugZ7FS1pO581E/edlVVNbZKDy93evqmrfQ9/Y4uN0vVhX4iuchq26mK/iiA==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@typescript-eslint/visitor-keys@8.59.4': resolution: {integrity: sha512-U3gxVaDVnuZKhSspW/MzMxE1kq7zOdc072FcSNoqA1I9p8HyKbBFfEHoWckBAMgNMph4MamwS5iTVzFmrnt8TQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} @@ -11653,6 +11621,9 @@ packages: cookie-es@2.0.1: resolution: {integrity: sha512-aVf4A4hI2w70LnF7GG+7xDQUkliwiXWXFvTjkip4+b64ygDQ2sJPRSKFDHbxn8o0xu9QzPkMuuiWIXyFSE2slA==} + cookie-es@3.1.1: + resolution: {integrity: sha512-UaXxwISYJPTr9hwQxMFYZ7kNhSXboMXP+Z3TRX6f1/NyaGPfuNUZOWP1pUEb75B2HjfklIYLVRfWiFZJyC6Npg==} + cookie-signature@1.2.2: resolution: {integrity: sha512-D76uU73ulSXrD1UXF4KE2TMxVVwhsnCgfAyTg9k8P6KGZjlXKrOLe4dJQKI3Bxi5wjesZoFXJWElNWBjPZMbhg==} engines: {node: '>=6.6.0'} @@ -12386,13 +12357,6 @@ packages: engines: {node: '>=6.0'} hasBin: true - eslint-plugin-solid@0.14.5: - resolution: {integrity: sha512-nfuYK09ah5aJG/oEN6P1qziy1zLgW4PDWe75VNPi4CEFYk1x2AEqwFeQfEPR7gNn0F2jOeqKhx2E+5oNCOBYWQ==} - engines: {node: '>=18.0.0'} - peerDependencies: - eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 || ^9.0.0 - typescript: '>=4.8.4' - eslint-plugin-unused-imports@4.3.0: resolution: {integrity: sha512-ZFBmXMGBYfHttdRtOG9nFFpmUvMtbHSjsKrS20vdWdbfiVYsO3yA2SGYy9i9XmZJDfMGBflZGBCm70SEnFQtOA==} peerDependencies: @@ -13044,6 +13008,16 @@ packages: crossws: optional: true + h3@2.0.1-rc.20: + resolution: {integrity: sha512-28ljodXuUp0fZovdiSRq4G9OgrxCztrJe5VdYzXAB7ueRvI7pIUqLU14Xi3XqdYJ/khXjfpUOOD2EQa6CmBgsg==} + engines: {node: '>=20.11.1'} + hasBin: true + peerDependencies: + crossws: ^0.4.1 + peerDependenciesMeta: + crossws: + optional: true + h3@2.0.1-rc.22: resolution: {integrity: sha512-Esv0DMIuPkCTSWCA0vO73vcTqwzH1wjSrAO1TXNu/K3up1sZHa9EKMapbmxCDYBeymC3fVTk4qxp7ogQWQ+KgA==} engines: {node: '>=20.11.1'} @@ -13169,10 +13143,6 @@ packages: html-link-extractor@1.0.5: resolution: {integrity: sha512-ADd49pudM157uWHwHQPUSX4ssMsvR/yHIswOR5CUfBdK9g9ZYGMhVSE6KZVHJ6kCkR0gH4htsfzU6zECDNVwyw==} - html-tags@3.3.1: - resolution: {integrity: sha512-ztqyC3kLto0e9WbNp0aeP+M3kTt+nbaIveGmUxAtZa+8iFgKLUOD4YKM5j+f3QD89bra7UeumolZHKuOXnTmeQ==} - engines: {node: '>=8'} - html-url-attributes@3.0.1: resolution: {integrity: sha512-ol6UPyBWqsrO6EJySPz2O7ZSr856WDrEzM5zMqp+FJJLGMW35cLYmmZnl0vztAZxRUoNZJFTCohfjuIJ8I4QBQ==} @@ -13400,10 +13370,6 @@ packages: is-hexadecimal@2.0.1: resolution: {integrity: sha512-DgZQp241c8oO6cA1SbTEWiXeoxV42vlcJxgH+B3hi1AiqqKruZR3ZGF8In3fj4+/y/7rHvlOZLZtgJ/4ttYGZg==} - is-html@2.0.0: - resolution: {integrity: sha512-S+OpgB5i7wzIue/YSE5hg0e5ZYfG3hhpNh9KGl6ayJ38p7ED6wxQLd1TV91xHpcTvw90KMJ9EwN3F/iNflHBVg==} - engines: {node: '>=8'} - is-inside-container@1.0.0: resolution: {integrity: sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA==} engines: {node: '>=14.16'} @@ -13727,9 +13693,6 @@ packages: jws@4.0.1: resolution: {integrity: sha512-EKI/M/yqPncGUUh44xz0PxSidXFr/+r0pA70+gIYhjv+et7yxM+s29Y+VGDkovRofQem0fs7Uvf4+YmAdyRduA==} - kebab-case@1.0.2: - resolution: {integrity: sha512-7n6wXq4gNgBELfDCpzKc+mRrZFs7D+wgfF5WRFLNAr4DA/qtr9Js8uOAVAfHhuLMfAcQ0pRKqbpjx+TcJVdE1Q==} - keyv@4.5.4: resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==} @@ -13764,9 +13727,6 @@ packages: knitwork@1.3.0: resolution: {integrity: sha512-4LqMNoONzR43B1W0ek0fhXMsDNW/zxa1NdFAVMY+k28pgZLovR4G3PB5MrpTxCy1QaZCqNoiaKPr5w5qZHfSNw==} - known-css-properties@0.30.0: - resolution: {integrity: sha512-VSWXYUnsPu9+WYKkfmJyLKtIvaRJi1kXUqVmBACORXZQxT5oZDsoZ2vQP+bQFDnWtpI/4eq3MLoRMjI2fnLzTQ==} - kolorist@1.8.0: resolution: {integrity: sha512-Y+60/zizpJ3HRH8DCss+q95yr6145JXZo46OTpFvDZWLfRCE4qChOyk1b26nMaNpfHHgxagk9dXT5OP0Tfe+dQ==} @@ -15966,6 +15926,12 @@ packages: peerDependencies: seroval: ^1.0 + seroval-plugins@1.6.2: + resolution: {integrity: sha512-TfxuUjlbBESzUOWdTkTKqvSmav0ABym+itetDXLK6mDz8SmrpdI30aF8RTXE8Bvq+tH/1yIDkvy3W0lfQb1ipQ==} + engines: {node: '>=10'} + peerDependencies: + seroval: ^1.0 + seroval@1.3.2: resolution: {integrity: sha512-RbcPH1n5cfwKrru7v7+zrZvjLurgHhGyso3HTyGtRivGWgYjbOmGuivCQaORNELjNONoK35nj28EoWul9sb1zQ==} engines: {node: '>=10'} @@ -15978,6 +15944,10 @@ packages: resolution: {integrity: sha512-OE4cvmJ1uSPrKorFIH9/w/Qwuvi/IMcGbv5RKgcJ/zjA/IohDLU6SVaxFN9FwajbP7nsX0dQqMDes1whk3y+yw==} engines: {node: '>=10'} + seroval@1.6.2: + resolution: {integrity: sha512-mPT+SD2TrlB6wvte1KkYOYUkubaTbd6pZ/6Kk3C9nxzrHmCZyhxOO7XGAeL7f+yLKZglzGtM9odUVvg/EhO+vQ==} + engines: {node: '>=10'} + serve-placeholder@2.0.2: resolution: {integrity: sha512-/TMG8SboeiQbZJWRlfTCqMs2DD3SZgWp0kDQePz9yUuCnDfDh/92gf7/PxGhzXTKBIPASIHxFcZndoNbp6QOLQ==} @@ -16560,12 +16530,6 @@ packages: ts-algebra@2.0.0: resolution: {integrity: sha512-FPAhNPFMrkwz76P7cdjdmiShwMynZYN6SgOujD1urY4oNm80Ou9oMdmbR45LotcKOXoy7wSmHkRFE6Mxbrhefw==} - ts-api-utils@2.1.0: - resolution: {integrity: sha512-CUgTZL1irw8u29bzrOD/nH85jqyc74D6SshFgujOIA7osm2Rz7dYH77agkx7H4FBNxDq7Cjf+IjaX/8zwFW+ZQ==} - engines: {node: '>=18.12'} - peerDependencies: - typescript: '>=4.8.4' - ts-api-utils@2.5.0: resolution: {integrity: sha512-OJ/ibxhPlqrMM0UiNHJ/0CKQkoKF243/AEmplt3qpRgkW8VG7IfOS41h7V8TjITqdByHzrjcS/2si+y4lIh8NA==} engines: {node: '>=18.12'} @@ -16891,6 +16855,39 @@ packages: resolution: {integrity: sha512-5uKD0nqiYVzlmCRs01Fhs2BdkEgBS3SAVP6ndrBsuK42iC2+JHyxM05Rm9G8+5mkmRtzMZGY8Ct5+mliZxU/Ww==} engines: {node: '>=18.12.0'} + unplugin@3.3.0: + resolution: {integrity: sha512-qa66K+crbfyE6JK10GjvbJeRrOsuC/JpbnHctfyp/i4oBTxWOzJfRZyDiOk1PtErMFRu8JhsU/wPvOdBNWe5Rg==} + engines: {node: ^20.19.0 || >=22.12.0} + peerDependencies: + '@farmfe/core': '*' + '@rspack/core': '*' + bun-types-no-globals: '*' + esbuild: '*' + rolldown: '*' + rollup: '*' + unloader: '*' + vite: '*' + webpack: '*' + peerDependenciesMeta: + '@farmfe/core': + optional: true + '@rspack/core': + optional: true + bun-types-no-globals: + optional: true + esbuild: + optional: true + rolldown: + optional: true + rollup: + optional: true + unloader: + optional: true + vite: + optional: true + webpack: + optional: true + unrun@0.2.19: resolution: {integrity: sha512-DbwbJ9BvPEb3BeZnIpP9S5tGLO/JIgPQ3JrpMRFIfZMZfMG19f26OlLbC2ml8RRdrI2ZA7z2t+at5tsIHbh6Qw==} engines: {node: '>=20.19.0'} @@ -17300,14 +17297,6 @@ packages: yaml: optional: true - vitefu@1.1.1: - resolution: {integrity: sha512-B/Fegf3i8zh0yFbpzZ21amWzHmuNlLlmJT6n7bu5e+pCHUKQIfXSYokrqOBGEMMe9UG2sostKQF9mml/vYaWJQ==} - peerDependencies: - vite: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0-beta.0 - peerDependenciesMeta: - vite: - optional: true - vitefu@1.1.3: resolution: {integrity: sha512-ub4okH7Z5KLjb6hDyjqrGXqWtWvoYdU3IGm/NorpgHncKoLTCfRIbvlhBm7r0YstIaQRYlp4yEbFqDcKSzXSSg==} peerDependencies: @@ -17715,6 +17704,9 @@ packages: zod@4.3.6: resolution: {integrity: sha512-rftlrkhHZOcjDwkGlnUtZZkvaPHCsDATp4pGpuOOMDaTdDDXF91wuVDJoWoPsKX/3YPQ5fHuF3STjcYyKr+Qhg==} + zod@4.4.3: + resolution: {integrity: sha512-ytENFjIJFl2UwYglde2jchW2Hwm4GJFLDiSXWdTrJQBIN9Fcyp7n4DhxJEiWNAJMV1/BqWfW/kkg71UDcHJyTQ==} + zone.js@0.15.1: resolution: {integrity: sha512-XE96n56IQpJM7NAoXswY3XRLcWFW83xe0BiAOeMD7K5k5xecOeul3Qcpx6GqEeeHNkW5DWL5zOyTbEfB4eti8w==} @@ -17909,7 +17901,7 @@ snapshots: '@angular/compiler-cli@21.2.17(@angular/compiler@21.2.20)(typescript@5.9.3)': dependencies: '@angular/compiler': 21.2.20 - '@babel/core': 7.29.0(supports-color@7.2.0) + '@babel/core': 7.29.0 '@jridgewell/sourcemap-codec': 1.5.5 chokidar: 5.0.0 convert-source-map: 1.9.0 @@ -18396,9 +18388,9 @@ snapshots: '@babel/helper-module-transforms': 7.28.3(@babel/core@7.28.5) '@babel/helpers': 7.28.4 '@babel/parser': 7.28.5 - '@babel/template': 7.27.2 + '@babel/template': 7.29.7 '@babel/traverse': 7.28.5 - '@babel/types': 7.28.5 + '@babel/types': 7.29.7 '@jridgewell/remapping': 2.3.5 convert-source-map: 2.0.0 debug: 4.4.3(supports-color@7.2.0) @@ -18416,9 +18408,9 @@ snapshots: '@babel/helper-module-transforms': 7.28.3(@babel/core@7.28.5(supports-color@7.2.0)) '@babel/helpers': 7.28.4 '@babel/parser': 7.28.5 - '@babel/template': 7.27.2 + '@babel/template': 7.29.7 '@babel/traverse': 7.28.5 - '@babel/types': 7.28.5 + '@babel/types': 7.29.7 '@jridgewell/remapping': 2.3.5 convert-source-map: 2.0.0 debug: 4.4.3(supports-color@7.2.0) @@ -18428,12 +18420,12 @@ snapshots: transitivePeerDependencies: - supports-color - '@babel/core@7.29.0(supports-color@7.2.0)': + '@babel/core@7.29.0': dependencies: '@babel/code-frame': 7.29.7 '@babel/generator': 7.29.7 '@babel/helper-compilation-targets': 7.29.7 - '@babel/helper-module-transforms': 7.29.7(@babel/core@7.29.0(supports-color@7.2.0)) + '@babel/helper-module-transforms': 7.29.7(@babel/core@7.29.0) '@babel/helpers': 7.29.7 '@babel/parser': 7.29.7 '@babel/template': 7.29.7 @@ -18471,7 +18463,7 @@ snapshots: '@babel/generator@7.28.5': dependencies: '@babel/parser': 7.29.0 - '@babel/types': 7.29.0 + '@babel/types': 7.29.7 '@jridgewell/gen-mapping': 0.3.13 '@jridgewell/trace-mapping': 0.3.31 jsesc: 3.1.0 @@ -18555,19 +18547,6 @@ snapshots: transitivePeerDependencies: - supports-color - '@babel/helper-create-class-features-plugin@7.29.7(@babel/core@7.29.0)': - dependencies: - '@babel/core': 7.29.0(supports-color@7.2.0) - '@babel/helper-annotate-as-pure': 7.29.7 - '@babel/helper-member-expression-to-functions': 7.29.7 - '@babel/helper-optimise-call-expression': 7.29.7 - '@babel/helper-replace-supers': 7.29.7(@babel/core@7.29.0) - '@babel/helper-skip-transparent-expression-wrappers': 7.29.7 - '@babel/traverse': 7.29.7 - semver: 6.3.1 - transitivePeerDependencies: - - supports-color - '@babel/helper-create-class-features-plugin@7.29.7(@babel/core@7.29.7)': dependencies: '@babel/core': 7.29.7 @@ -18653,15 +18632,6 @@ snapshots: transitivePeerDependencies: - supports-color - '@babel/helper-module-transforms@7.28.3(@babel/core@7.29.0)': - dependencies: - '@babel/core': 7.29.0(supports-color@7.2.0) - '@babel/helper-module-imports': 7.29.7 - '@babel/helper-validator-identifier': 7.29.7 - '@babel/traverse': 7.29.7 - transitivePeerDependencies: - - supports-color - '@babel/helper-module-transforms@7.28.3(@babel/core@7.29.7)': dependencies: '@babel/core': 7.29.7 @@ -18671,9 +18641,9 @@ snapshots: transitivePeerDependencies: - supports-color - '@babel/helper-module-transforms@7.29.7(@babel/core@7.29.0(supports-color@7.2.0))': + '@babel/helper-module-transforms@7.29.7(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.29.0(supports-color@7.2.0) + '@babel/core': 7.29.0 '@babel/helper-module-imports': 7.29.7 '@babel/helper-validator-identifier': 7.29.7 '@babel/traverse': 7.29.7 @@ -18739,15 +18709,6 @@ snapshots: transitivePeerDependencies: - supports-color - '@babel/helper-replace-supers@7.29.7(@babel/core@7.29.0)': - dependencies: - '@babel/core': 7.29.0(supports-color@7.2.0) - '@babel/helper-member-expression-to-functions': 7.29.7 - '@babel/helper-optimise-call-expression': 7.29.7 - '@babel/traverse': 7.29.7 - transitivePeerDependencies: - - supports-color - '@babel/helper-replace-supers@7.29.7(@babel/core@7.29.7)': dependencies: '@babel/core': 7.29.7 @@ -18811,7 +18772,7 @@ snapshots: '@babel/parser@7.29.0': dependencies: - '@babel/types': 7.29.0 + '@babel/types': 7.29.7 '@babel/parser@7.29.7': dependencies: @@ -18861,21 +18822,11 @@ snapshots: '@babel/core': 7.28.5(supports-color@7.2.0) '@babel/helper-plugin-utils': 7.29.7 - '@babel/plugin-syntax-jsx@7.27.1(@babel/core@7.29.0)': - dependencies: - '@babel/core': 7.29.0(supports-color@7.2.0) - '@babel/helper-plugin-utils': 7.29.7 - '@babel/plugin-syntax-jsx@7.27.1(@babel/core@7.29.7)': dependencies: '@babel/core': 7.29.7 '@babel/helper-plugin-utils': 7.29.7 - '@babel/plugin-syntax-jsx@7.29.7(@babel/core@7.29.0)': - dependencies: - '@babel/core': 7.29.0(supports-color@7.2.0) - '@babel/helper-plugin-utils': 7.29.7 - '@babel/plugin-syntax-jsx@7.29.7(@babel/core@7.29.7)': dependencies: '@babel/core': 7.29.7 @@ -18896,11 +18847,6 @@ snapshots: '@babel/core': 7.28.5(supports-color@7.2.0) '@babel/helper-plugin-utils': 7.29.7 - '@babel/plugin-syntax-typescript@7.27.1(@babel/core@7.29.0)': - dependencies: - '@babel/core': 7.29.0(supports-color@7.2.0) - '@babel/helper-plugin-utils': 7.29.7 - '@babel/plugin-syntax-typescript@7.27.1(@babel/core@7.29.7)': dependencies: '@babel/core': 7.29.7 @@ -19011,14 +18957,6 @@ snapshots: transitivePeerDependencies: - supports-color - '@babel/plugin-transform-modules-commonjs@7.27.1(@babel/core@7.29.0)': - dependencies: - '@babel/core': 7.29.0(supports-color@7.2.0) - '@babel/helper-module-transforms': 7.28.3(@babel/core@7.29.0) - '@babel/helper-plugin-utils': 7.27.1 - transitivePeerDependencies: - - supports-color - '@babel/plugin-transform-modules-commonjs@7.27.1(@babel/core@7.29.7)': dependencies: '@babel/core': 7.29.7 @@ -19167,17 +19105,6 @@ snapshots: transitivePeerDependencies: - supports-color - '@babel/plugin-transform-typescript@7.28.5(@babel/core@7.29.0)': - dependencies: - '@babel/core': 7.29.0(supports-color@7.2.0) - '@babel/helper-annotate-as-pure': 7.29.7 - '@babel/helper-create-class-features-plugin': 7.29.7(@babel/core@7.29.0) - '@babel/helper-plugin-utils': 7.29.7 - '@babel/helper-skip-transparent-expression-wrappers': 7.27.1 - '@babel/plugin-syntax-typescript': 7.27.1(@babel/core@7.29.0) - transitivePeerDependencies: - - supports-color - '@babel/plugin-transform-typescript@7.28.5(@babel/core@7.29.7)': dependencies: '@babel/core': 7.29.7 @@ -19213,17 +19140,6 @@ snapshots: transitivePeerDependencies: - supports-color - '@babel/preset-typescript@7.28.5(@babel/core@7.29.0)': - dependencies: - '@babel/core': 7.29.0(supports-color@7.2.0) - '@babel/helper-plugin-utils': 7.27.1 - '@babel/helper-validator-option': 7.27.1 - '@babel/plugin-syntax-jsx': 7.27.1(@babel/core@7.29.0) - '@babel/plugin-transform-modules-commonjs': 7.27.1(@babel/core@7.29.0) - '@babel/plugin-transform-typescript': 7.28.5(@babel/core@7.29.0) - transitivePeerDependencies: - - supports-color - '@babel/preset-typescript@7.28.5(@babel/core@7.29.7)': dependencies: '@babel/core': 7.29.7 @@ -19246,12 +19162,6 @@ snapshots: '@babel/runtime@7.29.2': {} - '@babel/template@7.27.2': - dependencies: - '@babel/code-frame': 7.29.7 - '@babel/parser': 7.29.7 - '@babel/types': 7.29.7 - '@babel/template@7.29.7': dependencies: '@babel/code-frame': 7.29.7 @@ -19264,8 +19174,8 @@ snapshots: '@babel/generator': 7.28.5 '@babel/helper-globals': 7.28.0 '@babel/parser': 7.28.5 - '@babel/template': 7.27.2 - '@babel/types': 7.28.5 + '@babel/template': 7.29.7 + '@babel/types': 7.29.7 debug: 4.4.3(supports-color@7.2.0) transitivePeerDependencies: - supports-color @@ -19294,11 +19204,6 @@ snapshots: transitivePeerDependencies: - supports-color - '@babel/types@7.28.5': - dependencies: - '@babel/helper-string-parser': 7.29.7 - '@babel/helper-validator-identifier': 7.29.7 - '@babel/types@7.29.0': dependencies: '@babel/helper-string-parser': 7.27.1 @@ -20367,7 +20272,7 @@ snapshots: '@expo/metro-config@56.0.13(expo@56.0.5)(typescript@5.9.3)': dependencies: '@babel/code-frame': 7.29.0 - '@babel/core': 7.29.0(supports-color@7.2.0) + '@babel/core': 7.29.7 '@babel/generator': 7.29.1 '@expo/config': 56.0.9(typescript@5.9.3) '@expo/env': 2.3.0 @@ -21202,8 +21107,6 @@ snapshots: '@nodelib/fs.scandir': 2.1.5 fastq: 1.19.1 - '@nothing-but/utils@0.17.0': {} - '@nx/nx-darwin-arm64@23.1.1': optional: true @@ -24348,8 +24251,6 @@ snapshots: '@rolldown/pluginutils@1.0.0-beta.27': {} - '@rolldown/pluginutils@1.0.0-beta.40': {} - '@rolldown/pluginutils@1.0.0-beta.53': {} '@rolldown/pluginutils@1.0.0-rc.3': {} @@ -24689,48 +24590,6 @@ snapshots: '@smithy/util-buffer-from': 2.2.0 tslib: 2.8.1 - '@solid-devtools/debugger@0.28.1(solid-js@1.9.10)': - dependencies: - '@nothing-but/utils': 0.17.0 - '@solid-devtools/shared': 0.20.0(solid-js@1.9.10) - '@solid-primitives/bounds': 0.1.3(solid-js@1.9.10) - '@solid-primitives/event-listener': 2.4.3(solid-js@1.9.10) - '@solid-primitives/keyboard': 1.3.3(solid-js@1.9.10) - '@solid-primitives/rootless': 1.5.2(solid-js@1.9.10) - '@solid-primitives/scheduled': 1.5.2(solid-js@1.9.10) - '@solid-primitives/static-store': 0.1.2(solid-js@1.9.10) - '@solid-primitives/utils': 6.3.2(solid-js@1.9.10) - solid-js: 1.9.10 - - '@solid-devtools/logger@0.9.11(solid-js@1.9.10)': - dependencies: - '@nothing-but/utils': 0.17.0 - '@solid-devtools/debugger': 0.28.1(solid-js@1.9.10) - '@solid-devtools/shared': 0.20.0(solid-js@1.9.10) - '@solid-primitives/utils': 6.3.2(solid-js@1.9.10) - solid-js: 1.9.10 - - '@solid-devtools/shared@0.20.0(solid-js@1.9.10)': - dependencies: - '@nothing-but/utils': 0.17.0 - '@solid-primitives/event-listener': 2.4.3(solid-js@1.9.10) - '@solid-primitives/media': 2.3.3(solid-js@1.9.10) - '@solid-primitives/refs': 1.1.2(solid-js@1.9.10) - '@solid-primitives/rootless': 1.5.2(solid-js@1.9.10) - '@solid-primitives/scheduled': 1.5.2(solid-js@1.9.10) - '@solid-primitives/static-store': 0.1.2(solid-js@1.9.10) - '@solid-primitives/styles': 0.1.2(solid-js@1.9.10) - '@solid-primitives/utils': 6.3.2(solid-js@1.9.10) - solid-js: 1.9.10 - - '@solid-primitives/bounds@0.1.3(solid-js@1.9.10)': - dependencies: - '@solid-primitives/event-listener': 2.4.3(solid-js@1.9.10) - '@solid-primitives/resize-observer': 2.1.3(solid-js@1.9.10) - '@solid-primitives/static-store': 0.1.2(solid-js@1.9.10) - '@solid-primitives/utils': 6.3.2(solid-js@1.9.10) - solid-js: 1.9.10 - '@solid-primitives/event-listener@2.4.3(solid-js@1.9.10)': dependencies: '@solid-primitives/utils': 6.3.2(solid-js@1.9.10) @@ -24743,14 +24602,6 @@ snapshots: '@solid-primitives/utils': 6.3.2(solid-js@1.9.10) solid-js: 1.9.10 - '@solid-primitives/media@2.3.3(solid-js@1.9.10)': - dependencies: - '@solid-primitives/event-listener': 2.4.3(solid-js@1.9.10) - '@solid-primitives/rootless': 1.5.2(solid-js@1.9.10) - '@solid-primitives/static-store': 0.1.2(solid-js@1.9.10) - '@solid-primitives/utils': 6.3.2(solid-js@1.9.10) - solid-js: 1.9.10 - '@solid-primitives/refs@1.1.2(solid-js@1.9.10)': dependencies: '@solid-primitives/utils': 6.3.2(solid-js@1.9.10) @@ -24769,21 +24620,11 @@ snapshots: '@solid-primitives/utils': 6.3.2(solid-js@1.9.10) solid-js: 1.9.10 - '@solid-primitives/scheduled@1.5.2(solid-js@1.9.10)': - dependencies: - solid-js: 1.9.10 - '@solid-primitives/static-store@0.1.2(solid-js@1.9.10)': dependencies: '@solid-primitives/utils': 6.3.2(solid-js@1.9.10) solid-js: 1.9.10 - '@solid-primitives/styles@0.1.2(solid-js@1.9.10)': - dependencies: - '@solid-primitives/rootless': 1.5.2(solid-js@1.9.10) - '@solid-primitives/utils': 6.3.2(solid-js@1.9.10) - solid-js: 1.9.10 - '@solid-primitives/utils@6.3.2(solid-js@1.9.10)': dependencies: solid-js: 1.9.10 @@ -25115,6 +24956,8 @@ snapshots: '@tanstack/history@1.154.14': {} + '@tanstack/history@1.162.1': {} + '@tanstack/nitro-v2-vite-plugin@1.155.0(@electric-sql/pglite@0.4.3)(aws4fetch@1.0.20)(better-sqlite3@12.11.1)(drizzle-orm@0.45.2(@cloudflare/workers-types@4.20260317.1)(@electric-sql/pglite@0.4.3)(@opentelemetry/api@1.9.1)(@prisma/client@7.9.0(prisma@7.9.0(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(better-sqlite3@12.11.1)(magicast@0.5.2)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(typescript@5.9.3))(typescript@5.9.3))(better-sqlite3@12.11.1)(bun-types@1.3.14)(mysql2@3.15.3)(postgres@3.4.7)(prisma@7.9.0(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(better-sqlite3@12.11.1)(magicast@0.5.2)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(typescript@5.9.3)))(mysql2@3.15.3)(rolldown@1.2.4)(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0))': dependencies: nitropack: 2.13.1(@electric-sql/pglite@0.4.3)(aws4fetch@1.0.20)(better-sqlite3@12.11.1)(drizzle-orm@0.45.2(@cloudflare/workers-types@4.20260317.1)(@electric-sql/pglite@0.4.3)(@opentelemetry/api@1.9.1)(@prisma/client@7.9.0(prisma@7.9.0(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(better-sqlite3@12.11.1)(magicast@0.5.2)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(typescript@5.9.3))(typescript@5.9.3))(better-sqlite3@12.11.1)(bun-types@1.3.14)(mysql2@3.15.3)(postgres@3.4.7)(prisma@7.9.0(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(better-sqlite3@12.11.1)(magicast@0.5.2)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(typescript@5.9.3)))(mysql2@3.15.3)(rolldown@1.2.4) @@ -25237,23 +25080,23 @@ snapshots: '@tanstack/query-core': 5.90.12 react: 19.2.3 - '@tanstack/react-router-devtools@1.159.5(@tanstack/react-router@1.159.5(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(@tanstack/router-core@1.159.4)(csstype@3.2.3)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': + '@tanstack/react-router-devtools@1.167.1(@tanstack/react-router@1.170.32(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(@tanstack/router-core@1.171.27)(csstype@3.2.3)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': dependencies: - '@tanstack/react-router': 1.159.5(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@tanstack/router-devtools-core': 1.159.4(@tanstack/router-core@1.159.4)(csstype@3.2.3) + '@tanstack/react-router': 1.170.32(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@tanstack/router-devtools-core': 1.168.1(@tanstack/router-core@1.171.27)(csstype@3.2.3) react: 19.2.3 react-dom: 19.2.3(react@19.2.3) optionalDependencies: - '@tanstack/router-core': 1.159.4 + '@tanstack/router-core': 1.171.27 transitivePeerDependencies: - csstype - '@tanstack/react-router-ssr-query@1.159.5(@tanstack/query-core@5.90.12)(@tanstack/react-query@5.90.12(react@19.2.3))(@tanstack/react-router@1.159.5(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(@tanstack/router-core@1.159.4)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': + '@tanstack/react-router-ssr-query@1.167.1(@tanstack/query-core@5.90.12)(@tanstack/react-query@5.90.12(react@19.2.3))(@tanstack/react-router@1.170.32(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(@tanstack/router-core@1.171.27)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': dependencies: '@tanstack/query-core': 5.90.12 '@tanstack/react-query': 5.90.12(react@19.2.3) - '@tanstack/react-router': 1.159.5(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@tanstack/router-ssr-query-core': 1.159.4(@tanstack/query-core@5.90.12)(@tanstack/router-core@1.159.4) + '@tanstack/react-router': 1.170.32(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@tanstack/router-ssr-query-core': 1.169.1(@tanstack/query-core@5.90.12)(@tanstack/router-core@1.171.27) react: 19.2.3 react-dom: 19.2.3(react@19.2.3) transitivePeerDependencies: @@ -25270,16 +25113,14 @@ snapshots: tiny-invariant: 1.3.3 tiny-warning: 1.0.3 - '@tanstack/react-router@1.159.5(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': + '@tanstack/react-router@1.170.32(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': dependencies: - '@tanstack/history': 1.154.14 - '@tanstack/react-store': 0.8.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@tanstack/router-core': 1.159.4 + '@tanstack/history': 1.162.1 + '@tanstack/react-store': 0.9.3(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@tanstack/router-core': 1.171.27 isbot: 5.1.32 react: 19.2.3 react-dom: 19.2.3(react@19.2.3) - tiny-invariant: 1.3.3 - tiny-warning: 1.0.3 '@tanstack/react-start-client@1.141.1(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': dependencies: @@ -25291,19 +25132,17 @@ snapshots: tiny-invariant: 1.3.3 tiny-warning: 1.0.3 - '@tanstack/react-start-client@1.159.5(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': + '@tanstack/react-start-client@1.168.30(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': dependencies: - '@tanstack/react-router': 1.159.5(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@tanstack/router-core': 1.159.4 - '@tanstack/start-client-core': 1.159.4 + '@tanstack/react-router': 1.170.32(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@tanstack/router-core': 1.171.27 + '@tanstack/start-client-core': 1.170.27 react: 19.2.3 react-dom: 19.2.3(react@19.2.3) - tiny-invariant: 1.3.3 - tiny-warning: 1.0.3 - '@tanstack/react-start-plugin@1.131.50(e7a157c953e155a2765d901b34df38b3)': + '@tanstack/react-start-plugin@1.131.50(5e76e58f58fcdc553da46eb093ac388b)': dependencies: - '@tanstack/start-plugin-core': 1.131.50(1a1cdd8b9c2c533357f243540b1932ef) + '@tanstack/start-plugin-core': 1.131.50(b114ec7757aa79b8f316a176b0457a25) '@vitejs/plugin-react': 4.7.0(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)) pathe: 2.0.3 vite: 8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0) @@ -25393,6 +25232,32 @@ snapshots: - xml2js - yaml + '@tanstack/react-start-rsc@0.1.48(crossws@0.4.6(srvx@0.11.17))(esbuild@0.28.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(rolldown@1.2.4)(rollup@4.60.1)(vite-plugin-solid@2.11.14(solid-js@1.9.10)(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)))(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0))': + dependencies: + '@tanstack/react-router': 1.170.32(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@tanstack/router-core': 1.171.27 + '@tanstack/router-utils': 1.162.2 + '@tanstack/start-client-core': 1.170.27 + '@tanstack/start-fn-stubs': 1.162.0 + '@tanstack/start-plugin-core': 1.171.39(@tanstack/react-router@1.170.32(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(crossws@0.4.6(srvx@0.11.17))(esbuild@0.28.1)(rolldown@1.2.4)(rollup@4.60.1)(vite-plugin-solid@2.11.14(solid-js@1.9.10)(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)))(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)) + '@tanstack/start-storage-context': 1.167.29 + pathe: 2.0.3 + react: 19.2.3 + react-dom: 19.2.3(react@19.2.3) + transitivePeerDependencies: + - '@farmfe/core' + - '@rsbuild/core' + - bun-types-no-globals + - crossws + - esbuild + - rolldown + - rollup + - supports-color + - unloader + - vite + - vite-plugin-solid + - webpack + '@tanstack/react-start-server@1.141.1(crossws@0.4.6(srvx@0.11.17))(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': dependencies: '@tanstack/history': 1.141.0 @@ -25405,38 +25270,52 @@ snapshots: transitivePeerDependencies: - crossws - '@tanstack/react-start-server@1.159.5(crossws@0.4.6(srvx@0.11.17))(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': + '@tanstack/react-start-server@1.167.37(crossws@0.4.6(srvx@0.11.17))(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': dependencies: - '@tanstack/history': 1.154.14 - '@tanstack/react-router': 1.159.5(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@tanstack/router-core': 1.159.4 - '@tanstack/start-client-core': 1.159.4 - '@tanstack/start-server-core': 1.159.4(crossws@0.4.6(srvx@0.11.17)) + '@tanstack/react-router': 1.170.32(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@tanstack/router-core': 1.171.27 + '@tanstack/start-server-core': 1.169.31(crossws@0.4.6(srvx@0.11.17)) react: 19.2.3 react-dom: 19.2.3(react@19.2.3) transitivePeerDependencies: - crossws - '@tanstack/react-start@1.159.5(crossws@0.4.6(srvx@0.11.17))(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(vite-plugin-solid@2.11.14(solid-js@1.9.10)(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)))(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0))': + '@tanstack/react-start@1.168.49(crossws@0.4.6(srvx@0.11.17))(esbuild@0.28.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(rolldown@1.2.4)(rollup@4.60.1)(vite-plugin-solid@2.11.14(solid-js@1.9.10)(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)))(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0))': dependencies: - '@tanstack/react-router': 1.159.5(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@tanstack/react-start-client': 1.159.5(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@tanstack/react-start-server': 1.159.5(crossws@0.4.6(srvx@0.11.17))(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@tanstack/router-utils': 1.158.0 - '@tanstack/start-client-core': 1.159.4 - '@tanstack/start-plugin-core': 1.159.5(@tanstack/react-router@1.159.5(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(crossws@0.4.6(srvx@0.11.17))(vite-plugin-solid@2.11.14(solid-js@1.9.10)(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)))(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)) - '@tanstack/start-server-core': 1.159.4(crossws@0.4.6(srvx@0.11.17)) + '@tanstack/react-router': 1.170.32(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@tanstack/react-start-client': 1.168.30(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@tanstack/react-start-rsc': 0.1.48(crossws@0.4.6(srvx@0.11.17))(esbuild@0.28.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(rolldown@1.2.4)(rollup@4.60.1)(vite-plugin-solid@2.11.14(solid-js@1.9.10)(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)))(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)) + '@tanstack/react-start-server': 1.167.37(crossws@0.4.6(srvx@0.11.17))(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@tanstack/router-utils': 1.162.2 + '@tanstack/start-client-core': 1.170.27 + '@tanstack/start-plugin-core': 1.171.39(@tanstack/react-router@1.170.32(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(crossws@0.4.6(srvx@0.11.17))(esbuild@0.28.1)(rolldown@1.2.4)(rollup@4.60.1)(vite-plugin-solid@2.11.14(solid-js@1.9.10)(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)))(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)) + '@tanstack/start-server-core': 1.169.31(crossws@0.4.6(srvx@0.11.17)) pathe: 2.0.3 react: 19.2.3 react-dom: 19.2.3(react@19.2.3) + optionalDependencies: vite: 8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0) transitivePeerDependencies: - - '@rsbuild/core' + - '@farmfe/core' + - '@rspack/core' + - bun-types-no-globals - crossws + - esbuild + - react-server-dom-rspack + - rolldown + - rollup - supports-color + - unloader - vite-plugin-solid - webpack + '@tanstack/react-store@0.11.1(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': + dependencies: + '@tanstack/store': 0.11.1 + react: 19.2.3 + react-dom: 19.2.3(react@19.2.3) + use-sync-external-store: 1.6.0(react@19.2.3) + '@tanstack/react-store@0.8.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': dependencies: '@tanstack/store': 0.8.0 @@ -25444,6 +25323,13 @@ snapshots: react-dom: 19.2.3(react@19.2.3) use-sync-external-store: 1.6.0(react@19.2.3) + '@tanstack/react-store@0.9.3(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': + dependencies: + '@tanstack/store': 0.9.3 + react: 19.2.3 + react-dom: 19.2.3(react@19.2.3) + use-sync-external-store: 1.6.0(react@19.2.3) + '@tanstack/router-core@1.131.50': dependencies: '@tanstack/history': 1.131.2 @@ -25474,22 +25360,18 @@ snapshots: tiny-invariant: 1.3.3 tiny-warning: 1.0.3 - '@tanstack/router-devtools-core@1.141.1(@tanstack/router-core@1.159.4)(csstype@3.2.3)(solid-js@1.9.10)': + '@tanstack/router-core@1.171.27': dependencies: - '@tanstack/router-core': 1.159.4 - clsx: 2.1.1 - goober: 2.1.18(csstype@3.2.3) - solid-js: 1.9.10 - tiny-invariant: 1.3.3 - optionalDependencies: - csstype: 3.2.3 + '@tanstack/history': 1.162.1 + cookie-es: 3.1.1 + seroval: 1.6.2 + seroval-plugins: 1.6.2(seroval@1.6.2) - '@tanstack/router-devtools-core@1.159.4(@tanstack/router-core@1.159.4)(csstype@3.2.3)': + '@tanstack/router-devtools-core@1.168.1(@tanstack/router-core@1.171.27)(csstype@3.2.3)': dependencies: - '@tanstack/router-core': 1.159.4 + '@tanstack/router-core': 1.171.27 clsx: 2.1.1 goober: 2.1.18(csstype@3.2.3) - tiny-invariant: 1.3.3 optionalDependencies: csstype: 3.2.3 @@ -25506,11 +25388,11 @@ snapshots: transitivePeerDependencies: - supports-color - '@tanstack/router-generator@1.141.1': + '@tanstack/router-generator@1.159.4': dependencies: - '@tanstack/router-core': 1.141.1 - '@tanstack/router-utils': 1.141.0 - '@tanstack/virtual-file-routes': 1.141.0 + '@tanstack/router-core': 1.159.4 + '@tanstack/router-utils': 1.158.0 + '@tanstack/virtual-file-routes': 1.154.7 prettier: 3.7.4 recast: 0.23.11 source-map: 0.7.6 @@ -25519,20 +25401,20 @@ snapshots: transitivePeerDependencies: - supports-color - '@tanstack/router-generator@1.159.4': + '@tanstack/router-generator@1.167.33': dependencies: - '@tanstack/router-core': 1.159.4 - '@tanstack/router-utils': 1.158.0 - '@tanstack/virtual-file-routes': 1.154.7 + '@babel/types': 7.29.7 + '@tanstack/router-core': 1.171.27 + '@tanstack/router-utils': 1.162.2 + '@tanstack/virtual-file-routes': 1.162.0 + jiti: 2.7.0 + magic-string: 0.30.21 prettier: 3.7.4 - recast: 0.23.11 - source-map: 0.7.6 - tsx: 4.21.0 - zod: 3.25.76 + zod: 4.4.3 transitivePeerDependencies: - supports-color - '@tanstack/router-plugin@1.131.50(@tanstack/react-router@1.159.5(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(vite-plugin-solid@2.11.14(solid-js@1.9.10)(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)))(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0))': + '@tanstack/router-plugin@1.131.50(@tanstack/react-router@1.170.32(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(vite-plugin-solid@2.11.14(solid-js@1.9.10)(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)))(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0))': dependencies: '@babel/core': 7.29.7 '@babel/plugin-syntax-jsx': 7.29.7(@babel/core@7.29.7) @@ -25549,13 +25431,13 @@ snapshots: unplugin: 2.3.11 zod: 3.25.76 optionalDependencies: - '@tanstack/react-router': 1.159.5(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@tanstack/react-router': 1.170.32(react-dom@19.2.3(react@19.2.3))(react@19.2.3) vite: 8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0) vite-plugin-solid: 2.11.14(solid-js@1.9.10)(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)) transitivePeerDependencies: - supports-color - '@tanstack/router-plugin@1.141.1(@tanstack/react-router@1.159.5(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(vite-plugin-solid@2.11.14(solid-js@1.9.10)(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)))(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0))': + '@tanstack/router-plugin@1.159.5(@tanstack/react-router@1.170.32(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(vite-plugin-solid@2.11.14(solid-js@1.9.10)(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)))(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0))': dependencies: '@babel/core': 7.29.7 '@babel/plugin-syntax-jsx': 7.29.7(@babel/core@7.29.7) @@ -25563,52 +25445,49 @@ snapshots: '@babel/template': 7.29.7 '@babel/traverse': 7.29.7 '@babel/types': 7.29.7 - '@tanstack/router-core': 1.141.1 - '@tanstack/router-generator': 1.141.1 - '@tanstack/router-utils': 1.141.0 - '@tanstack/virtual-file-routes': 1.141.0 - babel-dead-code-elimination: 1.0.10 + '@tanstack/router-core': 1.159.4 + '@tanstack/router-generator': 1.159.4 + '@tanstack/router-utils': 1.158.0 + '@tanstack/virtual-file-routes': 1.154.7 chokidar: 3.6.0 unplugin: 2.3.11 zod: 3.25.76 optionalDependencies: - '@tanstack/react-router': 1.159.5(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@tanstack/react-router': 1.170.32(react-dom@19.2.3(react@19.2.3))(react@19.2.3) vite: 8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0) vite-plugin-solid: 2.11.14(solid-js@1.9.10)(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)) transitivePeerDependencies: - supports-color - '@tanstack/router-plugin@1.159.5(@tanstack/react-router@1.159.5(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(supports-color@7.2.0)(vite-plugin-solid@2.11.14(solid-js@1.9.10)(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)))(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0))': + '@tanstack/router-plugin@1.168.35(@tanstack/react-router@1.170.32(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(esbuild@0.28.1)(rolldown@1.2.4)(rollup@4.60.1)(vite-plugin-solid@2.11.14(solid-js@1.9.10)(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)))(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0))': dependencies: - '@babel/core': 7.29.0(supports-color@7.2.0) - '@babel/plugin-syntax-jsx': 7.29.7(@babel/core@7.29.0) - '@babel/plugin-syntax-typescript': 7.27.1(@babel/core@7.29.0) + '@babel/core': 7.29.7 '@babel/template': 7.29.7 - '@babel/traverse': 7.29.7 '@babel/types': 7.29.7 - '@tanstack/router-core': 1.159.4 - '@tanstack/router-generator': 1.159.4 - '@tanstack/router-utils': 1.158.0 - '@tanstack/virtual-file-routes': 1.154.7 - chokidar: 3.6.0 - unplugin: 2.3.11 - zod: 3.25.76 + '@tanstack/router-core': 1.171.27 + '@tanstack/router-generator': 1.167.33 + '@tanstack/router-utils': 1.162.2 + chokidar: 5.0.0 + unplugin: 3.3.0(esbuild@0.28.1)(rolldown@1.2.4)(rollup@4.60.1)(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)) + zod: 4.4.3 optionalDependencies: - '@tanstack/react-router': 1.159.5(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@tanstack/react-router': 1.170.32(react-dom@19.2.3(react@19.2.3))(react@19.2.3) vite: 8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0) vite-plugin-solid: 2.11.14(solid-js@1.9.10)(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)) transitivePeerDependencies: + - '@farmfe/core' + - '@rspack/core' + - bun-types-no-globals + - esbuild + - rolldown + - rollup - supports-color + - unloader - '@tanstack/router-ssr-query-core@1.141.1(@tanstack/query-core@5.90.12)(@tanstack/router-core@1.159.4)': + '@tanstack/router-ssr-query-core@1.169.1(@tanstack/query-core@5.90.12)(@tanstack/router-core@1.171.27)': dependencies: '@tanstack/query-core': 5.90.12 - '@tanstack/router-core': 1.159.4 - - '@tanstack/router-ssr-query-core@1.159.4(@tanstack/query-core@5.90.12)(@tanstack/router-core@1.159.4)': - dependencies: - '@tanstack/query-core': 5.90.12 - '@tanstack/router-core': 1.159.4 + '@tanstack/router-core': 1.171.27 '@tanstack/router-utils@1.131.2': dependencies: @@ -25636,7 +25515,20 @@ snapshots: '@tanstack/router-utils@1.158.0': dependencies: - '@babel/core': 7.29.0(supports-color@7.2.0) + '@babel/core': 7.29.7 + '@babel/generator': 7.29.7 + '@babel/parser': 7.29.7 + '@babel/types': 7.29.7 + ansis: 4.2.0 + babel-dead-code-elimination: 1.0.12 + diff: 8.0.2 + pathe: 2.0.3 + tinyglobby: 0.2.17 + transitivePeerDependencies: + - supports-color + + '@tanstack/router-utils@1.162.2': + dependencies: '@babel/generator': 7.29.7 '@babel/parser': 7.29.7 '@babel/types': 7.29.7 @@ -25694,80 +25586,74 @@ snapshots: '@tanstack/query-core': 5.90.12 solid-js: 1.9.10 - '@tanstack/solid-router-devtools@1.141.1(@tanstack/router-core@1.159.4)(@tanstack/solid-router@1.141.1(solid-js@1.9.10))(csstype@3.2.3)(solid-js@1.9.10)': + '@tanstack/solid-router-devtools@1.167.1(@tanstack/router-core@1.171.27)(@tanstack/solid-router@1.170.30(solid-js@1.9.10))(csstype@3.2.3)(solid-js@1.9.10)': dependencies: - '@tanstack/router-devtools-core': 1.141.1(@tanstack/router-core@1.159.4)(csstype@3.2.3)(solid-js@1.9.10) - '@tanstack/solid-router': 1.141.1(solid-js@1.9.10) + '@tanstack/router-devtools-core': 1.168.1(@tanstack/router-core@1.171.27)(csstype@3.2.3) + '@tanstack/solid-router': 1.170.30(solid-js@1.9.10) solid-js: 1.9.10 optionalDependencies: - '@tanstack/router-core': 1.159.4 + '@tanstack/router-core': 1.171.27 transitivePeerDependencies: - csstype - '@tanstack/solid-router-ssr-query@1.141.1(@tanstack/query-core@5.90.12)(@tanstack/router-core@1.159.4)(@tanstack/solid-query@5.90.15(solid-js@1.9.10))(@tanstack/solid-router@1.141.1(solid-js@1.9.10))(eslint@9.39.4(jiti@2.7.0))(solid-js@1.9.10)(supports-color@7.2.0)(typescript@5.9.3)': + '@tanstack/solid-router-ssr-query@1.167.1(@tanstack/query-core@5.90.12)(@tanstack/router-core@1.171.27)(@tanstack/solid-query@5.90.15(solid-js@1.9.10))(@tanstack/solid-router@1.170.30(solid-js@1.9.10))(solid-js@1.9.10)': dependencies: '@tanstack/query-core': 5.90.12 - '@tanstack/router-ssr-query-core': 1.141.1(@tanstack/query-core@5.90.12)(@tanstack/router-core@1.159.4) + '@tanstack/router-ssr-query-core': 1.169.1(@tanstack/query-core@5.90.12)(@tanstack/router-core@1.171.27) '@tanstack/solid-query': 5.90.15(solid-js@1.9.10) - '@tanstack/solid-router': 1.141.1(solid-js@1.9.10) - eslint-plugin-solid: 0.14.5(eslint@9.39.4(jiti@2.7.0))(supports-color@7.2.0)(typescript@5.9.3) + '@tanstack/solid-router': 1.170.30(solid-js@1.9.10) solid-js: 1.9.10 transitivePeerDependencies: - '@tanstack/router-core' - - eslint - - supports-color - - typescript - '@tanstack/solid-router@1.141.1(solid-js@1.9.10)': + '@tanstack/solid-router@1.170.30(solid-js@1.9.10)': dependencies: - '@solid-devtools/logger': 0.9.11(solid-js@1.9.10) '@solid-primitives/refs': 1.1.2(solid-js@1.9.10) '@solidjs/meta': 0.29.4(solid-js@1.9.10) - '@tanstack/history': 1.141.0 - '@tanstack/router-core': 1.141.1 - '@tanstack/solid-store': 0.8.0(solid-js@1.9.10) + '@tanstack/history': 1.162.1 + '@tanstack/router-core': 1.171.27 isbot: 5.1.32 solid-js: 1.9.10 - tiny-invariant: 1.3.3 - tiny-warning: 1.0.3 - '@tanstack/solid-start-client@1.141.1(solid-js@1.9.10)': + '@tanstack/solid-start-client@1.168.29(solid-js@1.9.10)': dependencies: - '@tanstack/router-core': 1.141.1 - '@tanstack/solid-router': 1.141.1(solid-js@1.9.10) - '@tanstack/start-client-core': 1.141.1 + '@tanstack/router-core': 1.171.27 + '@tanstack/solid-router': 1.170.30(solid-js@1.9.10) + '@tanstack/start-client-core': 1.170.27 solid-js: 1.9.10 - tiny-invariant: 1.3.3 - tiny-warning: 1.0.3 - '@tanstack/solid-start-server@1.141.1(crossws@0.4.6(srvx@0.11.17))(solid-js@1.9.10)': + '@tanstack/solid-start-server@1.167.36(crossws@0.4.6(srvx@0.11.17))(solid-js@1.9.10)': dependencies: - '@solidjs/meta': 0.29.4(solid-js@1.9.10) - '@tanstack/history': 1.141.0 - '@tanstack/router-core': 1.141.1 - '@tanstack/solid-router': 1.141.1(solid-js@1.9.10) - '@tanstack/start-client-core': 1.141.1 - '@tanstack/start-server-core': 1.141.1(crossws@0.4.6(srvx@0.11.17)) + '@tanstack/router-core': 1.171.27 + '@tanstack/solid-router': 1.170.30(solid-js@1.9.10) + '@tanstack/start-server-core': 1.169.31(crossws@0.4.6(srvx@0.11.17)) solid-js: 1.9.10 transitivePeerDependencies: - crossws - '@tanstack/solid-start@1.141.1(@tanstack/react-router@1.159.5(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(crossws@0.4.6(srvx@0.11.17))(solid-js@1.9.10)(vite-plugin-solid@2.11.14(solid-js@1.9.10)(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)))(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0))': + '@tanstack/solid-start@1.168.47(@tanstack/react-router@1.170.32(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(crossws@0.4.6(srvx@0.11.17))(esbuild@0.28.1)(rolldown@1.2.4)(rollup@4.60.1)(solid-js@1.9.10)(vite-plugin-solid@2.11.14(solid-js@1.9.10)(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)))(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0))': dependencies: - '@tanstack/solid-router': 1.141.1(solid-js@1.9.10) - '@tanstack/solid-start-client': 1.141.1(solid-js@1.9.10) - '@tanstack/solid-start-server': 1.141.1(crossws@0.4.6(srvx@0.11.17))(solid-js@1.9.10) - '@tanstack/start-client-core': 1.141.1 - '@tanstack/start-plugin-core': 1.141.1(@tanstack/react-router@1.159.5(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(crossws@0.4.6(srvx@0.11.17))(vite-plugin-solid@2.11.14(solid-js@1.9.10)(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)))(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)) - '@tanstack/start-server-core': 1.141.1(crossws@0.4.6(srvx@0.11.17)) + '@tanstack/solid-router': 1.170.30(solid-js@1.9.10) + '@tanstack/solid-start-client': 1.168.29(solid-js@1.9.10) + '@tanstack/solid-start-server': 1.167.36(crossws@0.4.6(srvx@0.11.17))(solid-js@1.9.10) + '@tanstack/start-client-core': 1.170.27 + '@tanstack/start-plugin-core': 1.171.39(@tanstack/react-router@1.170.32(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(crossws@0.4.6(srvx@0.11.17))(esbuild@0.28.1)(rolldown@1.2.4)(rollup@4.60.1)(vite-plugin-solid@2.11.14(solid-js@1.9.10)(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)))(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)) + '@tanstack/start-server-core': 1.169.31(crossws@0.4.6(srvx@0.11.17)) pathe: 2.0.3 solid-js: 1.9.10 + optionalDependencies: vite: 8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0) transitivePeerDependencies: - - '@rsbuild/core' + - '@farmfe/core' + - '@rspack/core' - '@tanstack/react-router' + - bun-types-no-globals - crossws + - esbuild + - rolldown + - rollup - supports-color + - unloader - vite-plugin-solid - webpack @@ -25852,12 +25738,19 @@ snapshots: tiny-invariant: 1.3.3 tiny-warning: 1.0.3 + '@tanstack/start-client-core@1.170.27': + dependencies: + '@tanstack/router-core': 1.171.27 + '@tanstack/start-fn-stubs': 1.162.0 + '@tanstack/start-storage-context': 1.167.29 + seroval: 1.6.2 + '@tanstack/start-config@1.120.20(340eefabdbae5b0c948fd6f8943277d1)': dependencies: - '@tanstack/react-router': 1.159.5(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@tanstack/react-start-plugin': 1.131.50(e7a157c953e155a2765d901b34df38b3) + '@tanstack/react-router': 1.170.32(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@tanstack/react-start-plugin': 1.131.50(5e76e58f58fcdc553da46eb093ac388b) '@tanstack/router-generator': 1.159.4 - '@tanstack/router-plugin': 1.159.5(@tanstack/react-router@1.159.5(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(supports-color@7.2.0)(vite-plugin-solid@2.11.14(solid-js@1.9.10)(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)))(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)) + '@tanstack/router-plugin': 1.159.5(@tanstack/react-router@1.170.32(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(vite-plugin-solid@2.11.14(solid-js@1.9.10)(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)))(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)) '@tanstack/server-functions-plugin': 1.141.0(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)) '@tanstack/start-server-functions-handler': 1.120.19(crossws@0.4.6(srvx@0.11.17)) '@vitejs/plugin-react': 4.7.0(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)) @@ -25920,14 +25813,16 @@ snapshots: '@tanstack/start-fn-stubs@1.154.7': {} - '@tanstack/start-plugin-core@1.131.50(1a1cdd8b9c2c533357f243540b1932ef)': + '@tanstack/start-fn-stubs@1.162.0': {} + + '@tanstack/start-plugin-core@1.131.50(b114ec7757aa79b8f316a176b0457a25)': dependencies: '@babel/code-frame': 7.26.2 '@babel/core': 7.29.7 '@babel/types': 7.29.7 '@tanstack/router-core': 1.131.50 '@tanstack/router-generator': 1.131.50 - '@tanstack/router-plugin': 1.131.50(@tanstack/react-router@1.159.5(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(vite-plugin-solid@2.11.14(solid-js@1.9.10)(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)))(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)) + '@tanstack/router-plugin': 1.131.50(@tanstack/react-router@1.170.32(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(vite-plugin-solid@2.11.14(solid-js@1.9.10)(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)))(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)) '@tanstack/router-utils': 1.131.2 '@tanstack/server-functions-plugin': 1.131.2(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)) '@tanstack/start-server-core': 1.131.50 @@ -25940,7 +25835,7 @@ snapshots: pathe: 2.0.3 ufo: 1.6.3 vite: 8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0) - vitefu: 1.1.1(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)) + vitefu: 1.1.3(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)) xmlbuilder2: 3.1.1 zod: 3.25.76 transitivePeerDependencies: @@ -25978,65 +25873,41 @@ snapshots: - webpack - xml2js - '@tanstack/start-plugin-core@1.141.1(@tanstack/react-router@1.159.5(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(crossws@0.4.6(srvx@0.11.17))(vite-plugin-solid@2.11.14(solid-js@1.9.10)(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)))(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0))': - dependencies: - '@babel/code-frame': 7.26.2 - '@babel/core': 7.29.0(supports-color@7.2.0) - '@babel/types': 7.29.0 - '@rolldown/pluginutils': 1.0.0-beta.40 - '@tanstack/router-core': 1.141.1 - '@tanstack/router-generator': 1.141.1 - '@tanstack/router-plugin': 1.141.1(@tanstack/react-router@1.159.5(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(vite-plugin-solid@2.11.14(solid-js@1.9.10)(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)))(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)) - '@tanstack/router-utils': 1.141.0 - '@tanstack/server-functions-plugin': 1.141.0(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)) - '@tanstack/start-client-core': 1.141.1 - '@tanstack/start-server-core': 1.141.1(crossws@0.4.6(srvx@0.11.17)) - babel-dead-code-elimination: 1.0.10 - cheerio: 1.1.2 - exsolve: 1.0.8 - pathe: 2.0.3 - srvx: 0.8.16 - tinyglobby: 0.2.17 - ufo: 1.6.1 - vite: 8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0) - vitefu: 1.1.1(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)) - xmlbuilder2: 4.0.3 - zod: 3.25.76 - transitivePeerDependencies: - - '@rsbuild/core' - - '@tanstack/react-router' - - crossws - - supports-color - - vite-plugin-solid - - webpack - - '@tanstack/start-plugin-core@1.159.5(@tanstack/react-router@1.159.5(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(crossws@0.4.6(srvx@0.11.17))(vite-plugin-solid@2.11.14(solid-js@1.9.10)(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)))(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0))': + '@tanstack/start-plugin-core@1.171.39(@tanstack/react-router@1.170.32(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(crossws@0.4.6(srvx@0.11.17))(esbuild@0.28.1)(rolldown@1.2.4)(rollup@4.60.1)(vite-plugin-solid@2.11.14(solid-js@1.9.10)(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)))(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0))': dependencies: '@babel/code-frame': 7.27.1 - '@babel/core': 7.29.0(supports-color@7.2.0) + '@babel/core': 7.29.7 '@babel/types': 7.29.7 - '@rolldown/pluginutils': 1.0.0-beta.40 - '@tanstack/router-core': 1.159.4 - '@tanstack/router-generator': 1.159.4 - '@tanstack/router-plugin': 1.159.5(@tanstack/react-router@1.159.5(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(supports-color@7.2.0)(vite-plugin-solid@2.11.14(solid-js@1.9.10)(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)))(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)) - '@tanstack/router-utils': 1.158.0 - '@tanstack/start-client-core': 1.159.4 - '@tanstack/start-server-core': 1.159.4(crossws@0.4.6(srvx@0.11.17)) - cheerio: 1.1.2 + '@tanstack/router-core': 1.171.27 + '@tanstack/router-generator': 1.167.33 + '@tanstack/router-plugin': 1.168.35(@tanstack/react-router@1.170.32(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(esbuild@0.28.1)(rolldown@1.2.4)(rollup@4.60.1)(vite-plugin-solid@2.11.14(solid-js@1.9.10)(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)))(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)) + '@tanstack/router-utils': 1.162.2 + '@tanstack/start-server-core': 1.169.31(crossws@0.4.6(srvx@0.11.17)) exsolve: 1.0.8 + lightningcss: 1.33.0 pathe: 2.0.3 + picomatch: 4.0.5 + seroval: 1.6.2 + source-map: 0.7.6 srvx: 0.11.17 tinyglobby: 0.2.17 ufo: 1.6.3 - vite: 8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0) - vitefu: 1.1.1(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)) + vitefu: 1.1.3(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)) xmlbuilder2: 4.0.3 - zod: 3.25.76 + zod: 4.4.3 + optionalDependencies: + vite: 8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0) transitivePeerDependencies: - - '@rsbuild/core' + - '@farmfe/core' + - '@rspack/core' - '@tanstack/react-router' + - bun-types-no-globals - crossws + - esbuild + - rolldown + - rollup - supports-color + - unloader - vite-plugin-solid - webpack @@ -26076,6 +25947,18 @@ snapshots: transitivePeerDependencies: - crossws + '@tanstack/start-server-core@1.169.31(crossws@0.4.6(srvx@0.11.17))': + dependencies: + '@tanstack/history': 1.162.1 + '@tanstack/router-core': 1.171.27 + '@tanstack/start-client-core': 1.170.27 + '@tanstack/start-storage-context': 1.167.29 + fetchdts: 0.1.7 + h3-v2: h3@2.0.1-rc.20(crossws@0.4.6(srvx@0.11.17)) + seroval: 1.6.2 + transitivePeerDependencies: + - crossws + '@tanstack/start-server-functions-client@1.131.50(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0))': dependencies: '@tanstack/server-functions-plugin': 1.131.2(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)) @@ -26130,6 +26013,10 @@ snapshots: dependencies: '@tanstack/router-core': 1.159.4 + '@tanstack/start-storage-context@1.167.29': + dependencies: + '@tanstack/router-core': 1.171.27 + '@tanstack/start@1.120.20(340eefabdbae5b0c948fd6f8943277d1)': dependencies: '@tanstack/react-start-client': 1.141.1(react-dom@19.2.3(react@19.2.3))(react@19.2.3) @@ -26199,6 +26086,8 @@ snapshots: '@tanstack/store@0.8.0': {} + '@tanstack/store@0.9.3': {} + '@tanstack/typedoc-config@0.3.4': dependencies: typedoc: 0.28.20(@typescript/typescript6@6.0.2) @@ -26208,10 +26097,10 @@ snapshots: '@tanstack/virtual-file-routes@1.131.2': {} - '@tanstack/virtual-file-routes@1.141.0': {} - '@tanstack/virtual-file-routes@1.154.7': {} + '@tanstack/virtual-file-routes@1.162.0': {} + '@tanstack/vite-config@0.6.0(@microsoft/api-extractor@7.47.7(@types/node@24.10.3))(esbuild@0.28.1)(rolldown@1.1.5)(rollup@4.60.1)(supports-color@7.2.0)(typescript@7.0.2)(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0))': dependencies: vite: 8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0) @@ -26229,9 +26118,9 @@ snapshots: - typescript - webpack - '@tanstack/zod-adapter@1.166.9(@tanstack/react-router@1.159.5(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(zod@4.3.6)': + '@tanstack/zod-adapter@1.166.9(@tanstack/react-router@1.170.32(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(zod@4.3.6)': dependencies: - '@tanstack/react-router': 1.159.5(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@tanstack/react-router': 1.170.32(react-dom@19.2.3(react@19.2.3))(react@19.2.3) zod: 4.3.6 '@testing-library/dom@10.4.1': @@ -26566,15 +26455,6 @@ snapshots: - supports-color optional: true - '@typescript-eslint/project-service@8.49.0(supports-color@7.2.0)(typescript@5.9.3)': - dependencies: - '@typescript-eslint/tsconfig-utils': 8.49.0(typescript@5.9.3) - '@typescript-eslint/types': 8.59.4 - debug: 4.4.3(supports-color@7.2.0) - typescript: 5.9.3 - transitivePeerDependencies: - - supports-color - '@typescript-eslint/project-service@8.59.4(typescript@7.0.2)': dependencies: '@typescript-eslint/tsconfig-utils': 8.59.4(typescript@7.0.2) @@ -26585,21 +26465,12 @@ snapshots: - supports-color optional: true - '@typescript-eslint/scope-manager@8.49.0': - dependencies: - '@typescript-eslint/types': 8.49.0 - '@typescript-eslint/visitor-keys': 8.49.0 - '@typescript-eslint/scope-manager@8.59.4': dependencies: '@typescript-eslint/types': 8.59.4 '@typescript-eslint/visitor-keys': 8.59.4 optional: true - '@typescript-eslint/tsconfig-utils@8.49.0(typescript@5.9.3)': - dependencies: - typescript: 5.9.3 - '@typescript-eslint/tsconfig-utils@8.59.4(typescript@7.0.2)': dependencies: typescript: 7.0.2 @@ -26618,25 +26489,8 @@ snapshots: - supports-color optional: true - '@typescript-eslint/types@8.49.0': {} - '@typescript-eslint/types@8.59.4': {} - '@typescript-eslint/typescript-estree@8.49.0(supports-color@7.2.0)(typescript@5.9.3)': - dependencies: - '@typescript-eslint/project-service': 8.49.0(supports-color@7.2.0)(typescript@5.9.3) - '@typescript-eslint/tsconfig-utils': 8.49.0(typescript@5.9.3) - '@typescript-eslint/types': 8.49.0 - '@typescript-eslint/visitor-keys': 8.49.0 - debug: 4.4.3(supports-color@7.2.0) - minimatch: 9.0.5 - semver: 7.8.4 - tinyglobby: 0.2.17 - ts-api-utils: 2.1.0(typescript@5.9.3) - typescript: 5.9.3 - transitivePeerDependencies: - - supports-color - '@typescript-eslint/typescript-estree@8.59.4(typescript@7.0.2)': dependencies: '@typescript-eslint/project-service': 8.59.4(typescript@7.0.2) @@ -26653,17 +26507,6 @@ snapshots: - supports-color optional: true - '@typescript-eslint/utils@8.49.0(eslint@9.39.4(jiti@2.7.0))(supports-color@7.2.0)(typescript@5.9.3)': - dependencies: - '@eslint-community/eslint-utils': 4.9.1(eslint@9.39.4(jiti@2.7.0)) - '@typescript-eslint/scope-manager': 8.49.0 - '@typescript-eslint/types': 8.49.0 - '@typescript-eslint/typescript-estree': 8.49.0(supports-color@7.2.0)(typescript@5.9.3) - eslint: 9.39.4(jiti@2.7.0) - typescript: 5.9.3 - transitivePeerDependencies: - - supports-color - '@typescript-eslint/utils@8.59.4(eslint@9.39.4(jiti@2.7.0))(typescript@7.0.2)': dependencies: '@eslint-community/eslint-utils': 4.9.1(eslint@9.39.4(jiti@2.7.0)) @@ -26676,11 +26519,6 @@ snapshots: - supports-color optional: true - '@typescript-eslint/visitor-keys@8.49.0': - dependencies: - '@typescript-eslint/types': 8.49.0 - eslint-visitor-keys: 4.2.1 - '@typescript-eslint/visitor-keys@8.59.4': dependencies: '@typescript-eslint/types': 8.59.4 @@ -27413,15 +27251,6 @@ snapshots: transitivePeerDependencies: - supports-color - babel-plugin-jsx-dom-expressions@0.40.3(@babel/core@7.29.0): - dependencies: - '@babel/core': 7.29.0(supports-color@7.2.0) - '@babel/helper-module-imports': 7.18.6 - '@babel/plugin-syntax-jsx': 7.29.7(@babel/core@7.29.0) - '@babel/types': 7.29.7 - html-entities: 2.3.3 - parse5: 7.3.0 - babel-plugin-jsx-dom-expressions@0.40.3(@babel/core@7.29.7): dependencies: '@babel/core': 7.29.7 @@ -27575,13 +27404,6 @@ snapshots: - '@babel/core' - supports-color - babel-preset-solid@1.9.10(@babel/core@7.29.0)(solid-js@1.9.10): - dependencies: - '@babel/core': 7.29.0(supports-color@7.2.0) - babel-plugin-jsx-dom-expressions: 0.40.3(@babel/core@7.29.0) - optionalDependencies: - solid-js: 1.9.10 - babel-preset-solid@1.9.10(@babel/core@7.29.7)(solid-js@1.9.10): dependencies: '@babel/core': 7.29.7 @@ -28172,6 +27994,8 @@ snapshots: cookie-es@2.0.1: {} + cookie-es@3.1.1: {} + cookie-signature@1.2.2: {} cookie@0.6.0: {} @@ -28767,9 +28591,9 @@ snapshots: esbuild-plugin-solid@0.5.0(esbuild@0.28.1)(solid-js@1.9.10): dependencies: - '@babel/core': 7.29.0(supports-color@7.2.0) - '@babel/preset-typescript': 7.28.5(@babel/core@7.29.0) - babel-preset-solid: 1.9.10(@babel/core@7.29.0)(solid-js@1.9.10) + '@babel/core': 7.29.7 + '@babel/preset-typescript': 7.28.5(@babel/core@7.29.7) + babel-preset-solid: 1.9.10(@babel/core@7.29.7)(solid-js@1.9.10) esbuild: 0.28.1 solid-js: 1.9.10 transitivePeerDependencies: @@ -28906,19 +28730,6 @@ snapshots: optionalDependencies: source-map: 0.6.1 - eslint-plugin-solid@0.14.5(eslint@9.39.4(jiti@2.7.0))(supports-color@7.2.0)(typescript@5.9.3): - dependencies: - '@typescript-eslint/utils': 8.49.0(eslint@9.39.4(jiti@2.7.0))(supports-color@7.2.0)(typescript@5.9.3) - eslint: 9.39.4(jiti@2.7.0) - estraverse: 5.3.0 - is-html: 2.0.0 - kebab-case: 1.0.2 - known-css-properties: 0.30.0 - style-to-object: 1.0.14 - typescript: 5.9.3 - transitivePeerDependencies: - - supports-color - eslint-plugin-unused-imports@4.3.0(@typescript-eslint/eslint-plugin@8.59.4(@typescript-eslint/parser@8.59.4(eslint@9.39.4(jiti@2.7.0))(typescript@7.0.2))(eslint@9.39.4(jiti@2.7.0))(typescript@7.0.2))(eslint@9.39.4(jiti@2.7.0)): dependencies: eslint: 9.39.4(jiti@2.7.0) @@ -29762,6 +29573,13 @@ snapshots: optionalDependencies: crossws: 0.4.6(srvx@0.11.17) + h3@2.0.1-rc.20(crossws@0.4.6(srvx@0.11.17)): + dependencies: + rou3: 0.8.1 + srvx: 0.11.17 + optionalDependencies: + crossws: 0.4.6(srvx@0.11.17) + h3@2.0.1-rc.22(crossws@0.4.6(srvx@0.11.17)): dependencies: rou3: 0.8.1 @@ -29938,8 +29756,6 @@ snapshots: dependencies: cheerio: 1.1.2 - html-tags@3.3.1: {} - html-url-attributes@3.0.1: {} html-void-elements@3.0.0: {} @@ -30168,10 +29984,6 @@ snapshots: is-hexadecimal@2.0.1: {} - is-html@2.0.0: - dependencies: - html-tags: 3.3.1 - is-inside-container@1.0.0: dependencies: is-docker: 3.0.0 @@ -30536,8 +30348,6 @@ snapshots: jwa: 2.0.1 safe-buffer: 5.2.1 - kebab-case@1.0.2: {} - keyv@4.5.4: dependencies: json-buffer: 3.0.1 @@ -30579,8 +30389,6 @@ snapshots: knitwork@1.3.0: {} - known-css-properties@0.30.0: {} - kolorist@1.8.0: {} lan-network@0.2.1: {} @@ -31206,7 +31014,7 @@ snapshots: metro-source-map@0.84.4: dependencies: '@babel/traverse': 7.29.0 - '@babel/types': 7.29.0 + '@babel/types': 7.29.7 flow-enums-runtime: 0.0.6 invariant: 2.2.4 metro-symbolicate: 0.84.4 @@ -33883,7 +33691,7 @@ snapshots: dependencies: '@babel/generator': 7.28.5 '@babel/parser': 7.29.0 - '@babel/types': 7.29.0 + '@babel/types': 7.29.7 ast-kit: 2.2.0 birpc: 3.0.0 dts-resolver: 2.1.3(oxc-resolver@11.21.3) @@ -34220,12 +34028,18 @@ snapshots: dependencies: seroval: 1.5.0 + seroval-plugins@1.6.2(seroval@1.6.2): + dependencies: + seroval: 1.6.2 + seroval@1.3.2: {} seroval@1.4.0: {} seroval@1.5.0: {} + seroval@1.6.2: {} + serve-placeholder@2.0.2: dependencies: defu: 6.1.4 @@ -34882,10 +34696,6 @@ snapshots: ts-algebra@2.0.0: {} - ts-api-utils@2.1.0(typescript@5.9.3): - dependencies: - typescript: 5.9.3 - ts-api-utils@2.5.0(typescript@7.0.2): dependencies: typescript: 7.0.2 @@ -35278,6 +35088,17 @@ snapshots: picomatch: 4.0.5 webpack-virtual-modules: 0.6.2 + unplugin@3.3.0(esbuild@0.28.1)(rolldown@1.2.4)(rollup@4.60.1)(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)): + dependencies: + '@jridgewell/remapping': 2.3.5 + picomatch: 4.0.5 + webpack-virtual-modules: 0.6.2 + optionalDependencies: + esbuild: 0.28.1 + rolldown: 1.2.4 + rollup: 4.60.1 + vite: 8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0) + unrun@0.2.19(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.1): dependencies: rolldown: 1.0.0-beta.53(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.1) @@ -35673,10 +35494,6 @@ snapshots: tsx: 4.23.12 yaml: 2.9.0 - vitefu@1.1.1(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)): - optionalDependencies: - vite: 8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0) - vitefu@1.1.3(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)): optionalDependencies: vite: 8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0) @@ -36102,6 +35919,8 @@ snapshots: zod@4.3.6: {} + zod@4.4.3: {} + zone.js@0.15.1: {} zwitch@2.0.4: {} diff --git a/testing/e2e/package.json b/testing/e2e/package.json index a6d86fa5ec..cd6729fe1e 100644 --- a/testing/e2e/package.json +++ b/testing/e2e/package.json @@ -47,8 +47,8 @@ "@tanstack/devtools-event-bus": "^0.4.1", "@tanstack/nitro-v2-vite-plugin": "^1.155.0", "@tanstack/react-ai-devtools": "workspace:*", - "@tanstack/react-router": "^1.158.4", - "@tanstack/react-start": "^1.159.0", + "@tanstack/react-router": "^1.170.32", + "@tanstack/react-start": "^1.168.49", "arktype": "^2.1.28", "react": "^19.2.3", "react-dom": "^19.2.3", diff --git a/testing/e2e/src/components/ImageGenUI.tsx b/testing/e2e/src/components/ImageGenUI.tsx index 93cec8b7ce..bd59c7d159 100644 --- a/testing/e2e/src/components/ImageGenUI.tsx +++ b/testing/e2e/src/components/ImageGenUI.tsx @@ -1,4 +1,4 @@ -import { useState } from 'react' +import { useRef, useState } from 'react' import { useGenerateImage, fetchServerSentEvents, @@ -67,8 +67,12 @@ export function ImageGenUI({ } } - const { generate, result, isLoading, error, status } = + const { generate, result, isLoading, error, status, runId } = useGenerateImage(connectionOptions()) + const activeTuple = useRef({ runId: '', status: 'idle', isLoading: false }) + if (runId && status === 'generating' && isLoading) { + activeTuple.current = { runId, status, isLoading } + } const handleGenerate = async () => { if (!imageFile) { @@ -89,6 +93,12 @@ export function ImageGenUI({ return (
+ {activeTuple.current.runId} + {activeTuple.current.status} + + {String(activeTuple.current.isLoading)} + + {runId ?? ''}
{ if (!imageFile) { @@ -92,6 +96,12 @@ export function VideoGenUI({ return (
+ {activeTuple.current.runId} + {activeTuple.current.status} + + {String(activeTuple.current.isLoading)} + + {runId ?? ''}
{ 'Fender Stratocaster', ) + const hydrationErrors: Array = [] + page.on('pageerror', (error) => { + if ( + /hydration failed|hydrated but|server rendered html/i.test( + error.message, + ) + ) { + hydrationErrors.push(error.message) + } + }) + page.on('console', (message) => { + const text = message.text() + if ( + message.type() === 'error' && + /hydration failed|hydrated but|server rendered html/i.test(text) + ) { + hydrationErrors.push(text) + } + }) + await page.reload() await expect(page.getByTestId('user-message')).toContainText( @@ -232,6 +252,7 @@ test.describe('openai chat persistence', () => { await expect(page.getByTestId('assistant-message')).toContainText( 'Fender Stratocaster', ) + expect(hydrationErrors).toEqual([]) }) test('clear() removes the persisted conversation so a reload starts empty', async ({ diff --git a/testing/e2e/tests/generic-middleware-interrupts.spec.ts b/testing/e2e/tests/generic-middleware-interrupts.spec.ts index 083e841fd3..d6b65b69bf 100644 --- a/testing/e2e/tests/generic-middleware-interrupts.spec.ts +++ b/testing/e2e/tests/generic-middleware-interrupts.spec.ts @@ -307,6 +307,23 @@ test('restores a pending generic interrupt after reload and resumes it', async ( aimockPort, }) => { await startScenario(page, testId, aimockPort, 'generic-before-model') + const hydrationErrors: Array = [] + page.on('pageerror', (error) => { + if ( + /hydration failed|hydrated but|server rendered html/i.test(error.message) + ) { + hydrationErrors.push(error.message) + } + }) + page.on('console', (message) => { + const text = message.text() + if ( + message.type() === 'error' && + /hydration failed|hydrated but|server rendered html/i.test(text) + ) { + hydrationErrors.push(text) + } + }) await page.reload() await expect(page.getByTestId('generic-review-plan')).toBeVisible() await resolveReview(page) @@ -318,4 +335,5 @@ test('restores a pending generic interrupt after reload and resumes it', async ( expect(capture.resolutions).toEqual([ expect.objectContaining({ status: 'resolved' }), ]) + expect(hydrationErrors).toEqual([]) }) diff --git a/testing/e2e/tests/image-gen.spec.ts b/testing/e2e/tests/image-gen.spec.ts index 7997996fa5..927b6d77a5 100644 --- a/testing/e2e/tests/image-gen.spec.ts +++ b/testing/e2e/tests/image-gen.spec.ts @@ -20,6 +20,10 @@ for (const provider of providersFor('image-gen')) { await fillPrompt(page, 'a guitar in a music store') await clickGenerate(page) await waitForGenerationComplete(page) + await expect(page.getByTestId('active-run-id')).not.toHaveText('') + await expect(page.getByTestId('active-status')).toHaveText('generating') + await expect(page.getByTestId('active-loading')).toHaveText('true') + await expect(page.getByTestId('final-run-id')).toHaveText('') const images = page.getByTestId('generated-image') await expect(images).toHaveCount(1) }) @@ -35,6 +39,10 @@ for (const provider of providersFor('image-gen')) { await fillPrompt(page, 'a guitar in a music store') await clickGenerate(page) await waitForGenerationComplete(page) + await expect(page.getByTestId('active-run-id')).not.toHaveText('') + await expect(page.getByTestId('active-status')).toHaveText('generating') + await expect(page.getByTestId('active-loading')).toHaveText('true') + await expect(page.getByTestId('final-run-id')).toHaveText('') const images = page.getByTestId('generated-image') await expect(images).toHaveCount(1) }) @@ -50,6 +58,10 @@ for (const provider of providersFor('image-gen')) { await fillPrompt(page, 'a guitar in a music store') await clickGenerate(page) await waitForGenerationComplete(page) + await expect(page.getByTestId('active-run-id')).not.toHaveText('') + await expect(page.getByTestId('active-status')).toHaveText('generating') + await expect(page.getByTestId('active-loading')).toHaveText('true') + await expect(page.getByTestId('final-run-id')).toHaveText('') const images = page.getByTestId('generated-image') await expect(images).toHaveCount(1) }) diff --git a/testing/e2e/tests/persistence-durability.spec.ts b/testing/e2e/tests/persistence-durability.spec.ts index 0c57dcd9ff..a6af750e7f 100644 --- a/testing/e2e/tests/persistence-durability.spec.ts +++ b/testing/e2e/tests/persistence-durability.spec.ts @@ -59,6 +59,26 @@ test.describe('persistence durability (browser refresh)', () => { expect(Array.isArray(record.messages)).toBe(true) expect(record.messages.length).toBeGreaterThanOrEqual(2) + const hydrationErrors: Array = [] + page.on('pageerror', (error) => { + if ( + /hydration failed|hydrated but|server rendered html/i.test( + error.message, + ) + ) { + hydrationErrors.push(error.message) + } + }) + page.on('console', (message) => { + const text = message.text() + if ( + message.type() === 'error' && + /hydration failed|hydrated but|server rendered html/i.test(text) + ) { + hydrationErrors.push(text) + } + }) + // Full reload: the conversation must come back from localStorage alone. await page.reload() @@ -71,6 +91,7 @@ test.describe('persistence durability (browser refresh)', () => { ) // No in-flight run to rejoin after a clean finish — the page settles idle. await expect(page.getByTestId('loading-indicator')).toHaveCount(0) + expect(hydrationErrors).toEqual([]) }) test('a pending interrupt survives a reload (rehydrated from the resume snapshot)', async ({ @@ -98,6 +119,26 @@ test.describe('persistence durability (browser refresh)', () => { const record = JSON.parse(stored!) as { resume?: unknown } expect(record.resume).toBeTruthy() + const hydrationErrors: Array = [] + page.on('pageerror', (error) => { + if ( + /hydration failed|hydrated but|server rendered html/i.test( + error.message, + ) + ) { + hydrationErrors.push(error.message) + } + }) + page.on('console', (message) => { + const text = message.text() + if ( + message.type() === 'error' && + /hydration failed|hydrated but|server rendered html/i.test(text) + ) { + hydrationErrors.push(text) + } + }) + // Full reload: the interrupt must rehydrate from localStorage, not a refetch. await page.reload() @@ -108,6 +149,7 @@ test.describe('persistence durability (browser refresh)', () => { await expect(page.getByTestId('interrupt-confirm-shipment')).toBeVisible() await expect(page.getByTestId('interrupt-kind')).toHaveText('generic') await expect(page.getByTestId('interrupt-source')).toHaveText('hydrate') + expect(hydrationErrors).toEqual([]) }) test('restores a pending interrupt from the SERVER on a fresh load (persistence: true)', async ({ diff --git a/testing/e2e/tests/video-gen.spec.ts b/testing/e2e/tests/video-gen.spec.ts index 841fbccb8e..d7f5da6a62 100644 --- a/testing/e2e/tests/video-gen.spec.ts +++ b/testing/e2e/tests/video-gen.spec.ts @@ -20,6 +20,10 @@ for (const provider of providersFor('video-gen')) { await fillPrompt(page, 'a guitar being played in a store') await clickGenerate(page) await waitForGenerationComplete(page, 60_000) + await expect(page.getByTestId('active-run-id')).not.toHaveText('') + await expect(page.getByTestId('active-status')).toHaveText('generating') + await expect(page.getByTestId('active-loading')).toHaveText('true') + await expect(page.getByTestId('final-run-id')).toHaveText('') const video = page.getByTestId('generated-video') await expect(video).toBeVisible() }) @@ -35,6 +39,10 @@ for (const provider of providersFor('video-gen')) { await fillPrompt(page, 'a guitar being played in a store') await clickGenerate(page) await waitForGenerationComplete(page, 60_000) + await expect(page.getByTestId('active-run-id')).not.toHaveText('') + await expect(page.getByTestId('active-status')).toHaveText('generating') + await expect(page.getByTestId('active-loading')).toHaveText('true') + await expect(page.getByTestId('final-run-id')).toHaveText('') const video = page.getByTestId('generated-video') await expect(video).toBeVisible() }) @@ -50,6 +58,10 @@ for (const provider of providersFor('video-gen')) { await fillPrompt(page, 'a guitar being played in a store') await clickGenerate(page) await waitForGenerationComplete(page, 60_000) + await expect(page.getByTestId('active-run-id')).not.toHaveText('') + await expect(page.getByTestId('active-status')).toHaveText('generating') + await expect(page.getByTestId('active-loading')).toHaveText('true') + await expect(page.getByTestId('final-run-id')).toHaveText('') const video = page.getByTestId('generated-video') await expect(video).toBeVisible() }) diff --git a/testing/panel/package.json b/testing/panel/package.json index f51fa0b379..320270b00b 100644 --- a/testing/panel/package.json +++ b/testing/panel/package.json @@ -28,8 +28,8 @@ "@tanstack/nitro-v2-vite-plugin": "^1.155.0", "@tanstack/react-ai-devtools": "workspace:*", "@tanstack/react-devtools": "^0.9.10", - "@tanstack/react-router": "^1.158.4", - "@tanstack/react-start": "^1.159.0", + "@tanstack/react-router": "^1.170.32", + "@tanstack/react-start": "^1.168.49", "@tanstack/start": "^1.120.20", "highlight.js": "^11.11.1", "lucide-react": "^0.561.0", From 55f0682f987f41bc8aa1d61bdf29872a0f5dfcbc Mon Sep 17 00:00:00 2001 From: Alem Tuzlak Date: Thu, 27 Aug 2026 12:48:03 +0200 Subject: [PATCH 3/8] fix(ai-solid): apply chat snapshot before first paint createEffect runs after paint, so persisted messages and resume state never showed on the first render. Apply the snapshot during setup after live subscribe, same as Vue and Solid generation hooks. --- packages/ai-solid/src/use-chat.ts | 5 +++++ packages/ai-solid/tests/use-chat.test.ts | 16 +++++++++++----- 2 files changed, 16 insertions(+), 5 deletions(-) diff --git a/packages/ai-solid/src/use-chat.ts b/packages/ai-solid/src/use-chat.ts index 19ddf0f85b..b5eba10893 100644 --- a/packages/ai-solid/src/use-chat.ts +++ b/packages/ai-solid/src/use-chat.ts @@ -207,6 +207,11 @@ export function useChat< client().unsubscribe() } + // First paint must see constructor hydration (sync store / resume snapshot) + // and the live subscribe above. `createEffect` runs after paint, so the + // subscribe effect cannot be the first apply. + applySnapshot(client()) + createEffect(() => { if (options.live) { client().subscribe() diff --git a/packages/ai-solid/tests/use-chat.test.ts b/packages/ai-solid/tests/use-chat.test.ts index 050654c896..52d182bac7 100644 --- a/packages/ai-solid/tests/use-chat.test.ts +++ b/packages/ai-solid/tests/use-chat.test.ts @@ -153,14 +153,20 @@ describe('useChat', () => { removeItem: vi.fn(), } - const { result } = renderUseChat({ - connection: adapter, - threadId: 'persisted-chat', - persistence: persistence, + let firstMessages: Array | undefined + const rendered = renderHook(() => { + const chat = useChat({ + connection: adapter, + threadId: 'persisted-chat', + persistence, + }) + firstMessages ??= chat.messages() + return chat }) + expect(firstMessages).toEqual(persistedMessages) await waitFor(() => { - expect(result.current.messages).toEqual(persistedMessages) + expect(rendered.result.messages()).toEqual(persistedMessages) }) expect(persistence.getItem).toHaveBeenCalledWith('persisted-chat') }) From 8ce4ad333273d6f8633174ed0ff6411a9477d9df Mon Sep 17 00:00:00 2001 From: Tom Beckenham <34339192+tombeckenham@users.noreply.github.com> Date: Sun, 30 Aug 2026 12:40:12 +1000 Subject: [PATCH 4/8] fix(ai-client): address snapshot review after rebase Keep compaction custom-event routing. Freeze published generation results, keep in-flight run ids, apply Octane snapshots before first paint, and type snapshot collections as readonly. --- .changeset/ai-client-store-snapshot.md | 4 +- docs/api/ai-client.md | 24 +- docs/config.json | 2 +- examples/sandbox-cloudflare/package.json | 6 +- examples/sandbox-web/package.json | 6 +- examples/sandbox-web/src/routeTree.gen.ts | 26 +- examples/ts-code-mode-web/package.json | 6 +- .../ts-code-mode-web/src/routeTree.gen.ts | 640 ++++---- .../routes/_banking-demo/api.banking-demo.ts | 2 +- .../routes/_banking-demo/api.banking-init.ts | 2 +- .../src/routes/_banking-demo/banking-demo.tsx | 2 +- .../_database-demo/api.database-demo.ts | 4 +- .../routes/_database-demo/api.db-snippets.ts | 2 +- .../src/routes/_database-demo/api.judge.ts | 2 +- .../routes/_database-demo/database-demo.tsx | 2 +- .../_execute-prompt/api.execute-prompt.ts | 4 +- .../_execute-prompt/api.realtime-token.ts | 4 +- .../routes/_execute-prompt/execute-prompt.tsx | 2 +- .../src/routes/_reporting/api.invalidate.ts | 2 +- .../src/routes/_reporting/api.report-demo.ts | 2 +- .../src/routes/_reporting/api.report-event.ts | 2 +- .../src/routes/_reporting/api.report-sse.ts | 2 +- .../src/routes/_reporting/api.reports.ts | 2 +- examples/ts-group-chat/package.json | 8 +- examples/ts-react-chat/package.json | 12 +- examples/ts-react-media/package.json | 6 +- examples/ts-react-media/src/routeTree.gen.ts | 26 +- examples/ts-react-rerank/package.json | 6 +- examples/ts-react-search/package.json | 10 +- examples/ts-react-search/src/routeTree.gen.ts | 152 +- examples/ts-solid-chat/package.json | 10 +- examples/ts-solid-chat/src/routeTree.gen.ts | 6 +- packages/ai-angular/src/inject-chat.ts | 4 +- packages/ai-client/src/chat-client.ts | 10 +- packages/ai-client/src/generation-client.ts | 21 +- packages/ai-client/src/generation-types.ts | 14 +- packages/ai-client/src/realtime-types.ts | 12 +- packages/ai-client/src/snapshot-atom.ts | 6 + packages/ai-client/src/types.ts | 20 +- .../ai-client/src/video-generation-client.ts | 21 +- .../ai-client/tests/client-snapshots.test.ts | 8 + .../ai-client/tests/generation-client.test.ts | 51 + packages/ai-octane/src/use-chat.tsrx | 71 +- .../tests/conformance/use-chat.test.ts | 18 +- packages/ai-preact/src/use-chat.ts | 5 +- packages/ai-preact/tests/use-chat.test.ts | 37 + packages/ai-react/src/use-chat.ts | 10 +- packages/ai-react/tests/use-chat.test.ts | 37 + packages/ai-solid/src/use-chat.ts | 6 +- packages/ai-svelte/src/create-chat.svelte.ts | 4 +- packages/ai-vertex/package.json | 1 + packages/ai-vertex/tests/factories.test.ts | 86 +- packages/ai-vue/src/use-chat.ts | 4 +- pnpm-lock.yaml | 1297 ++++++++++------- testing/e2e/package.json | 4 +- testing/panel/package.json | 4 +- 56 files changed, 1519 insertions(+), 1218 deletions(-) diff --git a/.changeset/ai-client-store-snapshot.md b/.changeset/ai-client-store-snapshot.md index 6a54bb2918..8fa61cb5b7 100644 --- a/.changeset/ai-client-store-snapshot.md +++ b/.changeset/ai-client-store-snapshot.md @@ -9,6 +9,6 @@ '@tanstack/ai-octane': patch --- -Hold client UI state in a TanStack Store atom. Framework hooks read `getSnapshot()` instead of copying fields through change callbacks. React `useChat()` first commits `initialMessages` and `initialResumeSnapshot`, then applies browser persistence after attach. This timing applies to client-only rendering and keeps the server snapshot stable during SSR hydration. The `useChat()` return shape stays the same. +Hold client UI state in a TanStack Store atom. Framework hooks read `getSnapshot()` instead of copying fields through change callbacks. React `useChat()` first commits `initialMessages` and `initialResumeSnapshot`, then applies browser persistence after attach. This timing applies to client-only rendering and keeps the server snapshot stable during SSR hydration. The `useChat()` return shape stays the same. Frozen snapshot `messages` and `queue` arrays throw on in-place `push` in every adapter. Use `setMessages`. -`ChatClient` adds `subscribeSnapshot` / `getSnapshot`. The live connection method stays `subscribe()`. Generation, video, realtime, audio, and BYOK clients expose the same snapshot pair (`subscribe` / `getSnapshot`) where the name does not collide. +`ChatClient` adds `subscribeSnapshot` / `getSnapshot`. The live connection method stays `subscribe()`. Generation, video, realtime, and BYOK clients expose `subscribe` / `getSnapshot`. `AudioRecorder.subscribe` still passes the new state value. diff --git a/docs/api/ai-client.md b/docs/api/ai-client.md index 397919495d..3783965218 100644 --- a/docs/api/ai-client.md +++ b/docs/api/ai-client.md @@ -275,11 +275,14 @@ id, so a later `attach()` continues where it left off. See #### `getSnapshot()` -Returns the current UI snapshot: messages, status, loading, error, queue, run -id, subscription, connection, session generating, and interrupt state. - -`subscribeSnapshot(listener)` calls `listener` after that snapshot changes. It -does not fire with the current value. Read `getSnapshot()` first. This is not +Returns the current frozen `ChatClientSnapshot`. The field names are +`messages`, `status`, `isLoading`, `error`, `queue`, `runId`, `isSubscribed`, +`connectionStatus`, `sessionGenerating`, and `interruptState`. Nested +`messages` and `queue` entries are copies. In-place `messages.push` throws. +Use `setMessages`. + +`subscribeSnapshot(listener)` returns an unsubscribe function. It does not +fire with the current value. Read `getSnapshot()` first. This is not `subscribe()`, which starts the live connection loop. ```typescript @@ -296,7 +299,7 @@ function logSnapshot() { logSnapshot(); -const stop = client.subscribeSnapshot(() => { +const unsubscribe = client.subscribeSnapshot(() => { logSnapshot(); }); @@ -304,9 +307,12 @@ client.attach(); client.sendMessage("Hello"); ``` -`GenerationClient`, `VideoGenerationClient`, `RealtimeClient`, `AudioRecorder`, -and `ByokClient` use `subscribe(listener)` / `getSnapshot()` for the same job. -Their `subscribe` name does not collide with a live connection method. +`GenerationClient`, `VideoGenerationClient`, `RealtimeClient`, and +`ByokClient` use `subscribe(listener)` / `getSnapshot()`. The listener takes +no argument. Call `getSnapshot()` inside it. + +`AudioRecorder.subscribe` still passes the new state: +`subscribe((state) => ...)`. `getSnapshot()` returns that same state value. #### `stop()` diff --git a/docs/config.json b/docs/config.json index f2e7b13277..bfa93357e5 100644 --- a/docs/config.json +++ b/docs/config.json @@ -486,7 +486,7 @@ "label": "Client Persistence", "to": "persistence/client-persistence", "addedAt": "2026-08-04", - "updatedAt": "2026-08-20" + "updatedAt": "2026-08-24" }, { "label": "Generation Persistence", diff --git a/examples/sandbox-cloudflare/package.json b/examples/sandbox-cloudflare/package.json index 1375ec6d77..b6038d8cf8 100644 --- a/examples/sandbox-cloudflare/package.json +++ b/examples/sandbox-cloudflare/package.json @@ -22,8 +22,8 @@ "@tanstack/ai-sandbox": "workspace:*", "@tanstack/ai-sandbox-cloudflare": "workspace:*", "@tanstack/ai-sandbox-local-process": "workspace:*", - "@tanstack/react-router": "^1.170.32", - "@tanstack/react-start": "^1.168.49", + "@tanstack/react-router": "^1.158.4", + "@tanstack/react-start": "^1.159.0", "lucide-react": "^0.561.0", "react": "^19.2.3", "react-dom": "^19.2.3", @@ -37,7 +37,7 @@ "devDependencies": { "@cloudflare/vite-plugin": "^1.42.1", "@tailwindcss/vite": "^4.1.18", - "@tanstack/router-plugin": "^1.168.35", + "@tanstack/router-plugin": "^1.158.4", "@types/node": "^24.10.1", "@types/react": "^19.2.7", "@types/react-dom": "^19.2.3", diff --git a/examples/sandbox-web/package.json b/examples/sandbox-web/package.json index 941ff6df61..75f96ab13e 100644 --- a/examples/sandbox-web/package.json +++ b/examples/sandbox-web/package.json @@ -17,8 +17,8 @@ "@tanstack/ai-react": "workspace:*", "@tanstack/ai-sandbox": "workspace:*", "@tanstack/ai-sandbox-docker": "workspace:*", - "@tanstack/react-router": "^1.170.32", - "@tanstack/react-start": "^1.168.49", + "@tanstack/react-router": "^1.158.4", + "@tanstack/react-start": "^1.159.0", "lucide-react": "^0.561.0", "react": "^19.2.3", "react-dom": "^19.2.3", @@ -31,7 +31,7 @@ }, "devDependencies": { "@tailwindcss/vite": "^4.1.18", - "@tanstack/router-plugin": "^1.168.35", + "@tanstack/router-plugin": "^1.158.4", "@types/node": "^24.10.1", "@types/react": "^19.2.7", "@types/react-dom": "^19.2.3", diff --git a/examples/sandbox-web/src/routeTree.gen.ts b/examples/sandbox-web/src/routeTree.gen.ts index 1e6a913d7e..5bc1e9dd01 100644 --- a/examples/sandbox-web/src/routeTree.gen.ts +++ b/examples/sandbox-web/src/routeTree.gen.ts @@ -11,8 +11,8 @@ import { Route as rootRouteImport } from './routes/__root' import { Route as IndexRouteImport } from './routes/index' import { Route as ApiRunRouteImport } from './routes/api.run' -import { Route as ApiRunActiveRouteImport } from './routes/api.run.active' import { Route as ApiRunCancelRouteImport } from './routes/api.run.cancel' +import { Route as ApiRunActiveRouteImport } from './routes/api.run.active' const IndexRoute = IndexRouteImport.update({ id: '/', @@ -24,16 +24,16 @@ const ApiRunRoute = ApiRunRouteImport.update({ path: '/api/run', getParentRoute: () => rootRouteImport, } as any) -const ApiRunActiveRoute = ApiRunActiveRouteImport.update({ - id: '/active', - path: '/active', - getParentRoute: () => ApiRunRoute, -} as any) const ApiRunCancelRoute = ApiRunCancelRouteImport.update({ id: '/cancel', path: '/cancel', getParentRoute: () => ApiRunRoute, } as any) +const ApiRunActiveRoute = ApiRunActiveRouteImport.update({ + id: '/active', + path: '/active', + getParentRoute: () => ApiRunRoute, +} as any) export interface FileRoutesByFullPath { '/': typeof IndexRoute @@ -83,13 +83,6 @@ declare module '@tanstack/react-router' { preLoaderRoute: typeof ApiRunRouteImport parentRoute: typeof rootRouteImport } - '/api/run/active': { - id: '/api/run/active' - path: '/active' - fullPath: '/api/run/active' - preLoaderRoute: typeof ApiRunActiveRouteImport - parentRoute: typeof ApiRunRoute - } '/api/run/cancel': { id: '/api/run/cancel' path: '/cancel' @@ -97,6 +90,13 @@ declare module '@tanstack/react-router' { preLoaderRoute: typeof ApiRunCancelRouteImport parentRoute: typeof ApiRunRoute } + '/api/run/active': { + id: '/api/run/active' + path: '/active' + fullPath: '/api/run/active' + preLoaderRoute: typeof ApiRunActiveRouteImport + parentRoute: typeof ApiRunRoute + } } } diff --git a/examples/ts-code-mode-web/package.json b/examples/ts-code-mode-web/package.json index c829b45cf6..ed5a5978ee 100644 --- a/examples/ts-code-mode-web/package.json +++ b/examples/ts-code-mode-web/package.json @@ -32,9 +32,9 @@ "@tanstack/ai-ollama": "workspace:*", "@tanstack/ai-openai": "workspace:*", "@tanstack/ai-react": "workspace:*", - "@tanstack/react-router": "^1.170.32", - "@tanstack/react-start": "^1.168.49", - "@tanstack/router-plugin": "^1.168.35", + "@tanstack/react-router": "^1.158.4", + "@tanstack/react-start": "^1.159.0", + "@tanstack/router-plugin": "^1.158.4", "@tanstack/store": "^0.11.1", "framer-motion": "^11.15.0", "highlight.js": "^11.11.1", diff --git a/examples/ts-code-mode-web/src/routeTree.gen.ts b/examples/ts-code-mode-web/src/routeTree.gen.ts index 81c372c1ec..e8255fd491 100644 --- a/examples/ts-code-mode-web/src/routeTree.gen.ts +++ b/examples/ts-code-mode-web/src/routeTree.gen.ts @@ -9,101 +9,78 @@ // Additionally, you should also exclude this file from your linter and/or formatter to prevent it from being checked or modified. import { Route as rootRouteImport } from './routes/__root' -import { Route as BankingDemoRouteRouteImport } from './routes/_banking-demo/route' -import { Route as DatabaseDemoRouteRouteImport } from './routes/_database-demo/route' -import { Route as ExecutePromptRouteRouteImport } from './routes/_execute-prompt/route' -import { Route as HomeRouteRouteImport } from './routes/_home/route' -import { Route as NpmGithubChatRouteRouteImport } from './routes/_npm-github-chat/route' -import { Route as ReportingRouteRouteImport } from './routes/_reporting/route' import { Route as StructuredOutputRouteRouteImport } from './routes/_structured-output/route' -import { Route as BankingDemoBankingDemoRouteImport } from './routes/_banking-demo/banking-demo' -import { Route as DatabaseDemoDatabaseDemoRouteImport } from './routes/_database-demo/database-demo' -import { Route as ExecutePromptExecutePromptRouteImport } from './routes/_execute-prompt/execute-prompt' +import { Route as ReportingRouteRouteImport } from './routes/_reporting/route' +import { Route as NpmGithubChatRouteRouteImport } from './routes/_npm-github-chat/route' +import { Route as HomeRouteRouteImport } from './routes/_home/route' +import { Route as ExecutePromptRouteRouteImport } from './routes/_execute-prompt/route' +import { Route as DatabaseDemoRouteRouteImport } from './routes/_database-demo/route' +import { Route as BankingDemoRouteRouteImport } from './routes/_banking-demo/route' import { Route as HomeIndexRouteImport } from './routes/_home/index' -import { Route as NpmGithubChatNpmGithubChatRouteImport } from './routes/_npm-github-chat/npm-github-chat' -import { Route as ReportingReportingAgentRouteImport } from './routes/_reporting/reporting-agent' -import { Route as StructuredOutputStructuredOutputRouteImport } from './routes/_structured-output/structured-output' import { Route as ApiRuntimeRouteImport } from './routes/api.runtime' -import { Route as BankingDemoApiBankingDemoRouteImport } from './routes/_banking-demo/api.banking-demo' -import { Route as BankingDemoApiBankingInitRouteImport } from './routes/_banking-demo/api.banking-init' -import { Route as DatabaseDemoApiDatabaseDemoRouteImport } from './routes/_database-demo/api.database-demo' -import { Route as DatabaseDemoApiDbSnippetsRouteImport } from './routes/_database-demo/api.db-snippets' -import { Route as DatabaseDemoApiJudgeRouteImport } from './routes/_database-demo/api.judge' -import { Route as ExecutePromptApiExecutePromptRouteImport } from './routes/_execute-prompt/api.execute-prompt' -import { Route as ExecutePromptApiRealtimeTokenRouteImport } from './routes/_execute-prompt/api.realtime-token' -import { Route as HomeApiProductCodemodeRouteImport } from './routes/_home/api.product-codemode' -import { Route as HomeApiProductRegularRouteImport } from './routes/_home/api.product-regular' -import { Route as HomeApiSnippetsRouteImport } from './routes/_home/api.snippets' -import { Route as NpmGithubChatApiCodemodeRouteImport } from './routes/_npm-github-chat/api.codemode' -import { Route as NpmGithubChatApiGeneratePdfRouteImport } from './routes/_npm-github-chat/api.generate-pdf' -import { Route as ReportingApiInvalidateRouteImport } from './routes/_reporting/api.invalidate' -import { Route as ReportingApiReportDemoRouteImport } from './routes/_reporting/api.report-demo' -import { Route as ReportingApiReportEventRouteImport } from './routes/_reporting/api.report-event' -import { Route as ReportingApiReportSseRouteImport } from './routes/_reporting/api.report-sse' -import { Route as ReportingApiReportsRouteImport } from './routes/_reporting/api.reports' -import { Route as StructuredOutputApiStructuredOutputRouteImport } from './routes/_structured-output/api.structured-output' +import { Route as StructuredOutputStructuredOutputRouteImport } from './routes/_structured-output/structured-output' +import { Route as ReportingReportingAgentRouteImport } from './routes/_reporting/reporting-agent' +import { Route as NpmGithubChatNpmGithubChatRouteImport } from './routes/_npm-github-chat/npm-github-chat' +import { Route as ExecutePromptExecutePromptRouteImport } from './routes/_execute-prompt/execute-prompt' +import { Route as DatabaseDemoDatabaseDemoRouteImport } from './routes/_database-demo/database-demo' +import { Route as BankingDemoBankingDemoRouteImport } from './routes/_banking-demo/banking-demo' import { Route as StructuredOutputApiStructuredOutputSnippetsRouteImport } from './routes/_structured-output/api.structured-output-snippets' +import { Route as StructuredOutputApiStructuredOutputRouteImport } from './routes/_structured-output/api.structured-output' +import { Route as ReportingApiReportsRouteImport } from './routes/_reporting/api.reports' +import { Route as ReportingApiReportSseRouteImport } from './routes/_reporting/api.report-sse' +import { Route as ReportingApiReportEventRouteImport } from './routes/_reporting/api.report-event' +import { Route as ReportingApiReportDemoRouteImport } from './routes/_reporting/api.report-demo' +import { Route as ReportingApiInvalidateRouteImport } from './routes/_reporting/api.invalidate' +import { Route as NpmGithubChatApiGeneratePdfRouteImport } from './routes/_npm-github-chat/api.generate-pdf' +import { Route as NpmGithubChatApiCodemodeRouteImport } from './routes/_npm-github-chat/api.codemode' +import { Route as HomeApiSnippetsRouteImport } from './routes/_home/api.snippets' +import { Route as HomeApiProductRegularRouteImport } from './routes/_home/api.product-regular' +import { Route as HomeApiProductCodemodeRouteImport } from './routes/_home/api.product-codemode' +import { Route as ExecutePromptApiRealtimeTokenRouteImport } from './routes/_execute-prompt/api.realtime-token' +import { Route as ExecutePromptApiExecutePromptRouteImport } from './routes/_execute-prompt/api.execute-prompt' +import { Route as DatabaseDemoApiJudgeRouteImport } from './routes/_database-demo/api.judge' +import { Route as DatabaseDemoApiDbSnippetsRouteImport } from './routes/_database-demo/api.db-snippets' +import { Route as DatabaseDemoApiDatabaseDemoRouteImport } from './routes/_database-demo/api.database-demo' +import { Route as BankingDemoApiBankingInitRouteImport } from './routes/_banking-demo/api.banking-init' +import { Route as BankingDemoApiBankingDemoRouteImport } from './routes/_banking-demo/api.banking-demo' -const BankingDemoRouteRoute = BankingDemoRouteRouteImport.update({ - id: '/_banking-demo', +const StructuredOutputRouteRoute = StructuredOutputRouteRouteImport.update({ + id: '/_structured-output', getParentRoute: () => rootRouteImport, } as any) -const DatabaseDemoRouteRoute = DatabaseDemoRouteRouteImport.update({ - id: '/_database-demo', +const ReportingRouteRoute = ReportingRouteRouteImport.update({ + id: '/_reporting', getParentRoute: () => rootRouteImport, } as any) -const ExecutePromptRouteRoute = ExecutePromptRouteRouteImport.update({ - id: '/_execute-prompt', +const NpmGithubChatRouteRoute = NpmGithubChatRouteRouteImport.update({ + id: '/_npm-github-chat', getParentRoute: () => rootRouteImport, } as any) const HomeRouteRoute = HomeRouteRouteImport.update({ id: '/_home', getParentRoute: () => rootRouteImport, } as any) -const NpmGithubChatRouteRoute = NpmGithubChatRouteRouteImport.update({ - id: '/_npm-github-chat', +const ExecutePromptRouteRoute = ExecutePromptRouteRouteImport.update({ + id: '/_execute-prompt', getParentRoute: () => rootRouteImport, } as any) -const ReportingRouteRoute = ReportingRouteRouteImport.update({ - id: '/_reporting', +const DatabaseDemoRouteRoute = DatabaseDemoRouteRouteImport.update({ + id: '/_database-demo', getParentRoute: () => rootRouteImport, } as any) -const StructuredOutputRouteRoute = StructuredOutputRouteRouteImport.update({ - id: '/_structured-output', +const BankingDemoRouteRoute = BankingDemoRouteRouteImport.update({ + id: '/_banking-demo', getParentRoute: () => rootRouteImport, } as any) -const BankingDemoBankingDemoRoute = BankingDemoBankingDemoRouteImport.update({ - id: '/banking-demo', - path: '/banking-demo', - getParentRoute: () => BankingDemoRouteRoute, -} as any) -const DatabaseDemoDatabaseDemoRoute = - DatabaseDemoDatabaseDemoRouteImport.update({ - id: '/database-demo', - path: '/database-demo', - getParentRoute: () => DatabaseDemoRouteRoute, - } as any) -const ExecutePromptExecutePromptRoute = - ExecutePromptExecutePromptRouteImport.update({ - id: '/execute-prompt', - path: '/execute-prompt', - getParentRoute: () => ExecutePromptRouteRoute, - } as any) const HomeIndexRoute = HomeIndexRouteImport.update({ id: '/', path: '/', getParentRoute: () => HomeRouteRoute, } as any) -const NpmGithubChatNpmGithubChatRoute = - NpmGithubChatNpmGithubChatRouteImport.update({ - id: '/npm-github-chat', - path: '/npm-github-chat', - getParentRoute: () => NpmGithubChatRouteRoute, - } as any) -const ReportingReportingAgentRoute = ReportingReportingAgentRouteImport.update({ - id: '/reporting-agent', - path: '/reporting-agent', - getParentRoute: () => ReportingRouteRoute, +const ApiRuntimeRoute = ApiRuntimeRouteImport.update({ + id: '/api/runtime', + path: '/api/runtime', + getParentRoute: () => rootRouteImport, } as any) const StructuredOutputStructuredOutputRoute = StructuredOutputStructuredOutputRouteImport.update({ @@ -111,87 +88,54 @@ const StructuredOutputStructuredOutputRoute = path: '/structured-output', getParentRoute: () => StructuredOutputRouteRoute, } as any) -const ApiRuntimeRoute = ApiRuntimeRouteImport.update({ - id: '/api/runtime', - path: '/api/runtime', - getParentRoute: () => rootRouteImport, +const ReportingReportingAgentRoute = ReportingReportingAgentRouteImport.update({ + id: '/reporting-agent', + path: '/reporting-agent', + getParentRoute: () => ReportingRouteRoute, } as any) -const BankingDemoApiBankingDemoRoute = - BankingDemoApiBankingDemoRouteImport.update({ - id: '/api/banking-demo', - path: '/api/banking-demo', - getParentRoute: () => BankingDemoRouteRoute, - } as any) -const BankingDemoApiBankingInitRoute = - BankingDemoApiBankingInitRouteImport.update({ - id: '/api/banking-init', - path: '/api/banking-init', - getParentRoute: () => BankingDemoRouteRoute, - } as any) -const DatabaseDemoApiDatabaseDemoRoute = - DatabaseDemoApiDatabaseDemoRouteImport.update({ - id: '/api/database-demo', - path: '/api/database-demo', - getParentRoute: () => DatabaseDemoRouteRoute, - } as any) -const DatabaseDemoApiDbSnippetsRoute = - DatabaseDemoApiDbSnippetsRouteImport.update({ - id: '/api/db-snippets', - path: '/api/db-snippets', - getParentRoute: () => DatabaseDemoRouteRoute, +const NpmGithubChatNpmGithubChatRoute = + NpmGithubChatNpmGithubChatRouteImport.update({ + id: '/npm-github-chat', + path: '/npm-github-chat', + getParentRoute: () => NpmGithubChatRouteRoute, } as any) -const DatabaseDemoApiJudgeRoute = DatabaseDemoApiJudgeRouteImport.update({ - id: '/api/judge', - path: '/api/judge', - getParentRoute: () => DatabaseDemoRouteRoute, -} as any) -const ExecutePromptApiExecutePromptRoute = - ExecutePromptApiExecutePromptRouteImport.update({ - id: '/api/execute-prompt', - path: '/api/execute-prompt', +const ExecutePromptExecutePromptRoute = + ExecutePromptExecutePromptRouteImport.update({ + id: '/execute-prompt', + path: '/execute-prompt', getParentRoute: () => ExecutePromptRouteRoute, } as any) -const ExecutePromptApiRealtimeTokenRoute = - ExecutePromptApiRealtimeTokenRouteImport.update({ - id: '/api/realtime-token', - path: '/api/realtime-token', - getParentRoute: () => ExecutePromptRouteRoute, +const DatabaseDemoDatabaseDemoRoute = + DatabaseDemoDatabaseDemoRouteImport.update({ + id: '/database-demo', + path: '/database-demo', + getParentRoute: () => DatabaseDemoRouteRoute, } as any) -const HomeApiProductCodemodeRoute = HomeApiProductCodemodeRouteImport.update({ - id: '/api/product-codemode', - path: '/api/product-codemode', - getParentRoute: () => HomeRouteRoute, -} as any) -const HomeApiProductRegularRoute = HomeApiProductRegularRouteImport.update({ - id: '/api/product-regular', - path: '/api/product-regular', - getParentRoute: () => HomeRouteRoute, -} as any) -const HomeApiSnippetsRoute = HomeApiSnippetsRouteImport.update({ - id: '/api/snippets', - path: '/api/snippets', - getParentRoute: () => HomeRouteRoute, +const BankingDemoBankingDemoRoute = BankingDemoBankingDemoRouteImport.update({ + id: '/banking-demo', + path: '/banking-demo', + getParentRoute: () => BankingDemoRouteRoute, } as any) -const NpmGithubChatApiCodemodeRoute = - NpmGithubChatApiCodemodeRouteImport.update({ - id: '/api/codemode', - path: '/api/codemode', - getParentRoute: () => NpmGithubChatRouteRoute, +const StructuredOutputApiStructuredOutputSnippetsRoute = + StructuredOutputApiStructuredOutputSnippetsRouteImport.update({ + id: '/api/structured-output-snippets', + path: '/api/structured-output-snippets', + getParentRoute: () => StructuredOutputRouteRoute, } as any) -const NpmGithubChatApiGeneratePdfRoute = - NpmGithubChatApiGeneratePdfRouteImport.update({ - id: '/api/generate-pdf', - path: '/api/generate-pdf', - getParentRoute: () => NpmGithubChatRouteRoute, +const StructuredOutputApiStructuredOutputRoute = + StructuredOutputApiStructuredOutputRouteImport.update({ + id: '/api/structured-output', + path: '/api/structured-output', + getParentRoute: () => StructuredOutputRouteRoute, } as any) -const ReportingApiInvalidateRoute = ReportingApiInvalidateRouteImport.update({ - id: '/api/invalidate', - path: '/api/invalidate', +const ReportingApiReportsRoute = ReportingApiReportsRouteImport.update({ + id: '/api/reports', + path: '/api/reports', getParentRoute: () => ReportingRouteRoute, } as any) -const ReportingApiReportDemoRoute = ReportingApiReportDemoRouteImport.update({ - id: '/api/report-demo', - path: '/api/report-demo', +const ReportingApiReportSseRoute = ReportingApiReportSseRouteImport.update({ + id: '/api/report-sse', + path: '/api/report-sse', getParentRoute: () => ReportingRouteRoute, } as any) const ReportingApiReportEventRoute = ReportingApiReportEventRouteImport.update({ @@ -199,27 +143,83 @@ const ReportingApiReportEventRoute = ReportingApiReportEventRouteImport.update({ path: '/api/report-event', getParentRoute: () => ReportingRouteRoute, } as any) -const ReportingApiReportSseRoute = ReportingApiReportSseRouteImport.update({ - id: '/api/report-sse', - path: '/api/report-sse', +const ReportingApiReportDemoRoute = ReportingApiReportDemoRouteImport.update({ + id: '/api/report-demo', + path: '/api/report-demo', getParentRoute: () => ReportingRouteRoute, } as any) -const ReportingApiReportsRoute = ReportingApiReportsRouteImport.update({ - id: '/api/reports', - path: '/api/reports', +const ReportingApiInvalidateRoute = ReportingApiInvalidateRouteImport.update({ + id: '/api/invalidate', + path: '/api/invalidate', getParentRoute: () => ReportingRouteRoute, } as any) -const StructuredOutputApiStructuredOutputRoute = - StructuredOutputApiStructuredOutputRouteImport.update({ - id: '/api/structured-output', - path: '/api/structured-output', - getParentRoute: () => StructuredOutputRouteRoute, +const NpmGithubChatApiGeneratePdfRoute = + NpmGithubChatApiGeneratePdfRouteImport.update({ + id: '/api/generate-pdf', + path: '/api/generate-pdf', + getParentRoute: () => NpmGithubChatRouteRoute, } as any) -const StructuredOutputApiStructuredOutputSnippetsRoute = - StructuredOutputApiStructuredOutputSnippetsRouteImport.update({ - id: '/api/structured-output-snippets', - path: '/api/structured-output-snippets', - getParentRoute: () => StructuredOutputRouteRoute, +const NpmGithubChatApiCodemodeRoute = + NpmGithubChatApiCodemodeRouteImport.update({ + id: '/api/codemode', + path: '/api/codemode', + getParentRoute: () => NpmGithubChatRouteRoute, + } as any) +const HomeApiSnippetsRoute = HomeApiSnippetsRouteImport.update({ + id: '/api/snippets', + path: '/api/snippets', + getParentRoute: () => HomeRouteRoute, +} as any) +const HomeApiProductRegularRoute = HomeApiProductRegularRouteImport.update({ + id: '/api/product-regular', + path: '/api/product-regular', + getParentRoute: () => HomeRouteRoute, +} as any) +const HomeApiProductCodemodeRoute = HomeApiProductCodemodeRouteImport.update({ + id: '/api/product-codemode', + path: '/api/product-codemode', + getParentRoute: () => HomeRouteRoute, +} as any) +const ExecutePromptApiRealtimeTokenRoute = + ExecutePromptApiRealtimeTokenRouteImport.update({ + id: '/api/realtime-token', + path: '/api/realtime-token', + getParentRoute: () => ExecutePromptRouteRoute, + } as any) +const ExecutePromptApiExecutePromptRoute = + ExecutePromptApiExecutePromptRouteImport.update({ + id: '/api/execute-prompt', + path: '/api/execute-prompt', + getParentRoute: () => ExecutePromptRouteRoute, + } as any) +const DatabaseDemoApiJudgeRoute = DatabaseDemoApiJudgeRouteImport.update({ + id: '/api/judge', + path: '/api/judge', + getParentRoute: () => DatabaseDemoRouteRoute, +} as any) +const DatabaseDemoApiDbSnippetsRoute = + DatabaseDemoApiDbSnippetsRouteImport.update({ + id: '/api/db-snippets', + path: '/api/db-snippets', + getParentRoute: () => DatabaseDemoRouteRoute, + } as any) +const DatabaseDemoApiDatabaseDemoRoute = + DatabaseDemoApiDatabaseDemoRouteImport.update({ + id: '/api/database-demo', + path: '/api/database-demo', + getParentRoute: () => DatabaseDemoRouteRoute, + } as any) +const BankingDemoApiBankingInitRoute = + BankingDemoApiBankingInitRouteImport.update({ + id: '/api/banking-init', + path: '/api/banking-init', + getParentRoute: () => BankingDemoRouteRoute, + } as any) +const BankingDemoApiBankingDemoRoute = + BankingDemoApiBankingDemoRouteImport.update({ + id: '/api/banking-demo', + path: '/api/banking-demo', + getParentRoute: () => BankingDemoRouteRoute, } as any) export interface FileRoutesByFullPath { @@ -427,25 +427,25 @@ export interface RootRouteChildren { declare module '@tanstack/react-router' { interface FileRoutesByPath { - '/_banking-demo': { - id: '/_banking-demo' + '/_structured-output': { + id: '/_structured-output' path: '' fullPath: '/' - preLoaderRoute: typeof BankingDemoRouteRouteImport + preLoaderRoute: typeof StructuredOutputRouteRouteImport parentRoute: typeof rootRouteImport } - '/_database-demo': { - id: '/_database-demo' + '/_reporting': { + id: '/_reporting' path: '' fullPath: '/' - preLoaderRoute: typeof DatabaseDemoRouteRouteImport + preLoaderRoute: typeof ReportingRouteRouteImport parentRoute: typeof rootRouteImport } - '/_execute-prompt': { - id: '/_execute-prompt' + '/_npm-github-chat': { + id: '/_npm-github-chat' path: '' fullPath: '/' - preLoaderRoute: typeof ExecutePromptRouteRouteImport + preLoaderRoute: typeof NpmGithubChatRouteRouteImport parentRoute: typeof rootRouteImport } '/_home': { @@ -455,48 +455,27 @@ declare module '@tanstack/react-router' { preLoaderRoute: typeof HomeRouteRouteImport parentRoute: typeof rootRouteImport } - '/_npm-github-chat': { - id: '/_npm-github-chat' + '/_execute-prompt': { + id: '/_execute-prompt' path: '' fullPath: '/' - preLoaderRoute: typeof NpmGithubChatRouteRouteImport + preLoaderRoute: typeof ExecutePromptRouteRouteImport parentRoute: typeof rootRouteImport } - '/_reporting': { - id: '/_reporting' + '/_database-demo': { + id: '/_database-demo' path: '' fullPath: '/' - preLoaderRoute: typeof ReportingRouteRouteImport + preLoaderRoute: typeof DatabaseDemoRouteRouteImport parentRoute: typeof rootRouteImport } - '/_structured-output': { - id: '/_structured-output' + '/_banking-demo': { + id: '/_banking-demo' path: '' fullPath: '/' - preLoaderRoute: typeof StructuredOutputRouteRouteImport + preLoaderRoute: typeof BankingDemoRouteRouteImport parentRoute: typeof rootRouteImport } - '/_banking-demo/banking-demo': { - id: '/_banking-demo/banking-demo' - path: '/banking-demo' - fullPath: '/banking-demo' - preLoaderRoute: typeof BankingDemoBankingDemoRouteImport - parentRoute: typeof BankingDemoRouteRoute - } - '/_database-demo/database-demo': { - id: '/_database-demo/database-demo' - path: '/database-demo' - fullPath: '/database-demo' - preLoaderRoute: typeof DatabaseDemoDatabaseDemoRouteImport - parentRoute: typeof DatabaseDemoRouteRoute - } - '/_execute-prompt/execute-prompt': { - id: '/_execute-prompt/execute-prompt' - path: '/execute-prompt' - fullPath: '/execute-prompt' - preLoaderRoute: typeof ExecutePromptExecutePromptRouteImport - parentRoute: typeof ExecutePromptRouteRoute - } '/_home/': { id: '/_home/' path: '/' @@ -504,12 +483,19 @@ declare module '@tanstack/react-router' { preLoaderRoute: typeof HomeIndexRouteImport parentRoute: typeof HomeRouteRoute } - '/_npm-github-chat/npm-github-chat': { - id: '/_npm-github-chat/npm-github-chat' - path: '/npm-github-chat' - fullPath: '/npm-github-chat' - preLoaderRoute: typeof NpmGithubChatNpmGithubChatRouteImport - parentRoute: typeof NpmGithubChatRouteRoute + '/api/runtime': { + id: '/api/runtime' + path: '/api/runtime' + fullPath: '/api/runtime' + preLoaderRoute: typeof ApiRuntimeRouteImport + parentRoute: typeof rootRouteImport + } + '/_structured-output/structured-output': { + id: '/_structured-output/structured-output' + path: '/structured-output' + fullPath: '/structured-output' + preLoaderRoute: typeof StructuredOutputStructuredOutputRouteImport + parentRoute: typeof StructuredOutputRouteRoute } '/_reporting/reporting-agent': { id: '/_reporting/reporting-agent' @@ -518,89 +504,89 @@ declare module '@tanstack/react-router' { preLoaderRoute: typeof ReportingReportingAgentRouteImport parentRoute: typeof ReportingRouteRoute } - '/_structured-output/structured-output': { - id: '/_structured-output/structured-output' - path: '/structured-output' - fullPath: '/structured-output' - preLoaderRoute: typeof StructuredOutputStructuredOutputRouteImport - parentRoute: typeof StructuredOutputRouteRoute + '/_npm-github-chat/npm-github-chat': { + id: '/_npm-github-chat/npm-github-chat' + path: '/npm-github-chat' + fullPath: '/npm-github-chat' + preLoaderRoute: typeof NpmGithubChatNpmGithubChatRouteImport + parentRoute: typeof NpmGithubChatRouteRoute } - '/api/runtime': { - id: '/api/runtime' - path: '/api/runtime' - fullPath: '/api/runtime' - preLoaderRoute: typeof ApiRuntimeRouteImport - parentRoute: typeof rootRouteImport + '/_execute-prompt/execute-prompt': { + id: '/_execute-prompt/execute-prompt' + path: '/execute-prompt' + fullPath: '/execute-prompt' + preLoaderRoute: typeof ExecutePromptExecutePromptRouteImport + parentRoute: typeof ExecutePromptRouteRoute } - '/_banking-demo/api/banking-demo': { - id: '/_banking-demo/api/banking-demo' - path: '/api/banking-demo' - fullPath: '/api/banking-demo' - preLoaderRoute: typeof BankingDemoApiBankingDemoRouteImport - parentRoute: typeof BankingDemoRouteRoute + '/_database-demo/database-demo': { + id: '/_database-demo/database-demo' + path: '/database-demo' + fullPath: '/database-demo' + preLoaderRoute: typeof DatabaseDemoDatabaseDemoRouteImport + parentRoute: typeof DatabaseDemoRouteRoute } - '/_banking-demo/api/banking-init': { - id: '/_banking-demo/api/banking-init' - path: '/api/banking-init' - fullPath: '/api/banking-init' - preLoaderRoute: typeof BankingDemoApiBankingInitRouteImport + '/_banking-demo/banking-demo': { + id: '/_banking-demo/banking-demo' + path: '/banking-demo' + fullPath: '/banking-demo' + preLoaderRoute: typeof BankingDemoBankingDemoRouteImport parentRoute: typeof BankingDemoRouteRoute } - '/_database-demo/api/database-demo': { - id: '/_database-demo/api/database-demo' - path: '/api/database-demo' - fullPath: '/api/database-demo' - preLoaderRoute: typeof DatabaseDemoApiDatabaseDemoRouteImport - parentRoute: typeof DatabaseDemoRouteRoute + '/_structured-output/api/structured-output-snippets': { + id: '/_structured-output/api/structured-output-snippets' + path: '/api/structured-output-snippets' + fullPath: '/api/structured-output-snippets' + preLoaderRoute: typeof StructuredOutputApiStructuredOutputSnippetsRouteImport + parentRoute: typeof StructuredOutputRouteRoute } - '/_database-demo/api/db-snippets': { - id: '/_database-demo/api/db-snippets' - path: '/api/db-snippets' - fullPath: '/api/db-snippets' - preLoaderRoute: typeof DatabaseDemoApiDbSnippetsRouteImport - parentRoute: typeof DatabaseDemoRouteRoute + '/_structured-output/api/structured-output': { + id: '/_structured-output/api/structured-output' + path: '/api/structured-output' + fullPath: '/api/structured-output' + preLoaderRoute: typeof StructuredOutputApiStructuredOutputRouteImport + parentRoute: typeof StructuredOutputRouteRoute } - '/_database-demo/api/judge': { - id: '/_database-demo/api/judge' - path: '/api/judge' - fullPath: '/api/judge' - preLoaderRoute: typeof DatabaseDemoApiJudgeRouteImport - parentRoute: typeof DatabaseDemoRouteRoute + '/_reporting/api/reports': { + id: '/_reporting/api/reports' + path: '/api/reports' + fullPath: '/api/reports' + preLoaderRoute: typeof ReportingApiReportsRouteImport + parentRoute: typeof ReportingRouteRoute } - '/_execute-prompt/api/execute-prompt': { - id: '/_execute-prompt/api/execute-prompt' - path: '/api/execute-prompt' - fullPath: '/api/execute-prompt' - preLoaderRoute: typeof ExecutePromptApiExecutePromptRouteImport - parentRoute: typeof ExecutePromptRouteRoute + '/_reporting/api/report-sse': { + id: '/_reporting/api/report-sse' + path: '/api/report-sse' + fullPath: '/api/report-sse' + preLoaderRoute: typeof ReportingApiReportSseRouteImport + parentRoute: typeof ReportingRouteRoute } - '/_execute-prompt/api/realtime-token': { - id: '/_execute-prompt/api/realtime-token' - path: '/api/realtime-token' - fullPath: '/api/realtime-token' - preLoaderRoute: typeof ExecutePromptApiRealtimeTokenRouteImport - parentRoute: typeof ExecutePromptRouteRoute + '/_reporting/api/report-event': { + id: '/_reporting/api/report-event' + path: '/api/report-event' + fullPath: '/api/report-event' + preLoaderRoute: typeof ReportingApiReportEventRouteImport + parentRoute: typeof ReportingRouteRoute } - '/_home/api/product-codemode': { - id: '/_home/api/product-codemode' - path: '/api/product-codemode' - fullPath: '/api/product-codemode' - preLoaderRoute: typeof HomeApiProductCodemodeRouteImport - parentRoute: typeof HomeRouteRoute + '/_reporting/api/report-demo': { + id: '/_reporting/api/report-demo' + path: '/api/report-demo' + fullPath: '/api/report-demo' + preLoaderRoute: typeof ReportingApiReportDemoRouteImport + parentRoute: typeof ReportingRouteRoute } - '/_home/api/product-regular': { - id: '/_home/api/product-regular' - path: '/api/product-regular' - fullPath: '/api/product-regular' - preLoaderRoute: typeof HomeApiProductRegularRouteImport - parentRoute: typeof HomeRouteRoute + '/_reporting/api/invalidate': { + id: '/_reporting/api/invalidate' + path: '/api/invalidate' + fullPath: '/api/invalidate' + preLoaderRoute: typeof ReportingApiInvalidateRouteImport + parentRoute: typeof ReportingRouteRoute } - '/_home/api/snippets': { - id: '/_home/api/snippets' - path: '/api/snippets' - fullPath: '/api/snippets' - preLoaderRoute: typeof HomeApiSnippetsRouteImport - parentRoute: typeof HomeRouteRoute + '/_npm-github-chat/api/generate-pdf': { + id: '/_npm-github-chat/api/generate-pdf' + path: '/api/generate-pdf' + fullPath: '/api/generate-pdf' + preLoaderRoute: typeof NpmGithubChatApiGeneratePdfRouteImport + parentRoute: typeof NpmGithubChatRouteRoute } '/_npm-github-chat/api/codemode': { id: '/_npm-github-chat/api/codemode' @@ -609,61 +595,75 @@ declare module '@tanstack/react-router' { preLoaderRoute: typeof NpmGithubChatApiCodemodeRouteImport parentRoute: typeof NpmGithubChatRouteRoute } - '/_npm-github-chat/api/generate-pdf': { - id: '/_npm-github-chat/api/generate-pdf' - path: '/api/generate-pdf' - fullPath: '/api/generate-pdf' - preLoaderRoute: typeof NpmGithubChatApiGeneratePdfRouteImport - parentRoute: typeof NpmGithubChatRouteRoute + '/_home/api/snippets': { + id: '/_home/api/snippets' + path: '/api/snippets' + fullPath: '/api/snippets' + preLoaderRoute: typeof HomeApiSnippetsRouteImport + parentRoute: typeof HomeRouteRoute } - '/_reporting/api/invalidate': { - id: '/_reporting/api/invalidate' - path: '/api/invalidate' - fullPath: '/api/invalidate' - preLoaderRoute: typeof ReportingApiInvalidateRouteImport - parentRoute: typeof ReportingRouteRoute + '/_home/api/product-regular': { + id: '/_home/api/product-regular' + path: '/api/product-regular' + fullPath: '/api/product-regular' + preLoaderRoute: typeof HomeApiProductRegularRouteImport + parentRoute: typeof HomeRouteRoute } - '/_reporting/api/report-demo': { - id: '/_reporting/api/report-demo' - path: '/api/report-demo' - fullPath: '/api/report-demo' - preLoaderRoute: typeof ReportingApiReportDemoRouteImport - parentRoute: typeof ReportingRouteRoute + '/_home/api/product-codemode': { + id: '/_home/api/product-codemode' + path: '/api/product-codemode' + fullPath: '/api/product-codemode' + preLoaderRoute: typeof HomeApiProductCodemodeRouteImport + parentRoute: typeof HomeRouteRoute } - '/_reporting/api/report-event': { - id: '/_reporting/api/report-event' - path: '/api/report-event' - fullPath: '/api/report-event' - preLoaderRoute: typeof ReportingApiReportEventRouteImport - parentRoute: typeof ReportingRouteRoute + '/_execute-prompt/api/realtime-token': { + id: '/_execute-prompt/api/realtime-token' + path: '/api/realtime-token' + fullPath: '/api/realtime-token' + preLoaderRoute: typeof ExecutePromptApiRealtimeTokenRouteImport + parentRoute: typeof ExecutePromptRouteRoute } - '/_reporting/api/report-sse': { - id: '/_reporting/api/report-sse' - path: '/api/report-sse' - fullPath: '/api/report-sse' - preLoaderRoute: typeof ReportingApiReportSseRouteImport - parentRoute: typeof ReportingRouteRoute + '/_execute-prompt/api/execute-prompt': { + id: '/_execute-prompt/api/execute-prompt' + path: '/api/execute-prompt' + fullPath: '/api/execute-prompt' + preLoaderRoute: typeof ExecutePromptApiExecutePromptRouteImport + parentRoute: typeof ExecutePromptRouteRoute } - '/_reporting/api/reports': { - id: '/_reporting/api/reports' - path: '/api/reports' - fullPath: '/api/reports' - preLoaderRoute: typeof ReportingApiReportsRouteImport - parentRoute: typeof ReportingRouteRoute + '/_database-demo/api/judge': { + id: '/_database-demo/api/judge' + path: '/api/judge' + fullPath: '/api/judge' + preLoaderRoute: typeof DatabaseDemoApiJudgeRouteImport + parentRoute: typeof DatabaseDemoRouteRoute } - '/_structured-output/api/structured-output': { - id: '/_structured-output/api/structured-output' - path: '/api/structured-output' - fullPath: '/api/structured-output' - preLoaderRoute: typeof StructuredOutputApiStructuredOutputRouteImport - parentRoute: typeof StructuredOutputRouteRoute + '/_database-demo/api/db-snippets': { + id: '/_database-demo/api/db-snippets' + path: '/api/db-snippets' + fullPath: '/api/db-snippets' + preLoaderRoute: typeof DatabaseDemoApiDbSnippetsRouteImport + parentRoute: typeof DatabaseDemoRouteRoute } - '/_structured-output/api/structured-output-snippets': { - id: '/_structured-output/api/structured-output-snippets' - path: '/api/structured-output-snippets' - fullPath: '/api/structured-output-snippets' - preLoaderRoute: typeof StructuredOutputApiStructuredOutputSnippetsRouteImport - parentRoute: typeof StructuredOutputRouteRoute + '/_database-demo/api/database-demo': { + id: '/_database-demo/api/database-demo' + path: '/api/database-demo' + fullPath: '/api/database-demo' + preLoaderRoute: typeof DatabaseDemoApiDatabaseDemoRouteImport + parentRoute: typeof DatabaseDemoRouteRoute + } + '/_banking-demo/api/banking-init': { + id: '/_banking-demo/api/banking-init' + path: '/api/banking-init' + fullPath: '/api/banking-init' + preLoaderRoute: typeof BankingDemoApiBankingInitRouteImport + parentRoute: typeof BankingDemoRouteRoute + } + '/_banking-demo/api/banking-demo': { + id: '/_banking-demo/api/banking-demo' + path: '/api/banking-demo' + fullPath: '/api/banking-demo' + preLoaderRoute: typeof BankingDemoApiBankingDemoRouteImport + parentRoute: typeof BankingDemoRouteRoute } } } diff --git a/examples/ts-code-mode-web/src/routes/_banking-demo/api.banking-demo.ts b/examples/ts-code-mode-web/src/routes/_banking-demo/api.banking-demo.ts index 335115b4be..ff14d96999 100644 --- a/examples/ts-code-mode-web/src/routes/_banking-demo/api.banking-demo.ts +++ b/examples/ts-code-mode-web/src/routes/_banking-demo/api.banking-demo.ts @@ -199,7 +199,7 @@ async function getCodeModeTools() { return codeModeCache } -export const Route = createFileRoute('/_banking-demo/api/banking-demo')({ +export const Route = createFileRoute('/_banking-demo/api/banking-demo' as any)({ server: { handlers: { POST: async ({ request }) => { diff --git a/examples/ts-code-mode-web/src/routes/_banking-demo/api.banking-init.ts b/examples/ts-code-mode-web/src/routes/_banking-demo/api.banking-init.ts index 1275b6aca7..30630aaa38 100644 --- a/examples/ts-code-mode-web/src/routes/_banking-demo/api.banking-init.ts +++ b/examples/ts-code-mode-web/src/routes/_banking-demo/api.banking-init.ts @@ -10,7 +10,7 @@ import { getMockBalances } from '@/lib/reports/create-handler-bindings' const DASHBOARD_ID = 'dashboard' -export const Route = createFileRoute('/_banking-demo/api/banking-init')({ +export const Route = createFileRoute('/_banking-demo/api/banking-init' as any)({ server: { handlers: { POST: async () => { diff --git a/examples/ts-code-mode-web/src/routes/_banking-demo/banking-demo.tsx b/examples/ts-code-mode-web/src/routes/_banking-demo/banking-demo.tsx index 6dd38976e6..d0ab65e1db 100644 --- a/examples/ts-code-mode-web/src/routes/_banking-demo/banking-demo.tsx +++ b/examples/ts-code-mode-web/src/routes/_banking-demo/banking-demo.tsx @@ -28,7 +28,7 @@ import type { UIUpdate, } from '@/lib/reports/types' -export const Route = createFileRoute('/_banking-demo/banking-demo')({ +export const Route = createFileRoute('/_banking-demo/banking-demo' as any)({ component: BankingDemoPage, }) diff --git a/examples/ts-code-mode-web/src/routes/_database-demo/api.database-demo.ts b/examples/ts-code-mode-web/src/routes/_database-demo/api.database-demo.ts index 4258f9ceb3..10d7a12a85 100644 --- a/examples/ts-code-mode-web/src/routes/_database-demo/api.database-demo.ts +++ b/examples/ts-code-mode-web/src/routes/_database-demo/api.database-demo.ts @@ -226,7 +226,9 @@ function wrapWithTimingEvents( })() } -export const Route = createFileRoute('/_database-demo/api/database-demo')({ +export const Route = createFileRoute( + '/_database-demo/api/database-demo' as any, +)({ server: { handlers: { POST: async ({ request }) => { diff --git a/examples/ts-code-mode-web/src/routes/_database-demo/api.db-snippets.ts b/examples/ts-code-mode-web/src/routes/_database-demo/api.db-snippets.ts index a04274deb9..a7f0cdcac0 100644 --- a/examples/ts-code-mode-web/src/routes/_database-demo/api.db-snippets.ts +++ b/examples/ts-code-mode-web/src/routes/_database-demo/api.db-snippets.ts @@ -14,7 +14,7 @@ const snippetStorage = createFileSnippetStorage({ trustStrategy, }) -export const Route = createFileRoute('/_database-demo/api/db-snippets')({ +export const Route = createFileRoute('/_database-demo/api/db-snippets' as any)({ server: { handlers: { GET: async () => { diff --git a/examples/ts-code-mode-web/src/routes/_database-demo/api.judge.ts b/examples/ts-code-mode-web/src/routes/_database-demo/api.judge.ts index b231857928..3b31b0a3e3 100644 --- a/examples/ts-code-mode-web/src/routes/_database-demo/api.judge.ts +++ b/examples/ts-code-mode-web/src/routes/_database-demo/api.judge.ts @@ -29,7 +29,7 @@ Rate the candidate on two dimensions, each on a scale from 1 to 10 (10 = best): Provide a two sentence summary of your evaluation.` -export const Route = createFileRoute('/_database-demo/api/judge')({ +export const Route = createFileRoute('/_database-demo/api/judge' as any)({ server: { handlers: { POST: async ({ request }) => { diff --git a/examples/ts-code-mode-web/src/routes/_database-demo/database-demo.tsx b/examples/ts-code-mode-web/src/routes/_database-demo/database-demo.tsx index d4d9c966e2..c4a05fab1e 100644 --- a/examples/ts-code-mode-web/src/routes/_database-demo/database-demo.tsx +++ b/examples/ts-code-mode-web/src/routes/_database-demo/database-demo.tsx @@ -25,7 +25,7 @@ import ChatInput from '@/components/ChatInput' import { formatDuration } from '@/lib/efficiency' import { toolResultContentToString } from '@/lib/tool-result-content' -export const Route = createFileRoute('/_database-demo/database-demo')({ +export const Route = createFileRoute('/_database-demo/database-demo' as any)({ component: DatabaseDemoPage, }) diff --git a/examples/ts-code-mode-web/src/routes/_execute-prompt/api.execute-prompt.ts b/examples/ts-code-mode-web/src/routes/_execute-prompt/api.execute-prompt.ts index f49ecf5a4f..f5c83f3f42 100644 --- a/examples/ts-code-mode-web/src/routes/_execute-prompt/api.execute-prompt.ts +++ b/examples/ts-code-mode-web/src/routes/_execute-prompt/api.execute-prompt.ts @@ -33,7 +33,9 @@ async function getDriver(): Promise { return cachedDriver } -export const Route = createFileRoute('/_execute-prompt/api/execute-prompt')({ +export const Route = createFileRoute( + '/_execute-prompt/api/execute-prompt' as any, +)({ server: { handlers: { POST: async ({ request }) => { diff --git a/examples/ts-code-mode-web/src/routes/_execute-prompt/api.realtime-token.ts b/examples/ts-code-mode-web/src/routes/_execute-prompt/api.realtime-token.ts index 5b7ab96876..9b4b38cafe 100644 --- a/examples/ts-code-mode-web/src/routes/_execute-prompt/api.realtime-token.ts +++ b/examples/ts-code-mode-web/src/routes/_execute-prompt/api.realtime-token.ts @@ -2,7 +2,9 @@ import { createFileRoute } from '@tanstack/react-router' import { realtimeToken } from '@tanstack/ai' import { openaiRealtimeToken } from '@tanstack/ai-openai' -export const Route = createFileRoute('/_execute-prompt/api/realtime-token')({ +export const Route = createFileRoute( + '/_execute-prompt/api/realtime-token' as any, +)({ server: { handlers: { POST: async () => { diff --git a/examples/ts-code-mode-web/src/routes/_execute-prompt/execute-prompt.tsx b/examples/ts-code-mode-web/src/routes/_execute-prompt/execute-prompt.tsx index d42bebb877..e44c07563d 100644 --- a/examples/ts-code-mode-web/src/routes/_execute-prompt/execute-prompt.tsx +++ b/examples/ts-code-mode-web/src/routes/_execute-prompt/execute-prompt.tsx @@ -29,7 +29,7 @@ import type { CodeExecution, } from '@/lib/execute-prompt-realtime-tools' -export const Route = createFileRoute('/_execute-prompt/execute-prompt')({ +export const Route = createFileRoute('/_execute-prompt/execute-prompt' as any)({ component: DashboardDemoPage, }) diff --git a/examples/ts-code-mode-web/src/routes/_reporting/api.invalidate.ts b/examples/ts-code-mode-web/src/routes/_reporting/api.invalidate.ts index f473ebd017..f7100859e5 100644 --- a/examples/ts-code-mode-web/src/routes/_reporting/api.invalidate.ts +++ b/examples/ts-code-mode-web/src/routes/_reporting/api.invalidate.ts @@ -4,7 +4,7 @@ import { getReportState, getSSEController } from '@/lib/reports/report-storage' import { refreshComponent } from '@/lib/reports/refresh-component' import { evaluateWatchersForSignals } from '@/lib/reports/evaluate-watchers' -export const Route = createFileRoute('/_reporting/api/invalidate')({ +export const Route = createFileRoute('/_reporting/api/invalidate' as any)({ server: { handlers: { POST: async ({ request }) => { diff --git a/examples/ts-code-mode-web/src/routes/_reporting/api.report-demo.ts b/examples/ts-code-mode-web/src/routes/_reporting/api.report-demo.ts index 2ef92fdd4d..dcf599641b 100644 --- a/examples/ts-code-mode-web/src/routes/_reporting/api.report-demo.ts +++ b/examples/ts-code-mode-web/src/routes/_reporting/api.report-demo.ts @@ -4,7 +4,7 @@ import { simulateDeposit, } from '@/lib/reports/create-handler-bindings' -export const Route = createFileRoute('/_reporting/api/report-demo')({ +export const Route = createFileRoute('/_reporting/api/report-demo' as any)({ server: { handlers: { POST: async ({ request }) => { diff --git a/examples/ts-code-mode-web/src/routes/_reporting/api.report-event.ts b/examples/ts-code-mode-web/src/routes/_reporting/api.report-event.ts index 11d97742ee..90bf68b2f5 100644 --- a/examples/ts-code-mode-web/src/routes/_reporting/api.report-event.ts +++ b/examples/ts-code-mode-web/src/routes/_reporting/api.report-event.ts @@ -16,7 +16,7 @@ import { import { refreshComponent } from '@/lib/reports/refresh-component' import { evaluateWatchersForSignals } from '@/lib/reports/evaluate-watchers' -export const Route = createFileRoute('/_reporting/api/report-event')({ +export const Route = createFileRoute('/_reporting/api/report-event' as any)({ server: { handlers: { POST: async ({ request }) => { diff --git a/examples/ts-code-mode-web/src/routes/_reporting/api.report-sse.ts b/examples/ts-code-mode-web/src/routes/_reporting/api.report-sse.ts index 97a429b400..d53bf55080 100644 --- a/examples/ts-code-mode-web/src/routes/_reporting/api.report-sse.ts +++ b/examples/ts-code-mode-web/src/routes/_reporting/api.report-sse.ts @@ -5,7 +5,7 @@ import { getSSEController, } from '@/lib/reports/report-storage' -export const Route = createFileRoute('/_reporting/api/report-sse')({ +export const Route = createFileRoute('/_reporting/api/report-sse' as any)({ server: { handlers: { GET: async ({ request }) => { diff --git a/examples/ts-code-mode-web/src/routes/_reporting/api.reports.ts b/examples/ts-code-mode-web/src/routes/_reporting/api.reports.ts index 4a64e80fa1..4ff06ad390 100644 --- a/examples/ts-code-mode-web/src/routes/_reporting/api.reports.ts +++ b/examples/ts-code-mode-web/src/routes/_reporting/api.reports.ts @@ -49,7 +49,7 @@ async function getCodeModeTools() { return codeModeCache } -export const Route = createFileRoute('/_reporting/api/reports')({ +export const Route = createFileRoute('/_reporting/api/reports' as any)({ server: { handlers: { POST: async ({ request }) => { diff --git a/examples/ts-group-chat/package.json b/examples/ts-group-chat/package.json index 66edb51124..8b0e844330 100644 --- a/examples/ts-group-chat/package.json +++ b/examples/ts-group-chat/package.json @@ -14,10 +14,10 @@ "@tanstack/ai": "workspace:*", "@tanstack/ai-anthropic": "workspace:*", "@tanstack/react-devtools": "^0.9.10", - "@tanstack/react-router": "^1.170.32", - "@tanstack/react-router-devtools": "^1.167.1", - "@tanstack/react-start": "^1.168.49", - "@tanstack/router-plugin": "^1.168.35", + "@tanstack/react-router": "^1.158.4", + "@tanstack/react-router-devtools": "^1.158.4", + "@tanstack/react-start": "^1.159.0", + "@tanstack/router-plugin": "^1.158.4", "capnweb": "^0.10.0", "nitro": "3.0.260610-beta", "react": "^19.2.3", diff --git a/examples/ts-react-chat/package.json b/examples/ts-react-chat/package.json index a9c642f6a9..8afb8f862d 100644 --- a/examples/ts-react-chat/package.json +++ b/examples/ts-react-chat/package.json @@ -49,12 +49,12 @@ "@tanstack/ai-sandbox-local-process": "workspace:*", "@tanstack/ai-sandbox-vercel": "workspace:*", "@tanstack/react-devtools": "^0.9.10", - "@tanstack/react-router": "^1.170.32", - "@tanstack/react-router-devtools": "^1.167.1", - "@tanstack/react-router-ssr-query": "^1.167.1", - "@tanstack/react-start": "^1.168.49", - "@tanstack/react-store": "^0.11.1", - "@tanstack/router-plugin": "^1.168.35", + "@tanstack/react-router": "^1.158.4", + "@tanstack/react-router-devtools": "^1.158.4", + "@tanstack/react-router-ssr-query": "^1.158.4", + "@tanstack/react-start": "^1.159.0", + "@tanstack/react-store": "^0.8.0", + "@tanstack/router-plugin": "^1.158.4", "@tanstack/store": "^0.11.1", "dockerode": "^4.0.2", "highlight.js": "^11.11.1", diff --git a/examples/ts-react-media/package.json b/examples/ts-react-media/package.json index 1f832eb91c..89f5d0b74f 100644 --- a/examples/ts-react-media/package.json +++ b/examples/ts-react-media/package.json @@ -18,9 +18,9 @@ "@tanstack/ai-grok": "workspace:*", "@tanstack/ai-openrouter": "workspace:*", "@tanstack/ai-react": "workspace:*", - "@tanstack/react-router": "^1.170.32", - "@tanstack/react-start": "^1.168.49", - "@tanstack/router-plugin": "^1.168.35", + "@tanstack/react-router": "^1.158.4", + "@tanstack/react-start": "^1.159.0", + "@tanstack/router-plugin": "^1.158.4", "lucide-react": "^0.561.0", "nitro": "3.0.260610-beta", "react": "^19.2.3", diff --git a/examples/ts-react-media/src/routeTree.gen.ts b/examples/ts-react-media/src/routeTree.gen.ts index 3182bcf153..cfbe5387c9 100644 --- a/examples/ts-react-media/src/routeTree.gen.ts +++ b/examples/ts-react-media/src/routeTree.gen.ts @@ -9,19 +9,19 @@ // Additionally, you should also exclude this file from your linter and/or formatter to prevent it from being checked or modified. import { Route as rootRouteImport } from './routes/__root' -import { Route as IndexRouteImport } from './routes/index' import { Route as SeedanceRouteImport } from './routes/seedance' +import { Route as IndexRouteImport } from './routes/index' -const IndexRoute = IndexRouteImport.update({ - id: '/', - path: '/', - getParentRoute: () => rootRouteImport, -} as any) const SeedanceRoute = SeedanceRouteImport.update({ id: '/seedance', path: '/seedance', getParentRoute: () => rootRouteImport, } as any) +const IndexRoute = IndexRouteImport.update({ + id: '/', + path: '/', + getParentRoute: () => rootRouteImport, +} as any) export interface FileRoutesByFullPath { '/': typeof IndexRoute @@ -51,13 +51,6 @@ export interface RootRouteChildren { declare module '@tanstack/react-router' { interface FileRoutesByPath { - '/': { - id: '/' - path: '/' - fullPath: '/' - preLoaderRoute: typeof IndexRouteImport - parentRoute: typeof rootRouteImport - } '/seedance': { id: '/seedance' path: '/seedance' @@ -65,6 +58,13 @@ declare module '@tanstack/react-router' { preLoaderRoute: typeof SeedanceRouteImport parentRoute: typeof rootRouteImport } + '/': { + id: '/' + path: '/' + fullPath: '/' + preLoaderRoute: typeof IndexRouteImport + parentRoute: typeof rootRouteImport + } } } diff --git a/examples/ts-react-rerank/package.json b/examples/ts-react-rerank/package.json index 045fd110d7..83785b9b13 100644 --- a/examples/ts-react-rerank/package.json +++ b/examples/ts-react-rerank/package.json @@ -14,9 +14,9 @@ "@tanstack/ai": "workspace:*", "@tanstack/ai-cohere": "workspace:*", "@tanstack/ai-openrouter": "workspace:*", - "@tanstack/react-router": "^1.170.32", - "@tanstack/react-start": "^1.168.49", - "@tanstack/router-plugin": "^1.168.35", + "@tanstack/react-router": "^1.158.4", + "@tanstack/react-start": "^1.159.0", + "@tanstack/router-plugin": "^1.158.4", "lucide-react": "^0.561.0", "nitro": "3.0.260610-beta", "react": "^19.2.3", diff --git a/examples/ts-react-search/package.json b/examples/ts-react-search/package.json index 3ffaa70b71..26b915c7df 100644 --- a/examples/ts-react-search/package.json +++ b/examples/ts-react-search/package.json @@ -19,11 +19,11 @@ "@tanstack/react-db": "^0.1.55", "@tanstack/react-devtools": "^0.9.10", "@tanstack/react-query": "^5.90.12", - "@tanstack/react-router": "^1.170.32", - "@tanstack/react-router-devtools": "^1.167.1", - "@tanstack/react-router-ssr-query": "^1.167.1", - "@tanstack/react-start": "^1.168.49", - "@tanstack/router-plugin": "^1.168.35", + "@tanstack/react-router": "^1.158.4", + "@tanstack/react-router-devtools": "^1.158.4", + "@tanstack/react-router-ssr-query": "^1.158.4", + "@tanstack/react-start": "^1.159.0", + "@tanstack/router-plugin": "^1.158.4", "@tanstack/zod-adapter": "^1.140.1", "class-variance-authority": "^0.7.1", "clsx": "^2.1.1", diff --git a/examples/ts-react-search/src/routeTree.gen.ts b/examples/ts-react-search/src/routeTree.gen.ts index 3fa520b194..1ef02fbb58 100644 --- a/examples/ts-react-search/src/routeTree.gen.ts +++ b/examples/ts-react-search/src/routeTree.gen.ts @@ -9,43 +9,33 @@ // Additionally, you should also exclude this file from your linter and/or formatter to prevent it from being checked or modified. import { Route as rootRouteImport } from './routes/__root' -import { Route as IndexRouteImport } from './routes/index' import { Route as LayoutRouteRouteImport } from './routes/_layout/route' -import { Route as LayoutDisputesRouteImport } from './routes/_layout/disputes' -import { Route as LayoutOrdersRouteImport } from './routes/_layout/orders' -import { Route as LayoutSettlementsRouteImport } from './routes/_layout/settlements' -import { Route as ApiDisputesRouteImport } from './routes/api/disputes' -import { Route as ApiOrdersRouteImport } from './routes/api/orders' -import { Route as ApiSearchRouteImport } from './routes/api/search' +import { Route as IndexRouteImport } from './routes/index' import { Route as ApiSettlementsRouteImport } from './routes/api/settlements' +import { Route as ApiSearchRouteImport } from './routes/api/search' +import { Route as ApiOrdersRouteImport } from './routes/api/orders' +import { Route as ApiDisputesRouteImport } from './routes/api/disputes' +import { Route as LayoutSettlementsRouteImport } from './routes/_layout/settlements' +import { Route as LayoutOrdersRouteImport } from './routes/_layout/orders' +import { Route as LayoutDisputesRouteImport } from './routes/_layout/disputes' +const LayoutRouteRoute = LayoutRouteRouteImport.update({ + id: '/_layout', + getParentRoute: () => rootRouteImport, +} as any) const IndexRoute = IndexRouteImport.update({ id: '/', path: '/', getParentRoute: () => rootRouteImport, } as any) -const LayoutRouteRoute = LayoutRouteRouteImport.update({ - id: '/_layout', +const ApiSettlementsRoute = ApiSettlementsRouteImport.update({ + id: '/api/settlements', + path: '/api/settlements', getParentRoute: () => rootRouteImport, } as any) -const LayoutDisputesRoute = LayoutDisputesRouteImport.update({ - id: '/disputes', - path: '/disputes', - getParentRoute: () => LayoutRouteRoute, -} as any) -const LayoutOrdersRoute = LayoutOrdersRouteImport.update({ - id: '/orders', - path: '/orders', - getParentRoute: () => LayoutRouteRoute, -} as any) -const LayoutSettlementsRoute = LayoutSettlementsRouteImport.update({ - id: '/settlements', - path: '/settlements', - getParentRoute: () => LayoutRouteRoute, -} as any) -const ApiDisputesRoute = ApiDisputesRouteImport.update({ - id: '/api/disputes', - path: '/api/disputes', +const ApiSearchRoute = ApiSearchRouteImport.update({ + id: '/api/search', + path: '/api/search', getParentRoute: () => rootRouteImport, } as any) const ApiOrdersRoute = ApiOrdersRouteImport.update({ @@ -53,15 +43,25 @@ const ApiOrdersRoute = ApiOrdersRouteImport.update({ path: '/api/orders', getParentRoute: () => rootRouteImport, } as any) -const ApiSearchRoute = ApiSearchRouteImport.update({ - id: '/api/search', - path: '/api/search', +const ApiDisputesRoute = ApiDisputesRouteImport.update({ + id: '/api/disputes', + path: '/api/disputes', getParentRoute: () => rootRouteImport, } as any) -const ApiSettlementsRoute = ApiSettlementsRouteImport.update({ - id: '/api/settlements', - path: '/api/settlements', - getParentRoute: () => rootRouteImport, +const LayoutSettlementsRoute = LayoutSettlementsRouteImport.update({ + id: '/settlements', + path: '/settlements', + getParentRoute: () => LayoutRouteRoute, +} as any) +const LayoutOrdersRoute = LayoutOrdersRouteImport.update({ + id: '/orders', + path: '/orders', + getParentRoute: () => LayoutRouteRoute, +} as any) +const LayoutDisputesRoute = LayoutDisputesRouteImport.update({ + id: '/disputes', + path: '/disputes', + getParentRoute: () => LayoutRouteRoute, } as any) export interface FileRoutesByFullPath { @@ -141,13 +141,6 @@ export interface RootRouteChildren { declare module '@tanstack/react-router' { interface FileRoutesByPath { - '/': { - id: '/' - path: '/' - fullPath: '/' - preLoaderRoute: typeof IndexRouteImport - parentRoute: typeof rootRouteImport - } '/_layout': { id: '/_layout' path: '' @@ -155,32 +148,25 @@ declare module '@tanstack/react-router' { preLoaderRoute: typeof LayoutRouteRouteImport parentRoute: typeof rootRouteImport } - '/_layout/disputes': { - id: '/_layout/disputes' - path: '/disputes' - fullPath: '/disputes' - preLoaderRoute: typeof LayoutDisputesRouteImport - parentRoute: typeof LayoutRouteRoute - } - '/_layout/orders': { - id: '/_layout/orders' - path: '/orders' - fullPath: '/orders' - preLoaderRoute: typeof LayoutOrdersRouteImport - parentRoute: typeof LayoutRouteRoute + '/': { + id: '/' + path: '/' + fullPath: '/' + preLoaderRoute: typeof IndexRouteImport + parentRoute: typeof rootRouteImport } - '/_layout/settlements': { - id: '/_layout/settlements' - path: '/settlements' - fullPath: '/settlements' - preLoaderRoute: typeof LayoutSettlementsRouteImport - parentRoute: typeof LayoutRouteRoute + '/api/settlements': { + id: '/api/settlements' + path: '/api/settlements' + fullPath: '/api/settlements' + preLoaderRoute: typeof ApiSettlementsRouteImport + parentRoute: typeof rootRouteImport } - '/api/disputes': { - id: '/api/disputes' - path: '/api/disputes' - fullPath: '/api/disputes' - preLoaderRoute: typeof ApiDisputesRouteImport + '/api/search': { + id: '/api/search' + path: '/api/search' + fullPath: '/api/search' + preLoaderRoute: typeof ApiSearchRouteImport parentRoute: typeof rootRouteImport } '/api/orders': { @@ -190,19 +176,33 @@ declare module '@tanstack/react-router' { preLoaderRoute: typeof ApiOrdersRouteImport parentRoute: typeof rootRouteImport } - '/api/search': { - id: '/api/search' - path: '/api/search' - fullPath: '/api/search' - preLoaderRoute: typeof ApiSearchRouteImport + '/api/disputes': { + id: '/api/disputes' + path: '/api/disputes' + fullPath: '/api/disputes' + preLoaderRoute: typeof ApiDisputesRouteImport parentRoute: typeof rootRouteImport } - '/api/settlements': { - id: '/api/settlements' - path: '/api/settlements' - fullPath: '/api/settlements' - preLoaderRoute: typeof ApiSettlementsRouteImport - parentRoute: typeof rootRouteImport + '/_layout/settlements': { + id: '/_layout/settlements' + path: '/settlements' + fullPath: '/settlements' + preLoaderRoute: typeof LayoutSettlementsRouteImport + parentRoute: typeof LayoutRouteRoute + } + '/_layout/orders': { + id: '/_layout/orders' + path: '/orders' + fullPath: '/orders' + preLoaderRoute: typeof LayoutOrdersRouteImport + parentRoute: typeof LayoutRouteRoute + } + '/_layout/disputes': { + id: '/_layout/disputes' + path: '/disputes' + fullPath: '/disputes' + preLoaderRoute: typeof LayoutDisputesRouteImport + parentRoute: typeof LayoutRouteRoute } } } diff --git a/examples/ts-solid-chat/package.json b/examples/ts-solid-chat/package.json index d67411add8..5ac6e3b16a 100644 --- a/examples/ts-solid-chat/package.json +++ b/examples/ts-solid-chat/package.json @@ -20,13 +20,13 @@ "@tanstack/ai-openai": "workspace:*", "@tanstack/ai-solid": "workspace:*", "@tanstack/nitro-v2-vite-plugin": "^1.155.0", - "@tanstack/router-plugin": "^1.168.35", + "@tanstack/router-plugin": "^1.158.4", "@tanstack/solid-ai-devtools": "workspace:*", "@tanstack/solid-devtools": "^0.7.15", - "@tanstack/solid-router": "^1.170.30", - "@tanstack/solid-router-devtools": "^1.167.1", - "@tanstack/solid-router-ssr-query": "^1.167.1", - "@tanstack/solid-start": "^1.168.47", + "@tanstack/solid-router": "^1.139.10", + "@tanstack/solid-router-devtools": "^1.139.10", + "@tanstack/solid-router-ssr-query": "^1.139.10", + "@tanstack/solid-start": "^1.139.10", "@tanstack/solid-store": "^0.8.0", "@tanstack/store": "^0.11.1", "highlight.js": "^11.11.1", diff --git a/examples/ts-solid-chat/src/routeTree.gen.ts b/examples/ts-solid-chat/src/routeTree.gen.ts index 80d094ec75..09f7e9514c 100644 --- a/examples/ts-solid-chat/src/routeTree.gen.ts +++ b/examples/ts-solid-chat/src/routeTree.gen.ts @@ -46,7 +46,7 @@ export interface FileRoutesByFullPath { '/solid-ui': typeof SolidUiRoute '/api/chat': typeof ApiChatRoute '/example/guitars/$guitarId': typeof ExampleGuitarsGuitarIdRoute - '/example/guitars/': typeof ExampleGuitarsIndexRoute + '/example/guitars': typeof ExampleGuitarsIndexRoute } export interface FileRoutesByTo { '/': typeof IndexRoute @@ -70,7 +70,7 @@ export interface FileRouteTypes { | '/solid-ui' | '/api/chat' | '/example/guitars/$guitarId' - | '/example/guitars/' + | '/example/guitars' fileRoutesByTo: FileRoutesByTo to: | '/' @@ -121,7 +121,7 @@ declare module '@tanstack/solid-router' { '/example/guitars/': { id: '/example/guitars/' path: '/example/guitars' - fullPath: '/example/guitars/' + fullPath: '/example/guitars' preLoaderRoute: typeof ExampleGuitarsIndexRouteImport parentRoute: typeof rootRouteImport } diff --git a/packages/ai-angular/src/inject-chat.ts b/packages/ai-angular/src/inject-chat.ts index 77847b3823..58eec12139 100644 --- a/packages/ai-angular/src/inject-chat.ts +++ b/packages/ai-angular/src/inject-chat.ts @@ -74,7 +74,7 @@ export function injectChat< const isSubscribed = signal(false) const connectionStatus = signal('disconnected') const sessionGenerating = signal(false) - const queue = signal>([]) + const queue = signal>([]) const runId = signal(null) const interruptState = signal>({ interrupts: EMPTY_INTERRUPTS, @@ -150,7 +150,7 @@ export function injectChat< const applySnapshot = () => { const next = client.getSnapshot() - messages.set(next.messages) + messages.set(next.messages as Array>) isLoading.set(next.isLoading) error.set(next.error) status.set(next.status) diff --git a/packages/ai-client/src/chat-client.ts b/packages/ai-client/src/chat-client.ts index f3eb2ba289..6139584a17 100644 --- a/packages/ai-client/src/chat-client.ts +++ b/packages/ai-client/src/chat-client.ts @@ -1535,7 +1535,7 @@ export class ChatClient< private freezeSnapshotMessages( messages: Array>, - ): Array> { + ): ReadonlyArray> { return Object.freeze( messages.map((message) => Object.freeze({ @@ -1545,12 +1545,12 @@ export class ChatClient< ), }), ), - ) as Array> + ) as ReadonlyArray> } private freezeSnapshotQueue( queue: Array, - ): Array { + ): ReadonlyArray { return Object.freeze( queue.map((item) => Object.freeze({ @@ -1573,7 +1573,7 @@ export class ChatClient< : {}), }), ), - ) as Array + ) as ReadonlyArray } private readSnapshot(): ChatClientSnapshot { @@ -1608,7 +1608,7 @@ export class ChatClient< subscribeSnapshot = (listener: () => void): (() => void) => subscribeAtom(this.snapshotAtom, listener) - /** Current UI snapshot. */ + /** Current UI snapshot. Frozen. Nested messages and queue entries are copies. */ getSnapshot = (): ChatClientSnapshot => this.snapshotAtom.get() diff --git a/packages/ai-client/src/generation-client.ts b/packages/ai-client/src/generation-client.ts index a6fed26e1c..394852262e 100644 --- a/packages/ai-client/src/generation-client.ts +++ b/packages/ai-client/src/generation-client.ts @@ -29,7 +29,12 @@ import type { GenerationDevtoolsBridge, GenerationDevtoolsBridgeOptions, } from './devtools' -import { createAtom, patchAtom, subscribeAtom } from './snapshot-atom' +import { + cloneSnapshotValue, + createAtom, + patchAtom, + subscribeAtom, +} from './snapshot-atom' import type { Atom } from './snapshot-atom' import type { GenerationClientOptions, @@ -610,7 +615,7 @@ export class GenerationClient< subscribe = (listener: () => void): (() => void) => subscribeAtom(this.snapshotAtom, listener) - /** Current UI snapshot. */ + /** Current UI snapshot. Frozen envelope. `result` is a shallow copy. */ getSnapshot = (): GenerationClientSnapshot => this.snapshotAtom.get() getResult(): TOutput | null { @@ -685,7 +690,9 @@ export class GenerationClient< if (transformed !== undefined) { // Non-null, non-undefined → use transformed value this.result = transformed - patchAtom(this.snapshotAtom, { result: this.result }) + patchAtom(this.snapshotAtom, { + result: cloneSnapshotValue(this.result), + }) if (controller && !this.ownsRun(controller)) return this.callbacksRef.onResultChange?.(this.result) if (controller && !this.ownsRun(controller)) return @@ -699,7 +706,7 @@ export class GenerationClient< // `TOutput` defaults to `TResult`, so the runtime cast is sound. // oxlint-disable-next-line eslint-js/no-restricted-syntax -- TOutput defaults to TResult when no onResult transform is supplied this.result = rawResult as unknown as TOutput - patchAtom(this.snapshotAtom, { result: this.result }) + patchAtom(this.snapshotAtom, { result: cloneSnapshotValue(this.result) }) if (controller && !this.ownsRun(controller)) return this.callbacksRef.onResultChange?.(this.result) if (controller && !this.ownsRun(controller)) return @@ -844,7 +851,11 @@ export class GenerationClient< return } this.lastEmittedResumeState = signature - patchAtom(this.snapshotAtom, { runId: resumeState?.runId ?? null }) + if (resumeState?.runId) { + patchAtom(this.snapshotAtom, { runId: resumeState.runId }) + } else if (!this.isLoading) { + patchAtom(this.snapshotAtom, { runId: null }) + } if (controller && !this.ownsRun(controller)) return this.callbacksRef.onResumeStateChange?.(resumeState) } diff --git a/packages/ai-client/src/generation-types.ts b/packages/ai-client/src/generation-types.ts index cb2cf82c01..32036e5269 100644 --- a/packages/ai-client/src/generation-types.ts +++ b/packages/ai-client/src/generation-types.ts @@ -69,11 +69,11 @@ export type GenerationClientState = 'idle' | 'generating' | 'success' | 'error' * {@link GenerationClient.getSnapshot}. */ export interface GenerationClientSnapshot { - result: TOutput | null - isLoading: boolean - error: Error | undefined - status: GenerationClientState - runId: string | null + readonly result: TOutput | null + readonly isLoading: boolean + readonly error: Error | undefined + readonly status: GenerationClientState + readonly runId: string | null } /** @@ -83,8 +83,8 @@ export interface GenerationClientSnapshot { export interface VideoGenerationClientSnapshot< TOutput = unknown, > extends GenerationClientSnapshot { - jobId: string | null - videoStatus: VideoStatusInfo | null + readonly jobId: string | null + readonly videoStatus: VideoStatusInfo | null } /** diff --git a/packages/ai-client/src/realtime-types.ts b/packages/ai-client/src/realtime-types.ts index c6f2470a97..1b4c205c88 100644 --- a/packages/ai-client/src/realtime-types.ts +++ b/packages/ai-client/src/realtime-types.ts @@ -108,12 +108,12 @@ export interface RealtimeClientOptions { * Internal state of the RealtimeClient */ export interface RealtimeClientState { - status: RealtimeStatus - mode: RealtimeMode - messages: Array - pendingUserTranscript: string | null - pendingAssistantTranscript: string | null - error: Error | null + readonly status: RealtimeStatus + readonly mode: RealtimeMode + readonly messages: Array + readonly pendingUserTranscript: string | null + readonly pendingAssistantTranscript: string | null + readonly error: Error | null } /** diff --git a/packages/ai-client/src/snapshot-atom.ts b/packages/ai-client/src/snapshot-atom.ts index b05b7ff9d2..ad409f79e7 100644 --- a/packages/ai-client/src/snapshot-atom.ts +++ b/packages/ai-client/src/snapshot-atom.ts @@ -9,6 +9,12 @@ function freezeSnapshot(value: T): T { : value } +/** Shallow copy, then freeze. Use for published snapshot fields that must not alias client internals. */ +export function cloneSnapshotValue(value: T): T { + if (value === null || typeof value !== 'object') return value + return Object.freeze(Array.isArray(value) ? [...value] : { ...value }) as T +} + export function createAtom(initialValue: T): Atom { const atom = createStoreAtom(freezeSnapshot(initialValue)) const set = atom.set.bind(atom) diff --git a/packages/ai-client/src/types.ts b/packages/ai-client/src/types.ts index 9c6868b837..1631e03df2 100644 --- a/packages/ai-client/src/types.ts +++ b/packages/ai-client/src/types.ts @@ -373,16 +373,16 @@ export interface ChatClientSnapshot< TInterrupts extends ReadonlyArray> = readonly [], > { - messages: Array> - status: ChatClientState - isLoading: boolean - error: Error | undefined - isSubscribed: boolean - connectionStatus: ConnectionStatus - sessionGenerating: boolean - queue: Array - runId: string | null - interruptState: ChatInterruptState + readonly messages: ReadonlyArray> + readonly status: ChatClientState + readonly isLoading: boolean + readonly error: Error | undefined + readonly isSubscribed: boolean + readonly connectionStatus: ConnectionStatus + readonly sessionGenerating: boolean + readonly queue: ReadonlyArray + readonly runId: string | null + readonly interruptState: ChatInterruptState } /** diff --git a/packages/ai-client/src/video-generation-client.ts b/packages/ai-client/src/video-generation-client.ts index eceddf9595..cf4675bc49 100644 --- a/packages/ai-client/src/video-generation-client.ts +++ b/packages/ai-client/src/video-generation-client.ts @@ -29,7 +29,12 @@ import type { VideoDevtoolsBridge, VideoDevtoolsBridgeOptions, } from './devtools' -import { createAtom, patchAtom, subscribeAtom } from './snapshot-atom' +import { + cloneSnapshotValue, + createAtom, + patchAtom, + subscribeAtom, +} from './snapshot-atom' import type { Atom } from './snapshot-atom' import type { GenerationClientState, @@ -631,7 +636,7 @@ export class VideoGenerationClient { subscribe = (listener: () => void): (() => void) => subscribeAtom(this.snapshotAtom, listener) - /** Current UI snapshot. */ + /** Current UI snapshot. Frozen envelope. `result` is a shallow copy. */ getSnapshot = (): VideoGenerationClientSnapshot => this.snapshotAtom.get() @@ -725,7 +730,9 @@ export class VideoGenerationClient { if (transformed !== undefined) { // Non-null, non-undefined → use transformed value this.result = transformed - patchAtom(this.snapshotAtom, { result: this.result }) + patchAtom(this.snapshotAtom, { + result: cloneSnapshotValue(this.result), + }) if (controller && !this.ownsRun(controller)) return this.callbacksRef.onResultChange?.(this.result) if (controller && !this.ownsRun(controller)) return @@ -740,7 +747,7 @@ export class VideoGenerationClient { // sound. // oxlint-disable-next-line eslint-js/no-restricted-syntax -- TOutput defaults to VideoGenerateResult when no onResult transform is supplied this.result = rawResult as unknown as TOutput - patchAtom(this.snapshotAtom, { result: this.result }) + patchAtom(this.snapshotAtom, { result: cloneSnapshotValue(this.result) }) if (controller && !this.ownsRun(controller)) return this.callbacksRef.onResultChange?.(this.result) if (controller && !this.ownsRun(controller)) return @@ -902,7 +909,11 @@ export class VideoGenerationClient { : {}), } : null - patchAtom(this.snapshotAtom, { runId: resumeState?.runId ?? null }) + if (resumeState?.runId) { + patchAtom(this.snapshotAtom, { runId: resumeState.runId }) + } else if (!this.isLoading) { + patchAtom(this.snapshotAtom, { runId: null }) + } if (controller && !this.ownsRun(controller)) return this.callbacksRef.onResumeStateChange?.(resumeState) } diff --git a/packages/ai-client/tests/client-snapshots.test.ts b/packages/ai-client/tests/client-snapshots.test.ts index bcbf6b8636..835885e495 100644 --- a/packages/ai-client/tests/client-snapshots.test.ts +++ b/packages/ai-client/tests/client-snapshots.test.ts @@ -46,6 +46,12 @@ describe('client UI snapshots', () => { expect(client.getSnapshot().status).toBe('success') expect(client.getSnapshot().result).toEqual({ id: '1' }) expect(client.getSnapshot()).not.toBe(snapshot) + const published = client.getSnapshot().result + expect(published).toEqual({ id: '1' }) + if (published) { + Reflect.set(published, 'id', 'mutated') + } + expect(client.getResult()).toEqual({ id: '1' }) stop() }) @@ -70,6 +76,8 @@ describe('client UI snapshots', () => { expect(listener).toHaveBeenCalled() expect(client.getSnapshot().status).toBe('success') expect(client.getSnapshot().result).toEqual(result) + expect(client.getSnapshot().jobId).toBe('job-1') + expect(client.getSnapshot().videoStatus?.status).toBe('completed') expect(client.getSnapshot()).not.toBe(snapshot) const completed = client.getSnapshot() expect(Object.isFrozen(completed.videoStatus)).toBe(true) diff --git a/packages/ai-client/tests/generation-client.test.ts b/packages/ai-client/tests/generation-client.test.ts index cf93a55495..66ddeed6c4 100644 --- a/packages/ai-client/tests/generation-client.test.ts +++ b/packages/ai-client/tests/generation-client.test.ts @@ -246,6 +246,57 @@ describe('GenerationClient', () => { expect(client.getStatus()).toBe('success') }) + it('keeps the local run id when a stream chunk has no resume pointer', async () => { + const gate = createDeferred() + const chunks: Array = [ + { + type: EventType.CUSTOM, + name: 'generation:progress', + value: { percent: 1 }, + timestamp: Date.now(), + }, + { + type: EventType.RUN_STARTED, + runId: 'run-1', + threadId: 'thread-1', + timestamp: Date.now(), + }, + { + type: EventType.CUSTOM, + name: 'generation:result', + value: { id: '1' }, + timestamp: Date.now(), + }, + { + type: EventType.RUN_FINISHED, + runId: 'run-1', + threadId: 'thread-1', + metadata: { tanstack: { finishReason: 'stop' as const } }, + timestamp: Date.now(), + }, + ] + const connection = { + async *connect() { + yield chunks[0]! + await gate.promise + for (const chunk of chunks.slice(1)) { + yield chunk + } + }, + } + + const client = new GenerationClient({ connection }) + const pending = client.generate({ prompt: 'test' }) + await waitForCondition(() => { + expect(client.getSnapshot().isLoading).toBe(true) + }) + expect(client.getSnapshot().runId).toEqual(expect.any(String)) + expect(client.getSnapshot().runId).not.toBe('') + gate.resolve() + await pending + expect(client.getSnapshot().runId).toBeNull() + }) + it('should handle RUN_ERROR from stream', async () => { const onError = vi.fn() diff --git a/packages/ai-octane/src/use-chat.tsrx b/packages/ai-octane/src/use-chat.tsrx index d197d37ba9..3a11537649 100644 --- a/packages/ai-octane/src/use-chat.tsrx +++ b/packages/ai-octane/src/use-chat.tsrx @@ -11,11 +11,8 @@ import type { StreamChunk, } from '@tanstack/ai/client' import type { - ChatClientState, ResolvableChatInterrupt, - ChatInterruptState, ChatResumeState, - ConnectionStatus, InferredClientContext, QueuedMessage, SendMessageOptions, @@ -30,9 +27,6 @@ import type { UseChatReturn, } from './types' -const EMPTY_INTERRUPTS = Object.freeze([]) -const EMPTY_INTERRUPT_ERRORS = Object.freeze([]) - export function useChat< const TTools extends ReadonlyArray = any, TSchema extends SchemaInput | undefined = undefined, @@ -49,43 +43,9 @@ export function useChat< const hookId = useId() const clientId = options.threadId ?? hookId - const [messages, setMessages] = useState>>( - options.initialMessages || [], - ) - const [isLoading, setIsLoading] = useState(false) - const [error, setError] = useState(undefined) - const [status, setStatus] = useState('ready') - const [isSubscribed, setIsSubscribed] = useState(false) - const [connectionStatus, setConnectionStatus] = - useState('disconnected') - const [sessionGenerating, setSessionGenerating] = useState(false) - const [queue, setQueue] = useState>([]) - const [runId, setRunId] = useState(null) - const [interruptState, setInterruptState] = useState< - ChatInterruptState - >(() => ({ - interrupts: EMPTY_INTERRUPTS, - pendingInterrupts: EMPTY_INTERRUPTS, - interruptErrors: EMPTY_INTERRUPT_ERRORS, - resuming: false, - })) - - type Partial = DeepPartial>> - type Final = InferSchemaType> - - // Track the rendered snapshot so a replacement client only synchronizes - // state when its messages actually differ. - const messagesRef = useRef>>( - options.initialMessages || [], - ) const subscribedRef = useRef(false) const activeClientRef = useRef(null) const seenClientRef = useRef(null) - - // Update ref synchronously during render so it's always current when useMemo runs. - messagesRef.current = messages - - // Track current options in a ref to avoid recreating client when options change const optionsRef = useRef>(options) optionsRef.current = options @@ -213,6 +173,33 @@ export function useChat< return { client: instance, initialization: initializationState } }, [clientId]) + type Partial = DeepPartial>> + type Final = InferSchemaType> + + // Constructor hydration (sync store / resume snapshot) must be on the first + // paint. `useEffect` runs after paint, so seed from the snapshot here. + const firstPaint = client.getSnapshot() + const [messages, setMessages] = useState>>( + firstPaint.messages as Array>, + ) + const [isLoading, setIsLoading] = useState(firstPaint.isLoading) + const [error, setError] = useState(firstPaint.error) + const [status, setStatus] = useState(firstPaint.status) + const [isSubscribed, setIsSubscribed] = useState(firstPaint.isSubscribed) + const [connectionStatus, setConnectionStatus] = useState( + firstPaint.connectionStatus, + ) + const [sessionGenerating, setSessionGenerating] = useState( + firstPaint.sessionGenerating, + ) + const [queue, setQueue] = useState>( + firstPaint.queue as Array, + ) + const [runId, setRunId] = useState(firstPaint.runId) + const [interruptState, setInterruptState] = useState( + firstPaint.interruptState, + ) + useEffect(() => { activeClientRef.current = client try { @@ -234,14 +221,14 @@ export function useChat< useEffect(() => { const applySnapshot = () => { const next = client.getSnapshot() - setMessages(next.messages) + setMessages(next.messages as Array>) setIsLoading(next.isLoading) setError(next.error) setStatus(next.status) setIsSubscribed(next.isSubscribed) setConnectionStatus(next.connectionStatus) setSessionGenerating(next.sessionGenerating) - setQueue(next.queue) + setQueue(next.queue as Array) setRunId(next.runId) setInterruptState(next.interruptState) } diff --git a/packages/ai-octane/tests/conformance/use-chat.test.ts b/packages/ai-octane/tests/conformance/use-chat.test.ts index ccc5147141..b6898e10a4 100644 --- a/packages/ai-octane/tests/conformance/use-chat.test.ts +++ b/packages/ai-octane/tests/conformance/use-chat.test.ts @@ -215,15 +215,19 @@ describe('useChat', () => { removeItem: vi.fn(), } - const { result } = renderUseChat({ - connection: adapter, - threadId: 'persisted-chat', - persistence, + let firstMessages: ReadonlyArray | undefined + const { result } = renderHook(() => { + const chat = useChat({ + connection: adapter, + threadId: 'persisted-chat', + persistence, + }) + firstMessages ??= chat.messages + return chat }) - await waitFor(() => { - expect(result.current.messages).toEqual(persistedMessages) - }) + expect(firstMessages).toEqual(persistedMessages) + expect(result.current.messages).toEqual(persistedMessages) expect(persistence.getItem).toHaveBeenCalledWith('persisted-chat') }) diff --git a/packages/ai-preact/src/use-chat.ts b/packages/ai-preact/src/use-chat.ts index 2eaaeb7c62..7d5492e343 100644 --- a/packages/ai-preact/src/use-chat.ts +++ b/packages/ai-preact/src/use-chat.ts @@ -6,6 +6,7 @@ import type { ResolvableChatInterrupt, ChatResumeState, InferredClientContext, + QueuedMessage, SendMessageOptions, } from '@tanstack/ai-client' import type { @@ -394,7 +395,7 @@ export function useChat< const renderedMessages = snapshot.messages return { - messages: renderedMessages, + messages: renderedMessages as Array>, sendMessage, append, reload, @@ -409,7 +410,7 @@ export function useChat< clear, addToolResult, addToolApprovalResponse, - queue: snapshot.queue, + queue: snapshot.queue as Array, cancelQueued, runId: snapshot.runId, interrupts: snapshot.interruptState.interrupts, diff --git a/packages/ai-preact/tests/use-chat.test.ts b/packages/ai-preact/tests/use-chat.test.ts index 0d3ebea95d..949d5c665b 100644 --- a/packages/ai-preact/tests/use-chat.test.ts +++ b/packages/ai-preact/tests/use-chat.test.ts @@ -195,6 +195,43 @@ describe('useChat', () => { expect(result.current.messages).toEqual(initialMessages) }) + it('throws on in-place messages.push and accepts setMessages', () => { + const { result } = renderUseChat({ + connection: createMockConnectionAdapter(), + initialMessages: [ + { + id: 'msg-1', + role: 'user', + parts: [{ type: 'text', content: 'Hello' }], + createdAt: new Date(), + }, + ], + }) + + expect(Object.isFrozen(result.current.messages)).toBe(true) + expect(() => { + Array.prototype.push.call(result.current.messages, { + id: 'x', + role: 'user', + parts: [{ type: 'text', content: 'nope' }], + createdAt: new Date(), + }) + }).toThrow(TypeError) + + act(() => { + result.current.setMessages([ + ...result.current.messages, + { + id: 'ok', + role: 'user', + parts: [{ type: 'text', content: 'ok' }], + createdAt: new Date(), + }, + ]) + }) + expect(result.current.messages).toHaveLength(2) + }) + it('should initialize with persisted messages', async () => { const adapter = createMockConnectionAdapter() const persistedMessages: Array = [ diff --git a/packages/ai-react/src/use-chat.ts b/packages/ai-react/src/use-chat.ts index e1cdf0e004..2fa6568bcc 100644 --- a/packages/ai-react/src/use-chat.ts +++ b/packages/ai-react/src/use-chat.ts @@ -68,7 +68,7 @@ export function useChat< useRef>(options) optionsRef.current = options - // Create ChatClient instance with callbacks to sync state + // Create ChatClient once per clientId. User callbacks read latest options. const { client, initialization, serverSnapshot, startPersistenceHydration } = useMemo(() => { const messagesToUse = options.initialMessages || [] @@ -136,10 +136,10 @@ export function useChat< } return currentInstance } - // ChatClient may publish while its constructor is running or while async - // persistence resolves before commit. Preserve those exact notifications - // until this render commits; invoking them here would run state setters and - // user callbacks for a client React may abandon. + // Queue user callbacks until this instance is the committed client. + // Invoking them here would run onChunk/onFinish/onError for a client + // React may abandon. Browser persistence is gated until attach so the + // first paint stays on initialMessages / initialResumeSnapshot. const initializationState = { ready: false, callbacks: [] as Array<() => void>, diff --git a/packages/ai-react/tests/use-chat.test.ts b/packages/ai-react/tests/use-chat.test.ts index 04f2fe9f01..c43acf3f3d 100644 --- a/packages/ai-react/tests/use-chat.test.ts +++ b/packages/ai-react/tests/use-chat.test.ts @@ -210,6 +210,43 @@ describe('useChat', () => { expect(result.current.messages).toEqual(initialMessages) }) + it('throws on in-place messages.push and accepts setMessages', () => { + const { result } = renderUseChat({ + connection: createMockConnectionAdapter(), + initialMessages: [ + { + id: 'msg-1', + role: 'user', + parts: [{ type: 'text', content: 'Hello' }], + createdAt: new Date(), + }, + ], + }) + + expect(Object.isFrozen(result.current.messages)).toBe(true) + expect(() => { + Array.prototype.push.call(result.current.messages, { + id: 'x', + role: 'user', + parts: [{ type: 'text', content: 'nope' }], + createdAt: new Date(), + }) + }).toThrow(TypeError) + + act(() => { + result.current.setMessages([ + ...result.current.messages, + { + id: 'ok', + role: 'user', + parts: [{ type: 'text', content: 'ok' }], + createdAt: new Date(), + }, + ]) + }) + expect(result.current.messages).toHaveLength(2) + }) + it('should initialize with persisted messages', async () => { const adapter = createMockConnectionAdapter() const persistedMessages: Array = [ diff --git a/packages/ai-solid/src/use-chat.ts b/packages/ai-solid/src/use-chat.ts index b5eba10893..59e38c2541 100644 --- a/packages/ai-solid/src/use-chat.ts +++ b/packages/ai-solid/src/use-chat.ts @@ -89,7 +89,7 @@ export function useChat< type Partial = DeepPartial>> type Final = InferSchemaType> - // Create ChatClient instance with callbacks to sync state. + // Build the client once per clientId. User callbacks read latest options. // Every user-provided callback is wrapped so the LATEST `options.xxx` value // is read at call time. Direct assignment would freeze the callback to the // reference we saw at creation; the wrapper lets reactive `options` or @@ -165,14 +165,14 @@ export function useChat< const applySnapshot = (target: ChatClient) => { const next = target.getSnapshot() - setMessages(next.messages) + setMessages(next.messages as Array>) setIsLoading(next.isLoading) setError(next.error) setStatus(next.status) setIsSubscribed(next.isSubscribed) setConnectionStatus(next.connectionStatus) setSessionGenerating(next.sessionGenerating) - setQueue(next.queue) + setQueue(next.queue as Array) setRunId(next.runId) setInterruptState(next.interruptState) } diff --git a/packages/ai-svelte/src/create-chat.svelte.ts b/packages/ai-svelte/src/create-chat.svelte.ts index 97cd334617..8d89f6ab4b 100644 --- a/packages/ai-svelte/src/create-chat.svelte.ts +++ b/packages/ai-svelte/src/create-chat.svelte.ts @@ -171,14 +171,14 @@ export function createChat< function applySnapshot() { const next = client.getSnapshot() - messages = next.messages + messages = next.messages as Array> isLoading = next.isLoading error = next.error status = next.status isSubscribed = next.isSubscribed connectionStatus = next.connectionStatus sessionGenerating = next.sessionGenerating - queue = next.queue + queue = next.queue as Array runId = next.runId interruptState = next.interruptState } diff --git a/packages/ai-vertex/package.json b/packages/ai-vertex/package.json index f5d635271c..0fead1cade 100644 --- a/packages/ai-vertex/package.json +++ b/packages/ai-vertex/package.json @@ -58,6 +58,7 @@ "@tanstack/ai": "workspace:^" }, "devDependencies": { + "@google/genai": "^2.10.0", "@tanstack/ai": "workspace:*", "@vitest/coverage-v8": "4.1.10", "vite": "^8.2.1" diff --git a/packages/ai-vertex/tests/factories.test.ts b/packages/ai-vertex/tests/factories.test.ts index c21f6c0d5e..54c9c86b84 100644 --- a/packages/ai-vertex/tests/factories.test.ts +++ b/packages/ai-vertex/tests/factories.test.ts @@ -11,35 +11,22 @@ import { const mocks = vi.hoisted(() => { return { - constructorSpy: - vi.fn< - (kind: string, options: Record, model: string) => void - >(), + constructorSpy: vi.fn<(options: Record) => void>(), } }) -vi.mock('@tanstack/ai-gemini', async (importOriginal) => { - const actual = await importOriginal() - const adapterClass = (kind: string) => { - return class { - readonly name = 'gemini' - readonly model: string +vi.mock('@google/genai', async (importOriginal) => { + const actual = await importOriginal() - constructor(options: Record, model: string) { - this.model = model - mocks.constructorSpy(kind, options, model) - } + class MockGoogleGenAI { + constructor(options: Record) { + mocks.constructorSpy(options) } } return { ...actual, - GeminiTextAdapter: adapterClass('text'), - GeminiImageAdapter: adapterClass('image'), - GeminiEmbeddingAdapter: adapterClass('embedding'), - GeminiTTSAdapter: adapterClass('speech'), - GeminiAudioAdapter: adapterClass('audio'), - GeminiVideoAdapter: adapterClass('video'), + GoogleGenAI: MockGoogleGenAI, } }) @@ -62,15 +49,11 @@ describe('vertex factories', () => { expect(adapter.name).toBe('gemini') expect(adapter.model).toBe('gemini-3.7-flash') - expect(mocks.constructorSpy).toHaveBeenCalledExactlyOnceWith( - 'text', - { - project: 'my-project', - location: 'europe-west1', - vertexai: true, - }, - 'gemini-3.7-flash', - ) + expect(mocks.constructorSpy).toHaveBeenCalledExactlyOnceWith({ + project: 'my-project', + location: 'europe-west1', + vertexai: true, + }) }) it('builds summarize, image, embedding, speech, audio, and video adapters', () => { @@ -83,42 +66,13 @@ describe('vertex factories', () => { expect(vertexAudio('lyria-3-pro-preview', auth).name).toBe('gemini') expect(vertexVideo('veo-3.1-generate-preview', auth).name).toBe('gemini') - expect(mocks.constructorSpy.mock.calls).toEqual([ - [ - 'text', - { project: 'my-project', location: 'europe-west1', vertexai: true }, - 'gemini-3.7-flash', - ], - [ - 'image', - { project: 'my-project', location: 'europe-west1', vertexai: true }, - 'gemini-3.1-flash-image', - ], - [ - 'embedding', - { project: 'my-project', location: 'europe-west1', vertexai: true }, - 'gemini-embedding-001', - ], - [ - 'speech', - { project: 'my-project', location: 'europe-west1', vertexai: true }, - 'gemini-3.1-flash-tts-preview', - ], - [ - 'audio', - { project: 'my-project', location: 'europe-west1', vertexai: true }, - 'lyria-3-pro-preview', - ], - [ - 'video', - { - project: 'my-project', - location: 'europe-west1', - vertexai: true, - allowUrlFetch: undefined, - }, - 'veo-3.1-generate-preview', - ], - ]) + expect(mocks.constructorSpy).toHaveBeenCalledTimes(6) + for (const call of mocks.constructorSpy.mock.calls) { + expect(call[0]).toMatchObject({ + project: 'my-project', + location: 'europe-west1', + vertexai: true, + }) + } }) }) diff --git a/packages/ai-vue/src/use-chat.ts b/packages/ai-vue/src/use-chat.ts index a51299cccd..e1a4cdf1f5 100644 --- a/packages/ai-vue/src/use-chat.ts +++ b/packages/ai-vue/src/use-chat.ts @@ -157,14 +157,14 @@ export function useChat< function applySnapshot() { const next = client.getSnapshot() - messages.value = next.messages + messages.value = next.messages as Array> isLoading.value = next.isLoading error.value = next.error status.value = next.status isSubscribed.value = next.isSubscribed connectionStatus.value = next.connectionStatus sessionGenerating.value = next.sessionGenerating - queue.value = next.queue + queue.value = next.queue as Array runId.value = next.runId interruptState.value = next.interruptState } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 3a0b698ac8..b529405795 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -204,11 +204,11 @@ importers: specifier: workspace:* version: link:../../packages/ai-sandbox-local-process '@tanstack/react-router': - specifier: ^1.170.32 - version: 1.170.32(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + specifier: ^1.158.4 + version: 1.159.5(react-dom@19.2.3(react@19.2.3))(react@19.2.3) '@tanstack/react-start': - specifier: ^1.168.49 - version: 1.168.49(crossws@0.4.6(srvx@0.11.17))(esbuild@0.28.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(rolldown@1.2.4)(rollup@4.60.1)(vite-plugin-solid@2.11.14(solid-js@1.9.10)(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)))(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)) + specifier: ^1.159.0 + version: 1.159.5(crossws@0.4.6(srvx@0.11.17))(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(vite-plugin-solid@2.11.14(solid-js@1.9.10)(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)))(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)) lucide-react: specifier: ^0.561.0 version: 0.561.0(react@19.2.3) @@ -244,8 +244,8 @@ importers: specifier: ^4.1.18 version: 4.1.18(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)) '@tanstack/router-plugin': - specifier: ^1.168.35 - version: 1.168.35(@tanstack/react-router@1.170.32(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(esbuild@0.28.1)(rolldown@1.2.4)(rollup@4.60.1)(vite-plugin-solid@2.11.14(solid-js@1.9.10)(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)))(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)) + specifier: ^1.158.4 + version: 1.159.5(@tanstack/react-router@1.159.5(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(supports-color@7.2.0)(vite-plugin-solid@2.11.14(solid-js@1.9.10)(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)))(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)) '@types/node': specifier: ^24.10.1 version: 24.10.3 @@ -292,11 +292,11 @@ importers: specifier: workspace:* version: link:../../packages/ai-sandbox-docker '@tanstack/react-router': - specifier: ^1.170.32 - version: 1.170.32(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + specifier: ^1.158.4 + version: 1.159.5(react-dom@19.2.3(react@19.2.3))(react@19.2.3) '@tanstack/react-start': - specifier: ^1.168.49 - version: 1.168.49(crossws@0.4.6(srvx@0.11.17))(esbuild@0.28.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(rolldown@1.2.4)(rollup@4.60.1)(vite-plugin-solid@2.11.14(solid-js@1.9.10)(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)))(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)) + specifier: ^1.159.0 + version: 1.159.5(crossws@0.4.6(srvx@0.11.17))(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(vite-plugin-solid@2.11.14(solid-js@1.9.10)(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)))(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)) lucide-react: specifier: ^0.561.0 version: 0.561.0(react@19.2.3) @@ -329,8 +329,8 @@ importers: specifier: ^4.1.18 version: 4.1.18(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)) '@tanstack/router-plugin': - specifier: ^1.168.35 - version: 1.168.35(@tanstack/react-router@1.170.32(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(esbuild@0.28.1)(rolldown@1.2.4)(rollup@4.60.1)(vite-plugin-solid@2.11.14(solid-js@1.9.10)(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)))(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)) + specifier: ^1.158.4 + version: 1.159.5(@tanstack/react-router@1.159.5(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(supports-color@7.2.0)(vite-plugin-solid@2.11.14(solid-js@1.9.10)(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)))(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)) '@types/node': specifier: ^24.10.1 version: 24.10.3 @@ -480,14 +480,14 @@ importers: specifier: workspace:* version: link:../../packages/ai-react '@tanstack/react-router': - specifier: ^1.170.32 - version: 1.170.32(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + specifier: ^1.158.4 + version: 1.159.5(react-dom@19.2.3(react@19.2.3))(react@19.2.3) '@tanstack/react-start': - specifier: ^1.168.49 - version: 1.168.49(crossws@0.4.6(srvx@0.11.17))(esbuild@0.28.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(rolldown@1.2.4)(rollup@4.60.1)(vite-plugin-solid@2.11.14(solid-js@1.9.10)(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)))(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)) + specifier: ^1.159.0 + version: 1.159.5(crossws@0.4.6(srvx@0.11.17))(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(vite-plugin-solid@2.11.14(solid-js@1.9.10)(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)))(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)) '@tanstack/router-plugin': - specifier: ^1.168.35 - version: 1.168.35(@tanstack/react-router@1.170.32(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(esbuild@0.28.1)(rolldown@1.2.4)(rollup@4.60.1)(vite-plugin-solid@2.11.14(solid-js@1.9.10)(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)))(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)) + specifier: ^1.158.4 + version: 1.159.5(@tanstack/react-router@1.159.5(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(supports-color@7.2.0)(vite-plugin-solid@2.11.14(solid-js@1.9.10)(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)))(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)) '@tanstack/store': specifier: ^0.11.1 version: 0.11.1 @@ -589,17 +589,17 @@ importers: specifier: ^0.9.10 version: 0.9.10(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(csstype@3.2.3)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(solid-js@1.9.10) '@tanstack/react-router': - specifier: ^1.170.32 - version: 1.170.32(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + specifier: ^1.158.4 + version: 1.159.5(react-dom@19.2.3(react@19.2.3))(react@19.2.3) '@tanstack/react-router-devtools': - specifier: ^1.167.1 - version: 1.167.1(@tanstack/react-router@1.170.32(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(@tanstack/router-core@1.171.27)(csstype@3.2.3)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + specifier: ^1.158.4 + version: 1.159.5(@tanstack/react-router@1.159.5(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(@tanstack/router-core@1.159.4)(csstype@3.2.3)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) '@tanstack/react-start': - specifier: ^1.168.49 - version: 1.168.49(crossws@0.4.6(srvx@0.11.17))(esbuild@0.28.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(rolldown@1.2.4)(rollup@4.60.1)(vite-plugin-solid@2.11.14(solid-js@1.9.10)(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)))(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)) + specifier: ^1.159.0 + version: 1.159.5(crossws@0.4.6(srvx@0.11.17))(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(vite-plugin-solid@2.11.14(solid-js@1.9.10)(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)))(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)) '@tanstack/router-plugin': - specifier: ^1.168.35 - version: 1.168.35(@tanstack/react-router@1.170.32(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(esbuild@0.28.1)(rolldown@1.2.4)(rollup@4.60.1)(vite-plugin-solid@2.11.14(solid-js@1.9.10)(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)))(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)) + specifier: ^1.158.4 + version: 1.159.5(@tanstack/react-router@1.159.5(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(supports-color@7.2.0)(vite-plugin-solid@2.11.14(solid-js@1.9.10)(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)))(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)) capnweb: specifier: ^0.10.0 version: 0.10.0 @@ -773,23 +773,23 @@ importers: specifier: ^0.9.10 version: 0.9.10(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(csstype@3.2.3)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(solid-js@1.9.10) '@tanstack/react-router': - specifier: ^1.170.32 - version: 1.170.32(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + specifier: ^1.158.4 + version: 1.159.5(react-dom@19.2.3(react@19.2.3))(react@19.2.3) '@tanstack/react-router-devtools': - specifier: ^1.167.1 - version: 1.167.1(@tanstack/react-router@1.170.32(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(@tanstack/router-core@1.171.27)(csstype@3.2.3)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + specifier: ^1.158.4 + version: 1.159.5(@tanstack/react-router@1.159.5(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(@tanstack/router-core@1.159.4)(csstype@3.2.3)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) '@tanstack/react-router-ssr-query': - specifier: ^1.167.1 - version: 1.167.1(@tanstack/query-core@5.90.12)(@tanstack/react-query@5.90.12(react@19.2.3))(@tanstack/react-router@1.170.32(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(@tanstack/router-core@1.171.27)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + specifier: ^1.158.4 + version: 1.159.5(@tanstack/query-core@5.90.12)(@tanstack/react-query@5.90.12(react@19.2.3))(@tanstack/react-router@1.159.5(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(@tanstack/router-core@1.159.4)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) '@tanstack/react-start': - specifier: ^1.168.49 - version: 1.168.49(crossws@0.4.6(srvx@0.11.17))(esbuild@0.28.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(rolldown@1.2.4)(rollup@4.60.1)(vite-plugin-solid@2.11.14(solid-js@1.9.10)(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)))(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)) + specifier: ^1.159.0 + version: 1.159.5(crossws@0.4.6(srvx@0.11.17))(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(vite-plugin-solid@2.11.14(solid-js@1.9.10)(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)))(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)) '@tanstack/react-store': - specifier: ^0.11.1 - version: 0.11.1(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + specifier: ^0.8.0 + version: 0.8.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3) '@tanstack/router-plugin': - specifier: ^1.168.35 - version: 1.168.35(@tanstack/react-router@1.170.32(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(esbuild@0.28.1)(rolldown@1.2.4)(rollup@4.60.1)(vite-plugin-solid@2.11.14(solid-js@1.9.10)(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)))(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)) + specifier: ^1.158.4 + version: 1.159.5(@tanstack/react-router@1.159.5(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(supports-color@7.2.0)(vite-plugin-solid@2.11.14(solid-js@1.9.10)(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)))(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)) '@tanstack/store': specifier: ^0.11.1 version: 0.11.1 @@ -909,14 +909,14 @@ importers: specifier: workspace:* version: link:../../packages/ai-react '@tanstack/react-router': - specifier: ^1.170.32 - version: 1.170.32(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + specifier: ^1.158.4 + version: 1.159.5(react-dom@19.2.3(react@19.2.3))(react@19.2.3) '@tanstack/react-start': - specifier: ^1.168.49 - version: 1.168.49(crossws@0.4.6(srvx@0.11.17))(esbuild@0.28.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(rolldown@1.2.4)(rollup@4.60.1)(vite-plugin-solid@2.11.14(solid-js@1.9.10)(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)))(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)) + specifier: ^1.159.0 + version: 1.159.5(crossws@0.4.6(srvx@0.11.17))(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(vite-plugin-solid@2.11.14(solid-js@1.9.10)(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)))(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)) '@tanstack/router-plugin': - specifier: ^1.168.35 - version: 1.168.35(@tanstack/react-router@1.170.32(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(esbuild@0.28.1)(rolldown@1.2.4)(rollup@4.60.1)(vite-plugin-solid@2.11.14(solid-js@1.9.10)(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)))(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)) + specifier: ^1.158.4 + version: 1.159.5(@tanstack/react-router@1.159.5(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(supports-color@7.2.0)(vite-plugin-solid@2.11.14(solid-js@1.9.10)(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)))(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)) lucide-react: specifier: ^0.561.0 version: 0.561.0(react@19.2.3) @@ -1013,14 +1013,14 @@ importers: specifier: workspace:* version: link:../../packages/ai-openrouter '@tanstack/react-router': - specifier: ^1.170.32 - version: 1.170.32(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + specifier: ^1.158.4 + version: 1.159.5(react-dom@19.2.3(react@19.2.3))(react@19.2.3) '@tanstack/react-start': - specifier: ^1.168.49 - version: 1.168.49(crossws@0.4.6(srvx@0.11.17))(esbuild@0.28.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(rolldown@1.2.4)(rollup@4.60.1)(vite-plugin-solid@2.11.14(solid-js@1.9.10)(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)))(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)) + specifier: ^1.159.0 + version: 1.159.5(crossws@0.4.6(srvx@0.11.17))(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(vite-plugin-solid@2.11.14(solid-js@1.9.10)(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)))(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)) '@tanstack/router-plugin': - specifier: ^1.168.35 - version: 1.168.35(@tanstack/react-router@1.170.32(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(esbuild@0.28.1)(rolldown@1.2.4)(rollup@4.60.1)(vite-plugin-solid@2.11.14(solid-js@1.9.10)(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)))(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)) + specifier: ^1.158.4 + version: 1.159.5(@tanstack/react-router@1.159.5(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(supports-color@7.2.0)(vite-plugin-solid@2.11.14(solid-js@1.9.10)(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)))(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)) lucide-react: specifier: ^0.561.0 version: 0.561.0(react@19.2.3) @@ -1086,23 +1086,23 @@ importers: specifier: ^5.90.12 version: 5.90.12(react@19.2.3) '@tanstack/react-router': - specifier: ^1.170.32 - version: 1.170.32(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + specifier: ^1.158.4 + version: 1.159.5(react-dom@19.2.3(react@19.2.3))(react@19.2.3) '@tanstack/react-router-devtools': - specifier: ^1.167.1 - version: 1.167.1(@tanstack/react-router@1.170.32(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(@tanstack/router-core@1.171.27)(csstype@3.2.3)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + specifier: ^1.158.4 + version: 1.159.5(@tanstack/react-router@1.159.5(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(@tanstack/router-core@1.159.4)(csstype@3.2.3)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) '@tanstack/react-router-ssr-query': - specifier: ^1.167.1 - version: 1.167.1(@tanstack/query-core@5.90.12)(@tanstack/react-query@5.90.12(react@19.2.3))(@tanstack/react-router@1.170.32(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(@tanstack/router-core@1.171.27)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + specifier: ^1.158.4 + version: 1.159.5(@tanstack/query-core@5.90.12)(@tanstack/react-query@5.90.12(react@19.2.3))(@tanstack/react-router@1.159.5(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(@tanstack/router-core@1.159.4)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) '@tanstack/react-start': - specifier: ^1.168.49 - version: 1.168.49(crossws@0.4.6(srvx@0.11.17))(esbuild@0.28.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(rolldown@1.2.4)(rollup@4.60.1)(vite-plugin-solid@2.11.14(solid-js@1.9.10)(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)))(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)) + specifier: ^1.159.0 + version: 1.159.5(crossws@0.4.6(srvx@0.11.17))(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(vite-plugin-solid@2.11.14(solid-js@1.9.10)(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)))(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)) '@tanstack/router-plugin': - specifier: ^1.168.35 - version: 1.168.35(@tanstack/react-router@1.170.32(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(esbuild@0.28.1)(rolldown@1.2.4)(rollup@4.60.1)(vite-plugin-solid@2.11.14(solid-js@1.9.10)(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)))(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)) + specifier: ^1.158.4 + version: 1.159.5(@tanstack/react-router@1.159.5(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(supports-color@7.2.0)(vite-plugin-solid@2.11.14(solid-js@1.9.10)(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)))(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)) '@tanstack/zod-adapter': specifier: ^1.140.1 - version: 1.166.9(@tanstack/react-router@1.170.32(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(zod@4.3.6) + version: 1.166.9(@tanstack/react-router@1.159.5(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(zod@4.3.6) class-variance-authority: specifier: ^0.7.1 version: 0.7.1 @@ -1338,8 +1338,8 @@ importers: specifier: ^1.155.0 version: 1.155.0(@electric-sql/pglite@0.4.3)(aws4fetch@1.0.20)(better-sqlite3@12.11.1)(drizzle-orm@0.45.2(@cloudflare/workers-types@4.20260317.1)(@electric-sql/pglite@0.4.3)(@opentelemetry/api@1.9.1)(@prisma/client@7.9.0(prisma@7.9.0(@types/react@19.2.18)(better-sqlite3@12.11.1)(magicast@0.5.2)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(typescript@5.9.3))(typescript@5.9.3))(better-sqlite3@12.11.1)(bun-types@1.3.14)(mysql2@3.15.3)(postgres@3.4.7)(prisma@7.9.0(@types/react@19.2.18)(better-sqlite3@12.11.1)(magicast@0.5.2)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(typescript@5.9.3)))(mysql2@3.15.3)(rolldown@1.1.5)(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)) '@tanstack/router-plugin': - specifier: ^1.168.35 - version: 1.168.35(@tanstack/react-router@1.170.32(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(esbuild@0.28.1)(rolldown@1.2.4)(rollup@4.60.1)(vite-plugin-solid@2.11.14(solid-js@1.9.10)(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)))(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)) + specifier: ^1.158.4 + version: 1.159.5(@tanstack/react-router@1.159.5(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(supports-color@7.2.0)(vite-plugin-solid@2.11.14(solid-js@1.9.10)(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)))(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)) '@tanstack/solid-ai-devtools': specifier: workspace:* version: link:../../packages/solid-ai-devtools @@ -1347,17 +1347,17 @@ importers: specifier: ^0.7.15 version: 0.7.17(csstype@3.2.3)(solid-js@1.9.10) '@tanstack/solid-router': - specifier: ^1.170.30 - version: 1.170.30(solid-js@1.9.10) + specifier: ^1.139.10 + version: 1.141.1(solid-js@1.9.10) '@tanstack/solid-router-devtools': - specifier: ^1.167.1 - version: 1.167.1(@tanstack/router-core@1.171.27)(@tanstack/solid-router@1.170.30(solid-js@1.9.10))(csstype@3.2.3)(solid-js@1.9.10) + specifier: ^1.139.10 + version: 1.141.1(@tanstack/router-core@1.159.4)(@tanstack/solid-router@1.141.1(solid-js@1.9.10))(csstype@3.2.3)(solid-js@1.9.10) '@tanstack/solid-router-ssr-query': - specifier: ^1.167.1 - version: 1.167.1(@tanstack/query-core@5.90.12)(@tanstack/router-core@1.171.27)(@tanstack/solid-query@5.90.15(solid-js@1.9.10))(@tanstack/solid-router@1.170.30(solid-js@1.9.10))(solid-js@1.9.10) + specifier: ^1.139.10 + version: 1.141.1(@tanstack/query-core@5.90.12)(@tanstack/router-core@1.159.4)(@tanstack/solid-query@5.90.15(solid-js@1.9.10))(@tanstack/solid-router@1.141.1(solid-js@1.9.10))(eslint@9.39.4(jiti@2.7.0))(solid-js@1.9.10)(supports-color@7.2.0)(typescript@5.9.3) '@tanstack/solid-start': - specifier: ^1.168.47 - version: 1.168.47(@tanstack/react-router@1.170.32(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(crossws@0.4.6(srvx@0.11.17))(esbuild@0.28.1)(rolldown@1.2.4)(rollup@4.60.1)(solid-js@1.9.10)(vite-plugin-solid@2.11.14(solid-js@1.9.10)(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)))(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)) + specifier: ^1.139.10 + version: 1.141.1(@tanstack/react-router@1.159.5(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(crossws@0.4.6(srvx@0.11.17))(solid-js@1.9.10)(vite-plugin-solid@2.11.14(solid-js@1.9.10)(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)))(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)) '@tanstack/solid-store': specifier: ^0.8.0 version: 0.8.0(solid-js@1.9.10) @@ -2913,6 +2913,9 @@ importers: specifier: workspace:^ version: link:../ai-gemini devDependencies: + '@google/genai': + specifier: ^2.10.0 + version: 2.10.0(@modelcontextprotocol/sdk@1.29.0(zod@4.3.6)) '@tanstack/ai': specifier: workspace:* version: link:../ai @@ -3203,11 +3206,11 @@ importers: specifier: workspace:* version: link:../../packages/react-ai-devtools '@tanstack/react-router': - specifier: ^1.170.32 - version: 1.170.32(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + specifier: ^1.158.4 + version: 1.159.5(react-dom@19.2.3(react@19.2.3))(react@19.2.3) '@tanstack/react-start': - specifier: ^1.168.49 - version: 1.168.49(crossws@0.4.6(srvx@0.11.17))(esbuild@0.28.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(rolldown@1.2.4)(rollup@4.60.1)(vite-plugin-solid@2.11.14(solid-js@1.9.10)(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)))(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)) + specifier: ^1.159.0 + version: 1.159.5(crossws@0.4.6(srvx@0.11.17))(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(vite-plugin-solid@2.11.14(solid-js@1.9.10)(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)))(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)) arktype: specifier: ^2.1.28 version: 2.2.0 @@ -3327,11 +3330,11 @@ importers: specifier: ^0.9.10 version: 0.9.10(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(csstype@3.2.3)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(solid-js@1.9.10) '@tanstack/react-router': - specifier: ^1.170.32 - version: 1.170.32(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + specifier: ^1.158.4 + version: 1.159.5(react-dom@19.2.3(react@19.2.3))(react@19.2.3) '@tanstack/react-start': - specifier: ^1.168.49 - version: 1.168.49(crossws@0.4.6(srvx@0.11.17))(esbuild@0.28.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(rolldown@1.2.4)(rollup@4.60.1)(vite-plugin-solid@2.11.14(solid-js@1.9.10)(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)))(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)) + specifier: ^1.159.0 + version: 1.159.5(crossws@0.4.6(srvx@0.11.17))(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(vite-plugin-solid@2.11.14(solid-js@1.9.10)(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)))(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)) '@tanstack/start': specifier: ^1.120.20 version: 1.120.20(340eefabdbae5b0c948fd6f8943277d1) @@ -4261,6 +4264,10 @@ packages: resolution: {integrity: sha512-JiDShH45zKHWyGe4ZNVRrCjBz8Nh9TMmZG1kh4QTK8hCBTWBi8Da+i7s1fJw7/lYpM4ccepSNfqzZ/QvABBi5g==} engines: {node: '>=6.9.0'} + '@babel/template@7.27.2': + resolution: {integrity: sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw==} + engines: {node: '>=6.9.0'} + '@babel/template@7.29.7': resolution: {integrity: sha512-puq+Gf35oI24FeN11LkoUQFqv9uwNeWpxXZi/Ji3rRIoKAzKnxRaZ+Gkj0vKS9ZCiTESfng1N9LyOyXvo+m+Gg==} engines: {node: '>=6.9.0'} @@ -4277,6 +4284,10 @@ packages: resolution: {integrity: sha512-EhlfNQtZ+NK22w5BM61ciuiq1m58ed33Wr1Xan//ZRTy6hgjnwyCffRYwzsGXdASJSUJ1guZILsErh1eQcl+zw==} engines: {node: '>=6.9.0'} + '@babel/types@7.28.5': + resolution: {integrity: sha512-qQ5m48eI/MFLQ5PxQj4PFaprjyCTLI37ElWMmNs0K8Lk3dVeOdNpB3ks8jc7yM5CDmVC73eMVk/trk3fgmrUpA==} + engines: {node: '>=6.9.0'} + '@babel/types@7.29.0': resolution: {integrity: sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A==} engines: {node: '>=6.9.0'} @@ -6103,6 +6114,9 @@ packages: resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} engines: {node: '>= 8'} + '@nothing-but/utils@0.17.0': + resolution: {integrity: sha512-TuCHcHLOqDL0SnaAxACfuRHBNRgNJcNn9X0GiH5H3YSDBVquCr3qEIG3FOQAuMyZCbu9w8nk2CHhOsn7IvhIwQ==} + '@nx/nx-darwin-arm64@23.1.1': resolution: {integrity: sha512-Rq/RXLX5uIvJQfb6kuUgEirquT5ARaAgQyNaMZVnOPAL5wuxaDvQag8WX/WUCIgbUKZuGkclJwM7Vlnvtn3bdg==} cpu: [arm64] @@ -8825,6 +8839,9 @@ packages: '@rolldown/pluginutils@1.0.0-beta.27': resolution: {integrity: sha512-+d0F4MKMCbeVUJwG96uQ4SgAznZNSq93I3V+9NHA4OpvqG8mRCpGdKmK8l/dl02h2CCDHwW2FqilnTyDcAnqjA==} + '@rolldown/pluginutils@1.0.0-beta.40': + resolution: {integrity: sha512-s3GeJKSQOwBlzdUrj4ISjJj5SfSh+aqn0wjOar4Bx95iV1ETI7F6S/5hLcfAxZ9kXDcyrAkxPlqmd1ZITttf+w==} + '@rolldown/pluginutils@1.0.0-beta.53': resolution: {integrity: sha512-vENRlFU4YbrwVqNDZ7fLvy+JR1CRkyr01jhSiDpE1u6py3OMzQfztQU2jxykW3ALNxO4kSlqIDeYyD0Y9RcQeQ==} @@ -9274,6 +9291,26 @@ packages: resolution: {integrity: sha512-R8Rdn8Hy72KKcebgLiv8jQcQkXoLMOGGv5uI1/k0l+snqkOzQ1R0ChUBCxWMlBsFMekWjq0wRudIweFs7sKT5A==} engines: {node: '>=14.0.0'} + '@solid-devtools/debugger@0.28.1': + resolution: {integrity: sha512-6qIUI6VYkXoRnL8oF5bvh2KgH71qlJ18hNw/mwSyY6v48eb80ZR48/5PDXufUa3q+MBSuYa1uqTMwLewpay9eg==} + peerDependencies: + solid-js: ^1.9.0 + + '@solid-devtools/logger@0.9.11': + resolution: {integrity: sha512-THbiY1iQlieL6vdgJc4FIsLe7V8a57hod/Thm8zdKrTkWL88UPZjkBBfM+mVNGusd4OCnAN20tIFBhNnuT1Dew==} + peerDependencies: + solid-js: ^1.9.0 + + '@solid-devtools/shared@0.20.0': + resolution: {integrity: sha512-o5TACmUOQsxpzpOKCjbQqGk8wL8PMi+frXG9WNu4Lh3PQVUB6hs95Kl/S8xc++zwcMguUKZJn8h5URUiMOca6Q==} + peerDependencies: + solid-js: ^1.9.0 + + '@solid-primitives/bounds@0.1.3': + resolution: {integrity: sha512-UbiyKMdSPmtijcEDnYLQL3zzaejpwWDAJJ4Gt5P0hgVs6A72piov0GyNw7V2SroH7NZFwxlYS22YmOr8A5xc1Q==} + peerDependencies: + solid-js: ^1.6.12 + '@solid-primitives/event-listener@2.4.3': resolution: {integrity: sha512-h4VqkYFv6Gf+L7SQj+Y6puigL/5DIi7x5q07VZET7AWcS+9/G3WfIE9WheniHWJs51OEkRB43w6lDys5YeFceg==} peerDependencies: @@ -9284,6 +9321,11 @@ packages: peerDependencies: solid-js: ^1.6.12 + '@solid-primitives/media@2.3.3': + resolution: {integrity: sha512-hQ4hLOGvfbugQi5Eu1BFWAIJGIAzztq9x0h02xgBGl2l0Jaa3h7tg6bz5tV1NSuNYVGio4rPoa7zVQQLkkx9dA==} + peerDependencies: + solid-js: ^1.6.12 + '@solid-primitives/refs@1.1.2': resolution: {integrity: sha512-K7tf2thy7L+YJjdqXspXOg5xvNEOH8tgEWsp0+1mQk3obHBRD6hEjYZk7p7FlJphSZImS35je3UfmWuD7MhDfg==} peerDependencies: @@ -9299,11 +9341,21 @@ packages: peerDependencies: solid-js: ^1.6.12 + '@solid-primitives/scheduled@1.5.2': + resolution: {integrity: sha512-/j2igE0xyNaHhj6kMfcUQn5rAVSTLbAX+CDEBm25hSNBmNiHLu2lM7Usj2kJJ5j36D67bE8wR1hBNA8hjtvsQA==} + peerDependencies: + solid-js: ^1.6.12 + '@solid-primitives/static-store@0.1.2': resolution: {integrity: sha512-ReK+5O38lJ7fT+L6mUFvUr6igFwHBESZF+2Ug842s7fvlVeBdIVEdTCErygff6w7uR6+jrr7J8jQo+cYrEq4Iw==} peerDependencies: solid-js: ^1.6.12 + '@solid-primitives/styles@0.1.2': + resolution: {integrity: sha512-7iX5K+J5b1PRrbgw3Ki92uvU2LgQ0Kd/QMsrAZxDg5dpUBwMyTijZkA3bbs1ikZsT1oQhS41bTyKbjrXeU0Awg==} + peerDependencies: + solid-js: ^1.6.12 + '@solid-primitives/utils@6.3.2': resolution: {integrity: sha512-hZ/M/qr25QOCcwDPOHtGjxTD8w2mNyVAYvcfgwzBHq2RwNqHNdDNsMZYap20+ruRwW4A3Cdkczyoz0TSxLCAPQ==} peerDependencies: @@ -9595,10 +9647,6 @@ packages: resolution: {integrity: sha512-xyIfof8eHBuub1CkBnbKNKQXeRZC4dClhmzePHVOEel4G7lk/dW+TQ16da7CFdeNLv6u6Owf5VoBQxoo6DFTSA==} engines: {node: '>=12'} - '@tanstack/history@1.162.1': - resolution: {integrity: sha512-DR9t6lfLVdrjgCwpglrR9DR7Ok8/HlXjcOE+goWXF3zyuLUO/ug7vMbSFxTqrQTtbRghJfyhmIZ0S6LhPIy44w==} - engines: {node: '>=20.19'} - '@tanstack/nitro-v2-vite-plugin@1.155.0': resolution: {integrity: sha512-iW9S2c4QxlT+WgKVT+Mw8hzvLqyVSg4UefzX74LX5dfUxbGDahxZItp+07JSD5Ok8ZdTlUHzwLnIsncXh/MNAQ==} engines: {node: '>=22.12'} @@ -9637,21 +9685,21 @@ packages: peerDependencies: react: ^18 || ^19 - '@tanstack/react-router-devtools@1.167.1': - resolution: {integrity: sha512-pjfGrmjj4d7naEPM7oshqFfwBoxDPNo/UxltlHH5ePbHsJ+plBhd+JaAewm1ueYOjZ0js9hckjWWDYXpCrSfKw==} - engines: {node: '>=20.19'} + '@tanstack/react-router-devtools@1.159.5': + resolution: {integrity: sha512-IIyomu+ypWTxyoYT32mxamVmdTs7ZCGcTbdj7HVvtD3xp1lvo/bwRXj9oERENmb+OAPOaWF2doRYC/pmKjK5vg==} + engines: {node: '>=12'} peerDependencies: - '@tanstack/react-router': ^1.170.19 - '@tanstack/router-core': ^1.171.16 + '@tanstack/react-router': ^1.159.5 + '@tanstack/router-core': ^1.159.4 react: '>=18.0.0 || >=19.0.0' react-dom: '>=18.0.0 || >=19.0.0' peerDependenciesMeta: '@tanstack/router-core': optional: true - '@tanstack/react-router-ssr-query@1.167.1': - resolution: {integrity: sha512-W9j5JPnBikyafvuUfykFfHIWod58OAbAAa5leNkXBcoDoocghMmu6w9uZOmUZvAWT7CSvgj5tBUtF7CM2OoHXQ==} - engines: {node: '>=20.19'} + '@tanstack/react-router-ssr-query@1.159.5': + resolution: {integrity: sha512-r/Um9DASjmaTdiyXA3cpooGLrSD1BlcXUNsRz4zAlvD38m0gIFvaykOM2Naztqm9H+2CJkocRZp2/kR69Xcmyg==} + engines: {node: '>=12'} peerDependencies: '@tanstack/query-core': '>=5.90.0' '@tanstack/react-query': '>=5.90.0' @@ -9666,9 +9714,9 @@ packages: react: '>=18.0.0 || >=19.0.0' react-dom: '>=18.0.0 || >=19.0.0' - '@tanstack/react-router@1.170.32': - resolution: {integrity: sha512-SIpxvaTKco100a5ZR3ePmArbhtm3XOx+w1dpGYY9gxHDta4iXSKDdQuhLonwJbIMkVJsU1rwXf0UDHMrF/1snw==} - engines: {node: '>=20.19'} + '@tanstack/react-router@1.159.5': + resolution: {integrity: sha512-rVb0MtKzP5c0BkWIoFgWBiRAJHYSU3bhsEHbT0cRdRLmlJiw21Awb6VEjgYq3hJiEhowcKKm6J8AdRD/8oZ5dQ==} + engines: {node: '>=12'} peerDependencies: react: '>=18.0.0 || >=19.0.0' react-dom: '>=18.0.0 || >=19.0.0' @@ -9680,8 +9728,8 @@ packages: react: '>=18.0.0 || >=19.0.0' react-dom: '>=18.0.0 || >=19.0.0' - '@tanstack/react-start-client@1.168.30': - resolution: {integrity: sha512-qsZuykUl1EF0/rc1bin1RtjFzz07YMOTBzhOstSDzbOVm/WKf1QKFTN+qAZi74xlbXSWNuT2MiFRyg4RKwj8iw==} + '@tanstack/react-start-client@1.159.5': + resolution: {integrity: sha512-Qynx7XWHI1rhVpSUx6P40zazcQVJRhl2fnAcSH0I6vaAxSuZm8lvI37YacXPRu8flvI/ZGlF095arxiyps+A0w==} engines: {node: '>=22.12.0'} peerDependencies: react: '>=18.0.0 || >=19.0.0' @@ -9698,23 +9746,6 @@ packages: resolution: {integrity: sha512-z+4YL6shTtsHjk32yaIemQwgkx6FcqwPBYfeNt7Co2eOpWrvsoo/Fe9869/oIY2sPyhiWDs1rDb3e0qnAy8Cag==} engines: {node: '>=12'} - '@tanstack/react-start-rsc@0.1.48': - resolution: {integrity: sha512-UglRdTMuF3c4dvzL/gh4dMVbMWHsPy8ZgTQdT2qpTlyt1b/3m+R40tBFdsfTgw76VTXivW+qV/ih0PN9000XTw==} - engines: {node: '>=22.12.0'} - peerDependencies: - '@rspack/core': '>=2.0.0-0' - '@vitejs/plugin-rsc': '>=0.5.30' - react: '>=18.0.0 || >=19.0.0' - react-dom: '>=18.0.0 || >=19.0.0' - react-server-dom-rspack: '>=0.0.2' - peerDependenciesMeta: - '@rspack/core': - optional: true - '@vitejs/plugin-rsc': - optional: true - react-server-dom-rspack: - optional: true - '@tanstack/react-start-server@1.141.1': resolution: {integrity: sha512-GsZ7De5CCDkKcrimvwJiYJHMFGw7LQRu8IuLvqyzYgQvJPcbkfY5UIQd2IZfgRNFegzb2aYzkAXwv5lxfdu1VQ==} engines: {node: '>=22.12.0'} @@ -9722,35 +9753,20 @@ packages: react: '>=18.0.0 || >=19.0.0' react-dom: '>=18.0.0 || >=19.0.0' - '@tanstack/react-start-server@1.167.37': - resolution: {integrity: sha512-cODHpFU8vIm7AdHii9W3NEuwyruNmT5wLDZjRsJLT9Jp+7FACnfJrRbvxnp1ldSv/9mxcHKi/OgwbdHQeMZcAQ==} + '@tanstack/react-start-server@1.159.5': + resolution: {integrity: sha512-X4/SunwDTEbGkYTfM0gR+79amfk6phAM+2+NlC2s7TX2cD51xE8bUz2a//RxfOh9xg8f0f2CRIO34xTEDHGTfQ==} engines: {node: '>=22.12.0'} peerDependencies: react: '>=18.0.0 || >=19.0.0' react-dom: '>=18.0.0 || >=19.0.0' - '@tanstack/react-start@1.168.49': - resolution: {integrity: sha512-iQb1ZoEHqvZMGLR4G7v3tTtgL06yv/bwxvGP3waVHxVn7bRpyopM44YbOluaGkcJzc13ZTvdLKWYNAN3bxMX/Q==} + '@tanstack/react-start@1.159.5': + resolution: {integrity: sha512-vfnF7eYswAK54ru6Ay08nb0TXVzTBaVRsbbRW7hx2M0chgwtSx+YScYzoixqkccRARQBN8a/CeVq7vNFW8525w==} engines: {node: '>=22.12.0'} peerDependencies: - '@rsbuild/core': ^2.0.0 - '@vitejs/plugin-rsc': '*' react: '>=18.0.0 || >=19.0.0' react-dom: '>=18.0.0 || >=19.0.0' vite: '>=7.0.0' - peerDependenciesMeta: - '@rsbuild/core': - optional: true - '@vitejs/plugin-rsc': - optional: true - vite: - optional: true - - '@tanstack/react-store@0.11.1': - resolution: {integrity: sha512-HaIGKI3YLmjBYIvy5DFDY23oNaYZIsTZfngey07Uh5iLVJgM3bIGCnZeOFOqzjFld9JHWcaHJnasD/bKoGKwJQ==} - peerDependencies: - react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 - react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 '@tanstack/react-store@0.8.0': resolution: {integrity: sha512-1vG9beLIuB7q69skxK9r5xiLN3ztzIPfSQSs0GfeqWGO2tGIyInZx0x1COhpx97RKaONSoAb8C3dxacWksm1ow==} @@ -9758,12 +9774,6 @@ packages: react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 - '@tanstack/react-store@0.9.3': - resolution: {integrity: sha512-y2iHd/N9OkoQbFJLUX1T9vbc2O9tjH0pQRgTcx1/Nz4IlwLvkgpuglXUx+mXt0g5ZDFrEeDnONPqkbfxXJKwRg==} - peerDependencies: - react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 - react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 - '@tanstack/router-core@1.131.50': resolution: {integrity: sha512-eojd4JZ5ziUhGEmXZ4CaVX5mQdiTMiz56Sp8ZQ6r7deb55Q+5G4JQDkeuXpI7HMAvzr+4qlsFeLaDRXXjXyOqQ==} engines: {node: '>=12'} @@ -9776,15 +9786,22 @@ packages: resolution: {integrity: sha512-MFzPH39ijNO83qJN3pe7x4iAlhZyqgao3sJIzv3SJ4Pnk12xMnzuDzIAQT/1WV6JolPQEcw0Wr4L5agF8yxoeg==} engines: {node: '>=12'} - '@tanstack/router-core@1.171.27': - resolution: {integrity: sha512-wDwSLvoLwIaNcnx9UNcN9Mb7Y8QwCYq1U1RQZwyN186gnkIoIYI2SOxy8VqH1vFigbkHkk4FmwMAQlghPgDK2g==} - engines: {node: '>=20.19'} + '@tanstack/router-devtools-core@1.141.1': + resolution: {integrity: sha512-wD9yRvOk6FI+thiNBplhkGutPIPBlXvWu9ttU/obdFY5oXQj9WYgNS+IO9BEe8Pz5rNEu8zE/oLn4RUGIVdtnw==} + engines: {node: '>=12'} + peerDependencies: + '@tanstack/router-core': ^1.141.1 + csstype: ^3.0.10 + solid-js: '>=1.9.5' + peerDependenciesMeta: + csstype: + optional: true - '@tanstack/router-devtools-core@1.168.1': - resolution: {integrity: sha512-qr4voa4cpSMwQvS3867xkU3AB3MtJbTuovKIy+btjJ/Faju6er9w0nDylmD+005Mk/3YKw9/iueZJl2JAB7JOA==} - engines: {node: '>=20.19'} + '@tanstack/router-devtools-core@1.159.4': + resolution: {integrity: sha512-qMUeIv+6n1mZOcO2raCIbdOeDeMpJEmgm6oMs/nWEG61lYrzJYaCcpBTviAX0nRhSiQSUCX9cHiosUEA0e2HAw==} + engines: {node: '>=12'} peerDependencies: - '@tanstack/router-core': ^1.171.16 + '@tanstack/router-core': ^1.159.4 csstype: ^3.0.10 peerDependenciesMeta: csstype: @@ -9794,14 +9811,14 @@ packages: resolution: {integrity: sha512-zlMBw5l88GIg3v+378JsfDYq3ejEaJmD3P1R+m0yEPxh0N//Id1FjKNSS7yJbejlK2WGVm9DUG46iBdTDMQM+Q==} engines: {node: '>=12'} + '@tanstack/router-generator@1.141.1': + resolution: {integrity: sha512-21RbVAoIDn7s/n/PKMN6U60d5hCeVADrBH/uN6B/poMT4MVYtJXqISVzkc2RAboVRw6eRdYFeF+YlwA3nF6y3Q==} + engines: {node: '>=12'} + '@tanstack/router-generator@1.159.4': resolution: {integrity: sha512-O8tICQoSuvK6vs3mvBdI3zVLFmYfj/AYDCX0a5msSADP/2S0GsgDDTB5ah731TqYCtjeNriaWz9iqst38cjF/Q==} engines: {node: '>=12'} - '@tanstack/router-generator@1.167.33': - resolution: {integrity: sha512-Z3lCWIPuRUMPmuI8Mm48x/s49TxmHOaFVZ52j1W1QKYrsFHyT6U/h9bqfHJDxfQ8kz7y9q+W1YPKZ15Ee7yuCA==} - engines: {node: '>=20.19'} - '@tanstack/router-plugin@1.131.50': resolution: {integrity: sha512-gdEBPGzx7llQNRnaqfPJ1iaPS3oqB8SlvKRG5l7Fxp4q4yINgkeowFYSKEhPOc9bjoNhGrIHOlvPTPXEzAQXzQ==} engines: {node: '>=12'} @@ -9823,12 +9840,12 @@ packages: webpack: optional: true - '@tanstack/router-plugin@1.159.5': - resolution: {integrity: sha512-i2LR3WRaBOAZ1Uab5QBG9UxZIRJ3V56JVu890NysbuX15rgzRiL5yLAbfenOHdhaHy2+4joX35VICAHuVWy7Og==} + '@tanstack/router-plugin@1.141.1': + resolution: {integrity: sha512-SoNXm8QK8cqX1Q4y1AfLU0tZLOt4mB4wkdpBI/Mi3ZEezF8tIrmaenyJ3987cjT9jedTy3VDBab1wN0g8MoOXg==} engines: {node: '>=12'} peerDependencies: '@rsbuild/core': '>=1.0.2' - '@tanstack/react-router': ^1.159.5 + '@tanstack/react-router': ^1.141.1 vite: '>=5.0.0 || >=6.0.0 || >=7.0.0' vite-plugin-solid: ^2.11.10 webpack: '>=5.92.0' @@ -9844,14 +9861,14 @@ packages: webpack: optional: true - '@tanstack/router-plugin@1.168.35': - resolution: {integrity: sha512-foDAZKFqHXae+oFbIgcsSvy2QCVRn7XdS3nhwcRvD+ed6JrKPUP/1lQMsZLJqWycgR1vkZF7gs955KGa0NZQ0w==} - engines: {node: '>=20.19'} + '@tanstack/router-plugin@1.159.5': + resolution: {integrity: sha512-i2LR3WRaBOAZ1Uab5QBG9UxZIRJ3V56JVu890NysbuX15rgzRiL5yLAbfenOHdhaHy2+4joX35VICAHuVWy7Og==} + engines: {node: '>=12'} peerDependencies: - '@rsbuild/core': '>=1.0.2 || ^2.0.0' - '@tanstack/react-router': ^1.170.32 - vite: '>=5.0.0 || >=6.0.0 || >=7.0.0 || >=8.0.0' - vite-plugin-solid: ^2.11.10 || ^3.0.0-0 + '@rsbuild/core': '>=1.0.2' + '@tanstack/react-router': ^1.159.5 + vite: '>=5.0.0 || >=6.0.0 || >=7.0.0' + vite-plugin-solid: ^2.11.10 webpack: '>=5.92.0' peerDependenciesMeta: '@rsbuild/core': @@ -9865,9 +9882,16 @@ packages: webpack: optional: true - '@tanstack/router-ssr-query-core@1.169.1': - resolution: {integrity: sha512-rngux8s/3mPQzcjLYDLkNU31coYVyCgrVTfpdwqUdY5jIEHqGTXrO73DTkPR1PppwYUeVhmNCgl8TctRcnupjg==} - engines: {node: '>=20.19'} + '@tanstack/router-ssr-query-core@1.141.1': + resolution: {integrity: sha512-bkRXUhktifxBewnnphH59E0sGcsUI1NmNqxzCAmXIb93xYgafhjUGGYwfK6FqFBOmCB5isr32exGO3+UMHJr/A==} + engines: {node: '>=12'} + peerDependencies: + '@tanstack/query-core': '>=5.90.0' + '@tanstack/router-core': '>=1.127.0' + + '@tanstack/router-ssr-query-core@1.159.4': + resolution: {integrity: sha512-zqgJaf8iTk2ugrJqvU+b8NnFf3MKcnFaurtlp5tP38lNHQGW4En9UaOBOou/6zYZMlKQBcvqxSGJiwaLIyTK2g==} + engines: {node: '>=12'} peerDependencies: '@tanstack/query-core': '>=5.90.0' '@tanstack/router-core': '>=1.127.0' @@ -9884,10 +9908,6 @@ packages: resolution: {integrity: sha512-qZ76eaLKU6Ae9iI/mc5zizBX149DXXZkBVVO3/QRIll79uKLJZHQlMKR++2ba7JsciBWz1pgpIBcCJPE9S0LVg==} engines: {node: '>=12'} - '@tanstack/router-utils@1.162.2': - resolution: {integrity: sha512-hTWqJtqIFFdvuCl8WXNyrodp2L9zo2G37xKRrcVmVRWpAB2h+U1LuRAfS4tsFTiWOIoE/B+WDVFB8JpoEdw6jQ==} - engines: {node: '>=20.19'} - '@tanstack/server-functions-plugin@1.131.2': resolution: {integrity: sha512-hWsaSgEZAVyzHg8+IcJWCEtfI9ZSlNELErfLiGHG9XCHEXMegFWsrESsKHlASzJqef9RsuOLDl+1IMPIskwdDw==} engines: {node: '>=12'} @@ -9907,56 +9927,50 @@ packages: peerDependencies: solid-js: ^1.6.0 - '@tanstack/solid-router-devtools@1.167.1': - resolution: {integrity: sha512-GZiRbHx7E1vbuv1zGjPl1EmCKbwKZKoCU0TjycBjU6SW0rMt/24SON0MbtMbPlLs3XE28jFi7C5odwE2hryh/Q==} - engines: {node: '>=20.19'} + '@tanstack/solid-router-devtools@1.141.1': + resolution: {integrity: sha512-ezm8V1UR47kY/xquIobascexHkbWOcH1YXc8BRvYDKV33NEdeUhMVUqkZmwuojlRYXhF7LEfj2aSwZr0uBfH8A==} + engines: {node: '>=12'} peerDependencies: - '@tanstack/router-core': ^1.171.16 - '@tanstack/solid-router': ^1.170.19 + '@tanstack/router-core': ^1.141.1 + '@tanstack/solid-router': ^1.141.1 solid-js: ^1.9.10 peerDependenciesMeta: '@tanstack/router-core': optional: true - '@tanstack/solid-router-ssr-query@1.167.1': - resolution: {integrity: sha512-N76V3oz1ZQlTveBTRpLGOTlUtXU5GKOD++IkMnLBtuHEsge9ReluB94QBgVA+ElpQgdeso9uKUs/JsPluAynUA==} - engines: {node: '>=20.19'} + '@tanstack/solid-router-ssr-query@1.141.1': + resolution: {integrity: sha512-jM2RKblxWbrMV2nmZ+L+Y2HvfBZ448tZHXYBP/NrQa2YAHVXCZfVE5ojjB5vyDZHc7ueFAF8+yIvMGnIQQE99g==} + engines: {node: '>=12'} peerDependencies: '@tanstack/query-core': '>=5.90.0' '@tanstack/solid-query': '>=5.90.0' '@tanstack/solid-router': '>=1.127.0' solid-js: ^1.9.10 - '@tanstack/solid-router@1.170.30': - resolution: {integrity: sha512-FozWeln6hx6o2T45gFFdkGQJxvq/LN0EUlzx7+eENy9HJH/thEBSb89KTkQahULzs9bsMOufzeXJJVgB6H9/wA==} - engines: {node: '>=20.19'} + '@tanstack/solid-router@1.141.1': + resolution: {integrity: sha512-xcWkYdwvTXzQwLd4gI0efq7dUzXlcTyent/UDrGf1K5dDBqlFSAj9c11vNwP0+YvCaPt4U1r8czyMD1Qr3aNGA==} + engines: {node: '>=12'} peerDependencies: solid-js: ^1.9.10 - '@tanstack/solid-start-client@1.168.29': - resolution: {integrity: sha512-+F3Z/J1SVxPj2Hs53Wvos2DhIe7cGvlHpwZD9x0+aIWofIlkRSnrGm2wehWZzun1tzgZNnK2L2thkQlXVtuVaw==} + '@tanstack/solid-start-client@1.141.1': + resolution: {integrity: sha512-NGc70Jj9DoWFieFX9iQG70fmuTvX7nfTUG5vlboxBzvTuPrIdyeddrQVnBX/kXUdFzLGzez7QlxqyOrm3zouuQ==} engines: {node: '>=22.12.0'} peerDependencies: solid-js: '>=1.0.0' - '@tanstack/solid-start-server@1.167.36': - resolution: {integrity: sha512-7WMqLxe1Yr+9Q+Ze2dsYrPnousiPmA5LndJtg1MnaIRNecL1NInd5jsiIwNB42qOWTwcGr8aD8LnHH4dcVh/wA==} + '@tanstack/solid-start-server@1.141.1': + resolution: {integrity: sha512-vIuw74+6cgBmh1zAqc27dKHd5rU2K4V6nHt+u7vBKUUu/9QIF7PoQD0fj2dWnrjnz7EJKb1W7Gr9rAtOdglgGw==} engines: {node: '>=22.12.0'} peerDependencies: solid-js: ^1.0.0 - '@tanstack/solid-start@1.168.47': - resolution: {integrity: sha512-yqXrj5Q1wGh/9Gb/wGp117AavC48tFk29LP/2oGHBJKq4ZATYes8s3yPBRSWlSkqQG9N2yQzjmF+sutXZSZVzw==} + '@tanstack/solid-start@1.141.1': + resolution: {integrity: sha512-b7B7UUPn3GANvnvTusiryTr+CUEs+lMMFRRiDiBZXx+Yb1cqtp/UYilEDHdqnx2xUoAhR0FBd4kRcieCV69DVg==} engines: {node: '>=22.12.0'} peerDependencies: - '@rsbuild/core': ^2.0.0 solid-js: '>=1.0.0' vite: '>=7.0.0' - peerDependenciesMeta: - '@rsbuild/core': - optional: true - vite: - optional: true '@tanstack/solid-store@0.8.0': resolution: {integrity: sha512-JwqTedbxyOGw7mfmdGkB0RGgefRCw/tNauc8tlMcaS1mV5wTFT8c1KIB3LgttuHaanMJEBeqQJ7bc/R0WTP1fA==} @@ -9979,10 +9993,6 @@ packages: resolution: {integrity: sha512-9j2i1PRTIGcYAD+509znve0ngK81ZUfbX4XCpoNFMaUUpRHoEPPK5I9+PzLFvL9sNOto67x+WULCUggzX+lEKQ==} engines: {node: '>=22.12.0'} - '@tanstack/start-client-core@1.170.27': - resolution: {integrity: sha512-Ro6ZSM0NgYKDMxM0e8qyU4mBfnld2Zb74BA/9f4i35C0Y3IAA8Zxs/DIPfOo9VRYWp5c5n5Q8dRBn2qn0vtPhQ==} - engines: {node: '>=22.12.0'} - '@tanstack/start-config@1.120.20': resolution: {integrity: sha512-oH/mfTSHV8Qbil74tWicPLW6+kKmT3esXCnDzvrkhi3+N8ZuVUDr01Qpil0Wxf9lLPfM5L6VX03nF4hSU8vljg==} engines: {node: '>=12'} @@ -9995,27 +10005,23 @@ packages: resolution: {integrity: sha512-D69B78L6pcFN5X5PHaydv7CScQcKLzJeEYqs7jpuyyqGQHSUIZUjS955j+Sir8cHhuDIovCe2LmsYHeZfWf3dQ==} engines: {node: '>=22.12.0'} - '@tanstack/start-fn-stubs@1.162.0': - resolution: {integrity: sha512-QWfUZ3Yo923tdQn38LyKMU8rcTw69zc+T4dAvgTWV4O56SqFRsGfS0lSWIMhJRwXIx/bvdi7nTUBDdZtTHtpTQ==} - engines: {node: '>=22.12.0'} - '@tanstack/start-plugin-core@1.131.50': resolution: {integrity: sha512-eFvMA0chqLtHbq+8ojp1fXN7AQjhmeoOpQaZaU1d51wb7ugetrn0k3OuHblxtE/O0L4HEC9s4X5zmFJt0vLh0w==} engines: {node: '>=12'} peerDependencies: vite: '>=6.0.0' - '@tanstack/start-plugin-core@1.171.39': - resolution: {integrity: sha512-Zyj6G4MDFLXcHYhPavhewCBo8dsxi3qvPk31zl/QtTzYzOY9rJHDDBGarKsJq20ziChmkGn/sttYqb4vGCxJDA==} + '@tanstack/start-plugin-core@1.141.1': + resolution: {integrity: sha512-jXfgKeM4XX7aoP7WF/cJZH52N0ewIYRdP028ItXaSwUMcDyBO+PPTNbSEqTu3zbzLsmTOOyuJEpIrVA0/lmbjA==} + engines: {node: '>=22.12.0'} + peerDependencies: + vite: '>=7.0.0' + + '@tanstack/start-plugin-core@1.159.5': + resolution: {integrity: sha512-QGiBw+L3qu2sUY0Tg9KovxjDSi5kevoANEcq9RLX7iIhLkTjrILN6hnAlXZUzqk5Egaf0aN2yWhwI4HWucMprw==} engines: {node: '>=22.12.0'} peerDependencies: - '@rsbuild/core': ^2.0.0 vite: '>=7.0.0' - peerDependenciesMeta: - '@rsbuild/core': - optional: true - vite: - optional: true '@tanstack/start-server-core@1.131.50': resolution: {integrity: sha512-3SWwwhW2GKMhPSaqWRal6Jj1Y9ObfdWEXKFQid1LBuk5xk/Es4bmW68o++MbVgs/GxUxyeZ3TRVqb0c7RG1sog==} @@ -10029,10 +10035,6 @@ packages: resolution: {integrity: sha512-sGpr+iil+pcY3Gglvbnxaj7fCEPTQJv4oF7YA24SVv8YvayLXtBXpF26miJLA+KR9P31dQdPYe1gTjv5zRyvHg==} engines: {node: '>=22.12.0'} - '@tanstack/start-server-core@1.169.31': - resolution: {integrity: sha512-56w8l+Fao01YCrmv0hzNxL3b3FRmqLRGdE11izZNQsW+1CcSYuehAM5khWKABuI1DI/UIBLGV7BwL4Dlg0eHCw==} - engines: {node: '>=22.12.0'} - '@tanstack/start-server-functions-client@1.131.50': resolution: {integrity: sha512-4aM17fFdVAFH6uLPswKJxzrhhIjcCwKqzfTcgY3OnhUKnaZBTQwJA+nUHQCI6IWvEvrcrNVtFTtv13TkDk3YMw==} engines: {node: '>=12'} @@ -10065,10 +10067,6 @@ packages: resolution: {integrity: sha512-iGkmuCIq3PLI4GKOGwgUNHQKZ13YV8LGq62o2hVnyXE64Jm2SP7c5z6D1ndydpk4JwdRzQKlcOFT/1agvS6Nsg==} engines: {node: '>=22.12.0'} - '@tanstack/start-storage-context@1.167.29': - resolution: {integrity: sha512-8qfprC5774XMRDQlMogkfiGpFLiBf0xDG4bMFUbfkSzpCAQwpLbgGY4Zwft22O9rKYq2vUXusKAdVjvJTUEquQ==} - engines: {node: '>=22.12.0'} - '@tanstack/start@1.120.20': resolution: {integrity: sha512-fQO+O/5xJpli5KlV6pwDz6DtpbqO/0atdVSyVnkemzk0Mej9azm4HXtw+cKkIPtsSplWs4B1EbMtgGMb9ADhSA==} engines: {node: '>=12'} @@ -10082,9 +10080,6 @@ packages: '@tanstack/store@0.8.0': resolution: {integrity: sha512-Om+BO0YfMZe//X2z0uLF2j+75nQga6TpTJgLJQBiq85aOyZNIhkCgleNcud2KQg4k4v9Y9l+Uhru3qWMPGTOzQ==} - '@tanstack/store@0.9.3': - resolution: {integrity: sha512-8reSzl/qGWGGVKhBoxXPMWzATSbZLZFWhwBAFO9NAyp0TxzfBP0mIrGb8CP8KrQTmvzXlR/vFPPUrHTLBGyFyw==} - '@tanstack/typedoc-config@0.3.4': resolution: {integrity: sha512-WXJavpiNqumNwdBQTM3wBqbHaULgoZ3cIri7xJinKqX/mOGXgc6ZghfAardD2PydP8tOcPf+xhrd1Qk/am9DMg==} engines: {node: '>=18'} @@ -10093,14 +10088,14 @@ packages: resolution: {integrity: sha512-VEEOxc4mvyu67O+Bl0APtYjwcNRcL9it9B4HKbNgcBTIOEalhk+ufBl4kiqc8WP1sx1+NAaiS+3CcJBhrqaSRg==} engines: {node: '>=12'} + '@tanstack/virtual-file-routes@1.141.0': + resolution: {integrity: sha512-CJrWtr6L9TVzEImm9S7dQINx+xJcYP/aDkIi6gnaWtIgbZs1pnzsE0yJc2noqXZ+yAOqLx3TBGpBEs9tS0P9/A==} + engines: {node: '>=12'} + '@tanstack/virtual-file-routes@1.154.7': resolution: {integrity: sha512-cHHDnewHozgjpI+MIVp9tcib6lYEQK5MyUr0ChHpHFGBl8Xei55rohFK0I0ve/GKoHeioaK42Smd8OixPp6CTg==} engines: {node: '>=12'} - '@tanstack/virtual-file-routes@1.162.0': - resolution: {integrity: sha512-uhOeFyxLcU41HzvrxsGpiWdcMbScY1EDgbZ5K7DVRMYInbLYWAC0EA/kx9wXAoSM8q82bUG2hRl8+EAjE6XAbA==} - engines: {node: '>=20.19'} - '@tanstack/vite-config@0.6.0': resolution: {integrity: sha512-TtcetFc7aBm9BBclG3/8pM8ZlyzS8yNwi+eScN4gqsB9xnxyOPCbuvvkk//ybfQj8MVEZavQ03EOQxmOJdW8Rw==} engines: {node: '>=18'} @@ -10384,16 +10379,32 @@ packages: eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 typescript: '>=4.8.4 <6.1.0' + '@typescript-eslint/project-service@8.49.0': + resolution: {integrity: sha512-/wJN0/DKkmRUMXjZUXYZpD1NEQzQAAn9QWfGwo+Ai8gnzqH7tvqS7oNVdTjKqOcPyVIdZdyCMoqN66Ia789e7g==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + typescript: '>=4.8.4 <6.0.0' + '@typescript-eslint/project-service@8.59.4': resolution: {integrity: sha512-Ly00Vu4oAacfDeHp2Zg85ioNG6l8HG+tN1D7J+xTHSxu9y0awYKJ2zH1rFBn8ZSfuGK+7FxK3Cgl3uAz0aZZLg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: typescript: '>=4.8.4 <6.1.0' + '@typescript-eslint/scope-manager@8.49.0': + resolution: {integrity: sha512-npgS3zi+/30KSOkXNs0LQXtsg9ekZ8OISAOLGWA/ZOEn0ZH74Ginfl7foziV8DT+D98WfQ5Kopwqb/PZOaIJGg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@typescript-eslint/scope-manager@8.59.4': resolution: {integrity: sha512-mUeR/3H1WrTAddJrwut8OoPjfauaztMQmRwV5fQTUyNVJCLiUXXe4lGEyYIL2oFDpP7UtgbGJXCt72wT0z2S3Q==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@typescript-eslint/tsconfig-utils@8.49.0': + resolution: {integrity: sha512-8prixNi1/6nawsRYxet4YOhnbW+W9FK/bQPxsGB1D3ZrDzbJ5FXw5XmzxZv82X3B+ZccuSxo/X8q9nQ+mFecWA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + typescript: '>=4.8.4 <6.0.0' + '@typescript-eslint/tsconfig-utils@8.59.4': resolution: {integrity: sha512-DLCpnKgD4alVxTBSKulK+gU1KCqOgUXfDRDXh2mZgzokQKa/70ax93I2uVO3m/LLvIAtWZIFoiifudmIqAxpMA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} @@ -10407,16 +10418,33 @@ packages: eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 typescript: '>=4.8.4 <6.1.0' + '@typescript-eslint/types@8.49.0': + resolution: {integrity: sha512-e9k/fneezorUo6WShlQpMxXh8/8wfyc+biu6tnAqA81oWrEic0k21RHzP9uqqpyBBeBKu4T+Bsjy9/b8u7obXQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@typescript-eslint/types@8.59.4': resolution: {integrity: sha512-F1o7WJcCq+bc8dwcO/YsSEOudAH8RDtaOhM6wcAQhcUsFhnWQl81JKy48q1hoxAU0qrzM89+31GYh1515Zde3Q==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@typescript-eslint/typescript-estree@8.49.0': + resolution: {integrity: sha512-jrLdRuAbPfPIdYNppHJ/D0wN+wwNfJ32YTAm10eJVsFmrVpXQnDWBn8niCSMlWjvml8jsce5E/O+86IQtTbJWA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + typescript: '>=4.8.4 <6.0.0' + '@typescript-eslint/typescript-estree@8.59.4': resolution: {integrity: sha512-F+RuOmcDXo4+TPdfd/TCLS3m2nw8gE9XXyZLrA3JBfaA5tz9TtdkyD3YJFmPxulyc2cKbEok/CvFE3MgSLWnag==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: typescript: '>=4.8.4 <6.1.0' + '@typescript-eslint/utils@8.49.0': + resolution: {integrity: sha512-N3W7rJw7Rw+z1tRsHZbK395TWSYvufBXumYtEGzypgMUthlg0/hmCImeA8hgO2d2G4pd7ftpxxul2J8OdtdaFA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 + typescript: '>=4.8.4 <6.0.0' + '@typescript-eslint/utils@8.59.4': resolution: {integrity: sha512-cYXeNAUsG4lJo5dbc1FcKm+JwIWrj1/UpTORsC6tGMjEZ81DYcvIr9/ueikhMa/Y/gDQYGp+YX9/xQrXje5BJw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} @@ -10424,6 +10452,10 @@ packages: eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 typescript: '>=4.8.4 <6.1.0' + '@typescript-eslint/visitor-keys@8.49.0': + resolution: {integrity: sha512-LlKaciDe3GmZFphXIc79THF/YYBugZ7FS1pO581E/edlVVNbZKDy93evqmrfQ9/Y4uN0vVhX4iuchq26mK/iiA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@typescript-eslint/visitor-keys@8.59.4': resolution: {integrity: sha512-U3gxVaDVnuZKhSspW/MzMxE1kq7zOdc072FcSNoqA1I9p8HyKbBFfEHoWckBAMgNMph4MamwS5iTVzFmrnt8TQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} @@ -11621,9 +11653,6 @@ packages: cookie-es@2.0.1: resolution: {integrity: sha512-aVf4A4hI2w70LnF7GG+7xDQUkliwiXWXFvTjkip4+b64ygDQ2sJPRSKFDHbxn8o0xu9QzPkMuuiWIXyFSE2slA==} - cookie-es@3.1.1: - resolution: {integrity: sha512-UaXxwISYJPTr9hwQxMFYZ7kNhSXboMXP+Z3TRX6f1/NyaGPfuNUZOWP1pUEb75B2HjfklIYLVRfWiFZJyC6Npg==} - cookie-signature@1.2.2: resolution: {integrity: sha512-D76uU73ulSXrD1UXF4KE2TMxVVwhsnCgfAyTg9k8P6KGZjlXKrOLe4dJQKI3Bxi5wjesZoFXJWElNWBjPZMbhg==} engines: {node: '>=6.6.0'} @@ -12357,6 +12386,13 @@ packages: engines: {node: '>=6.0'} hasBin: true + eslint-plugin-solid@0.14.5: + resolution: {integrity: sha512-nfuYK09ah5aJG/oEN6P1qziy1zLgW4PDWe75VNPi4CEFYk1x2AEqwFeQfEPR7gNn0F2jOeqKhx2E+5oNCOBYWQ==} + engines: {node: '>=18.0.0'} + peerDependencies: + eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 || ^9.0.0 + typescript: '>=4.8.4' + eslint-plugin-unused-imports@4.3.0: resolution: {integrity: sha512-ZFBmXMGBYfHttdRtOG9nFFpmUvMtbHSjsKrS20vdWdbfiVYsO3yA2SGYy9i9XmZJDfMGBflZGBCm70SEnFQtOA==} peerDependencies: @@ -13008,16 +13044,6 @@ packages: crossws: optional: true - h3@2.0.1-rc.20: - resolution: {integrity: sha512-28ljodXuUp0fZovdiSRq4G9OgrxCztrJe5VdYzXAB7ueRvI7pIUqLU14Xi3XqdYJ/khXjfpUOOD2EQa6CmBgsg==} - engines: {node: '>=20.11.1'} - hasBin: true - peerDependencies: - crossws: ^0.4.1 - peerDependenciesMeta: - crossws: - optional: true - h3@2.0.1-rc.22: resolution: {integrity: sha512-Esv0DMIuPkCTSWCA0vO73vcTqwzH1wjSrAO1TXNu/K3up1sZHa9EKMapbmxCDYBeymC3fVTk4qxp7ogQWQ+KgA==} engines: {node: '>=20.11.1'} @@ -13143,6 +13169,10 @@ packages: html-link-extractor@1.0.5: resolution: {integrity: sha512-ADd49pudM157uWHwHQPUSX4ssMsvR/yHIswOR5CUfBdK9g9ZYGMhVSE6KZVHJ6kCkR0gH4htsfzU6zECDNVwyw==} + html-tags@3.3.1: + resolution: {integrity: sha512-ztqyC3kLto0e9WbNp0aeP+M3kTt+nbaIveGmUxAtZa+8iFgKLUOD4YKM5j+f3QD89bra7UeumolZHKuOXnTmeQ==} + engines: {node: '>=8'} + html-url-attributes@3.0.1: resolution: {integrity: sha512-ol6UPyBWqsrO6EJySPz2O7ZSr856WDrEzM5zMqp+FJJLGMW35cLYmmZnl0vztAZxRUoNZJFTCohfjuIJ8I4QBQ==} @@ -13370,6 +13400,10 @@ packages: is-hexadecimal@2.0.1: resolution: {integrity: sha512-DgZQp241c8oO6cA1SbTEWiXeoxV42vlcJxgH+B3hi1AiqqKruZR3ZGF8In3fj4+/y/7rHvlOZLZtgJ/4ttYGZg==} + is-html@2.0.0: + resolution: {integrity: sha512-S+OpgB5i7wzIue/YSE5hg0e5ZYfG3hhpNh9KGl6ayJ38p7ED6wxQLd1TV91xHpcTvw90KMJ9EwN3F/iNflHBVg==} + engines: {node: '>=8'} + is-inside-container@1.0.0: resolution: {integrity: sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA==} engines: {node: '>=14.16'} @@ -13693,6 +13727,9 @@ packages: jws@4.0.1: resolution: {integrity: sha512-EKI/M/yqPncGUUh44xz0PxSidXFr/+r0pA70+gIYhjv+et7yxM+s29Y+VGDkovRofQem0fs7Uvf4+YmAdyRduA==} + kebab-case@1.0.2: + resolution: {integrity: sha512-7n6wXq4gNgBELfDCpzKc+mRrZFs7D+wgfF5WRFLNAr4DA/qtr9Js8uOAVAfHhuLMfAcQ0pRKqbpjx+TcJVdE1Q==} + keyv@4.5.4: resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==} @@ -13727,6 +13764,9 @@ packages: knitwork@1.3.0: resolution: {integrity: sha512-4LqMNoONzR43B1W0ek0fhXMsDNW/zxa1NdFAVMY+k28pgZLovR4G3PB5MrpTxCy1QaZCqNoiaKPr5w5qZHfSNw==} + known-css-properties@0.30.0: + resolution: {integrity: sha512-VSWXYUnsPu9+WYKkfmJyLKtIvaRJi1kXUqVmBACORXZQxT5oZDsoZ2vQP+bQFDnWtpI/4eq3MLoRMjI2fnLzTQ==} + kolorist@1.8.0: resolution: {integrity: sha512-Y+60/zizpJ3HRH8DCss+q95yr6145JXZo46OTpFvDZWLfRCE4qChOyk1b26nMaNpfHHgxagk9dXT5OP0Tfe+dQ==} @@ -15926,12 +15966,6 @@ packages: peerDependencies: seroval: ^1.0 - seroval-plugins@1.6.2: - resolution: {integrity: sha512-TfxuUjlbBESzUOWdTkTKqvSmav0ABym+itetDXLK6mDz8SmrpdI30aF8RTXE8Bvq+tH/1yIDkvy3W0lfQb1ipQ==} - engines: {node: '>=10'} - peerDependencies: - seroval: ^1.0 - seroval@1.3.2: resolution: {integrity: sha512-RbcPH1n5cfwKrru7v7+zrZvjLurgHhGyso3HTyGtRivGWgYjbOmGuivCQaORNELjNONoK35nj28EoWul9sb1zQ==} engines: {node: '>=10'} @@ -15944,10 +15978,6 @@ packages: resolution: {integrity: sha512-OE4cvmJ1uSPrKorFIH9/w/Qwuvi/IMcGbv5RKgcJ/zjA/IohDLU6SVaxFN9FwajbP7nsX0dQqMDes1whk3y+yw==} engines: {node: '>=10'} - seroval@1.6.2: - resolution: {integrity: sha512-mPT+SD2TrlB6wvte1KkYOYUkubaTbd6pZ/6Kk3C9nxzrHmCZyhxOO7XGAeL7f+yLKZglzGtM9odUVvg/EhO+vQ==} - engines: {node: '>=10'} - serve-placeholder@2.0.2: resolution: {integrity: sha512-/TMG8SboeiQbZJWRlfTCqMs2DD3SZgWp0kDQePz9yUuCnDfDh/92gf7/PxGhzXTKBIPASIHxFcZndoNbp6QOLQ==} @@ -16530,6 +16560,12 @@ packages: ts-algebra@2.0.0: resolution: {integrity: sha512-FPAhNPFMrkwz76P7cdjdmiShwMynZYN6SgOujD1urY4oNm80Ou9oMdmbR45LotcKOXoy7wSmHkRFE6Mxbrhefw==} + ts-api-utils@2.1.0: + resolution: {integrity: sha512-CUgTZL1irw8u29bzrOD/nH85jqyc74D6SshFgujOIA7osm2Rz7dYH77agkx7H4FBNxDq7Cjf+IjaX/8zwFW+ZQ==} + engines: {node: '>=18.12'} + peerDependencies: + typescript: '>=4.8.4' + ts-api-utils@2.5.0: resolution: {integrity: sha512-OJ/ibxhPlqrMM0UiNHJ/0CKQkoKF243/AEmplt3qpRgkW8VG7IfOS41h7V8TjITqdByHzrjcS/2si+y4lIh8NA==} engines: {node: '>=18.12'} @@ -16855,39 +16891,6 @@ packages: resolution: {integrity: sha512-5uKD0nqiYVzlmCRs01Fhs2BdkEgBS3SAVP6ndrBsuK42iC2+JHyxM05Rm9G8+5mkmRtzMZGY8Ct5+mliZxU/Ww==} engines: {node: '>=18.12.0'} - unplugin@3.3.0: - resolution: {integrity: sha512-qa66K+crbfyE6JK10GjvbJeRrOsuC/JpbnHctfyp/i4oBTxWOzJfRZyDiOk1PtErMFRu8JhsU/wPvOdBNWe5Rg==} - engines: {node: ^20.19.0 || >=22.12.0} - peerDependencies: - '@farmfe/core': '*' - '@rspack/core': '*' - bun-types-no-globals: '*' - esbuild: '*' - rolldown: '*' - rollup: '*' - unloader: '*' - vite: '*' - webpack: '*' - peerDependenciesMeta: - '@farmfe/core': - optional: true - '@rspack/core': - optional: true - bun-types-no-globals: - optional: true - esbuild: - optional: true - rolldown: - optional: true - rollup: - optional: true - unloader: - optional: true - vite: - optional: true - webpack: - optional: true - unrun@0.2.19: resolution: {integrity: sha512-DbwbJ9BvPEb3BeZnIpP9S5tGLO/JIgPQ3JrpMRFIfZMZfMG19f26OlLbC2ml8RRdrI2ZA7z2t+at5tsIHbh6Qw==} engines: {node: '>=20.19.0'} @@ -17297,6 +17300,14 @@ packages: yaml: optional: true + vitefu@1.1.1: + resolution: {integrity: sha512-B/Fegf3i8zh0yFbpzZ21amWzHmuNlLlmJT6n7bu5e+pCHUKQIfXSYokrqOBGEMMe9UG2sostKQF9mml/vYaWJQ==} + peerDependencies: + vite: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0-beta.0 + peerDependenciesMeta: + vite: + optional: true + vitefu@1.1.3: resolution: {integrity: sha512-ub4okH7Z5KLjb6hDyjqrGXqWtWvoYdU3IGm/NorpgHncKoLTCfRIbvlhBm7r0YstIaQRYlp4yEbFqDcKSzXSSg==} peerDependencies: @@ -17704,9 +17715,6 @@ packages: zod@4.3.6: resolution: {integrity: sha512-rftlrkhHZOcjDwkGlnUtZZkvaPHCsDATp4pGpuOOMDaTdDDXF91wuVDJoWoPsKX/3YPQ5fHuF3STjcYyKr+Qhg==} - zod@4.4.3: - resolution: {integrity: sha512-ytENFjIJFl2UwYglde2jchW2Hwm4GJFLDiSXWdTrJQBIN9Fcyp7n4DhxJEiWNAJMV1/BqWfW/kkg71UDcHJyTQ==} - zone.js@0.15.1: resolution: {integrity: sha512-XE96n56IQpJM7NAoXswY3XRLcWFW83xe0BiAOeMD7K5k5xecOeul3Qcpx6GqEeeHNkW5DWL5zOyTbEfB4eti8w==} @@ -17901,7 +17909,7 @@ snapshots: '@angular/compiler-cli@21.2.17(@angular/compiler@21.2.20)(typescript@5.9.3)': dependencies: '@angular/compiler': 21.2.20 - '@babel/core': 7.29.0 + '@babel/core': 7.29.0(supports-color@7.2.0) '@jridgewell/sourcemap-codec': 1.5.5 chokidar: 5.0.0 convert-source-map: 1.9.0 @@ -18388,9 +18396,9 @@ snapshots: '@babel/helper-module-transforms': 7.28.3(@babel/core@7.28.5) '@babel/helpers': 7.28.4 '@babel/parser': 7.28.5 - '@babel/template': 7.29.7 + '@babel/template': 7.27.2 '@babel/traverse': 7.28.5 - '@babel/types': 7.29.7 + '@babel/types': 7.28.5 '@jridgewell/remapping': 2.3.5 convert-source-map: 2.0.0 debug: 4.4.3(supports-color@7.2.0) @@ -18408,9 +18416,9 @@ snapshots: '@babel/helper-module-transforms': 7.28.3(@babel/core@7.28.5(supports-color@7.2.0)) '@babel/helpers': 7.28.4 '@babel/parser': 7.28.5 - '@babel/template': 7.29.7 + '@babel/template': 7.27.2 '@babel/traverse': 7.28.5 - '@babel/types': 7.29.7 + '@babel/types': 7.28.5 '@jridgewell/remapping': 2.3.5 convert-source-map: 2.0.0 debug: 4.4.3(supports-color@7.2.0) @@ -18420,12 +18428,12 @@ snapshots: transitivePeerDependencies: - supports-color - '@babel/core@7.29.0': + '@babel/core@7.29.0(supports-color@7.2.0)': dependencies: '@babel/code-frame': 7.29.7 '@babel/generator': 7.29.7 '@babel/helper-compilation-targets': 7.29.7 - '@babel/helper-module-transforms': 7.29.7(@babel/core@7.29.0) + '@babel/helper-module-transforms': 7.29.7(@babel/core@7.29.0(supports-color@7.2.0)) '@babel/helpers': 7.29.7 '@babel/parser': 7.29.7 '@babel/template': 7.29.7 @@ -18463,7 +18471,7 @@ snapshots: '@babel/generator@7.28.5': dependencies: '@babel/parser': 7.29.0 - '@babel/types': 7.29.7 + '@babel/types': 7.29.0 '@jridgewell/gen-mapping': 0.3.13 '@jridgewell/trace-mapping': 0.3.31 jsesc: 3.1.0 @@ -18547,6 +18555,19 @@ snapshots: transitivePeerDependencies: - supports-color + '@babel/helper-create-class-features-plugin@7.29.7(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0(supports-color@7.2.0) + '@babel/helper-annotate-as-pure': 7.29.7 + '@babel/helper-member-expression-to-functions': 7.29.7 + '@babel/helper-optimise-call-expression': 7.29.7 + '@babel/helper-replace-supers': 7.29.7(@babel/core@7.29.0) + '@babel/helper-skip-transparent-expression-wrappers': 7.29.7 + '@babel/traverse': 7.29.7 + semver: 6.3.1 + transitivePeerDependencies: + - supports-color + '@babel/helper-create-class-features-plugin@7.29.7(@babel/core@7.29.7)': dependencies: '@babel/core': 7.29.7 @@ -18632,6 +18653,15 @@ snapshots: transitivePeerDependencies: - supports-color + '@babel/helper-module-transforms@7.28.3(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0(supports-color@7.2.0) + '@babel/helper-module-imports': 7.29.7 + '@babel/helper-validator-identifier': 7.29.7 + '@babel/traverse': 7.29.7 + transitivePeerDependencies: + - supports-color + '@babel/helper-module-transforms@7.28.3(@babel/core@7.29.7)': dependencies: '@babel/core': 7.29.7 @@ -18641,9 +18671,9 @@ snapshots: transitivePeerDependencies: - supports-color - '@babel/helper-module-transforms@7.29.7(@babel/core@7.29.0)': + '@babel/helper-module-transforms@7.29.7(@babel/core@7.29.0(supports-color@7.2.0))': dependencies: - '@babel/core': 7.29.0 + '@babel/core': 7.29.0(supports-color@7.2.0) '@babel/helper-module-imports': 7.29.7 '@babel/helper-validator-identifier': 7.29.7 '@babel/traverse': 7.29.7 @@ -18709,6 +18739,15 @@ snapshots: transitivePeerDependencies: - supports-color + '@babel/helper-replace-supers@7.29.7(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0(supports-color@7.2.0) + '@babel/helper-member-expression-to-functions': 7.29.7 + '@babel/helper-optimise-call-expression': 7.29.7 + '@babel/traverse': 7.29.7 + transitivePeerDependencies: + - supports-color + '@babel/helper-replace-supers@7.29.7(@babel/core@7.29.7)': dependencies: '@babel/core': 7.29.7 @@ -18772,7 +18811,7 @@ snapshots: '@babel/parser@7.29.0': dependencies: - '@babel/types': 7.29.7 + '@babel/types': 7.29.0 '@babel/parser@7.29.7': dependencies: @@ -18822,11 +18861,21 @@ snapshots: '@babel/core': 7.28.5(supports-color@7.2.0) '@babel/helper-plugin-utils': 7.29.7 + '@babel/plugin-syntax-jsx@7.27.1(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0(supports-color@7.2.0) + '@babel/helper-plugin-utils': 7.29.7 + '@babel/plugin-syntax-jsx@7.27.1(@babel/core@7.29.7)': dependencies: '@babel/core': 7.29.7 '@babel/helper-plugin-utils': 7.29.7 + '@babel/plugin-syntax-jsx@7.29.7(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0(supports-color@7.2.0) + '@babel/helper-plugin-utils': 7.29.7 + '@babel/plugin-syntax-jsx@7.29.7(@babel/core@7.29.7)': dependencies: '@babel/core': 7.29.7 @@ -18847,6 +18896,11 @@ snapshots: '@babel/core': 7.28.5(supports-color@7.2.0) '@babel/helper-plugin-utils': 7.29.7 + '@babel/plugin-syntax-typescript@7.27.1(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0(supports-color@7.2.0) + '@babel/helper-plugin-utils': 7.29.7 + '@babel/plugin-syntax-typescript@7.27.1(@babel/core@7.29.7)': dependencies: '@babel/core': 7.29.7 @@ -18957,6 +19011,14 @@ snapshots: transitivePeerDependencies: - supports-color + '@babel/plugin-transform-modules-commonjs@7.27.1(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0(supports-color@7.2.0) + '@babel/helper-module-transforms': 7.28.3(@babel/core@7.29.0) + '@babel/helper-plugin-utils': 7.27.1 + transitivePeerDependencies: + - supports-color + '@babel/plugin-transform-modules-commonjs@7.27.1(@babel/core@7.29.7)': dependencies: '@babel/core': 7.29.7 @@ -19105,6 +19167,17 @@ snapshots: transitivePeerDependencies: - supports-color + '@babel/plugin-transform-typescript@7.28.5(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0(supports-color@7.2.0) + '@babel/helper-annotate-as-pure': 7.29.7 + '@babel/helper-create-class-features-plugin': 7.29.7(@babel/core@7.29.0) + '@babel/helper-plugin-utils': 7.29.7 + '@babel/helper-skip-transparent-expression-wrappers': 7.27.1 + '@babel/plugin-syntax-typescript': 7.27.1(@babel/core@7.29.0) + transitivePeerDependencies: + - supports-color + '@babel/plugin-transform-typescript@7.28.5(@babel/core@7.29.7)': dependencies: '@babel/core': 7.29.7 @@ -19140,6 +19213,17 @@ snapshots: transitivePeerDependencies: - supports-color + '@babel/preset-typescript@7.28.5(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0(supports-color@7.2.0) + '@babel/helper-plugin-utils': 7.27.1 + '@babel/helper-validator-option': 7.27.1 + '@babel/plugin-syntax-jsx': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-modules-commonjs': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-typescript': 7.28.5(@babel/core@7.29.0) + transitivePeerDependencies: + - supports-color + '@babel/preset-typescript@7.28.5(@babel/core@7.29.7)': dependencies: '@babel/core': 7.29.7 @@ -19162,6 +19246,12 @@ snapshots: '@babel/runtime@7.29.2': {} + '@babel/template@7.27.2': + dependencies: + '@babel/code-frame': 7.29.7 + '@babel/parser': 7.29.7 + '@babel/types': 7.29.7 + '@babel/template@7.29.7': dependencies: '@babel/code-frame': 7.29.7 @@ -19174,8 +19264,8 @@ snapshots: '@babel/generator': 7.28.5 '@babel/helper-globals': 7.28.0 '@babel/parser': 7.28.5 - '@babel/template': 7.29.7 - '@babel/types': 7.29.7 + '@babel/template': 7.27.2 + '@babel/types': 7.28.5 debug: 4.4.3(supports-color@7.2.0) transitivePeerDependencies: - supports-color @@ -19204,6 +19294,11 @@ snapshots: transitivePeerDependencies: - supports-color + '@babel/types@7.28.5': + dependencies: + '@babel/helper-string-parser': 7.29.7 + '@babel/helper-validator-identifier': 7.29.7 + '@babel/types@7.29.0': dependencies: '@babel/helper-string-parser': 7.27.1 @@ -20272,7 +20367,7 @@ snapshots: '@expo/metro-config@56.0.13(expo@56.0.5)(typescript@5.9.3)': dependencies: '@babel/code-frame': 7.29.0 - '@babel/core': 7.29.7 + '@babel/core': 7.29.0(supports-color@7.2.0) '@babel/generator': 7.29.1 '@expo/config': 56.0.9(typescript@5.9.3) '@expo/env': 2.3.0 @@ -21107,6 +21202,8 @@ snapshots: '@nodelib/fs.scandir': 2.1.5 fastq: 1.19.1 + '@nothing-but/utils@0.17.0': {} + '@nx/nx-darwin-arm64@23.1.1': optional: true @@ -24251,6 +24348,8 @@ snapshots: '@rolldown/pluginutils@1.0.0-beta.27': {} + '@rolldown/pluginutils@1.0.0-beta.40': {} + '@rolldown/pluginutils@1.0.0-beta.53': {} '@rolldown/pluginutils@1.0.0-rc.3': {} @@ -24590,6 +24689,48 @@ snapshots: '@smithy/util-buffer-from': 2.2.0 tslib: 2.8.1 + '@solid-devtools/debugger@0.28.1(solid-js@1.9.10)': + dependencies: + '@nothing-but/utils': 0.17.0 + '@solid-devtools/shared': 0.20.0(solid-js@1.9.10) + '@solid-primitives/bounds': 0.1.3(solid-js@1.9.10) + '@solid-primitives/event-listener': 2.4.3(solid-js@1.9.10) + '@solid-primitives/keyboard': 1.3.3(solid-js@1.9.10) + '@solid-primitives/rootless': 1.5.2(solid-js@1.9.10) + '@solid-primitives/scheduled': 1.5.2(solid-js@1.9.10) + '@solid-primitives/static-store': 0.1.2(solid-js@1.9.10) + '@solid-primitives/utils': 6.3.2(solid-js@1.9.10) + solid-js: 1.9.10 + + '@solid-devtools/logger@0.9.11(solid-js@1.9.10)': + dependencies: + '@nothing-but/utils': 0.17.0 + '@solid-devtools/debugger': 0.28.1(solid-js@1.9.10) + '@solid-devtools/shared': 0.20.0(solid-js@1.9.10) + '@solid-primitives/utils': 6.3.2(solid-js@1.9.10) + solid-js: 1.9.10 + + '@solid-devtools/shared@0.20.0(solid-js@1.9.10)': + dependencies: + '@nothing-but/utils': 0.17.0 + '@solid-primitives/event-listener': 2.4.3(solid-js@1.9.10) + '@solid-primitives/media': 2.3.3(solid-js@1.9.10) + '@solid-primitives/refs': 1.1.2(solid-js@1.9.10) + '@solid-primitives/rootless': 1.5.2(solid-js@1.9.10) + '@solid-primitives/scheduled': 1.5.2(solid-js@1.9.10) + '@solid-primitives/static-store': 0.1.2(solid-js@1.9.10) + '@solid-primitives/styles': 0.1.2(solid-js@1.9.10) + '@solid-primitives/utils': 6.3.2(solid-js@1.9.10) + solid-js: 1.9.10 + + '@solid-primitives/bounds@0.1.3(solid-js@1.9.10)': + dependencies: + '@solid-primitives/event-listener': 2.4.3(solid-js@1.9.10) + '@solid-primitives/resize-observer': 2.1.3(solid-js@1.9.10) + '@solid-primitives/static-store': 0.1.2(solid-js@1.9.10) + '@solid-primitives/utils': 6.3.2(solid-js@1.9.10) + solid-js: 1.9.10 + '@solid-primitives/event-listener@2.4.3(solid-js@1.9.10)': dependencies: '@solid-primitives/utils': 6.3.2(solid-js@1.9.10) @@ -24602,6 +24743,14 @@ snapshots: '@solid-primitives/utils': 6.3.2(solid-js@1.9.10) solid-js: 1.9.10 + '@solid-primitives/media@2.3.3(solid-js@1.9.10)': + dependencies: + '@solid-primitives/event-listener': 2.4.3(solid-js@1.9.10) + '@solid-primitives/rootless': 1.5.2(solid-js@1.9.10) + '@solid-primitives/static-store': 0.1.2(solid-js@1.9.10) + '@solid-primitives/utils': 6.3.2(solid-js@1.9.10) + solid-js: 1.9.10 + '@solid-primitives/refs@1.1.2(solid-js@1.9.10)': dependencies: '@solid-primitives/utils': 6.3.2(solid-js@1.9.10) @@ -24620,11 +24769,21 @@ snapshots: '@solid-primitives/utils': 6.3.2(solid-js@1.9.10) solid-js: 1.9.10 + '@solid-primitives/scheduled@1.5.2(solid-js@1.9.10)': + dependencies: + solid-js: 1.9.10 + '@solid-primitives/static-store@0.1.2(solid-js@1.9.10)': dependencies: '@solid-primitives/utils': 6.3.2(solid-js@1.9.10) solid-js: 1.9.10 + '@solid-primitives/styles@0.1.2(solid-js@1.9.10)': + dependencies: + '@solid-primitives/rootless': 1.5.2(solid-js@1.9.10) + '@solid-primitives/utils': 6.3.2(solid-js@1.9.10) + solid-js: 1.9.10 + '@solid-primitives/utils@6.3.2(solid-js@1.9.10)': dependencies: solid-js: 1.9.10 @@ -24956,8 +25115,6 @@ snapshots: '@tanstack/history@1.154.14': {} - '@tanstack/history@1.162.1': {} - '@tanstack/nitro-v2-vite-plugin@1.155.0(@electric-sql/pglite@0.4.3)(aws4fetch@1.0.20)(better-sqlite3@12.11.1)(drizzle-orm@0.45.2(@cloudflare/workers-types@4.20260317.1)(@electric-sql/pglite@0.4.3)(@opentelemetry/api@1.9.1)(@prisma/client@7.9.0(prisma@7.9.0(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(better-sqlite3@12.11.1)(magicast@0.5.2)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(typescript@5.9.3))(typescript@5.9.3))(better-sqlite3@12.11.1)(bun-types@1.3.14)(mysql2@3.15.3)(postgres@3.4.7)(prisma@7.9.0(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(better-sqlite3@12.11.1)(magicast@0.5.2)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(typescript@5.9.3)))(mysql2@3.15.3)(rolldown@1.2.4)(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0))': dependencies: nitropack: 2.13.1(@electric-sql/pglite@0.4.3)(aws4fetch@1.0.20)(better-sqlite3@12.11.1)(drizzle-orm@0.45.2(@cloudflare/workers-types@4.20260317.1)(@electric-sql/pglite@0.4.3)(@opentelemetry/api@1.9.1)(@prisma/client@7.9.0(prisma@7.9.0(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(better-sqlite3@12.11.1)(magicast@0.5.2)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(typescript@5.9.3))(typescript@5.9.3))(better-sqlite3@12.11.1)(bun-types@1.3.14)(mysql2@3.15.3)(postgres@3.4.7)(prisma@7.9.0(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(better-sqlite3@12.11.1)(magicast@0.5.2)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(typescript@5.9.3)))(mysql2@3.15.3)(rolldown@1.2.4) @@ -25080,23 +25237,23 @@ snapshots: '@tanstack/query-core': 5.90.12 react: 19.2.3 - '@tanstack/react-router-devtools@1.167.1(@tanstack/react-router@1.170.32(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(@tanstack/router-core@1.171.27)(csstype@3.2.3)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': + '@tanstack/react-router-devtools@1.159.5(@tanstack/react-router@1.159.5(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(@tanstack/router-core@1.159.4)(csstype@3.2.3)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': dependencies: - '@tanstack/react-router': 1.170.32(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@tanstack/router-devtools-core': 1.168.1(@tanstack/router-core@1.171.27)(csstype@3.2.3) + '@tanstack/react-router': 1.159.5(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@tanstack/router-devtools-core': 1.159.4(@tanstack/router-core@1.159.4)(csstype@3.2.3) react: 19.2.3 react-dom: 19.2.3(react@19.2.3) optionalDependencies: - '@tanstack/router-core': 1.171.27 + '@tanstack/router-core': 1.159.4 transitivePeerDependencies: - csstype - '@tanstack/react-router-ssr-query@1.167.1(@tanstack/query-core@5.90.12)(@tanstack/react-query@5.90.12(react@19.2.3))(@tanstack/react-router@1.170.32(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(@tanstack/router-core@1.171.27)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': + '@tanstack/react-router-ssr-query@1.159.5(@tanstack/query-core@5.90.12)(@tanstack/react-query@5.90.12(react@19.2.3))(@tanstack/react-router@1.159.5(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(@tanstack/router-core@1.159.4)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': dependencies: '@tanstack/query-core': 5.90.12 '@tanstack/react-query': 5.90.12(react@19.2.3) - '@tanstack/react-router': 1.170.32(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@tanstack/router-ssr-query-core': 1.169.1(@tanstack/query-core@5.90.12)(@tanstack/router-core@1.171.27) + '@tanstack/react-router': 1.159.5(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@tanstack/router-ssr-query-core': 1.159.4(@tanstack/query-core@5.90.12)(@tanstack/router-core@1.159.4) react: 19.2.3 react-dom: 19.2.3(react@19.2.3) transitivePeerDependencies: @@ -25113,14 +25270,16 @@ snapshots: tiny-invariant: 1.3.3 tiny-warning: 1.0.3 - '@tanstack/react-router@1.170.32(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': + '@tanstack/react-router@1.159.5(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': dependencies: - '@tanstack/history': 1.162.1 - '@tanstack/react-store': 0.9.3(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@tanstack/router-core': 1.171.27 + '@tanstack/history': 1.154.14 + '@tanstack/react-store': 0.8.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@tanstack/router-core': 1.159.4 isbot: 5.1.32 react: 19.2.3 react-dom: 19.2.3(react@19.2.3) + tiny-invariant: 1.3.3 + tiny-warning: 1.0.3 '@tanstack/react-start-client@1.141.1(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': dependencies: @@ -25132,17 +25291,19 @@ snapshots: tiny-invariant: 1.3.3 tiny-warning: 1.0.3 - '@tanstack/react-start-client@1.168.30(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': + '@tanstack/react-start-client@1.159.5(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': dependencies: - '@tanstack/react-router': 1.170.32(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@tanstack/router-core': 1.171.27 - '@tanstack/start-client-core': 1.170.27 + '@tanstack/react-router': 1.159.5(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@tanstack/router-core': 1.159.4 + '@tanstack/start-client-core': 1.159.4 react: 19.2.3 react-dom: 19.2.3(react@19.2.3) + tiny-invariant: 1.3.3 + tiny-warning: 1.0.3 - '@tanstack/react-start-plugin@1.131.50(5e76e58f58fcdc553da46eb093ac388b)': + '@tanstack/react-start-plugin@1.131.50(e7a157c953e155a2765d901b34df38b3)': dependencies: - '@tanstack/start-plugin-core': 1.131.50(b114ec7757aa79b8f316a176b0457a25) + '@tanstack/start-plugin-core': 1.131.50(1a1cdd8b9c2c533357f243540b1932ef) '@vitejs/plugin-react': 4.7.0(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)) pathe: 2.0.3 vite: 8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0) @@ -25232,32 +25393,6 @@ snapshots: - xml2js - yaml - '@tanstack/react-start-rsc@0.1.48(crossws@0.4.6(srvx@0.11.17))(esbuild@0.28.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(rolldown@1.2.4)(rollup@4.60.1)(vite-plugin-solid@2.11.14(solid-js@1.9.10)(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)))(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0))': - dependencies: - '@tanstack/react-router': 1.170.32(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@tanstack/router-core': 1.171.27 - '@tanstack/router-utils': 1.162.2 - '@tanstack/start-client-core': 1.170.27 - '@tanstack/start-fn-stubs': 1.162.0 - '@tanstack/start-plugin-core': 1.171.39(@tanstack/react-router@1.170.32(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(crossws@0.4.6(srvx@0.11.17))(esbuild@0.28.1)(rolldown@1.2.4)(rollup@4.60.1)(vite-plugin-solid@2.11.14(solid-js@1.9.10)(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)))(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)) - '@tanstack/start-storage-context': 1.167.29 - pathe: 2.0.3 - react: 19.2.3 - react-dom: 19.2.3(react@19.2.3) - transitivePeerDependencies: - - '@farmfe/core' - - '@rsbuild/core' - - bun-types-no-globals - - crossws - - esbuild - - rolldown - - rollup - - supports-color - - unloader - - vite - - vite-plugin-solid - - webpack - '@tanstack/react-start-server@1.141.1(crossws@0.4.6(srvx@0.11.17))(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': dependencies: '@tanstack/history': 1.141.0 @@ -25270,52 +25405,38 @@ snapshots: transitivePeerDependencies: - crossws - '@tanstack/react-start-server@1.167.37(crossws@0.4.6(srvx@0.11.17))(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': + '@tanstack/react-start-server@1.159.5(crossws@0.4.6(srvx@0.11.17))(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': dependencies: - '@tanstack/react-router': 1.170.32(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@tanstack/router-core': 1.171.27 - '@tanstack/start-server-core': 1.169.31(crossws@0.4.6(srvx@0.11.17)) + '@tanstack/history': 1.154.14 + '@tanstack/react-router': 1.159.5(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@tanstack/router-core': 1.159.4 + '@tanstack/start-client-core': 1.159.4 + '@tanstack/start-server-core': 1.159.4(crossws@0.4.6(srvx@0.11.17)) react: 19.2.3 react-dom: 19.2.3(react@19.2.3) transitivePeerDependencies: - crossws - '@tanstack/react-start@1.168.49(crossws@0.4.6(srvx@0.11.17))(esbuild@0.28.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(rolldown@1.2.4)(rollup@4.60.1)(vite-plugin-solid@2.11.14(solid-js@1.9.10)(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)))(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0))': + '@tanstack/react-start@1.159.5(crossws@0.4.6(srvx@0.11.17))(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(vite-plugin-solid@2.11.14(solid-js@1.9.10)(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)))(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0))': dependencies: - '@tanstack/react-router': 1.170.32(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@tanstack/react-start-client': 1.168.30(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@tanstack/react-start-rsc': 0.1.48(crossws@0.4.6(srvx@0.11.17))(esbuild@0.28.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(rolldown@1.2.4)(rollup@4.60.1)(vite-plugin-solid@2.11.14(solid-js@1.9.10)(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)))(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)) - '@tanstack/react-start-server': 1.167.37(crossws@0.4.6(srvx@0.11.17))(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@tanstack/router-utils': 1.162.2 - '@tanstack/start-client-core': 1.170.27 - '@tanstack/start-plugin-core': 1.171.39(@tanstack/react-router@1.170.32(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(crossws@0.4.6(srvx@0.11.17))(esbuild@0.28.1)(rolldown@1.2.4)(rollup@4.60.1)(vite-plugin-solid@2.11.14(solid-js@1.9.10)(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)))(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)) - '@tanstack/start-server-core': 1.169.31(crossws@0.4.6(srvx@0.11.17)) + '@tanstack/react-router': 1.159.5(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@tanstack/react-start-client': 1.159.5(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@tanstack/react-start-server': 1.159.5(crossws@0.4.6(srvx@0.11.17))(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@tanstack/router-utils': 1.158.0 + '@tanstack/start-client-core': 1.159.4 + '@tanstack/start-plugin-core': 1.159.5(@tanstack/react-router@1.159.5(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(crossws@0.4.6(srvx@0.11.17))(vite-plugin-solid@2.11.14(solid-js@1.9.10)(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)))(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)) + '@tanstack/start-server-core': 1.159.4(crossws@0.4.6(srvx@0.11.17)) pathe: 2.0.3 react: 19.2.3 react-dom: 19.2.3(react@19.2.3) - optionalDependencies: vite: 8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0) transitivePeerDependencies: - - '@farmfe/core' - - '@rspack/core' - - bun-types-no-globals + - '@rsbuild/core' - crossws - - esbuild - - react-server-dom-rspack - - rolldown - - rollup - supports-color - - unloader - vite-plugin-solid - webpack - '@tanstack/react-store@0.11.1(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': - dependencies: - '@tanstack/store': 0.11.1 - react: 19.2.3 - react-dom: 19.2.3(react@19.2.3) - use-sync-external-store: 1.6.0(react@19.2.3) - '@tanstack/react-store@0.8.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': dependencies: '@tanstack/store': 0.8.0 @@ -25323,13 +25444,6 @@ snapshots: react-dom: 19.2.3(react@19.2.3) use-sync-external-store: 1.6.0(react@19.2.3) - '@tanstack/react-store@0.9.3(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': - dependencies: - '@tanstack/store': 0.9.3 - react: 19.2.3 - react-dom: 19.2.3(react@19.2.3) - use-sync-external-store: 1.6.0(react@19.2.3) - '@tanstack/router-core@1.131.50': dependencies: '@tanstack/history': 1.131.2 @@ -25360,18 +25474,22 @@ snapshots: tiny-invariant: 1.3.3 tiny-warning: 1.0.3 - '@tanstack/router-core@1.171.27': + '@tanstack/router-devtools-core@1.141.1(@tanstack/router-core@1.159.4)(csstype@3.2.3)(solid-js@1.9.10)': dependencies: - '@tanstack/history': 1.162.1 - cookie-es: 3.1.1 - seroval: 1.6.2 - seroval-plugins: 1.6.2(seroval@1.6.2) + '@tanstack/router-core': 1.159.4 + clsx: 2.1.1 + goober: 2.1.18(csstype@3.2.3) + solid-js: 1.9.10 + tiny-invariant: 1.3.3 + optionalDependencies: + csstype: 3.2.3 - '@tanstack/router-devtools-core@1.168.1(@tanstack/router-core@1.171.27)(csstype@3.2.3)': + '@tanstack/router-devtools-core@1.159.4(@tanstack/router-core@1.159.4)(csstype@3.2.3)': dependencies: - '@tanstack/router-core': 1.171.27 + '@tanstack/router-core': 1.159.4 clsx: 2.1.1 goober: 2.1.18(csstype@3.2.3) + tiny-invariant: 1.3.3 optionalDependencies: csstype: 3.2.3 @@ -25388,11 +25506,11 @@ snapshots: transitivePeerDependencies: - supports-color - '@tanstack/router-generator@1.159.4': + '@tanstack/router-generator@1.141.1': dependencies: - '@tanstack/router-core': 1.159.4 - '@tanstack/router-utils': 1.158.0 - '@tanstack/virtual-file-routes': 1.154.7 + '@tanstack/router-core': 1.141.1 + '@tanstack/router-utils': 1.141.0 + '@tanstack/virtual-file-routes': 1.141.0 prettier: 3.7.4 recast: 0.23.11 source-map: 0.7.6 @@ -25401,20 +25519,20 @@ snapshots: transitivePeerDependencies: - supports-color - '@tanstack/router-generator@1.167.33': + '@tanstack/router-generator@1.159.4': dependencies: - '@babel/types': 7.29.7 - '@tanstack/router-core': 1.171.27 - '@tanstack/router-utils': 1.162.2 - '@tanstack/virtual-file-routes': 1.162.0 - jiti: 2.7.0 - magic-string: 0.30.21 + '@tanstack/router-core': 1.159.4 + '@tanstack/router-utils': 1.158.0 + '@tanstack/virtual-file-routes': 1.154.7 prettier: 3.7.4 - zod: 4.4.3 + recast: 0.23.11 + source-map: 0.7.6 + tsx: 4.21.0 + zod: 3.25.76 transitivePeerDependencies: - supports-color - '@tanstack/router-plugin@1.131.50(@tanstack/react-router@1.170.32(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(vite-plugin-solid@2.11.14(solid-js@1.9.10)(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)))(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0))': + '@tanstack/router-plugin@1.131.50(@tanstack/react-router@1.159.5(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(vite-plugin-solid@2.11.14(solid-js@1.9.10)(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)))(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0))': dependencies: '@babel/core': 7.29.7 '@babel/plugin-syntax-jsx': 7.29.7(@babel/core@7.29.7) @@ -25431,13 +25549,13 @@ snapshots: unplugin: 2.3.11 zod: 3.25.76 optionalDependencies: - '@tanstack/react-router': 1.170.32(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@tanstack/react-router': 1.159.5(react-dom@19.2.3(react@19.2.3))(react@19.2.3) vite: 8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0) vite-plugin-solid: 2.11.14(solid-js@1.9.10)(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)) transitivePeerDependencies: - supports-color - '@tanstack/router-plugin@1.159.5(@tanstack/react-router@1.170.32(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(vite-plugin-solid@2.11.14(solid-js@1.9.10)(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)))(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0))': + '@tanstack/router-plugin@1.141.1(@tanstack/react-router@1.159.5(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(vite-plugin-solid@2.11.14(solid-js@1.9.10)(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)))(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0))': dependencies: '@babel/core': 7.29.7 '@babel/plugin-syntax-jsx': 7.29.7(@babel/core@7.29.7) @@ -25445,49 +25563,52 @@ snapshots: '@babel/template': 7.29.7 '@babel/traverse': 7.29.7 '@babel/types': 7.29.7 - '@tanstack/router-core': 1.159.4 - '@tanstack/router-generator': 1.159.4 - '@tanstack/router-utils': 1.158.0 - '@tanstack/virtual-file-routes': 1.154.7 + '@tanstack/router-core': 1.141.1 + '@tanstack/router-generator': 1.141.1 + '@tanstack/router-utils': 1.141.0 + '@tanstack/virtual-file-routes': 1.141.0 + babel-dead-code-elimination: 1.0.10 chokidar: 3.6.0 unplugin: 2.3.11 zod: 3.25.76 optionalDependencies: - '@tanstack/react-router': 1.170.32(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@tanstack/react-router': 1.159.5(react-dom@19.2.3(react@19.2.3))(react@19.2.3) vite: 8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0) vite-plugin-solid: 2.11.14(solid-js@1.9.10)(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)) transitivePeerDependencies: - supports-color - '@tanstack/router-plugin@1.168.35(@tanstack/react-router@1.170.32(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(esbuild@0.28.1)(rolldown@1.2.4)(rollup@4.60.1)(vite-plugin-solid@2.11.14(solid-js@1.9.10)(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)))(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0))': + '@tanstack/router-plugin@1.159.5(@tanstack/react-router@1.159.5(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(supports-color@7.2.0)(vite-plugin-solid@2.11.14(solid-js@1.9.10)(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)))(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0))': dependencies: - '@babel/core': 7.29.7 + '@babel/core': 7.29.0(supports-color@7.2.0) + '@babel/plugin-syntax-jsx': 7.29.7(@babel/core@7.29.0) + '@babel/plugin-syntax-typescript': 7.27.1(@babel/core@7.29.0) '@babel/template': 7.29.7 + '@babel/traverse': 7.29.7 '@babel/types': 7.29.7 - '@tanstack/router-core': 1.171.27 - '@tanstack/router-generator': 1.167.33 - '@tanstack/router-utils': 1.162.2 - chokidar: 5.0.0 - unplugin: 3.3.0(esbuild@0.28.1)(rolldown@1.2.4)(rollup@4.60.1)(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)) - zod: 4.4.3 + '@tanstack/router-core': 1.159.4 + '@tanstack/router-generator': 1.159.4 + '@tanstack/router-utils': 1.158.0 + '@tanstack/virtual-file-routes': 1.154.7 + chokidar: 3.6.0 + unplugin: 2.3.11 + zod: 3.25.76 optionalDependencies: - '@tanstack/react-router': 1.170.32(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@tanstack/react-router': 1.159.5(react-dom@19.2.3(react@19.2.3))(react@19.2.3) vite: 8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0) vite-plugin-solid: 2.11.14(solid-js@1.9.10)(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)) transitivePeerDependencies: - - '@farmfe/core' - - '@rspack/core' - - bun-types-no-globals - - esbuild - - rolldown - - rollup - supports-color - - unloader - '@tanstack/router-ssr-query-core@1.169.1(@tanstack/query-core@5.90.12)(@tanstack/router-core@1.171.27)': + '@tanstack/router-ssr-query-core@1.141.1(@tanstack/query-core@5.90.12)(@tanstack/router-core@1.159.4)': dependencies: '@tanstack/query-core': 5.90.12 - '@tanstack/router-core': 1.171.27 + '@tanstack/router-core': 1.159.4 + + '@tanstack/router-ssr-query-core@1.159.4(@tanstack/query-core@5.90.12)(@tanstack/router-core@1.159.4)': + dependencies: + '@tanstack/query-core': 5.90.12 + '@tanstack/router-core': 1.159.4 '@tanstack/router-utils@1.131.2': dependencies: @@ -25515,20 +25636,7 @@ snapshots: '@tanstack/router-utils@1.158.0': dependencies: - '@babel/core': 7.29.7 - '@babel/generator': 7.29.7 - '@babel/parser': 7.29.7 - '@babel/types': 7.29.7 - ansis: 4.2.0 - babel-dead-code-elimination: 1.0.12 - diff: 8.0.2 - pathe: 2.0.3 - tinyglobby: 0.2.17 - transitivePeerDependencies: - - supports-color - - '@tanstack/router-utils@1.162.2': - dependencies: + '@babel/core': 7.29.0(supports-color@7.2.0) '@babel/generator': 7.29.7 '@babel/parser': 7.29.7 '@babel/types': 7.29.7 @@ -25586,74 +25694,80 @@ snapshots: '@tanstack/query-core': 5.90.12 solid-js: 1.9.10 - '@tanstack/solid-router-devtools@1.167.1(@tanstack/router-core@1.171.27)(@tanstack/solid-router@1.170.30(solid-js@1.9.10))(csstype@3.2.3)(solid-js@1.9.10)': + '@tanstack/solid-router-devtools@1.141.1(@tanstack/router-core@1.159.4)(@tanstack/solid-router@1.141.1(solid-js@1.9.10))(csstype@3.2.3)(solid-js@1.9.10)': dependencies: - '@tanstack/router-devtools-core': 1.168.1(@tanstack/router-core@1.171.27)(csstype@3.2.3) - '@tanstack/solid-router': 1.170.30(solid-js@1.9.10) + '@tanstack/router-devtools-core': 1.141.1(@tanstack/router-core@1.159.4)(csstype@3.2.3)(solid-js@1.9.10) + '@tanstack/solid-router': 1.141.1(solid-js@1.9.10) solid-js: 1.9.10 optionalDependencies: - '@tanstack/router-core': 1.171.27 + '@tanstack/router-core': 1.159.4 transitivePeerDependencies: - csstype - '@tanstack/solid-router-ssr-query@1.167.1(@tanstack/query-core@5.90.12)(@tanstack/router-core@1.171.27)(@tanstack/solid-query@5.90.15(solid-js@1.9.10))(@tanstack/solid-router@1.170.30(solid-js@1.9.10))(solid-js@1.9.10)': + '@tanstack/solid-router-ssr-query@1.141.1(@tanstack/query-core@5.90.12)(@tanstack/router-core@1.159.4)(@tanstack/solid-query@5.90.15(solid-js@1.9.10))(@tanstack/solid-router@1.141.1(solid-js@1.9.10))(eslint@9.39.4(jiti@2.7.0))(solid-js@1.9.10)(supports-color@7.2.0)(typescript@5.9.3)': dependencies: '@tanstack/query-core': 5.90.12 - '@tanstack/router-ssr-query-core': 1.169.1(@tanstack/query-core@5.90.12)(@tanstack/router-core@1.171.27) + '@tanstack/router-ssr-query-core': 1.141.1(@tanstack/query-core@5.90.12)(@tanstack/router-core@1.159.4) '@tanstack/solid-query': 5.90.15(solid-js@1.9.10) - '@tanstack/solid-router': 1.170.30(solid-js@1.9.10) + '@tanstack/solid-router': 1.141.1(solid-js@1.9.10) + eslint-plugin-solid: 0.14.5(eslint@9.39.4(jiti@2.7.0))(supports-color@7.2.0)(typescript@5.9.3) solid-js: 1.9.10 transitivePeerDependencies: - '@tanstack/router-core' + - eslint + - supports-color + - typescript - '@tanstack/solid-router@1.170.30(solid-js@1.9.10)': + '@tanstack/solid-router@1.141.1(solid-js@1.9.10)': dependencies: + '@solid-devtools/logger': 0.9.11(solid-js@1.9.10) '@solid-primitives/refs': 1.1.2(solid-js@1.9.10) '@solidjs/meta': 0.29.4(solid-js@1.9.10) - '@tanstack/history': 1.162.1 - '@tanstack/router-core': 1.171.27 + '@tanstack/history': 1.141.0 + '@tanstack/router-core': 1.141.1 + '@tanstack/solid-store': 0.8.0(solid-js@1.9.10) isbot: 5.1.32 solid-js: 1.9.10 + tiny-invariant: 1.3.3 + tiny-warning: 1.0.3 - '@tanstack/solid-start-client@1.168.29(solid-js@1.9.10)': + '@tanstack/solid-start-client@1.141.1(solid-js@1.9.10)': dependencies: - '@tanstack/router-core': 1.171.27 - '@tanstack/solid-router': 1.170.30(solid-js@1.9.10) - '@tanstack/start-client-core': 1.170.27 + '@tanstack/router-core': 1.141.1 + '@tanstack/solid-router': 1.141.1(solid-js@1.9.10) + '@tanstack/start-client-core': 1.141.1 solid-js: 1.9.10 + tiny-invariant: 1.3.3 + tiny-warning: 1.0.3 - '@tanstack/solid-start-server@1.167.36(crossws@0.4.6(srvx@0.11.17))(solid-js@1.9.10)': + '@tanstack/solid-start-server@1.141.1(crossws@0.4.6(srvx@0.11.17))(solid-js@1.9.10)': dependencies: - '@tanstack/router-core': 1.171.27 - '@tanstack/solid-router': 1.170.30(solid-js@1.9.10) - '@tanstack/start-server-core': 1.169.31(crossws@0.4.6(srvx@0.11.17)) + '@solidjs/meta': 0.29.4(solid-js@1.9.10) + '@tanstack/history': 1.141.0 + '@tanstack/router-core': 1.141.1 + '@tanstack/solid-router': 1.141.1(solid-js@1.9.10) + '@tanstack/start-client-core': 1.141.1 + '@tanstack/start-server-core': 1.141.1(crossws@0.4.6(srvx@0.11.17)) solid-js: 1.9.10 transitivePeerDependencies: - crossws - '@tanstack/solid-start@1.168.47(@tanstack/react-router@1.170.32(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(crossws@0.4.6(srvx@0.11.17))(esbuild@0.28.1)(rolldown@1.2.4)(rollup@4.60.1)(solid-js@1.9.10)(vite-plugin-solid@2.11.14(solid-js@1.9.10)(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)))(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0))': + '@tanstack/solid-start@1.141.1(@tanstack/react-router@1.159.5(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(crossws@0.4.6(srvx@0.11.17))(solid-js@1.9.10)(vite-plugin-solid@2.11.14(solid-js@1.9.10)(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)))(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0))': dependencies: - '@tanstack/solid-router': 1.170.30(solid-js@1.9.10) - '@tanstack/solid-start-client': 1.168.29(solid-js@1.9.10) - '@tanstack/solid-start-server': 1.167.36(crossws@0.4.6(srvx@0.11.17))(solid-js@1.9.10) - '@tanstack/start-client-core': 1.170.27 - '@tanstack/start-plugin-core': 1.171.39(@tanstack/react-router@1.170.32(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(crossws@0.4.6(srvx@0.11.17))(esbuild@0.28.1)(rolldown@1.2.4)(rollup@4.60.1)(vite-plugin-solid@2.11.14(solid-js@1.9.10)(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)))(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)) - '@tanstack/start-server-core': 1.169.31(crossws@0.4.6(srvx@0.11.17)) + '@tanstack/solid-router': 1.141.1(solid-js@1.9.10) + '@tanstack/solid-start-client': 1.141.1(solid-js@1.9.10) + '@tanstack/solid-start-server': 1.141.1(crossws@0.4.6(srvx@0.11.17))(solid-js@1.9.10) + '@tanstack/start-client-core': 1.141.1 + '@tanstack/start-plugin-core': 1.141.1(@tanstack/react-router@1.159.5(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(crossws@0.4.6(srvx@0.11.17))(vite-plugin-solid@2.11.14(solid-js@1.9.10)(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)))(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)) + '@tanstack/start-server-core': 1.141.1(crossws@0.4.6(srvx@0.11.17)) pathe: 2.0.3 solid-js: 1.9.10 - optionalDependencies: vite: 8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0) transitivePeerDependencies: - - '@farmfe/core' - - '@rspack/core' + - '@rsbuild/core' - '@tanstack/react-router' - - bun-types-no-globals - crossws - - esbuild - - rolldown - - rollup - supports-color - - unloader - vite-plugin-solid - webpack @@ -25738,19 +25852,12 @@ snapshots: tiny-invariant: 1.3.3 tiny-warning: 1.0.3 - '@tanstack/start-client-core@1.170.27': - dependencies: - '@tanstack/router-core': 1.171.27 - '@tanstack/start-fn-stubs': 1.162.0 - '@tanstack/start-storage-context': 1.167.29 - seroval: 1.6.2 - '@tanstack/start-config@1.120.20(340eefabdbae5b0c948fd6f8943277d1)': dependencies: - '@tanstack/react-router': 1.170.32(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@tanstack/react-start-plugin': 1.131.50(5e76e58f58fcdc553da46eb093ac388b) + '@tanstack/react-router': 1.159.5(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@tanstack/react-start-plugin': 1.131.50(e7a157c953e155a2765d901b34df38b3) '@tanstack/router-generator': 1.159.4 - '@tanstack/router-plugin': 1.159.5(@tanstack/react-router@1.170.32(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(vite-plugin-solid@2.11.14(solid-js@1.9.10)(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)))(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)) + '@tanstack/router-plugin': 1.159.5(@tanstack/react-router@1.159.5(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(supports-color@7.2.0)(vite-plugin-solid@2.11.14(solid-js@1.9.10)(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)))(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)) '@tanstack/server-functions-plugin': 1.141.0(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)) '@tanstack/start-server-functions-handler': 1.120.19(crossws@0.4.6(srvx@0.11.17)) '@vitejs/plugin-react': 4.7.0(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)) @@ -25813,16 +25920,14 @@ snapshots: '@tanstack/start-fn-stubs@1.154.7': {} - '@tanstack/start-fn-stubs@1.162.0': {} - - '@tanstack/start-plugin-core@1.131.50(b114ec7757aa79b8f316a176b0457a25)': + '@tanstack/start-plugin-core@1.131.50(1a1cdd8b9c2c533357f243540b1932ef)': dependencies: '@babel/code-frame': 7.26.2 '@babel/core': 7.29.7 '@babel/types': 7.29.7 '@tanstack/router-core': 1.131.50 '@tanstack/router-generator': 1.131.50 - '@tanstack/router-plugin': 1.131.50(@tanstack/react-router@1.170.32(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(vite-plugin-solid@2.11.14(solid-js@1.9.10)(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)))(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)) + '@tanstack/router-plugin': 1.131.50(@tanstack/react-router@1.159.5(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(vite-plugin-solid@2.11.14(solid-js@1.9.10)(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)))(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)) '@tanstack/router-utils': 1.131.2 '@tanstack/server-functions-plugin': 1.131.2(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)) '@tanstack/start-server-core': 1.131.50 @@ -25835,7 +25940,7 @@ snapshots: pathe: 2.0.3 ufo: 1.6.3 vite: 8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0) - vitefu: 1.1.3(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)) + vitefu: 1.1.1(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)) xmlbuilder2: 3.1.1 zod: 3.25.76 transitivePeerDependencies: @@ -25873,41 +25978,65 @@ snapshots: - webpack - xml2js - '@tanstack/start-plugin-core@1.171.39(@tanstack/react-router@1.170.32(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(crossws@0.4.6(srvx@0.11.17))(esbuild@0.28.1)(rolldown@1.2.4)(rollup@4.60.1)(vite-plugin-solid@2.11.14(solid-js@1.9.10)(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)))(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0))': + '@tanstack/start-plugin-core@1.141.1(@tanstack/react-router@1.159.5(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(crossws@0.4.6(srvx@0.11.17))(vite-plugin-solid@2.11.14(solid-js@1.9.10)(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)))(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0))': + dependencies: + '@babel/code-frame': 7.26.2 + '@babel/core': 7.29.0(supports-color@7.2.0) + '@babel/types': 7.29.0 + '@rolldown/pluginutils': 1.0.0-beta.40 + '@tanstack/router-core': 1.141.1 + '@tanstack/router-generator': 1.141.1 + '@tanstack/router-plugin': 1.141.1(@tanstack/react-router@1.159.5(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(vite-plugin-solid@2.11.14(solid-js@1.9.10)(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)))(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)) + '@tanstack/router-utils': 1.141.0 + '@tanstack/server-functions-plugin': 1.141.0(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)) + '@tanstack/start-client-core': 1.141.1 + '@tanstack/start-server-core': 1.141.1(crossws@0.4.6(srvx@0.11.17)) + babel-dead-code-elimination: 1.0.10 + cheerio: 1.1.2 + exsolve: 1.0.8 + pathe: 2.0.3 + srvx: 0.8.16 + tinyglobby: 0.2.17 + ufo: 1.6.1 + vite: 8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0) + vitefu: 1.1.1(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)) + xmlbuilder2: 4.0.3 + zod: 3.25.76 + transitivePeerDependencies: + - '@rsbuild/core' + - '@tanstack/react-router' + - crossws + - supports-color + - vite-plugin-solid + - webpack + + '@tanstack/start-plugin-core@1.159.5(@tanstack/react-router@1.159.5(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(crossws@0.4.6(srvx@0.11.17))(vite-plugin-solid@2.11.14(solid-js@1.9.10)(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)))(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0))': dependencies: '@babel/code-frame': 7.27.1 - '@babel/core': 7.29.7 + '@babel/core': 7.29.0(supports-color@7.2.0) '@babel/types': 7.29.7 - '@tanstack/router-core': 1.171.27 - '@tanstack/router-generator': 1.167.33 - '@tanstack/router-plugin': 1.168.35(@tanstack/react-router@1.170.32(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(esbuild@0.28.1)(rolldown@1.2.4)(rollup@4.60.1)(vite-plugin-solid@2.11.14(solid-js@1.9.10)(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)))(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)) - '@tanstack/router-utils': 1.162.2 - '@tanstack/start-server-core': 1.169.31(crossws@0.4.6(srvx@0.11.17)) + '@rolldown/pluginutils': 1.0.0-beta.40 + '@tanstack/router-core': 1.159.4 + '@tanstack/router-generator': 1.159.4 + '@tanstack/router-plugin': 1.159.5(@tanstack/react-router@1.159.5(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(supports-color@7.2.0)(vite-plugin-solid@2.11.14(solid-js@1.9.10)(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)))(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)) + '@tanstack/router-utils': 1.158.0 + '@tanstack/start-client-core': 1.159.4 + '@tanstack/start-server-core': 1.159.4(crossws@0.4.6(srvx@0.11.17)) + cheerio: 1.1.2 exsolve: 1.0.8 - lightningcss: 1.33.0 pathe: 2.0.3 - picomatch: 4.0.5 - seroval: 1.6.2 - source-map: 0.7.6 srvx: 0.11.17 tinyglobby: 0.2.17 ufo: 1.6.3 - vitefu: 1.1.3(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)) - xmlbuilder2: 4.0.3 - zod: 4.4.3 - optionalDependencies: vite: 8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0) + vitefu: 1.1.1(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)) + xmlbuilder2: 4.0.3 + zod: 3.25.76 transitivePeerDependencies: - - '@farmfe/core' - - '@rspack/core' + - '@rsbuild/core' - '@tanstack/react-router' - - bun-types-no-globals - crossws - - esbuild - - rolldown - - rollup - supports-color - - unloader - vite-plugin-solid - webpack @@ -25947,18 +26076,6 @@ snapshots: transitivePeerDependencies: - crossws - '@tanstack/start-server-core@1.169.31(crossws@0.4.6(srvx@0.11.17))': - dependencies: - '@tanstack/history': 1.162.1 - '@tanstack/router-core': 1.171.27 - '@tanstack/start-client-core': 1.170.27 - '@tanstack/start-storage-context': 1.167.29 - fetchdts: 0.1.7 - h3-v2: h3@2.0.1-rc.20(crossws@0.4.6(srvx@0.11.17)) - seroval: 1.6.2 - transitivePeerDependencies: - - crossws - '@tanstack/start-server-functions-client@1.131.50(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0))': dependencies: '@tanstack/server-functions-plugin': 1.131.2(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)) @@ -26013,10 +26130,6 @@ snapshots: dependencies: '@tanstack/router-core': 1.159.4 - '@tanstack/start-storage-context@1.167.29': - dependencies: - '@tanstack/router-core': 1.171.27 - '@tanstack/start@1.120.20(340eefabdbae5b0c948fd6f8943277d1)': dependencies: '@tanstack/react-start-client': 1.141.1(react-dom@19.2.3(react@19.2.3))(react@19.2.3) @@ -26086,8 +26199,6 @@ snapshots: '@tanstack/store@0.8.0': {} - '@tanstack/store@0.9.3': {} - '@tanstack/typedoc-config@0.3.4': dependencies: typedoc: 0.28.20(@typescript/typescript6@6.0.2) @@ -26097,9 +26208,9 @@ snapshots: '@tanstack/virtual-file-routes@1.131.2': {} - '@tanstack/virtual-file-routes@1.154.7': {} + '@tanstack/virtual-file-routes@1.141.0': {} - '@tanstack/virtual-file-routes@1.162.0': {} + '@tanstack/virtual-file-routes@1.154.7': {} '@tanstack/vite-config@0.6.0(@microsoft/api-extractor@7.47.7(@types/node@24.10.3))(esbuild@0.28.1)(rolldown@1.1.5)(rollup@4.60.1)(supports-color@7.2.0)(typescript@7.0.2)(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0))': dependencies: @@ -26118,9 +26229,9 @@ snapshots: - typescript - webpack - '@tanstack/zod-adapter@1.166.9(@tanstack/react-router@1.170.32(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(zod@4.3.6)': + '@tanstack/zod-adapter@1.166.9(@tanstack/react-router@1.159.5(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(zod@4.3.6)': dependencies: - '@tanstack/react-router': 1.170.32(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@tanstack/react-router': 1.159.5(react-dom@19.2.3(react@19.2.3))(react@19.2.3) zod: 4.3.6 '@testing-library/dom@10.4.1': @@ -26455,6 +26566,15 @@ snapshots: - supports-color optional: true + '@typescript-eslint/project-service@8.49.0(supports-color@7.2.0)(typescript@5.9.3)': + dependencies: + '@typescript-eslint/tsconfig-utils': 8.49.0(typescript@5.9.3) + '@typescript-eslint/types': 8.59.4 + debug: 4.4.3(supports-color@7.2.0) + typescript: 5.9.3 + transitivePeerDependencies: + - supports-color + '@typescript-eslint/project-service@8.59.4(typescript@7.0.2)': dependencies: '@typescript-eslint/tsconfig-utils': 8.59.4(typescript@7.0.2) @@ -26465,12 +26585,21 @@ snapshots: - supports-color optional: true + '@typescript-eslint/scope-manager@8.49.0': + dependencies: + '@typescript-eslint/types': 8.49.0 + '@typescript-eslint/visitor-keys': 8.49.0 + '@typescript-eslint/scope-manager@8.59.4': dependencies: '@typescript-eslint/types': 8.59.4 '@typescript-eslint/visitor-keys': 8.59.4 optional: true + '@typescript-eslint/tsconfig-utils@8.49.0(typescript@5.9.3)': + dependencies: + typescript: 5.9.3 + '@typescript-eslint/tsconfig-utils@8.59.4(typescript@7.0.2)': dependencies: typescript: 7.0.2 @@ -26489,8 +26618,25 @@ snapshots: - supports-color optional: true + '@typescript-eslint/types@8.49.0': {} + '@typescript-eslint/types@8.59.4': {} + '@typescript-eslint/typescript-estree@8.49.0(supports-color@7.2.0)(typescript@5.9.3)': + dependencies: + '@typescript-eslint/project-service': 8.49.0(supports-color@7.2.0)(typescript@5.9.3) + '@typescript-eslint/tsconfig-utils': 8.49.0(typescript@5.9.3) + '@typescript-eslint/types': 8.49.0 + '@typescript-eslint/visitor-keys': 8.49.0 + debug: 4.4.3(supports-color@7.2.0) + minimatch: 9.0.5 + semver: 7.8.4 + tinyglobby: 0.2.17 + ts-api-utils: 2.1.0(typescript@5.9.3) + typescript: 5.9.3 + transitivePeerDependencies: + - supports-color + '@typescript-eslint/typescript-estree@8.59.4(typescript@7.0.2)': dependencies: '@typescript-eslint/project-service': 8.59.4(typescript@7.0.2) @@ -26507,6 +26653,17 @@ snapshots: - supports-color optional: true + '@typescript-eslint/utils@8.49.0(eslint@9.39.4(jiti@2.7.0))(supports-color@7.2.0)(typescript@5.9.3)': + dependencies: + '@eslint-community/eslint-utils': 4.9.1(eslint@9.39.4(jiti@2.7.0)) + '@typescript-eslint/scope-manager': 8.49.0 + '@typescript-eslint/types': 8.49.0 + '@typescript-eslint/typescript-estree': 8.49.0(supports-color@7.2.0)(typescript@5.9.3) + eslint: 9.39.4(jiti@2.7.0) + typescript: 5.9.3 + transitivePeerDependencies: + - supports-color + '@typescript-eslint/utils@8.59.4(eslint@9.39.4(jiti@2.7.0))(typescript@7.0.2)': dependencies: '@eslint-community/eslint-utils': 4.9.1(eslint@9.39.4(jiti@2.7.0)) @@ -26519,6 +26676,11 @@ snapshots: - supports-color optional: true + '@typescript-eslint/visitor-keys@8.49.0': + dependencies: + '@typescript-eslint/types': 8.49.0 + eslint-visitor-keys: 4.2.1 + '@typescript-eslint/visitor-keys@8.59.4': dependencies: '@typescript-eslint/types': 8.59.4 @@ -27251,6 +27413,15 @@ snapshots: transitivePeerDependencies: - supports-color + babel-plugin-jsx-dom-expressions@0.40.3(@babel/core@7.29.0): + dependencies: + '@babel/core': 7.29.0(supports-color@7.2.0) + '@babel/helper-module-imports': 7.18.6 + '@babel/plugin-syntax-jsx': 7.29.7(@babel/core@7.29.0) + '@babel/types': 7.29.7 + html-entities: 2.3.3 + parse5: 7.3.0 + babel-plugin-jsx-dom-expressions@0.40.3(@babel/core@7.29.7): dependencies: '@babel/core': 7.29.7 @@ -27404,6 +27575,13 @@ snapshots: - '@babel/core' - supports-color + babel-preset-solid@1.9.10(@babel/core@7.29.0)(solid-js@1.9.10): + dependencies: + '@babel/core': 7.29.0(supports-color@7.2.0) + babel-plugin-jsx-dom-expressions: 0.40.3(@babel/core@7.29.0) + optionalDependencies: + solid-js: 1.9.10 + babel-preset-solid@1.9.10(@babel/core@7.29.7)(solid-js@1.9.10): dependencies: '@babel/core': 7.29.7 @@ -27994,8 +28172,6 @@ snapshots: cookie-es@2.0.1: {} - cookie-es@3.1.1: {} - cookie-signature@1.2.2: {} cookie@0.6.0: {} @@ -28591,9 +28767,9 @@ snapshots: esbuild-plugin-solid@0.5.0(esbuild@0.28.1)(solid-js@1.9.10): dependencies: - '@babel/core': 7.29.7 - '@babel/preset-typescript': 7.28.5(@babel/core@7.29.7) - babel-preset-solid: 1.9.10(@babel/core@7.29.7)(solid-js@1.9.10) + '@babel/core': 7.29.0(supports-color@7.2.0) + '@babel/preset-typescript': 7.28.5(@babel/core@7.29.0) + babel-preset-solid: 1.9.10(@babel/core@7.29.0)(solid-js@1.9.10) esbuild: 0.28.1 solid-js: 1.9.10 transitivePeerDependencies: @@ -28730,6 +28906,19 @@ snapshots: optionalDependencies: source-map: 0.6.1 + eslint-plugin-solid@0.14.5(eslint@9.39.4(jiti@2.7.0))(supports-color@7.2.0)(typescript@5.9.3): + dependencies: + '@typescript-eslint/utils': 8.49.0(eslint@9.39.4(jiti@2.7.0))(supports-color@7.2.0)(typescript@5.9.3) + eslint: 9.39.4(jiti@2.7.0) + estraverse: 5.3.0 + is-html: 2.0.0 + kebab-case: 1.0.2 + known-css-properties: 0.30.0 + style-to-object: 1.0.14 + typescript: 5.9.3 + transitivePeerDependencies: + - supports-color + eslint-plugin-unused-imports@4.3.0(@typescript-eslint/eslint-plugin@8.59.4(@typescript-eslint/parser@8.59.4(eslint@9.39.4(jiti@2.7.0))(typescript@7.0.2))(eslint@9.39.4(jiti@2.7.0))(typescript@7.0.2))(eslint@9.39.4(jiti@2.7.0)): dependencies: eslint: 9.39.4(jiti@2.7.0) @@ -29573,13 +29762,6 @@ snapshots: optionalDependencies: crossws: 0.4.6(srvx@0.11.17) - h3@2.0.1-rc.20(crossws@0.4.6(srvx@0.11.17)): - dependencies: - rou3: 0.8.1 - srvx: 0.11.17 - optionalDependencies: - crossws: 0.4.6(srvx@0.11.17) - h3@2.0.1-rc.22(crossws@0.4.6(srvx@0.11.17)): dependencies: rou3: 0.8.1 @@ -29756,6 +29938,8 @@ snapshots: dependencies: cheerio: 1.1.2 + html-tags@3.3.1: {} + html-url-attributes@3.0.1: {} html-void-elements@3.0.0: {} @@ -29984,6 +30168,10 @@ snapshots: is-hexadecimal@2.0.1: {} + is-html@2.0.0: + dependencies: + html-tags: 3.3.1 + is-inside-container@1.0.0: dependencies: is-docker: 3.0.0 @@ -30348,6 +30536,8 @@ snapshots: jwa: 2.0.1 safe-buffer: 5.2.1 + kebab-case@1.0.2: {} + keyv@4.5.4: dependencies: json-buffer: 3.0.1 @@ -30389,6 +30579,8 @@ snapshots: knitwork@1.3.0: {} + known-css-properties@0.30.0: {} + kolorist@1.8.0: {} lan-network@0.2.1: {} @@ -31014,7 +31206,7 @@ snapshots: metro-source-map@0.84.4: dependencies: '@babel/traverse': 7.29.0 - '@babel/types': 7.29.7 + '@babel/types': 7.29.0 flow-enums-runtime: 0.0.6 invariant: 2.2.4 metro-symbolicate: 0.84.4 @@ -33691,7 +33883,7 @@ snapshots: dependencies: '@babel/generator': 7.28.5 '@babel/parser': 7.29.0 - '@babel/types': 7.29.7 + '@babel/types': 7.29.0 ast-kit: 2.2.0 birpc: 3.0.0 dts-resolver: 2.1.3(oxc-resolver@11.21.3) @@ -34028,18 +34220,12 @@ snapshots: dependencies: seroval: 1.5.0 - seroval-plugins@1.6.2(seroval@1.6.2): - dependencies: - seroval: 1.6.2 - seroval@1.3.2: {} seroval@1.4.0: {} seroval@1.5.0: {} - seroval@1.6.2: {} - serve-placeholder@2.0.2: dependencies: defu: 6.1.4 @@ -34696,6 +34882,10 @@ snapshots: ts-algebra@2.0.0: {} + ts-api-utils@2.1.0(typescript@5.9.3): + dependencies: + typescript: 5.9.3 + ts-api-utils@2.5.0(typescript@7.0.2): dependencies: typescript: 7.0.2 @@ -35088,17 +35278,6 @@ snapshots: picomatch: 4.0.5 webpack-virtual-modules: 0.6.2 - unplugin@3.3.0(esbuild@0.28.1)(rolldown@1.2.4)(rollup@4.60.1)(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)): - dependencies: - '@jridgewell/remapping': 2.3.5 - picomatch: 4.0.5 - webpack-virtual-modules: 0.6.2 - optionalDependencies: - esbuild: 0.28.1 - rolldown: 1.2.4 - rollup: 4.60.1 - vite: 8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0) - unrun@0.2.19(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.1): dependencies: rolldown: 1.0.0-beta.53(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.1) @@ -35494,6 +35673,10 @@ snapshots: tsx: 4.23.12 yaml: 2.9.0 + vitefu@1.1.1(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)): + optionalDependencies: + vite: 8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0) + vitefu@1.1.3(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)): optionalDependencies: vite: 8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0) @@ -35919,8 +36102,6 @@ snapshots: zod@4.3.6: {} - zod@4.4.3: {} - zone.js@0.15.1: {} zwitch@2.0.4: {} diff --git a/testing/e2e/package.json b/testing/e2e/package.json index cd6729fe1e..a6d86fa5ec 100644 --- a/testing/e2e/package.json +++ b/testing/e2e/package.json @@ -47,8 +47,8 @@ "@tanstack/devtools-event-bus": "^0.4.1", "@tanstack/nitro-v2-vite-plugin": "^1.155.0", "@tanstack/react-ai-devtools": "workspace:*", - "@tanstack/react-router": "^1.170.32", - "@tanstack/react-start": "^1.168.49", + "@tanstack/react-router": "^1.158.4", + "@tanstack/react-start": "^1.159.0", "arktype": "^2.1.28", "react": "^19.2.3", "react-dom": "^19.2.3", diff --git a/testing/panel/package.json b/testing/panel/package.json index 320270b00b..f51fa0b379 100644 --- a/testing/panel/package.json +++ b/testing/panel/package.json @@ -28,8 +28,8 @@ "@tanstack/nitro-v2-vite-plugin": "^1.155.0", "@tanstack/react-ai-devtools": "workspace:*", "@tanstack/react-devtools": "^0.9.10", - "@tanstack/react-router": "^1.170.32", - "@tanstack/react-start": "^1.168.49", + "@tanstack/react-router": "^1.158.4", + "@tanstack/react-start": "^1.159.0", "@tanstack/start": "^1.120.20", "highlight.js": "^11.11.1", "lucide-react": "^0.561.0", From 9338b26d2f45f7d2b888f33e272c0f6624995e9e Mon Sep 17 00:00:00 2001 From: Tom Beckenham <34339192+tombeckenham@users.noreply.github.com> Date: Thu, 3 Sep 2026 12:58:29 +1000 Subject: [PATCH 5/8] fix(e2e): keep Store 0.8 and 0.11 from sharing a Vite bundle Router 1.159 still calls `new Store(state, { onUpdate })`. ai-client uses Store 0.11 `createAtom`. Prebundling both into one module makes hydration throw `actionsFactory is not a function` and blanks the page. --- testing/e2e/vite.config.ts | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/testing/e2e/vite.config.ts b/testing/e2e/vite.config.ts index 47dad6f737..a6db58d789 100644 --- a/testing/e2e/vite.config.ts +++ b/testing/e2e/vite.config.ts @@ -14,7 +14,13 @@ const config = defineConfig({ // option only affects the SSR build, where we want the SDK resolved at // runtime via require() instead of inlined into the rollup chunk. ssr: { - external: ['@elevenlabs/elevenlabs-js'], + external: ['@elevenlabs/elevenlabs-js', '@tanstack/store'], + }, + // Router 1.159 calls `new Store(state, { onUpdate })` (Store 0.8). + // ai-client uses Store 0.11 `createAtom`. Vite prebundling them into one + // `@tanstack_store.js` makes hydration throw `actionsFactory is not a function`. + optimizeDeps: { + exclude: ['@tanstack/store'], }, resolve: { tsconfigPaths: true }, plugins: [ From 9716e3f93950d35805455a70c64685d20d139da6 Mon Sep 17 00:00:00 2001 From: Tom Beckenham <34339192+tombeckenham@users.noreply.github.com> Date: Thu, 3 Sep 2026 17:14:21 +1000 Subject: [PATCH 6/8] chore: bump Router and Start onto Store 0.11 Upgrade react-router to 1.170.32 and react-start to 1.168.49 so router-core no longer constructs Store 0.8. Align react-store and solid-store with @tanstack/store 0.11.1. Drop the e2e Vite Store prebundle exclude; it is not needed after the Router upgrade. --- examples/sandbox-cloudflare/package.json | 6 +- examples/sandbox-web/package.json | 6 +- examples/ts-code-mode-web/package.json | 6 +- .../routes/_banking-demo/api.banking-demo.ts | 2 +- .../routes/_banking-demo/api.banking-init.ts | 2 +- .../src/routes/_banking-demo/banking-demo.tsx | 2 +- .../_database-demo/api.database-demo.ts | 2 +- .../routes/_database-demo/api.db-snippets.ts | 2 +- .../src/routes/_database-demo/api.judge.ts | 2 +- .../routes/_database-demo/database-demo.tsx | 2 +- .../_execute-prompt/api.execute-prompt.ts | 2 +- .../_execute-prompt/api.realtime-token.ts | 2 +- .../routes/_execute-prompt/execute-prompt.tsx | 2 +- .../src/routes/_reporting/api.invalidate.ts | 2 +- .../src/routes/_reporting/api.report-demo.ts | 2 +- .../src/routes/_reporting/api.report-event.ts | 2 +- .../src/routes/_reporting/api.report-sse.ts | 2 +- .../src/routes/_reporting/api.reports.ts | 2 +- examples/ts-group-chat/package.json | 8 +- examples/ts-react-chat/package.json | 12 +- examples/ts-react-media/package.json | 6 +- examples/ts-react-rerank/package.json | 6 +- examples/ts-react-search/package.json | 10 +- examples/ts-react-ui-chatbot/package.json | 8 +- examples/ts-solid-chat/package.json | 12 +- pnpm-lock.yaml | 1418 ++++++++--------- testing/e2e/package.json | 4 +- testing/e2e/vite.config.ts | 8 +- testing/panel/package.json | 4 +- 29 files changed, 685 insertions(+), 859 deletions(-) diff --git a/examples/sandbox-cloudflare/package.json b/examples/sandbox-cloudflare/package.json index b6038d8cf8..1375ec6d77 100644 --- a/examples/sandbox-cloudflare/package.json +++ b/examples/sandbox-cloudflare/package.json @@ -22,8 +22,8 @@ "@tanstack/ai-sandbox": "workspace:*", "@tanstack/ai-sandbox-cloudflare": "workspace:*", "@tanstack/ai-sandbox-local-process": "workspace:*", - "@tanstack/react-router": "^1.158.4", - "@tanstack/react-start": "^1.159.0", + "@tanstack/react-router": "^1.170.32", + "@tanstack/react-start": "^1.168.49", "lucide-react": "^0.561.0", "react": "^19.2.3", "react-dom": "^19.2.3", @@ -37,7 +37,7 @@ "devDependencies": { "@cloudflare/vite-plugin": "^1.42.1", "@tailwindcss/vite": "^4.1.18", - "@tanstack/router-plugin": "^1.158.4", + "@tanstack/router-plugin": "^1.168.35", "@types/node": "^24.10.1", "@types/react": "^19.2.7", "@types/react-dom": "^19.2.3", diff --git a/examples/sandbox-web/package.json b/examples/sandbox-web/package.json index 75f96ab13e..941ff6df61 100644 --- a/examples/sandbox-web/package.json +++ b/examples/sandbox-web/package.json @@ -17,8 +17,8 @@ "@tanstack/ai-react": "workspace:*", "@tanstack/ai-sandbox": "workspace:*", "@tanstack/ai-sandbox-docker": "workspace:*", - "@tanstack/react-router": "^1.158.4", - "@tanstack/react-start": "^1.159.0", + "@tanstack/react-router": "^1.170.32", + "@tanstack/react-start": "^1.168.49", "lucide-react": "^0.561.0", "react": "^19.2.3", "react-dom": "^19.2.3", @@ -31,7 +31,7 @@ }, "devDependencies": { "@tailwindcss/vite": "^4.1.18", - "@tanstack/router-plugin": "^1.158.4", + "@tanstack/router-plugin": "^1.168.35", "@types/node": "^24.10.1", "@types/react": "^19.2.7", "@types/react-dom": "^19.2.3", diff --git a/examples/ts-code-mode-web/package.json b/examples/ts-code-mode-web/package.json index ed5a5978ee..c829b45cf6 100644 --- a/examples/ts-code-mode-web/package.json +++ b/examples/ts-code-mode-web/package.json @@ -32,9 +32,9 @@ "@tanstack/ai-ollama": "workspace:*", "@tanstack/ai-openai": "workspace:*", "@tanstack/ai-react": "workspace:*", - "@tanstack/react-router": "^1.158.4", - "@tanstack/react-start": "^1.159.0", - "@tanstack/router-plugin": "^1.158.4", + "@tanstack/react-router": "^1.170.32", + "@tanstack/react-start": "^1.168.49", + "@tanstack/router-plugin": "^1.168.35", "@tanstack/store": "^0.11.1", "framer-motion": "^11.15.0", "highlight.js": "^11.11.1", diff --git a/examples/ts-code-mode-web/src/routes/_banking-demo/api.banking-demo.ts b/examples/ts-code-mode-web/src/routes/_banking-demo/api.banking-demo.ts index ff14d96999..335115b4be 100644 --- a/examples/ts-code-mode-web/src/routes/_banking-demo/api.banking-demo.ts +++ b/examples/ts-code-mode-web/src/routes/_banking-demo/api.banking-demo.ts @@ -199,7 +199,7 @@ async function getCodeModeTools() { return codeModeCache } -export const Route = createFileRoute('/_banking-demo/api/banking-demo' as any)({ +export const Route = createFileRoute('/_banking-demo/api/banking-demo')({ server: { handlers: { POST: async ({ request }) => { diff --git a/examples/ts-code-mode-web/src/routes/_banking-demo/api.banking-init.ts b/examples/ts-code-mode-web/src/routes/_banking-demo/api.banking-init.ts index 30630aaa38..1275b6aca7 100644 --- a/examples/ts-code-mode-web/src/routes/_banking-demo/api.banking-init.ts +++ b/examples/ts-code-mode-web/src/routes/_banking-demo/api.banking-init.ts @@ -10,7 +10,7 @@ import { getMockBalances } from '@/lib/reports/create-handler-bindings' const DASHBOARD_ID = 'dashboard' -export const Route = createFileRoute('/_banking-demo/api/banking-init' as any)({ +export const Route = createFileRoute('/_banking-demo/api/banking-init')({ server: { handlers: { POST: async () => { diff --git a/examples/ts-code-mode-web/src/routes/_banking-demo/banking-demo.tsx b/examples/ts-code-mode-web/src/routes/_banking-demo/banking-demo.tsx index d0ab65e1db..6dd38976e6 100644 --- a/examples/ts-code-mode-web/src/routes/_banking-demo/banking-demo.tsx +++ b/examples/ts-code-mode-web/src/routes/_banking-demo/banking-demo.tsx @@ -28,7 +28,7 @@ import type { UIUpdate, } from '@/lib/reports/types' -export const Route = createFileRoute('/_banking-demo/banking-demo' as any)({ +export const Route = createFileRoute('/_banking-demo/banking-demo')({ component: BankingDemoPage, }) diff --git a/examples/ts-code-mode-web/src/routes/_database-demo/api.database-demo.ts b/examples/ts-code-mode-web/src/routes/_database-demo/api.database-demo.ts index 10d7a12a85..f74be7c6c9 100644 --- a/examples/ts-code-mode-web/src/routes/_database-demo/api.database-demo.ts +++ b/examples/ts-code-mode-web/src/routes/_database-demo/api.database-demo.ts @@ -227,7 +227,7 @@ function wrapWithTimingEvents( } export const Route = createFileRoute( - '/_database-demo/api/database-demo' as any, + '/_database-demo/api/database-demo', )({ server: { handlers: { diff --git a/examples/ts-code-mode-web/src/routes/_database-demo/api.db-snippets.ts b/examples/ts-code-mode-web/src/routes/_database-demo/api.db-snippets.ts index a7f0cdcac0..a04274deb9 100644 --- a/examples/ts-code-mode-web/src/routes/_database-demo/api.db-snippets.ts +++ b/examples/ts-code-mode-web/src/routes/_database-demo/api.db-snippets.ts @@ -14,7 +14,7 @@ const snippetStorage = createFileSnippetStorage({ trustStrategy, }) -export const Route = createFileRoute('/_database-demo/api/db-snippets' as any)({ +export const Route = createFileRoute('/_database-demo/api/db-snippets')({ server: { handlers: { GET: async () => { diff --git a/examples/ts-code-mode-web/src/routes/_database-demo/api.judge.ts b/examples/ts-code-mode-web/src/routes/_database-demo/api.judge.ts index 3b31b0a3e3..b231857928 100644 --- a/examples/ts-code-mode-web/src/routes/_database-demo/api.judge.ts +++ b/examples/ts-code-mode-web/src/routes/_database-demo/api.judge.ts @@ -29,7 +29,7 @@ Rate the candidate on two dimensions, each on a scale from 1 to 10 (10 = best): Provide a two sentence summary of your evaluation.` -export const Route = createFileRoute('/_database-demo/api/judge' as any)({ +export const Route = createFileRoute('/_database-demo/api/judge')({ server: { handlers: { POST: async ({ request }) => { diff --git a/examples/ts-code-mode-web/src/routes/_database-demo/database-demo.tsx b/examples/ts-code-mode-web/src/routes/_database-demo/database-demo.tsx index c4a05fab1e..d4d9c966e2 100644 --- a/examples/ts-code-mode-web/src/routes/_database-demo/database-demo.tsx +++ b/examples/ts-code-mode-web/src/routes/_database-demo/database-demo.tsx @@ -25,7 +25,7 @@ import ChatInput from '@/components/ChatInput' import { formatDuration } from '@/lib/efficiency' import { toolResultContentToString } from '@/lib/tool-result-content' -export const Route = createFileRoute('/_database-demo/database-demo' as any)({ +export const Route = createFileRoute('/_database-demo/database-demo')({ component: DatabaseDemoPage, }) diff --git a/examples/ts-code-mode-web/src/routes/_execute-prompt/api.execute-prompt.ts b/examples/ts-code-mode-web/src/routes/_execute-prompt/api.execute-prompt.ts index f5c83f3f42..6c9a6149a4 100644 --- a/examples/ts-code-mode-web/src/routes/_execute-prompt/api.execute-prompt.ts +++ b/examples/ts-code-mode-web/src/routes/_execute-prompt/api.execute-prompt.ts @@ -34,7 +34,7 @@ async function getDriver(): Promise { } export const Route = createFileRoute( - '/_execute-prompt/api/execute-prompt' as any, + '/_execute-prompt/api/execute-prompt', )({ server: { handlers: { diff --git a/examples/ts-code-mode-web/src/routes/_execute-prompt/api.realtime-token.ts b/examples/ts-code-mode-web/src/routes/_execute-prompt/api.realtime-token.ts index 9b4b38cafe..5cfcd1157e 100644 --- a/examples/ts-code-mode-web/src/routes/_execute-prompt/api.realtime-token.ts +++ b/examples/ts-code-mode-web/src/routes/_execute-prompt/api.realtime-token.ts @@ -3,7 +3,7 @@ import { realtimeToken } from '@tanstack/ai' import { openaiRealtimeToken } from '@tanstack/ai-openai' export const Route = createFileRoute( - '/_execute-prompt/api/realtime-token' as any, + '/_execute-prompt/api/realtime-token', )({ server: { handlers: { diff --git a/examples/ts-code-mode-web/src/routes/_execute-prompt/execute-prompt.tsx b/examples/ts-code-mode-web/src/routes/_execute-prompt/execute-prompt.tsx index e44c07563d..d42bebb877 100644 --- a/examples/ts-code-mode-web/src/routes/_execute-prompt/execute-prompt.tsx +++ b/examples/ts-code-mode-web/src/routes/_execute-prompt/execute-prompt.tsx @@ -29,7 +29,7 @@ import type { CodeExecution, } from '@/lib/execute-prompt-realtime-tools' -export const Route = createFileRoute('/_execute-prompt/execute-prompt' as any)({ +export const Route = createFileRoute('/_execute-prompt/execute-prompt')({ component: DashboardDemoPage, }) diff --git a/examples/ts-code-mode-web/src/routes/_reporting/api.invalidate.ts b/examples/ts-code-mode-web/src/routes/_reporting/api.invalidate.ts index f7100859e5..f473ebd017 100644 --- a/examples/ts-code-mode-web/src/routes/_reporting/api.invalidate.ts +++ b/examples/ts-code-mode-web/src/routes/_reporting/api.invalidate.ts @@ -4,7 +4,7 @@ import { getReportState, getSSEController } from '@/lib/reports/report-storage' import { refreshComponent } from '@/lib/reports/refresh-component' import { evaluateWatchersForSignals } from '@/lib/reports/evaluate-watchers' -export const Route = createFileRoute('/_reporting/api/invalidate' as any)({ +export const Route = createFileRoute('/_reporting/api/invalidate')({ server: { handlers: { POST: async ({ request }) => { diff --git a/examples/ts-code-mode-web/src/routes/_reporting/api.report-demo.ts b/examples/ts-code-mode-web/src/routes/_reporting/api.report-demo.ts index dcf599641b..2ef92fdd4d 100644 --- a/examples/ts-code-mode-web/src/routes/_reporting/api.report-demo.ts +++ b/examples/ts-code-mode-web/src/routes/_reporting/api.report-demo.ts @@ -4,7 +4,7 @@ import { simulateDeposit, } from '@/lib/reports/create-handler-bindings' -export const Route = createFileRoute('/_reporting/api/report-demo' as any)({ +export const Route = createFileRoute('/_reporting/api/report-demo')({ server: { handlers: { POST: async ({ request }) => { diff --git a/examples/ts-code-mode-web/src/routes/_reporting/api.report-event.ts b/examples/ts-code-mode-web/src/routes/_reporting/api.report-event.ts index 90bf68b2f5..11d97742ee 100644 --- a/examples/ts-code-mode-web/src/routes/_reporting/api.report-event.ts +++ b/examples/ts-code-mode-web/src/routes/_reporting/api.report-event.ts @@ -16,7 +16,7 @@ import { import { refreshComponent } from '@/lib/reports/refresh-component' import { evaluateWatchersForSignals } from '@/lib/reports/evaluate-watchers' -export const Route = createFileRoute('/_reporting/api/report-event' as any)({ +export const Route = createFileRoute('/_reporting/api/report-event')({ server: { handlers: { POST: async ({ request }) => { diff --git a/examples/ts-code-mode-web/src/routes/_reporting/api.report-sse.ts b/examples/ts-code-mode-web/src/routes/_reporting/api.report-sse.ts index d53bf55080..97a429b400 100644 --- a/examples/ts-code-mode-web/src/routes/_reporting/api.report-sse.ts +++ b/examples/ts-code-mode-web/src/routes/_reporting/api.report-sse.ts @@ -5,7 +5,7 @@ import { getSSEController, } from '@/lib/reports/report-storage' -export const Route = createFileRoute('/_reporting/api/report-sse' as any)({ +export const Route = createFileRoute('/_reporting/api/report-sse')({ server: { handlers: { GET: async ({ request }) => { diff --git a/examples/ts-code-mode-web/src/routes/_reporting/api.reports.ts b/examples/ts-code-mode-web/src/routes/_reporting/api.reports.ts index 4ff06ad390..4a64e80fa1 100644 --- a/examples/ts-code-mode-web/src/routes/_reporting/api.reports.ts +++ b/examples/ts-code-mode-web/src/routes/_reporting/api.reports.ts @@ -49,7 +49,7 @@ async function getCodeModeTools() { return codeModeCache } -export const Route = createFileRoute('/_reporting/api/reports' as any)({ +export const Route = createFileRoute('/_reporting/api/reports')({ server: { handlers: { POST: async ({ request }) => { diff --git a/examples/ts-group-chat/package.json b/examples/ts-group-chat/package.json index 8b0e844330..66edb51124 100644 --- a/examples/ts-group-chat/package.json +++ b/examples/ts-group-chat/package.json @@ -14,10 +14,10 @@ "@tanstack/ai": "workspace:*", "@tanstack/ai-anthropic": "workspace:*", "@tanstack/react-devtools": "^0.9.10", - "@tanstack/react-router": "^1.158.4", - "@tanstack/react-router-devtools": "^1.158.4", - "@tanstack/react-start": "^1.159.0", - "@tanstack/router-plugin": "^1.158.4", + "@tanstack/react-router": "^1.170.32", + "@tanstack/react-router-devtools": "^1.167.1", + "@tanstack/react-start": "^1.168.49", + "@tanstack/router-plugin": "^1.168.35", "capnweb": "^0.10.0", "nitro": "3.0.260610-beta", "react": "^19.2.3", diff --git a/examples/ts-react-chat/package.json b/examples/ts-react-chat/package.json index 8afb8f862d..2c3c924468 100644 --- a/examples/ts-react-chat/package.json +++ b/examples/ts-react-chat/package.json @@ -49,12 +49,12 @@ "@tanstack/ai-sandbox-local-process": "workspace:*", "@tanstack/ai-sandbox-vercel": "workspace:*", "@tanstack/react-devtools": "^0.9.10", - "@tanstack/react-router": "^1.158.4", - "@tanstack/react-router-devtools": "^1.158.4", - "@tanstack/react-router-ssr-query": "^1.158.4", - "@tanstack/react-start": "^1.159.0", - "@tanstack/react-store": "^0.8.0", - "@tanstack/router-plugin": "^1.158.4", + "@tanstack/react-router": "^1.170.32", + "@tanstack/react-router-devtools": "^1.167.1", + "@tanstack/react-router-ssr-query": "^1.167.2", + "@tanstack/react-start": "^1.168.49", + "@tanstack/react-store": "^0.11.1", + "@tanstack/router-plugin": "^1.168.35", "@tanstack/store": "^0.11.1", "dockerode": "^4.0.2", "highlight.js": "^11.11.1", diff --git a/examples/ts-react-media/package.json b/examples/ts-react-media/package.json index 89f5d0b74f..1f832eb91c 100644 --- a/examples/ts-react-media/package.json +++ b/examples/ts-react-media/package.json @@ -18,9 +18,9 @@ "@tanstack/ai-grok": "workspace:*", "@tanstack/ai-openrouter": "workspace:*", "@tanstack/ai-react": "workspace:*", - "@tanstack/react-router": "^1.158.4", - "@tanstack/react-start": "^1.159.0", - "@tanstack/router-plugin": "^1.158.4", + "@tanstack/react-router": "^1.170.32", + "@tanstack/react-start": "^1.168.49", + "@tanstack/router-plugin": "^1.168.35", "lucide-react": "^0.561.0", "nitro": "3.0.260610-beta", "react": "^19.2.3", diff --git a/examples/ts-react-rerank/package.json b/examples/ts-react-rerank/package.json index 83785b9b13..045fd110d7 100644 --- a/examples/ts-react-rerank/package.json +++ b/examples/ts-react-rerank/package.json @@ -14,9 +14,9 @@ "@tanstack/ai": "workspace:*", "@tanstack/ai-cohere": "workspace:*", "@tanstack/ai-openrouter": "workspace:*", - "@tanstack/react-router": "^1.158.4", - "@tanstack/react-start": "^1.159.0", - "@tanstack/router-plugin": "^1.158.4", + "@tanstack/react-router": "^1.170.32", + "@tanstack/react-start": "^1.168.49", + "@tanstack/router-plugin": "^1.168.35", "lucide-react": "^0.561.0", "nitro": "3.0.260610-beta", "react": "^19.2.3", diff --git a/examples/ts-react-search/package.json b/examples/ts-react-search/package.json index 26b915c7df..d901fb4b1b 100644 --- a/examples/ts-react-search/package.json +++ b/examples/ts-react-search/package.json @@ -19,11 +19,11 @@ "@tanstack/react-db": "^0.1.55", "@tanstack/react-devtools": "^0.9.10", "@tanstack/react-query": "^5.90.12", - "@tanstack/react-router": "^1.158.4", - "@tanstack/react-router-devtools": "^1.158.4", - "@tanstack/react-router-ssr-query": "^1.158.4", - "@tanstack/react-start": "^1.159.0", - "@tanstack/router-plugin": "^1.158.4", + "@tanstack/react-router": "^1.170.32", + "@tanstack/react-router-devtools": "^1.167.1", + "@tanstack/react-router-ssr-query": "^1.167.2", + "@tanstack/react-start": "^1.168.49", + "@tanstack/router-plugin": "^1.168.35", "@tanstack/zod-adapter": "^1.140.1", "class-variance-authority": "^0.7.1", "clsx": "^2.1.1", diff --git a/examples/ts-react-ui-chatbot/package.json b/examples/ts-react-ui-chatbot/package.json index a33bc233fd..4c6f33f742 100644 --- a/examples/ts-react-ui-chatbot/package.json +++ b/examples/ts-react-ui-chatbot/package.json @@ -16,10 +16,10 @@ "@tanstack/ai-openai": "workspace:*", "@tanstack/ai-react": "workspace:*", "@tanstack/react-devtools": "^0.9.10", - "@tanstack/react-router": "^1.158.4", - "@tanstack/react-router-devtools": "^1.158.4", - "@tanstack/react-start": "^1.159.0", - "@tanstack/router-plugin": "^1.158.4", + "@tanstack/react-router": "^1.170.32", + "@tanstack/react-router-devtools": "^1.167.1", + "@tanstack/react-start": "^1.168.49", + "@tanstack/router-plugin": "^1.168.35", "class-variance-authority": "^0.7.1", "clsx": "^2.1.1", "lucide-react": "^0.561.0", diff --git a/examples/ts-solid-chat/package.json b/examples/ts-solid-chat/package.json index 5ac6e3b16a..15bf5276a3 100644 --- a/examples/ts-solid-chat/package.json +++ b/examples/ts-solid-chat/package.json @@ -20,14 +20,14 @@ "@tanstack/ai-openai": "workspace:*", "@tanstack/ai-solid": "workspace:*", "@tanstack/nitro-v2-vite-plugin": "^1.155.0", - "@tanstack/router-plugin": "^1.158.4", + "@tanstack/router-plugin": "^1.168.35", "@tanstack/solid-ai-devtools": "workspace:*", "@tanstack/solid-devtools": "^0.7.15", - "@tanstack/solid-router": "^1.139.10", - "@tanstack/solid-router-devtools": "^1.139.10", - "@tanstack/solid-router-ssr-query": "^1.139.10", - "@tanstack/solid-start": "^1.139.10", - "@tanstack/solid-store": "^0.8.0", + "@tanstack/solid-router": "^1.170.30", + "@tanstack/solid-router-devtools": "^1.167.1", + "@tanstack/solid-router-ssr-query": "^1.167.2", + "@tanstack/solid-start": "^1.168.47", + "@tanstack/solid-store": "^0.11.1", "@tanstack/store": "^0.11.1", "highlight.js": "^11.11.1", "lucide-solid": "^0.554.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index b529405795..8b051ac1f7 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -204,11 +204,11 @@ importers: specifier: workspace:* version: link:../../packages/ai-sandbox-local-process '@tanstack/react-router': - specifier: ^1.158.4 - version: 1.159.5(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + specifier: ^1.170.32 + version: 1.170.32(react-dom@19.2.3(react@19.2.3))(react@19.2.3) '@tanstack/react-start': - specifier: ^1.159.0 - version: 1.159.5(crossws@0.4.6(srvx@0.11.17))(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(vite-plugin-solid@2.11.14(solid-js@1.9.10)(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)))(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)) + specifier: ^1.168.49 + version: 1.168.49(crossws@0.4.6(srvx@0.11.17))(esbuild@0.28.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(rolldown@1.2.4)(rollup@4.60.1)(vite-plugin-solid@2.11.14(solid-js@1.9.10)(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)))(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)) lucide-react: specifier: ^0.561.0 version: 0.561.0(react@19.2.3) @@ -244,8 +244,8 @@ importers: specifier: ^4.1.18 version: 4.1.18(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)) '@tanstack/router-plugin': - specifier: ^1.158.4 - version: 1.159.5(@tanstack/react-router@1.159.5(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(supports-color@7.2.0)(vite-plugin-solid@2.11.14(solid-js@1.9.10)(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)))(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)) + specifier: ^1.168.35 + version: 1.168.35(@tanstack/react-router@1.170.32(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(esbuild@0.28.1)(rolldown@1.2.4)(rollup@4.60.1)(vite-plugin-solid@2.11.14(solid-js@1.9.10)(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)))(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)) '@types/node': specifier: ^24.10.1 version: 24.10.3 @@ -292,11 +292,11 @@ importers: specifier: workspace:* version: link:../../packages/ai-sandbox-docker '@tanstack/react-router': - specifier: ^1.158.4 - version: 1.159.5(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + specifier: ^1.170.32 + version: 1.170.32(react-dom@19.2.3(react@19.2.3))(react@19.2.3) '@tanstack/react-start': - specifier: ^1.159.0 - version: 1.159.5(crossws@0.4.6(srvx@0.11.17))(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(vite-plugin-solid@2.11.14(solid-js@1.9.10)(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)))(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)) + specifier: ^1.168.49 + version: 1.168.49(crossws@0.4.6(srvx@0.11.17))(esbuild@0.28.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(rolldown@1.2.4)(rollup@4.60.1)(vite-plugin-solid@2.11.14(solid-js@1.9.10)(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)))(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)) lucide-react: specifier: ^0.561.0 version: 0.561.0(react@19.2.3) @@ -329,8 +329,8 @@ importers: specifier: ^4.1.18 version: 4.1.18(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)) '@tanstack/router-plugin': - specifier: ^1.158.4 - version: 1.159.5(@tanstack/react-router@1.159.5(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(supports-color@7.2.0)(vite-plugin-solid@2.11.14(solid-js@1.9.10)(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)))(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)) + specifier: ^1.168.35 + version: 1.168.35(@tanstack/react-router@1.170.32(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(esbuild@0.28.1)(rolldown@1.2.4)(rollup@4.60.1)(vite-plugin-solid@2.11.14(solid-js@1.9.10)(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)))(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)) '@types/node': specifier: ^24.10.1 version: 24.10.3 @@ -480,14 +480,14 @@ importers: specifier: workspace:* version: link:../../packages/ai-react '@tanstack/react-router': - specifier: ^1.158.4 - version: 1.159.5(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + specifier: ^1.170.32 + version: 1.170.32(react-dom@19.2.3(react@19.2.3))(react@19.2.3) '@tanstack/react-start': - specifier: ^1.159.0 - version: 1.159.5(crossws@0.4.6(srvx@0.11.17))(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(vite-plugin-solid@2.11.14(solid-js@1.9.10)(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)))(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)) + specifier: ^1.168.49 + version: 1.168.49(crossws@0.4.6(srvx@0.11.17))(esbuild@0.28.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(rolldown@1.2.4)(rollup@4.60.1)(vite-plugin-solid@2.11.14(solid-js@1.9.10)(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)))(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)) '@tanstack/router-plugin': - specifier: ^1.158.4 - version: 1.159.5(@tanstack/react-router@1.159.5(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(supports-color@7.2.0)(vite-plugin-solid@2.11.14(solid-js@1.9.10)(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)))(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)) + specifier: ^1.168.35 + version: 1.168.35(@tanstack/react-router@1.170.32(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(esbuild@0.28.1)(rolldown@1.2.4)(rollup@4.60.1)(vite-plugin-solid@2.11.14(solid-js@1.9.10)(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)))(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)) '@tanstack/store': specifier: ^0.11.1 version: 0.11.1 @@ -589,17 +589,17 @@ importers: specifier: ^0.9.10 version: 0.9.10(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(csstype@3.2.3)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(solid-js@1.9.10) '@tanstack/react-router': - specifier: ^1.158.4 - version: 1.159.5(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + specifier: ^1.170.32 + version: 1.170.32(react-dom@19.2.3(react@19.2.3))(react@19.2.3) '@tanstack/react-router-devtools': - specifier: ^1.158.4 - version: 1.159.5(@tanstack/react-router@1.159.5(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(@tanstack/router-core@1.159.4)(csstype@3.2.3)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + specifier: ^1.167.1 + version: 1.167.1(@tanstack/react-router@1.170.32(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(@tanstack/router-core@1.171.27)(csstype@3.2.3)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) '@tanstack/react-start': - specifier: ^1.159.0 - version: 1.159.5(crossws@0.4.6(srvx@0.11.17))(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(vite-plugin-solid@2.11.14(solid-js@1.9.10)(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)))(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)) + specifier: ^1.168.49 + version: 1.168.49(crossws@0.4.6(srvx@0.11.17))(esbuild@0.28.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(rolldown@1.2.4)(rollup@4.60.1)(vite-plugin-solid@2.11.14(solid-js@1.9.10)(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)))(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)) '@tanstack/router-plugin': - specifier: ^1.158.4 - version: 1.159.5(@tanstack/react-router@1.159.5(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(supports-color@7.2.0)(vite-plugin-solid@2.11.14(solid-js@1.9.10)(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)))(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)) + specifier: ^1.168.35 + version: 1.168.35(@tanstack/react-router@1.170.32(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(esbuild@0.28.1)(rolldown@1.2.4)(rollup@4.60.1)(vite-plugin-solid@2.11.14(solid-js@1.9.10)(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)))(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)) capnweb: specifier: ^0.10.0 version: 0.10.0 @@ -773,23 +773,23 @@ importers: specifier: ^0.9.10 version: 0.9.10(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(csstype@3.2.3)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(solid-js@1.9.10) '@tanstack/react-router': - specifier: ^1.158.4 - version: 1.159.5(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + specifier: ^1.170.32 + version: 1.170.32(react-dom@19.2.3(react@19.2.3))(react@19.2.3) '@tanstack/react-router-devtools': - specifier: ^1.158.4 - version: 1.159.5(@tanstack/react-router@1.159.5(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(@tanstack/router-core@1.159.4)(csstype@3.2.3)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + specifier: ^1.167.1 + version: 1.167.1(@tanstack/react-router@1.170.32(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(@tanstack/router-core@1.171.27)(csstype@3.2.3)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) '@tanstack/react-router-ssr-query': - specifier: ^1.158.4 - version: 1.159.5(@tanstack/query-core@5.90.12)(@tanstack/react-query@5.90.12(react@19.2.3))(@tanstack/react-router@1.159.5(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(@tanstack/router-core@1.159.4)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + specifier: ^1.167.2 + version: 1.167.2(@tanstack/query-core@5.90.12)(@tanstack/react-query@5.90.12(react@19.2.3))(@tanstack/react-router@1.170.32(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(@tanstack/router-core@1.171.27)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) '@tanstack/react-start': - specifier: ^1.159.0 - version: 1.159.5(crossws@0.4.6(srvx@0.11.17))(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(vite-plugin-solid@2.11.14(solid-js@1.9.10)(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)))(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)) + specifier: ^1.168.49 + version: 1.168.49(crossws@0.4.6(srvx@0.11.17))(esbuild@0.28.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(rolldown@1.2.4)(rollup@4.60.1)(vite-plugin-solid@2.11.14(solid-js@1.9.10)(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)))(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)) '@tanstack/react-store': - specifier: ^0.8.0 - version: 0.8.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + specifier: ^0.11.1 + version: 0.11.1(react-dom@19.2.3(react@19.2.3))(react@19.2.3) '@tanstack/router-plugin': - specifier: ^1.158.4 - version: 1.159.5(@tanstack/react-router@1.159.5(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(supports-color@7.2.0)(vite-plugin-solid@2.11.14(solid-js@1.9.10)(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)))(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)) + specifier: ^1.168.35 + version: 1.168.35(@tanstack/react-router@1.170.32(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(esbuild@0.28.1)(rolldown@1.2.4)(rollup@4.60.1)(vite-plugin-solid@2.11.14(solid-js@1.9.10)(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)))(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)) '@tanstack/store': specifier: ^0.11.1 version: 0.11.1 @@ -909,14 +909,14 @@ importers: specifier: workspace:* version: link:../../packages/ai-react '@tanstack/react-router': - specifier: ^1.158.4 - version: 1.159.5(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + specifier: ^1.170.32 + version: 1.170.32(react-dom@19.2.3(react@19.2.3))(react@19.2.3) '@tanstack/react-start': - specifier: ^1.159.0 - version: 1.159.5(crossws@0.4.6(srvx@0.11.17))(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(vite-plugin-solid@2.11.14(solid-js@1.9.10)(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)))(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)) + specifier: ^1.168.49 + version: 1.168.49(crossws@0.4.6(srvx@0.11.17))(esbuild@0.28.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(rolldown@1.2.4)(rollup@4.60.1)(vite-plugin-solid@2.11.14(solid-js@1.9.10)(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)))(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)) '@tanstack/router-plugin': - specifier: ^1.158.4 - version: 1.159.5(@tanstack/react-router@1.159.5(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(supports-color@7.2.0)(vite-plugin-solid@2.11.14(solid-js@1.9.10)(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)))(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)) + specifier: ^1.168.35 + version: 1.168.35(@tanstack/react-router@1.170.32(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(esbuild@0.28.1)(rolldown@1.2.4)(rollup@4.60.1)(vite-plugin-solid@2.11.14(solid-js@1.9.10)(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)))(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)) lucide-react: specifier: ^0.561.0 version: 0.561.0(react@19.2.3) @@ -1013,14 +1013,14 @@ importers: specifier: workspace:* version: link:../../packages/ai-openrouter '@tanstack/react-router': - specifier: ^1.158.4 - version: 1.159.5(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + specifier: ^1.170.32 + version: 1.170.32(react-dom@19.2.3(react@19.2.3))(react@19.2.3) '@tanstack/react-start': - specifier: ^1.159.0 - version: 1.159.5(crossws@0.4.6(srvx@0.11.17))(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(vite-plugin-solid@2.11.14(solid-js@1.9.10)(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)))(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)) + specifier: ^1.168.49 + version: 1.168.49(crossws@0.4.6(srvx@0.11.17))(esbuild@0.28.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(rolldown@1.2.4)(rollup@4.60.1)(vite-plugin-solid@2.11.14(solid-js@1.9.10)(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)))(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)) '@tanstack/router-plugin': - specifier: ^1.158.4 - version: 1.159.5(@tanstack/react-router@1.159.5(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(supports-color@7.2.0)(vite-plugin-solid@2.11.14(solid-js@1.9.10)(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)))(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)) + specifier: ^1.168.35 + version: 1.168.35(@tanstack/react-router@1.170.32(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(esbuild@0.28.1)(rolldown@1.2.4)(rollup@4.60.1)(vite-plugin-solid@2.11.14(solid-js@1.9.10)(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)))(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)) lucide-react: specifier: ^0.561.0 version: 0.561.0(react@19.2.3) @@ -1086,23 +1086,23 @@ importers: specifier: ^5.90.12 version: 5.90.12(react@19.2.3) '@tanstack/react-router': - specifier: ^1.158.4 - version: 1.159.5(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + specifier: ^1.170.32 + version: 1.170.32(react-dom@19.2.3(react@19.2.3))(react@19.2.3) '@tanstack/react-router-devtools': - specifier: ^1.158.4 - version: 1.159.5(@tanstack/react-router@1.159.5(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(@tanstack/router-core@1.159.4)(csstype@3.2.3)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + specifier: ^1.167.1 + version: 1.167.1(@tanstack/react-router@1.170.32(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(@tanstack/router-core@1.171.27)(csstype@3.2.3)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) '@tanstack/react-router-ssr-query': - specifier: ^1.158.4 - version: 1.159.5(@tanstack/query-core@5.90.12)(@tanstack/react-query@5.90.12(react@19.2.3))(@tanstack/react-router@1.159.5(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(@tanstack/router-core@1.159.4)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + specifier: ^1.167.2 + version: 1.167.2(@tanstack/query-core@5.90.12)(@tanstack/react-query@5.90.12(react@19.2.3))(@tanstack/react-router@1.170.32(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(@tanstack/router-core@1.171.27)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) '@tanstack/react-start': - specifier: ^1.159.0 - version: 1.159.5(crossws@0.4.6(srvx@0.11.17))(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(vite-plugin-solid@2.11.14(solid-js@1.9.10)(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)))(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)) + specifier: ^1.168.49 + version: 1.168.49(crossws@0.4.6(srvx@0.11.17))(esbuild@0.28.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(rolldown@1.2.4)(rollup@4.60.1)(vite-plugin-solid@2.11.14(solid-js@1.9.10)(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)))(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)) '@tanstack/router-plugin': - specifier: ^1.158.4 - version: 1.159.5(@tanstack/react-router@1.159.5(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(supports-color@7.2.0)(vite-plugin-solid@2.11.14(solid-js@1.9.10)(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)))(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)) + specifier: ^1.168.35 + version: 1.168.35(@tanstack/react-router@1.170.32(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(esbuild@0.28.1)(rolldown@1.2.4)(rollup@4.60.1)(vite-plugin-solid@2.11.14(solid-js@1.9.10)(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)))(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)) '@tanstack/zod-adapter': specifier: ^1.140.1 - version: 1.166.9(@tanstack/react-router@1.159.5(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(zod@4.3.6) + version: 1.166.9(@tanstack/react-router@1.170.32(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(zod@4.3.6) class-variance-authority: specifier: ^0.7.1 version: 0.7.1 @@ -1201,17 +1201,17 @@ importers: specifier: ^0.9.10 version: 0.9.10(@types/react-dom@19.2.3(@types/react@19.2.18))(@types/react@19.2.18)(csstype@3.2.3)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(solid-js@1.9.10) '@tanstack/react-router': - specifier: ^1.158.4 - version: 1.159.5(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + specifier: ^1.170.32 + version: 1.170.32(react-dom@19.2.3(react@19.2.3))(react@19.2.3) '@tanstack/react-router-devtools': - specifier: ^1.158.4 - version: 1.159.5(@tanstack/react-router@1.159.5(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(@tanstack/router-core@1.159.4)(csstype@3.2.3)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + specifier: ^1.167.1 + version: 1.167.1(@tanstack/react-router@1.170.32(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(@tanstack/router-core@1.171.27)(csstype@3.2.3)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) '@tanstack/react-start': - specifier: ^1.159.0 - version: 1.159.5(crossws@0.4.6(srvx@0.11.17))(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(vite-plugin-solid@2.11.14(solid-js@1.9.10)(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)))(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)) + specifier: ^1.168.49 + version: 1.168.49(crossws@0.4.6(srvx@0.11.17))(esbuild@0.28.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(rolldown@1.2.4)(rollup@4.60.1)(vite-plugin-solid@2.11.14(solid-js@1.9.10)(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)))(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)) '@tanstack/router-plugin': - specifier: ^1.158.4 - version: 1.159.5(@tanstack/react-router@1.159.5(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(supports-color@7.2.0)(vite-plugin-solid@2.11.14(solid-js@1.9.10)(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)))(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)) + specifier: ^1.168.35 + version: 1.168.35(@tanstack/react-router@1.170.32(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(esbuild@0.28.1)(rolldown@1.2.4)(rollup@4.60.1)(vite-plugin-solid@2.11.14(solid-js@1.9.10)(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)))(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)) class-variance-authority: specifier: ^0.7.1 version: 0.7.1 @@ -1338,8 +1338,8 @@ importers: specifier: ^1.155.0 version: 1.155.0(@electric-sql/pglite@0.4.3)(aws4fetch@1.0.20)(better-sqlite3@12.11.1)(drizzle-orm@0.45.2(@cloudflare/workers-types@4.20260317.1)(@electric-sql/pglite@0.4.3)(@opentelemetry/api@1.9.1)(@prisma/client@7.9.0(prisma@7.9.0(@types/react@19.2.18)(better-sqlite3@12.11.1)(magicast@0.5.2)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(typescript@5.9.3))(typescript@5.9.3))(better-sqlite3@12.11.1)(bun-types@1.3.14)(mysql2@3.15.3)(postgres@3.4.7)(prisma@7.9.0(@types/react@19.2.18)(better-sqlite3@12.11.1)(magicast@0.5.2)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(typescript@5.9.3)))(mysql2@3.15.3)(rolldown@1.1.5)(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)) '@tanstack/router-plugin': - specifier: ^1.158.4 - version: 1.159.5(@tanstack/react-router@1.159.5(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(supports-color@7.2.0)(vite-plugin-solid@2.11.14(solid-js@1.9.10)(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)))(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)) + specifier: ^1.168.35 + version: 1.168.35(@tanstack/react-router@1.170.32(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(esbuild@0.28.1)(rolldown@1.2.4)(rollup@4.60.1)(vite-plugin-solid@2.11.14(solid-js@1.9.10)(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)))(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)) '@tanstack/solid-ai-devtools': specifier: workspace:* version: link:../../packages/solid-ai-devtools @@ -1347,20 +1347,20 @@ importers: specifier: ^0.7.15 version: 0.7.17(csstype@3.2.3)(solid-js@1.9.10) '@tanstack/solid-router': - specifier: ^1.139.10 - version: 1.141.1(solid-js@1.9.10) + specifier: ^1.170.30 + version: 1.170.30(solid-js@1.9.10) '@tanstack/solid-router-devtools': - specifier: ^1.139.10 - version: 1.141.1(@tanstack/router-core@1.159.4)(@tanstack/solid-router@1.141.1(solid-js@1.9.10))(csstype@3.2.3)(solid-js@1.9.10) + specifier: ^1.167.1 + version: 1.167.1(@tanstack/router-core@1.171.27)(@tanstack/solid-router@1.170.30(solid-js@1.9.10))(csstype@3.2.3)(solid-js@1.9.10) '@tanstack/solid-router-ssr-query': - specifier: ^1.139.10 - version: 1.141.1(@tanstack/query-core@5.90.12)(@tanstack/router-core@1.159.4)(@tanstack/solid-query@5.90.15(solid-js@1.9.10))(@tanstack/solid-router@1.141.1(solid-js@1.9.10))(eslint@9.39.4(jiti@2.7.0))(solid-js@1.9.10)(supports-color@7.2.0)(typescript@5.9.3) + specifier: ^1.167.2 + version: 1.167.2(@tanstack/query-core@5.90.12)(@tanstack/router-core@1.171.27)(@tanstack/solid-query@5.90.15(solid-js@1.9.10))(@tanstack/solid-router@1.170.30(solid-js@1.9.10))(solid-js@1.9.10) '@tanstack/solid-start': - specifier: ^1.139.10 - version: 1.141.1(@tanstack/react-router@1.159.5(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(crossws@0.4.6(srvx@0.11.17))(solid-js@1.9.10)(vite-plugin-solid@2.11.14(solid-js@1.9.10)(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)))(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)) + specifier: ^1.168.47 + version: 1.168.47(@tanstack/react-router@1.170.32(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(crossws@0.4.6(srvx@0.11.17))(esbuild@0.28.1)(rolldown@1.2.4)(rollup@4.60.1)(solid-js@1.9.10)(vite-plugin-solid@2.11.14(solid-js@1.9.10)(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)))(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)) '@tanstack/solid-store': - specifier: ^0.8.0 - version: 0.8.0(solid-js@1.9.10) + specifier: ^0.11.1 + version: 0.11.1(solid-js@1.9.10) '@tanstack/store': specifier: ^0.11.1 version: 0.11.1 @@ -2915,7 +2915,7 @@ importers: devDependencies: '@google/genai': specifier: ^2.10.0 - version: 2.10.0(@modelcontextprotocol/sdk@1.29.0(zod@4.3.6)) + version: 2.10.0(@modelcontextprotocol/sdk@1.29.0(zod@4.5.4)) '@tanstack/ai': specifier: workspace:* version: link:../ai @@ -3206,11 +3206,11 @@ importers: specifier: workspace:* version: link:../../packages/react-ai-devtools '@tanstack/react-router': - specifier: ^1.158.4 - version: 1.159.5(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + specifier: ^1.170.32 + version: 1.170.32(react-dom@19.2.3(react@19.2.3))(react@19.2.3) '@tanstack/react-start': - specifier: ^1.159.0 - version: 1.159.5(crossws@0.4.6(srvx@0.11.17))(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(vite-plugin-solid@2.11.14(solid-js@1.9.10)(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)))(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)) + specifier: ^1.168.49 + version: 1.168.49(crossws@0.4.6(srvx@0.11.17))(esbuild@0.28.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(rolldown@1.2.4)(rollup@4.60.1)(vite-plugin-solid@2.11.14(solid-js@1.9.10)(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)))(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)) arktype: specifier: ^2.1.28 version: 2.2.0 @@ -3330,14 +3330,14 @@ importers: specifier: ^0.9.10 version: 0.9.10(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(csstype@3.2.3)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(solid-js@1.9.10) '@tanstack/react-router': - specifier: ^1.158.4 - version: 1.159.5(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + specifier: ^1.170.32 + version: 1.170.32(react-dom@19.2.3(react@19.2.3))(react@19.2.3) '@tanstack/react-start': - specifier: ^1.159.0 - version: 1.159.5(crossws@0.4.6(srvx@0.11.17))(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(vite-plugin-solid@2.11.14(solid-js@1.9.10)(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)))(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)) + specifier: ^1.168.49 + version: 1.168.49(crossws@0.4.6(srvx@0.11.17))(esbuild@0.28.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(rolldown@1.2.4)(rollup@4.60.1)(vite-plugin-solid@2.11.14(solid-js@1.9.10)(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)))(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)) '@tanstack/start': specifier: ^1.120.20 - version: 1.120.20(340eefabdbae5b0c948fd6f8943277d1) + version: 1.120.20(c688c64811f9265f6bbbab232e625bf6) highlight.js: specifier: ^11.11.1 version: 11.11.1 @@ -4264,10 +4264,6 @@ packages: resolution: {integrity: sha512-JiDShH45zKHWyGe4ZNVRrCjBz8Nh9TMmZG1kh4QTK8hCBTWBi8Da+i7s1fJw7/lYpM4ccepSNfqzZ/QvABBi5g==} engines: {node: '>=6.9.0'} - '@babel/template@7.27.2': - resolution: {integrity: sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw==} - engines: {node: '>=6.9.0'} - '@babel/template@7.29.7': resolution: {integrity: sha512-puq+Gf35oI24FeN11LkoUQFqv9uwNeWpxXZi/Ji3rRIoKAzKnxRaZ+Gkj0vKS9ZCiTESfng1N9LyOyXvo+m+Gg==} engines: {node: '>=6.9.0'} @@ -4284,10 +4280,6 @@ packages: resolution: {integrity: sha512-EhlfNQtZ+NK22w5BM61ciuiq1m58ed33Wr1Xan//ZRTy6hgjnwyCffRYwzsGXdASJSUJ1guZILsErh1eQcl+zw==} engines: {node: '>=6.9.0'} - '@babel/types@7.28.5': - resolution: {integrity: sha512-qQ5m48eI/MFLQ5PxQj4PFaprjyCTLI37ElWMmNs0K8Lk3dVeOdNpB3ks8jc7yM5CDmVC73eMVk/trk3fgmrUpA==} - engines: {node: '>=6.9.0'} - '@babel/types@7.29.0': resolution: {integrity: sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A==} engines: {node: '>=6.9.0'} @@ -6114,9 +6106,6 @@ packages: resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} engines: {node: '>= 8'} - '@nothing-but/utils@0.17.0': - resolution: {integrity: sha512-TuCHcHLOqDL0SnaAxACfuRHBNRgNJcNn9X0GiH5H3YSDBVquCr3qEIG3FOQAuMyZCbu9w8nk2CHhOsn7IvhIwQ==} - '@nx/nx-darwin-arm64@23.1.1': resolution: {integrity: sha512-Rq/RXLX5uIvJQfb6kuUgEirquT5ARaAgQyNaMZVnOPAL5wuxaDvQag8WX/WUCIgbUKZuGkclJwM7Vlnvtn3bdg==} cpu: [arm64] @@ -8839,9 +8828,6 @@ packages: '@rolldown/pluginutils@1.0.0-beta.27': resolution: {integrity: sha512-+d0F4MKMCbeVUJwG96uQ4SgAznZNSq93I3V+9NHA4OpvqG8mRCpGdKmK8l/dl02h2CCDHwW2FqilnTyDcAnqjA==} - '@rolldown/pluginutils@1.0.0-beta.40': - resolution: {integrity: sha512-s3GeJKSQOwBlzdUrj4ISjJj5SfSh+aqn0wjOar4Bx95iV1ETI7F6S/5hLcfAxZ9kXDcyrAkxPlqmd1ZITttf+w==} - '@rolldown/pluginutils@1.0.0-beta.53': resolution: {integrity: sha512-vENRlFU4YbrwVqNDZ7fLvy+JR1CRkyr01jhSiDpE1u6py3OMzQfztQU2jxykW3ALNxO4kSlqIDeYyD0Y9RcQeQ==} @@ -9291,26 +9277,6 @@ packages: resolution: {integrity: sha512-R8Rdn8Hy72KKcebgLiv8jQcQkXoLMOGGv5uI1/k0l+snqkOzQ1R0ChUBCxWMlBsFMekWjq0wRudIweFs7sKT5A==} engines: {node: '>=14.0.0'} - '@solid-devtools/debugger@0.28.1': - resolution: {integrity: sha512-6qIUI6VYkXoRnL8oF5bvh2KgH71qlJ18hNw/mwSyY6v48eb80ZR48/5PDXufUa3q+MBSuYa1uqTMwLewpay9eg==} - peerDependencies: - solid-js: ^1.9.0 - - '@solid-devtools/logger@0.9.11': - resolution: {integrity: sha512-THbiY1iQlieL6vdgJc4FIsLe7V8a57hod/Thm8zdKrTkWL88UPZjkBBfM+mVNGusd4OCnAN20tIFBhNnuT1Dew==} - peerDependencies: - solid-js: ^1.9.0 - - '@solid-devtools/shared@0.20.0': - resolution: {integrity: sha512-o5TACmUOQsxpzpOKCjbQqGk8wL8PMi+frXG9WNu4Lh3PQVUB6hs95Kl/S8xc++zwcMguUKZJn8h5URUiMOca6Q==} - peerDependencies: - solid-js: ^1.9.0 - - '@solid-primitives/bounds@0.1.3': - resolution: {integrity: sha512-UbiyKMdSPmtijcEDnYLQL3zzaejpwWDAJJ4Gt5P0hgVs6A72piov0GyNw7V2SroH7NZFwxlYS22YmOr8A5xc1Q==} - peerDependencies: - solid-js: ^1.6.12 - '@solid-primitives/event-listener@2.4.3': resolution: {integrity: sha512-h4VqkYFv6Gf+L7SQj+Y6puigL/5DIi7x5q07VZET7AWcS+9/G3WfIE9WheniHWJs51OEkRB43w6lDys5YeFceg==} peerDependencies: @@ -9321,11 +9287,6 @@ packages: peerDependencies: solid-js: ^1.6.12 - '@solid-primitives/media@2.3.3': - resolution: {integrity: sha512-hQ4hLOGvfbugQi5Eu1BFWAIJGIAzztq9x0h02xgBGl2l0Jaa3h7tg6bz5tV1NSuNYVGio4rPoa7zVQQLkkx9dA==} - peerDependencies: - solid-js: ^1.6.12 - '@solid-primitives/refs@1.1.2': resolution: {integrity: sha512-K7tf2thy7L+YJjdqXspXOg5xvNEOH8tgEWsp0+1mQk3obHBRD6hEjYZk7p7FlJphSZImS35je3UfmWuD7MhDfg==} peerDependencies: @@ -9341,21 +9302,11 @@ packages: peerDependencies: solid-js: ^1.6.12 - '@solid-primitives/scheduled@1.5.2': - resolution: {integrity: sha512-/j2igE0xyNaHhj6kMfcUQn5rAVSTLbAX+CDEBm25hSNBmNiHLu2lM7Usj2kJJ5j36D67bE8wR1hBNA8hjtvsQA==} - peerDependencies: - solid-js: ^1.6.12 - '@solid-primitives/static-store@0.1.2': resolution: {integrity: sha512-ReK+5O38lJ7fT+L6mUFvUr6igFwHBESZF+2Ug842s7fvlVeBdIVEdTCErygff6w7uR6+jrr7J8jQo+cYrEq4Iw==} peerDependencies: solid-js: ^1.6.12 - '@solid-primitives/styles@0.1.2': - resolution: {integrity: sha512-7iX5K+J5b1PRrbgw3Ki92uvU2LgQ0Kd/QMsrAZxDg5dpUBwMyTijZkA3bbs1ikZsT1oQhS41bTyKbjrXeU0Awg==} - peerDependencies: - solid-js: ^1.6.12 - '@solid-primitives/utils@6.3.2': resolution: {integrity: sha512-hZ/M/qr25QOCcwDPOHtGjxTD8w2mNyVAYvcfgwzBHq2RwNqHNdDNsMZYap20+ruRwW4A3Cdkczyoz0TSxLCAPQ==} peerDependencies: @@ -9647,6 +9598,10 @@ packages: resolution: {integrity: sha512-xyIfof8eHBuub1CkBnbKNKQXeRZC4dClhmzePHVOEel4G7lk/dW+TQ16da7CFdeNLv6u6Owf5VoBQxoo6DFTSA==} engines: {node: '>=12'} + '@tanstack/history@1.162.1': + resolution: {integrity: sha512-DR9t6lfLVdrjgCwpglrR9DR7Ok8/HlXjcOE+goWXF3zyuLUO/ug7vMbSFxTqrQTtbRghJfyhmIZ0S6LhPIy44w==} + engines: {node: '>=20.19'} + '@tanstack/nitro-v2-vite-plugin@1.155.0': resolution: {integrity: sha512-iW9S2c4QxlT+WgKVT+Mw8hzvLqyVSg4UefzX74LX5dfUxbGDahxZItp+07JSD5Ok8ZdTlUHzwLnIsncXh/MNAQ==} engines: {node: '>=22.12'} @@ -9685,24 +9640,24 @@ packages: peerDependencies: react: ^18 || ^19 - '@tanstack/react-router-devtools@1.159.5': - resolution: {integrity: sha512-IIyomu+ypWTxyoYT32mxamVmdTs7ZCGcTbdj7HVvtD3xp1lvo/bwRXj9oERENmb+OAPOaWF2doRYC/pmKjK5vg==} - engines: {node: '>=12'} + '@tanstack/react-router-devtools@1.167.1': + resolution: {integrity: sha512-pjfGrmjj4d7naEPM7oshqFfwBoxDPNo/UxltlHH5ePbHsJ+plBhd+JaAewm1ueYOjZ0js9hckjWWDYXpCrSfKw==} + engines: {node: '>=20.19'} peerDependencies: - '@tanstack/react-router': ^1.159.5 - '@tanstack/router-core': ^1.159.4 + '@tanstack/react-router': ^1.170.19 + '@tanstack/router-core': ^1.171.16 react: '>=18.0.0 || >=19.0.0' react-dom: '>=18.0.0 || >=19.0.0' peerDependenciesMeta: '@tanstack/router-core': optional: true - '@tanstack/react-router-ssr-query@1.159.5': - resolution: {integrity: sha512-r/Um9DASjmaTdiyXA3cpooGLrSD1BlcXUNsRz4zAlvD38m0gIFvaykOM2Naztqm9H+2CJkocRZp2/kR69Xcmyg==} - engines: {node: '>=12'} + '@tanstack/react-router-ssr-query@1.167.2': + resolution: {integrity: sha512-yRvy0VJ00R8huPuquk+qyYQGMpYRc/G33mc6/yZ4f7LaBZz9h/VbACjmLzhm/+6u5WSmUt6ouJJZnI1/5Npfag==} + engines: {node: '>=20.19'} peerDependencies: - '@tanstack/query-core': '>=5.90.0' - '@tanstack/react-query': '>=5.90.0' + '@tanstack/query-core': '>=5.102.0' + '@tanstack/react-query': '>=5.102.0' '@tanstack/react-router': '>=1.127.0' react: '>=18.0.0 || >=19.0.0' react-dom: '>=18.0.0 || >=19.0.0' @@ -9714,9 +9669,9 @@ packages: react: '>=18.0.0 || >=19.0.0' react-dom: '>=18.0.0 || >=19.0.0' - '@tanstack/react-router@1.159.5': - resolution: {integrity: sha512-rVb0MtKzP5c0BkWIoFgWBiRAJHYSU3bhsEHbT0cRdRLmlJiw21Awb6VEjgYq3hJiEhowcKKm6J8AdRD/8oZ5dQ==} - engines: {node: '>=12'} + '@tanstack/react-router@1.170.32': + resolution: {integrity: sha512-SIpxvaTKco100a5ZR3ePmArbhtm3XOx+w1dpGYY9gxHDta4iXSKDdQuhLonwJbIMkVJsU1rwXf0UDHMrF/1snw==} + engines: {node: '>=20.19'} peerDependencies: react: '>=18.0.0 || >=19.0.0' react-dom: '>=18.0.0 || >=19.0.0' @@ -9728,8 +9683,8 @@ packages: react: '>=18.0.0 || >=19.0.0' react-dom: '>=18.0.0 || >=19.0.0' - '@tanstack/react-start-client@1.159.5': - resolution: {integrity: sha512-Qynx7XWHI1rhVpSUx6P40zazcQVJRhl2fnAcSH0I6vaAxSuZm8lvI37YacXPRu8flvI/ZGlF095arxiyps+A0w==} + '@tanstack/react-start-client@1.168.30': + resolution: {integrity: sha512-qsZuykUl1EF0/rc1bin1RtjFzz07YMOTBzhOstSDzbOVm/WKf1QKFTN+qAZi74xlbXSWNuT2MiFRyg4RKwj8iw==} engines: {node: '>=22.12.0'} peerDependencies: react: '>=18.0.0 || >=19.0.0' @@ -9746,6 +9701,23 @@ packages: resolution: {integrity: sha512-z+4YL6shTtsHjk32yaIemQwgkx6FcqwPBYfeNt7Co2eOpWrvsoo/Fe9869/oIY2sPyhiWDs1rDb3e0qnAy8Cag==} engines: {node: '>=12'} + '@tanstack/react-start-rsc@0.1.48': + resolution: {integrity: sha512-UglRdTMuF3c4dvzL/gh4dMVbMWHsPy8ZgTQdT2qpTlyt1b/3m+R40tBFdsfTgw76VTXivW+qV/ih0PN9000XTw==} + engines: {node: '>=22.12.0'} + peerDependencies: + '@rspack/core': '>=2.0.0-0' + '@vitejs/plugin-rsc': '>=0.5.30' + react: '>=18.0.0 || >=19.0.0' + react-dom: '>=18.0.0 || >=19.0.0' + react-server-dom-rspack: '>=0.0.2' + peerDependenciesMeta: + '@rspack/core': + optional: true + '@vitejs/plugin-rsc': + optional: true + react-server-dom-rspack: + optional: true + '@tanstack/react-start-server@1.141.1': resolution: {integrity: sha512-GsZ7De5CCDkKcrimvwJiYJHMFGw7LQRu8IuLvqyzYgQvJPcbkfY5UIQd2IZfgRNFegzb2aYzkAXwv5lxfdu1VQ==} engines: {node: '>=22.12.0'} @@ -9753,20 +9725,35 @@ packages: react: '>=18.0.0 || >=19.0.0' react-dom: '>=18.0.0 || >=19.0.0' - '@tanstack/react-start-server@1.159.5': - resolution: {integrity: sha512-X4/SunwDTEbGkYTfM0gR+79amfk6phAM+2+NlC2s7TX2cD51xE8bUz2a//RxfOh9xg8f0f2CRIO34xTEDHGTfQ==} + '@tanstack/react-start-server@1.167.37': + resolution: {integrity: sha512-cODHpFU8vIm7AdHii9W3NEuwyruNmT5wLDZjRsJLT9Jp+7FACnfJrRbvxnp1ldSv/9mxcHKi/OgwbdHQeMZcAQ==} engines: {node: '>=22.12.0'} peerDependencies: react: '>=18.0.0 || >=19.0.0' react-dom: '>=18.0.0 || >=19.0.0' - '@tanstack/react-start@1.159.5': - resolution: {integrity: sha512-vfnF7eYswAK54ru6Ay08nb0TXVzTBaVRsbbRW7hx2M0chgwtSx+YScYzoixqkccRARQBN8a/CeVq7vNFW8525w==} + '@tanstack/react-start@1.168.49': + resolution: {integrity: sha512-iQb1ZoEHqvZMGLR4G7v3tTtgL06yv/bwxvGP3waVHxVn7bRpyopM44YbOluaGkcJzc13ZTvdLKWYNAN3bxMX/Q==} engines: {node: '>=22.12.0'} peerDependencies: + '@rsbuild/core': ^2.0.0 + '@vitejs/plugin-rsc': '*' react: '>=18.0.0 || >=19.0.0' react-dom: '>=18.0.0 || >=19.0.0' vite: '>=7.0.0' + peerDependenciesMeta: + '@rsbuild/core': + optional: true + '@vitejs/plugin-rsc': + optional: true + vite: + optional: true + + '@tanstack/react-store@0.11.1': + resolution: {integrity: sha512-HaIGKI3YLmjBYIvy5DFDY23oNaYZIsTZfngey07Uh5iLVJgM3bIGCnZeOFOqzjFld9JHWcaHJnasD/bKoGKwJQ==} + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 '@tanstack/react-store@0.8.0': resolution: {integrity: sha512-1vG9beLIuB7q69skxK9r5xiLN3ztzIPfSQSs0GfeqWGO2tGIyInZx0x1COhpx97RKaONSoAb8C3dxacWksm1ow==} @@ -9774,6 +9761,12 @@ packages: react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + '@tanstack/react-store@0.9.3': + resolution: {integrity: sha512-y2iHd/N9OkoQbFJLUX1T9vbc2O9tjH0pQRgTcx1/Nz4IlwLvkgpuglXUx+mXt0g5ZDFrEeDnONPqkbfxXJKwRg==} + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + '@tanstack/router-core@1.131.50': resolution: {integrity: sha512-eojd4JZ5ziUhGEmXZ4CaVX5mQdiTMiz56Sp8ZQ6r7deb55Q+5G4JQDkeuXpI7HMAvzr+4qlsFeLaDRXXjXyOqQ==} engines: {node: '>=12'} @@ -9786,22 +9779,15 @@ packages: resolution: {integrity: sha512-MFzPH39ijNO83qJN3pe7x4iAlhZyqgao3sJIzv3SJ4Pnk12xMnzuDzIAQT/1WV6JolPQEcw0Wr4L5agF8yxoeg==} engines: {node: '>=12'} - '@tanstack/router-devtools-core@1.141.1': - resolution: {integrity: sha512-wD9yRvOk6FI+thiNBplhkGutPIPBlXvWu9ttU/obdFY5oXQj9WYgNS+IO9BEe8Pz5rNEu8zE/oLn4RUGIVdtnw==} - engines: {node: '>=12'} - peerDependencies: - '@tanstack/router-core': ^1.141.1 - csstype: ^3.0.10 - solid-js: '>=1.9.5' - peerDependenciesMeta: - csstype: - optional: true + '@tanstack/router-core@1.171.27': + resolution: {integrity: sha512-wDwSLvoLwIaNcnx9UNcN9Mb7Y8QwCYq1U1RQZwyN186gnkIoIYI2SOxy8VqH1vFigbkHkk4FmwMAQlghPgDK2g==} + engines: {node: '>=20.19'} - '@tanstack/router-devtools-core@1.159.4': - resolution: {integrity: sha512-qMUeIv+6n1mZOcO2raCIbdOeDeMpJEmgm6oMs/nWEG61lYrzJYaCcpBTviAX0nRhSiQSUCX9cHiosUEA0e2HAw==} - engines: {node: '>=12'} + '@tanstack/router-devtools-core@1.168.1': + resolution: {integrity: sha512-qr4voa4cpSMwQvS3867xkU3AB3MtJbTuovKIy+btjJ/Faju6er9w0nDylmD+005Mk/3YKw9/iueZJl2JAB7JOA==} + engines: {node: '>=20.19'} peerDependencies: - '@tanstack/router-core': ^1.159.4 + '@tanstack/router-core': ^1.171.16 csstype: ^3.0.10 peerDependenciesMeta: csstype: @@ -9811,14 +9797,14 @@ packages: resolution: {integrity: sha512-zlMBw5l88GIg3v+378JsfDYq3ejEaJmD3P1R+m0yEPxh0N//Id1FjKNSS7yJbejlK2WGVm9DUG46iBdTDMQM+Q==} engines: {node: '>=12'} - '@tanstack/router-generator@1.141.1': - resolution: {integrity: sha512-21RbVAoIDn7s/n/PKMN6U60d5hCeVADrBH/uN6B/poMT4MVYtJXqISVzkc2RAboVRw6eRdYFeF+YlwA3nF6y3Q==} - engines: {node: '>=12'} - '@tanstack/router-generator@1.159.4': resolution: {integrity: sha512-O8tICQoSuvK6vs3mvBdI3zVLFmYfj/AYDCX0a5msSADP/2S0GsgDDTB5ah731TqYCtjeNriaWz9iqst38cjF/Q==} engines: {node: '>=12'} + '@tanstack/router-generator@1.167.33': + resolution: {integrity: sha512-Z3lCWIPuRUMPmuI8Mm48x/s49TxmHOaFVZ52j1W1QKYrsFHyT6U/h9bqfHJDxfQ8kz7y9q+W1YPKZ15Ee7yuCA==} + engines: {node: '>=20.19'} + '@tanstack/router-plugin@1.131.50': resolution: {integrity: sha512-gdEBPGzx7llQNRnaqfPJ1iaPS3oqB8SlvKRG5l7Fxp4q4yINgkeowFYSKEhPOc9bjoNhGrIHOlvPTPXEzAQXzQ==} engines: {node: '>=12'} @@ -9840,35 +9826,14 @@ packages: webpack: optional: true - '@tanstack/router-plugin@1.141.1': - resolution: {integrity: sha512-SoNXm8QK8cqX1Q4y1AfLU0tZLOt4mB4wkdpBI/Mi3ZEezF8tIrmaenyJ3987cjT9jedTy3VDBab1wN0g8MoOXg==} - engines: {node: '>=12'} - peerDependencies: - '@rsbuild/core': '>=1.0.2' - '@tanstack/react-router': ^1.141.1 - vite: '>=5.0.0 || >=6.0.0 || >=7.0.0' - vite-plugin-solid: ^2.11.10 - webpack: '>=5.92.0' - peerDependenciesMeta: - '@rsbuild/core': - optional: true - '@tanstack/react-router': - optional: true - vite: - optional: true - vite-plugin-solid: - optional: true - webpack: - optional: true - - '@tanstack/router-plugin@1.159.5': - resolution: {integrity: sha512-i2LR3WRaBOAZ1Uab5QBG9UxZIRJ3V56JVu890NysbuX15rgzRiL5yLAbfenOHdhaHy2+4joX35VICAHuVWy7Og==} - engines: {node: '>=12'} + '@tanstack/router-plugin@1.168.35': + resolution: {integrity: sha512-foDAZKFqHXae+oFbIgcsSvy2QCVRn7XdS3nhwcRvD+ed6JrKPUP/1lQMsZLJqWycgR1vkZF7gs955KGa0NZQ0w==} + engines: {node: '>=20.19'} peerDependencies: - '@rsbuild/core': '>=1.0.2' - '@tanstack/react-router': ^1.159.5 - vite: '>=5.0.0 || >=6.0.0 || >=7.0.0' - vite-plugin-solid: ^2.11.10 + '@rsbuild/core': '>=1.0.2 || ^2.0.0' + '@tanstack/react-router': ^1.170.32 + vite: '>=5.0.0 || >=6.0.0 || >=7.0.0 || >=8.0.0' + vite-plugin-solid: ^2.11.10 || ^3.0.0-0 webpack: '>=5.92.0' peerDependenciesMeta: '@rsbuild/core': @@ -9882,18 +9847,11 @@ packages: webpack: optional: true - '@tanstack/router-ssr-query-core@1.141.1': - resolution: {integrity: sha512-bkRXUhktifxBewnnphH59E0sGcsUI1NmNqxzCAmXIb93xYgafhjUGGYwfK6FqFBOmCB5isr32exGO3+UMHJr/A==} - engines: {node: '>=12'} - peerDependencies: - '@tanstack/query-core': '>=5.90.0' - '@tanstack/router-core': '>=1.127.0' - - '@tanstack/router-ssr-query-core@1.159.4': - resolution: {integrity: sha512-zqgJaf8iTk2ugrJqvU+b8NnFf3MKcnFaurtlp5tP38lNHQGW4En9UaOBOou/6zYZMlKQBcvqxSGJiwaLIyTK2g==} - engines: {node: '>=12'} + '@tanstack/router-ssr-query-core@1.169.2': + resolution: {integrity: sha512-7pO65Aiq/1+aS3Mb6vSGtIjzQ/YGv9JTfBbn2EYlHcZnJ4s4ZGCeTPI847geB1RfJqVhfwxM8bZgGM51mYkolg==} + engines: {node: '>=20.19'} peerDependencies: - '@tanstack/query-core': '>=5.90.0' + '@tanstack/query-core': '>=5.102.0' '@tanstack/router-core': '>=1.127.0' '@tanstack/router-utils@1.131.2': @@ -9908,6 +9866,10 @@ packages: resolution: {integrity: sha512-qZ76eaLKU6Ae9iI/mc5zizBX149DXXZkBVVO3/QRIll79uKLJZHQlMKR++2ba7JsciBWz1pgpIBcCJPE9S0LVg==} engines: {node: '>=12'} + '@tanstack/router-utils@1.162.2': + resolution: {integrity: sha512-hTWqJtqIFFdvuCl8WXNyrodp2L9zo2G37xKRrcVmVRWpAB2h+U1LuRAfS4tsFTiWOIoE/B+WDVFB8JpoEdw6jQ==} + engines: {node: '>=20.19'} + '@tanstack/server-functions-plugin@1.131.2': resolution: {integrity: sha512-hWsaSgEZAVyzHg8+IcJWCEtfI9ZSlNELErfLiGHG9XCHEXMegFWsrESsKHlASzJqef9RsuOLDl+1IMPIskwdDw==} engines: {node: '>=12'} @@ -9927,53 +9889,59 @@ packages: peerDependencies: solid-js: ^1.6.0 - '@tanstack/solid-router-devtools@1.141.1': - resolution: {integrity: sha512-ezm8V1UR47kY/xquIobascexHkbWOcH1YXc8BRvYDKV33NEdeUhMVUqkZmwuojlRYXhF7LEfj2aSwZr0uBfH8A==} - engines: {node: '>=12'} + '@tanstack/solid-router-devtools@1.167.1': + resolution: {integrity: sha512-GZiRbHx7E1vbuv1zGjPl1EmCKbwKZKoCU0TjycBjU6SW0rMt/24SON0MbtMbPlLs3XE28jFi7C5odwE2hryh/Q==} + engines: {node: '>=20.19'} peerDependencies: - '@tanstack/router-core': ^1.141.1 - '@tanstack/solid-router': ^1.141.1 + '@tanstack/router-core': ^1.171.16 + '@tanstack/solid-router': ^1.170.19 solid-js: ^1.9.10 peerDependenciesMeta: '@tanstack/router-core': optional: true - '@tanstack/solid-router-ssr-query@1.141.1': - resolution: {integrity: sha512-jM2RKblxWbrMV2nmZ+L+Y2HvfBZ448tZHXYBP/NrQa2YAHVXCZfVE5ojjB5vyDZHc7ueFAF8+yIvMGnIQQE99g==} - engines: {node: '>=12'} + '@tanstack/solid-router-ssr-query@1.167.2': + resolution: {integrity: sha512-4epfTG9kLKnD/azHJAU5pKTLD258X93OgKXCF342Caiq2y3Y8QfdTPl11efTA+TAcZlj4CjYT2Y/7WvBR19FAA==} + engines: {node: '>=20.19'} peerDependencies: - '@tanstack/query-core': '>=5.90.0' - '@tanstack/solid-query': '>=5.90.0' + '@tanstack/query-core': '>=5.102.0' + '@tanstack/solid-query': '>=5.102.0' '@tanstack/solid-router': '>=1.127.0' solid-js: ^1.9.10 - '@tanstack/solid-router@1.141.1': - resolution: {integrity: sha512-xcWkYdwvTXzQwLd4gI0efq7dUzXlcTyent/UDrGf1K5dDBqlFSAj9c11vNwP0+YvCaPt4U1r8czyMD1Qr3aNGA==} - engines: {node: '>=12'} + '@tanstack/solid-router@1.170.30': + resolution: {integrity: sha512-FozWeln6hx6o2T45gFFdkGQJxvq/LN0EUlzx7+eENy9HJH/thEBSb89KTkQahULzs9bsMOufzeXJJVgB6H9/wA==} + engines: {node: '>=20.19'} peerDependencies: solid-js: ^1.9.10 - '@tanstack/solid-start-client@1.141.1': - resolution: {integrity: sha512-NGc70Jj9DoWFieFX9iQG70fmuTvX7nfTUG5vlboxBzvTuPrIdyeddrQVnBX/kXUdFzLGzez7QlxqyOrm3zouuQ==} + '@tanstack/solid-start-client@1.168.29': + resolution: {integrity: sha512-+F3Z/J1SVxPj2Hs53Wvos2DhIe7cGvlHpwZD9x0+aIWofIlkRSnrGm2wehWZzun1tzgZNnK2L2thkQlXVtuVaw==} engines: {node: '>=22.12.0'} peerDependencies: solid-js: '>=1.0.0' - '@tanstack/solid-start-server@1.141.1': - resolution: {integrity: sha512-vIuw74+6cgBmh1zAqc27dKHd5rU2K4V6nHt+u7vBKUUu/9QIF7PoQD0fj2dWnrjnz7EJKb1W7Gr9rAtOdglgGw==} + '@tanstack/solid-start-server@1.167.36': + resolution: {integrity: sha512-7WMqLxe1Yr+9Q+Ze2dsYrPnousiPmA5LndJtg1MnaIRNecL1NInd5jsiIwNB42qOWTwcGr8aD8LnHH4dcVh/wA==} engines: {node: '>=22.12.0'} peerDependencies: solid-js: ^1.0.0 - '@tanstack/solid-start@1.141.1': - resolution: {integrity: sha512-b7B7UUPn3GANvnvTusiryTr+CUEs+lMMFRRiDiBZXx+Yb1cqtp/UYilEDHdqnx2xUoAhR0FBd4kRcieCV69DVg==} + '@tanstack/solid-start@1.168.47': + resolution: {integrity: sha512-yqXrj5Q1wGh/9Gb/wGp117AavC48tFk29LP/2oGHBJKq4ZATYes8s3yPBRSWlSkqQG9N2yQzjmF+sutXZSZVzw==} engines: {node: '>=22.12.0'} peerDependencies: + '@rsbuild/core': ^2.0.0 solid-js: '>=1.0.0' vite: '>=7.0.0' + peerDependenciesMeta: + '@rsbuild/core': + optional: true + vite: + optional: true - '@tanstack/solid-store@0.8.0': - resolution: {integrity: sha512-JwqTedbxyOGw7mfmdGkB0RGgefRCw/tNauc8tlMcaS1mV5wTFT8c1KIB3LgttuHaanMJEBeqQJ7bc/R0WTP1fA==} + '@tanstack/solid-store@0.11.1': + resolution: {integrity: sha512-wzJsiqqLHyQacqbYPT8dKNfhR00NNu743vGeWz2lEpOyE/R+6AYIfFLhXsCIT/Kb+KKiT1KDkB2/35DhLEGx8g==} peerDependencies: solid-js: ^1.6.0 @@ -9993,6 +9961,10 @@ packages: resolution: {integrity: sha512-9j2i1PRTIGcYAD+509znve0ngK81ZUfbX4XCpoNFMaUUpRHoEPPK5I9+PzLFvL9sNOto67x+WULCUggzX+lEKQ==} engines: {node: '>=22.12.0'} + '@tanstack/start-client-core@1.170.27': + resolution: {integrity: sha512-Ro6ZSM0NgYKDMxM0e8qyU4mBfnld2Zb74BA/9f4i35C0Y3IAA8Zxs/DIPfOo9VRYWp5c5n5Q8dRBn2qn0vtPhQ==} + engines: {node: '>=22.12.0'} + '@tanstack/start-config@1.120.20': resolution: {integrity: sha512-oH/mfTSHV8Qbil74tWicPLW6+kKmT3esXCnDzvrkhi3+N8ZuVUDr01Qpil0Wxf9lLPfM5L6VX03nF4hSU8vljg==} engines: {node: '>=12'} @@ -10005,23 +9977,27 @@ packages: resolution: {integrity: sha512-D69B78L6pcFN5X5PHaydv7CScQcKLzJeEYqs7jpuyyqGQHSUIZUjS955j+Sir8cHhuDIovCe2LmsYHeZfWf3dQ==} engines: {node: '>=22.12.0'} + '@tanstack/start-fn-stubs@1.162.0': + resolution: {integrity: sha512-QWfUZ3Yo923tdQn38LyKMU8rcTw69zc+T4dAvgTWV4O56SqFRsGfS0lSWIMhJRwXIx/bvdi7nTUBDdZtTHtpTQ==} + engines: {node: '>=22.12.0'} + '@tanstack/start-plugin-core@1.131.50': resolution: {integrity: sha512-eFvMA0chqLtHbq+8ojp1fXN7AQjhmeoOpQaZaU1d51wb7ugetrn0k3OuHblxtE/O0L4HEC9s4X5zmFJt0vLh0w==} engines: {node: '>=12'} peerDependencies: vite: '>=6.0.0' - '@tanstack/start-plugin-core@1.141.1': - resolution: {integrity: sha512-jXfgKeM4XX7aoP7WF/cJZH52N0ewIYRdP028ItXaSwUMcDyBO+PPTNbSEqTu3zbzLsmTOOyuJEpIrVA0/lmbjA==} - engines: {node: '>=22.12.0'} - peerDependencies: - vite: '>=7.0.0' - - '@tanstack/start-plugin-core@1.159.5': - resolution: {integrity: sha512-QGiBw+L3qu2sUY0Tg9KovxjDSi5kevoANEcq9RLX7iIhLkTjrILN6hnAlXZUzqk5Egaf0aN2yWhwI4HWucMprw==} + '@tanstack/start-plugin-core@1.171.39': + resolution: {integrity: sha512-Zyj6G4MDFLXcHYhPavhewCBo8dsxi3qvPk31zl/QtTzYzOY9rJHDDBGarKsJq20ziChmkGn/sttYqb4vGCxJDA==} engines: {node: '>=22.12.0'} peerDependencies: + '@rsbuild/core': ^2.0.0 vite: '>=7.0.0' + peerDependenciesMeta: + '@rsbuild/core': + optional: true + vite: + optional: true '@tanstack/start-server-core@1.131.50': resolution: {integrity: sha512-3SWwwhW2GKMhPSaqWRal6Jj1Y9ObfdWEXKFQid1LBuk5xk/Es4bmW68o++MbVgs/GxUxyeZ3TRVqb0c7RG1sog==} @@ -10035,6 +10011,10 @@ packages: resolution: {integrity: sha512-sGpr+iil+pcY3Gglvbnxaj7fCEPTQJv4oF7YA24SVv8YvayLXtBXpF26miJLA+KR9P31dQdPYe1gTjv5zRyvHg==} engines: {node: '>=22.12.0'} + '@tanstack/start-server-core@1.169.31': + resolution: {integrity: sha512-56w8l+Fao01YCrmv0hzNxL3b3FRmqLRGdE11izZNQsW+1CcSYuehAM5khWKABuI1DI/UIBLGV7BwL4Dlg0eHCw==} + engines: {node: '>=22.12.0'} + '@tanstack/start-server-functions-client@1.131.50': resolution: {integrity: sha512-4aM17fFdVAFH6uLPswKJxzrhhIjcCwKqzfTcgY3OnhUKnaZBTQwJA+nUHQCI6IWvEvrcrNVtFTtv13TkDk3YMw==} engines: {node: '>=12'} @@ -10067,6 +10047,10 @@ packages: resolution: {integrity: sha512-iGkmuCIq3PLI4GKOGwgUNHQKZ13YV8LGq62o2hVnyXE64Jm2SP7c5z6D1ndydpk4JwdRzQKlcOFT/1agvS6Nsg==} engines: {node: '>=22.12.0'} + '@tanstack/start-storage-context@1.167.29': + resolution: {integrity: sha512-8qfprC5774XMRDQlMogkfiGpFLiBf0xDG4bMFUbfkSzpCAQwpLbgGY4Zwft22O9rKYq2vUXusKAdVjvJTUEquQ==} + engines: {node: '>=22.12.0'} + '@tanstack/start@1.120.20': resolution: {integrity: sha512-fQO+O/5xJpli5KlV6pwDz6DtpbqO/0atdVSyVnkemzk0Mej9azm4HXtw+cKkIPtsSplWs4B1EbMtgGMb9ADhSA==} engines: {node: '>=12'} @@ -10080,6 +10064,9 @@ packages: '@tanstack/store@0.8.0': resolution: {integrity: sha512-Om+BO0YfMZe//X2z0uLF2j+75nQga6TpTJgLJQBiq85aOyZNIhkCgleNcud2KQg4k4v9Y9l+Uhru3qWMPGTOzQ==} + '@tanstack/store@0.9.3': + resolution: {integrity: sha512-8reSzl/qGWGGVKhBoxXPMWzATSbZLZFWhwBAFO9NAyp0TxzfBP0mIrGb8CP8KrQTmvzXlR/vFPPUrHTLBGyFyw==} + '@tanstack/typedoc-config@0.3.4': resolution: {integrity: sha512-WXJavpiNqumNwdBQTM3wBqbHaULgoZ3cIri7xJinKqX/mOGXgc6ZghfAardD2PydP8tOcPf+xhrd1Qk/am9DMg==} engines: {node: '>=18'} @@ -10088,14 +10075,14 @@ packages: resolution: {integrity: sha512-VEEOxc4mvyu67O+Bl0APtYjwcNRcL9it9B4HKbNgcBTIOEalhk+ufBl4kiqc8WP1sx1+NAaiS+3CcJBhrqaSRg==} engines: {node: '>=12'} - '@tanstack/virtual-file-routes@1.141.0': - resolution: {integrity: sha512-CJrWtr6L9TVzEImm9S7dQINx+xJcYP/aDkIi6gnaWtIgbZs1pnzsE0yJc2noqXZ+yAOqLx3TBGpBEs9tS0P9/A==} - engines: {node: '>=12'} - '@tanstack/virtual-file-routes@1.154.7': resolution: {integrity: sha512-cHHDnewHozgjpI+MIVp9tcib6lYEQK5MyUr0ChHpHFGBl8Xei55rohFK0I0ve/GKoHeioaK42Smd8OixPp6CTg==} engines: {node: '>=12'} + '@tanstack/virtual-file-routes@1.162.0': + resolution: {integrity: sha512-uhOeFyxLcU41HzvrxsGpiWdcMbScY1EDgbZ5K7DVRMYInbLYWAC0EA/kx9wXAoSM8q82bUG2hRl8+EAjE6XAbA==} + engines: {node: '>=20.19'} + '@tanstack/vite-config@0.6.0': resolution: {integrity: sha512-TtcetFc7aBm9BBclG3/8pM8ZlyzS8yNwi+eScN4gqsB9xnxyOPCbuvvkk//ybfQj8MVEZavQ03EOQxmOJdW8Rw==} engines: {node: '>=18'} @@ -10379,32 +10366,16 @@ packages: eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 typescript: '>=4.8.4 <6.1.0' - '@typescript-eslint/project-service@8.49.0': - resolution: {integrity: sha512-/wJN0/DKkmRUMXjZUXYZpD1NEQzQAAn9QWfGwo+Ai8gnzqH7tvqS7oNVdTjKqOcPyVIdZdyCMoqN66Ia789e7g==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - peerDependencies: - typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/project-service@8.59.4': resolution: {integrity: sha512-Ly00Vu4oAacfDeHp2Zg85ioNG6l8HG+tN1D7J+xTHSxu9y0awYKJ2zH1rFBn8ZSfuGK+7FxK3Cgl3uAz0aZZLg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: typescript: '>=4.8.4 <6.1.0' - '@typescript-eslint/scope-manager@8.49.0': - resolution: {integrity: sha512-npgS3zi+/30KSOkXNs0LQXtsg9ekZ8OISAOLGWA/ZOEn0ZH74Ginfl7foziV8DT+D98WfQ5Kopwqb/PZOaIJGg==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@typescript-eslint/scope-manager@8.59.4': resolution: {integrity: sha512-mUeR/3H1WrTAddJrwut8OoPjfauaztMQmRwV5fQTUyNVJCLiUXXe4lGEyYIL2oFDpP7UtgbGJXCt72wT0z2S3Q==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@typescript-eslint/tsconfig-utils@8.49.0': - resolution: {integrity: sha512-8prixNi1/6nawsRYxet4YOhnbW+W9FK/bQPxsGB1D3ZrDzbJ5FXw5XmzxZv82X3B+ZccuSxo/X8q9nQ+mFecWA==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - peerDependencies: - typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/tsconfig-utils@8.59.4': resolution: {integrity: sha512-DLCpnKgD4alVxTBSKulK+gU1KCqOgUXfDRDXh2mZgzokQKa/70ax93I2uVO3m/LLvIAtWZIFoiifudmIqAxpMA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} @@ -10418,33 +10389,16 @@ packages: eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 typescript: '>=4.8.4 <6.1.0' - '@typescript-eslint/types@8.49.0': - resolution: {integrity: sha512-e9k/fneezorUo6WShlQpMxXh8/8wfyc+biu6tnAqA81oWrEic0k21RHzP9uqqpyBBeBKu4T+Bsjy9/b8u7obXQ==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@typescript-eslint/types@8.59.4': resolution: {integrity: sha512-F1o7WJcCq+bc8dwcO/YsSEOudAH8RDtaOhM6wcAQhcUsFhnWQl81JKy48q1hoxAU0qrzM89+31GYh1515Zde3Q==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@typescript-eslint/typescript-estree@8.49.0': - resolution: {integrity: sha512-jrLdRuAbPfPIdYNppHJ/D0wN+wwNfJ32YTAm10eJVsFmrVpXQnDWBn8niCSMlWjvml8jsce5E/O+86IQtTbJWA==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - peerDependencies: - typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/typescript-estree@8.59.4': resolution: {integrity: sha512-F+RuOmcDXo4+TPdfd/TCLS3m2nw8gE9XXyZLrA3JBfaA5tz9TtdkyD3YJFmPxulyc2cKbEok/CvFE3MgSLWnag==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: typescript: '>=4.8.4 <6.1.0' - '@typescript-eslint/utils@8.49.0': - resolution: {integrity: sha512-N3W7rJw7Rw+z1tRsHZbK395TWSYvufBXumYtEGzypgMUthlg0/hmCImeA8hgO2d2G4pd7ftpxxul2J8OdtdaFA==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - peerDependencies: - eslint: ^8.57.0 || ^9.0.0 - typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/utils@8.59.4': resolution: {integrity: sha512-cYXeNAUsG4lJo5dbc1FcKm+JwIWrj1/UpTORsC6tGMjEZ81DYcvIr9/ueikhMa/Y/gDQYGp+YX9/xQrXje5BJw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} @@ -10452,10 +10406,6 @@ packages: eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 typescript: '>=4.8.4 <6.1.0' - '@typescript-eslint/visitor-keys@8.49.0': - resolution: {integrity: sha512-LlKaciDe3GmZFphXIc79THF/YYBugZ7FS1pO581E/edlVVNbZKDy93evqmrfQ9/Y4uN0vVhX4iuchq26mK/iiA==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@typescript-eslint/visitor-keys@8.59.4': resolution: {integrity: sha512-U3gxVaDVnuZKhSspW/MzMxE1kq7zOdc072FcSNoqA1I9p8HyKbBFfEHoWckBAMgNMph4MamwS5iTVzFmrnt8TQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} @@ -11653,6 +11603,9 @@ packages: cookie-es@2.0.1: resolution: {integrity: sha512-aVf4A4hI2w70LnF7GG+7xDQUkliwiXWXFvTjkip4+b64ygDQ2sJPRSKFDHbxn8o0xu9QzPkMuuiWIXyFSE2slA==} + cookie-es@3.1.1: + resolution: {integrity: sha512-UaXxwISYJPTr9hwQxMFYZ7kNhSXboMXP+Z3TRX6f1/NyaGPfuNUZOWP1pUEb75B2HjfklIYLVRfWiFZJyC6Npg==} + cookie-signature@1.2.2: resolution: {integrity: sha512-D76uU73ulSXrD1UXF4KE2TMxVVwhsnCgfAyTg9k8P6KGZjlXKrOLe4dJQKI3Bxi5wjesZoFXJWElNWBjPZMbhg==} engines: {node: '>=6.6.0'} @@ -12386,13 +12339,6 @@ packages: engines: {node: '>=6.0'} hasBin: true - eslint-plugin-solid@0.14.5: - resolution: {integrity: sha512-nfuYK09ah5aJG/oEN6P1qziy1zLgW4PDWe75VNPi4CEFYk1x2AEqwFeQfEPR7gNn0F2jOeqKhx2E+5oNCOBYWQ==} - engines: {node: '>=18.0.0'} - peerDependencies: - eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 || ^9.0.0 - typescript: '>=4.8.4' - eslint-plugin-unused-imports@4.3.0: resolution: {integrity: sha512-ZFBmXMGBYfHttdRtOG9nFFpmUvMtbHSjsKrS20vdWdbfiVYsO3yA2SGYy9i9XmZJDfMGBflZGBCm70SEnFQtOA==} peerDependencies: @@ -13044,6 +12990,16 @@ packages: crossws: optional: true + h3@2.0.1-rc.20: + resolution: {integrity: sha512-28ljodXuUp0fZovdiSRq4G9OgrxCztrJe5VdYzXAB7ueRvI7pIUqLU14Xi3XqdYJ/khXjfpUOOD2EQa6CmBgsg==} + engines: {node: '>=20.11.1'} + hasBin: true + peerDependencies: + crossws: ^0.4.1 + peerDependenciesMeta: + crossws: + optional: true + h3@2.0.1-rc.22: resolution: {integrity: sha512-Esv0DMIuPkCTSWCA0vO73vcTqwzH1wjSrAO1TXNu/K3up1sZHa9EKMapbmxCDYBeymC3fVTk4qxp7ogQWQ+KgA==} engines: {node: '>=20.11.1'} @@ -13169,10 +13125,6 @@ packages: html-link-extractor@1.0.5: resolution: {integrity: sha512-ADd49pudM157uWHwHQPUSX4ssMsvR/yHIswOR5CUfBdK9g9ZYGMhVSE6KZVHJ6kCkR0gH4htsfzU6zECDNVwyw==} - html-tags@3.3.1: - resolution: {integrity: sha512-ztqyC3kLto0e9WbNp0aeP+M3kTt+nbaIveGmUxAtZa+8iFgKLUOD4YKM5j+f3QD89bra7UeumolZHKuOXnTmeQ==} - engines: {node: '>=8'} - html-url-attributes@3.0.1: resolution: {integrity: sha512-ol6UPyBWqsrO6EJySPz2O7ZSr856WDrEzM5zMqp+FJJLGMW35cLYmmZnl0vztAZxRUoNZJFTCohfjuIJ8I4QBQ==} @@ -13400,10 +13352,6 @@ packages: is-hexadecimal@2.0.1: resolution: {integrity: sha512-DgZQp241c8oO6cA1SbTEWiXeoxV42vlcJxgH+B3hi1AiqqKruZR3ZGF8In3fj4+/y/7rHvlOZLZtgJ/4ttYGZg==} - is-html@2.0.0: - resolution: {integrity: sha512-S+OpgB5i7wzIue/YSE5hg0e5ZYfG3hhpNh9KGl6ayJ38p7ED6wxQLd1TV91xHpcTvw90KMJ9EwN3F/iNflHBVg==} - engines: {node: '>=8'} - is-inside-container@1.0.0: resolution: {integrity: sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA==} engines: {node: '>=14.16'} @@ -13727,9 +13675,6 @@ packages: jws@4.0.1: resolution: {integrity: sha512-EKI/M/yqPncGUUh44xz0PxSidXFr/+r0pA70+gIYhjv+et7yxM+s29Y+VGDkovRofQem0fs7Uvf4+YmAdyRduA==} - kebab-case@1.0.2: - resolution: {integrity: sha512-7n6wXq4gNgBELfDCpzKc+mRrZFs7D+wgfF5WRFLNAr4DA/qtr9Js8uOAVAfHhuLMfAcQ0pRKqbpjx+TcJVdE1Q==} - keyv@4.5.4: resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==} @@ -13764,9 +13709,6 @@ packages: knitwork@1.3.0: resolution: {integrity: sha512-4LqMNoONzR43B1W0ek0fhXMsDNW/zxa1NdFAVMY+k28pgZLovR4G3PB5MrpTxCy1QaZCqNoiaKPr5w5qZHfSNw==} - known-css-properties@0.30.0: - resolution: {integrity: sha512-VSWXYUnsPu9+WYKkfmJyLKtIvaRJi1kXUqVmBACORXZQxT5oZDsoZ2vQP+bQFDnWtpI/4eq3MLoRMjI2fnLzTQ==} - kolorist@1.8.0: resolution: {integrity: sha512-Y+60/zizpJ3HRH8DCss+q95yr6145JXZo46OTpFvDZWLfRCE4qChOyk1b26nMaNpfHHgxagk9dXT5OP0Tfe+dQ==} @@ -15966,6 +15908,12 @@ packages: peerDependencies: seroval: ^1.0 + seroval-plugins@1.6.4: + resolution: {integrity: sha512-R0f1U9hmn38+dFMz6b6ab8lwucmw4AtiY7St+JPWudy1dm+Bs3g884nyrsH9Cy6rKpZKLYayXuMda9GZ/fl8JQ==} + engines: {node: '>=10'} + peerDependencies: + seroval: ^1.0 + seroval@1.3.2: resolution: {integrity: sha512-RbcPH1n5cfwKrru7v7+zrZvjLurgHhGyso3HTyGtRivGWgYjbOmGuivCQaORNELjNONoK35nj28EoWul9sb1zQ==} engines: {node: '>=10'} @@ -15978,6 +15926,10 @@ packages: resolution: {integrity: sha512-OE4cvmJ1uSPrKorFIH9/w/Qwuvi/IMcGbv5RKgcJ/zjA/IohDLU6SVaxFN9FwajbP7nsX0dQqMDes1whk3y+yw==} engines: {node: '>=10'} + seroval@1.6.4: + resolution: {integrity: sha512-LErWMNS2RRFdu2RMA5u/PA59/IWs0XsikyEXGQ2/36iEWFrdG0ABmg17E17cikrv76891kOAMq3TkTFXpwAHXw==} + engines: {node: '>=10'} + serve-placeholder@2.0.2: resolution: {integrity: sha512-/TMG8SboeiQbZJWRlfTCqMs2DD3SZgWp0kDQePz9yUuCnDfDh/92gf7/PxGhzXTKBIPASIHxFcZndoNbp6QOLQ==} @@ -16560,12 +16512,6 @@ packages: ts-algebra@2.0.0: resolution: {integrity: sha512-FPAhNPFMrkwz76P7cdjdmiShwMynZYN6SgOujD1urY4oNm80Ou9oMdmbR45LotcKOXoy7wSmHkRFE6Mxbrhefw==} - ts-api-utils@2.1.0: - resolution: {integrity: sha512-CUgTZL1irw8u29bzrOD/nH85jqyc74D6SshFgujOIA7osm2Rz7dYH77agkx7H4FBNxDq7Cjf+IjaX/8zwFW+ZQ==} - engines: {node: '>=18.12'} - peerDependencies: - typescript: '>=4.8.4' - ts-api-utils@2.5.0: resolution: {integrity: sha512-OJ/ibxhPlqrMM0UiNHJ/0CKQkoKF243/AEmplt3qpRgkW8VG7IfOS41h7V8TjITqdByHzrjcS/2si+y4lIh8NA==} engines: {node: '>=18.12'} @@ -16891,6 +16837,39 @@ packages: resolution: {integrity: sha512-5uKD0nqiYVzlmCRs01Fhs2BdkEgBS3SAVP6ndrBsuK42iC2+JHyxM05Rm9G8+5mkmRtzMZGY8Ct5+mliZxU/Ww==} engines: {node: '>=18.12.0'} + unplugin@3.3.0: + resolution: {integrity: sha512-qa66K+crbfyE6JK10GjvbJeRrOsuC/JpbnHctfyp/i4oBTxWOzJfRZyDiOk1PtErMFRu8JhsU/wPvOdBNWe5Rg==} + engines: {node: ^20.19.0 || >=22.12.0} + peerDependencies: + '@farmfe/core': '*' + '@rspack/core': '*' + bun-types-no-globals: '*' + esbuild: '*' + rolldown: '*' + rollup: '*' + unloader: '*' + vite: '*' + webpack: '*' + peerDependenciesMeta: + '@farmfe/core': + optional: true + '@rspack/core': + optional: true + bun-types-no-globals: + optional: true + esbuild: + optional: true + rolldown: + optional: true + rollup: + optional: true + unloader: + optional: true + vite: + optional: true + webpack: + optional: true + unrun@0.2.19: resolution: {integrity: sha512-DbwbJ9BvPEb3BeZnIpP9S5tGLO/JIgPQ3JrpMRFIfZMZfMG19f26OlLbC2ml8RRdrI2ZA7z2t+at5tsIHbh6Qw==} engines: {node: '>=20.19.0'} @@ -17300,14 +17279,6 @@ packages: yaml: optional: true - vitefu@1.1.1: - resolution: {integrity: sha512-B/Fegf3i8zh0yFbpzZ21amWzHmuNlLlmJT6n7bu5e+pCHUKQIfXSYokrqOBGEMMe9UG2sostKQF9mml/vYaWJQ==} - peerDependencies: - vite: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0-beta.0 - peerDependenciesMeta: - vite: - optional: true - vitefu@1.1.3: resolution: {integrity: sha512-ub4okH7Z5KLjb6hDyjqrGXqWtWvoYdU3IGm/NorpgHncKoLTCfRIbvlhBm7r0YstIaQRYlp4yEbFqDcKSzXSSg==} peerDependencies: @@ -17715,6 +17686,9 @@ packages: zod@4.3.6: resolution: {integrity: sha512-rftlrkhHZOcjDwkGlnUtZZkvaPHCsDATp4pGpuOOMDaTdDDXF91wuVDJoWoPsKX/3YPQ5fHuF3STjcYyKr+Qhg==} + zod@4.5.4: + resolution: {integrity: sha512-sC95tT5iHHH9gtpj6A81kh+NEaRAUFN+qlUPDUbRfOMvNf5QCBqsb3WgvnpVtK5Y+4UfA6KqufotuTvMGiTlsA==} + zone.js@0.15.1: resolution: {integrity: sha512-XE96n56IQpJM7NAoXswY3XRLcWFW83xe0BiAOeMD7K5k5xecOeul3Qcpx6GqEeeHNkW5DWL5zOyTbEfB4eti8w==} @@ -17909,7 +17883,7 @@ snapshots: '@angular/compiler-cli@21.2.17(@angular/compiler@21.2.20)(typescript@5.9.3)': dependencies: '@angular/compiler': 21.2.20 - '@babel/core': 7.29.0(supports-color@7.2.0) + '@babel/core': 7.29.0 '@jridgewell/sourcemap-codec': 1.5.5 chokidar: 5.0.0 convert-source-map: 1.9.0 @@ -18396,9 +18370,9 @@ snapshots: '@babel/helper-module-transforms': 7.28.3(@babel/core@7.28.5) '@babel/helpers': 7.28.4 '@babel/parser': 7.28.5 - '@babel/template': 7.27.2 + '@babel/template': 7.29.7 '@babel/traverse': 7.28.5 - '@babel/types': 7.28.5 + '@babel/types': 7.29.7 '@jridgewell/remapping': 2.3.5 convert-source-map: 2.0.0 debug: 4.4.3(supports-color@7.2.0) @@ -18416,9 +18390,9 @@ snapshots: '@babel/helper-module-transforms': 7.28.3(@babel/core@7.28.5(supports-color@7.2.0)) '@babel/helpers': 7.28.4 '@babel/parser': 7.28.5 - '@babel/template': 7.27.2 + '@babel/template': 7.29.7 '@babel/traverse': 7.28.5 - '@babel/types': 7.28.5 + '@babel/types': 7.29.7 '@jridgewell/remapping': 2.3.5 convert-source-map: 2.0.0 debug: 4.4.3(supports-color@7.2.0) @@ -18428,12 +18402,12 @@ snapshots: transitivePeerDependencies: - supports-color - '@babel/core@7.29.0(supports-color@7.2.0)': + '@babel/core@7.29.0': dependencies: '@babel/code-frame': 7.29.7 '@babel/generator': 7.29.7 '@babel/helper-compilation-targets': 7.29.7 - '@babel/helper-module-transforms': 7.29.7(@babel/core@7.29.0(supports-color@7.2.0)) + '@babel/helper-module-transforms': 7.29.7(@babel/core@7.29.0) '@babel/helpers': 7.29.7 '@babel/parser': 7.29.7 '@babel/template': 7.29.7 @@ -18471,7 +18445,7 @@ snapshots: '@babel/generator@7.28.5': dependencies: '@babel/parser': 7.29.0 - '@babel/types': 7.29.0 + '@babel/types': 7.29.7 '@jridgewell/gen-mapping': 0.3.13 '@jridgewell/trace-mapping': 0.3.31 jsesc: 3.1.0 @@ -18555,19 +18529,6 @@ snapshots: transitivePeerDependencies: - supports-color - '@babel/helper-create-class-features-plugin@7.29.7(@babel/core@7.29.0)': - dependencies: - '@babel/core': 7.29.0(supports-color@7.2.0) - '@babel/helper-annotate-as-pure': 7.29.7 - '@babel/helper-member-expression-to-functions': 7.29.7 - '@babel/helper-optimise-call-expression': 7.29.7 - '@babel/helper-replace-supers': 7.29.7(@babel/core@7.29.0) - '@babel/helper-skip-transparent-expression-wrappers': 7.29.7 - '@babel/traverse': 7.29.7 - semver: 6.3.1 - transitivePeerDependencies: - - supports-color - '@babel/helper-create-class-features-plugin@7.29.7(@babel/core@7.29.7)': dependencies: '@babel/core': 7.29.7 @@ -18653,15 +18614,6 @@ snapshots: transitivePeerDependencies: - supports-color - '@babel/helper-module-transforms@7.28.3(@babel/core@7.29.0)': - dependencies: - '@babel/core': 7.29.0(supports-color@7.2.0) - '@babel/helper-module-imports': 7.29.7 - '@babel/helper-validator-identifier': 7.29.7 - '@babel/traverse': 7.29.7 - transitivePeerDependencies: - - supports-color - '@babel/helper-module-transforms@7.28.3(@babel/core@7.29.7)': dependencies: '@babel/core': 7.29.7 @@ -18671,9 +18623,9 @@ snapshots: transitivePeerDependencies: - supports-color - '@babel/helper-module-transforms@7.29.7(@babel/core@7.29.0(supports-color@7.2.0))': + '@babel/helper-module-transforms@7.29.7(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.29.0(supports-color@7.2.0) + '@babel/core': 7.29.0 '@babel/helper-module-imports': 7.29.7 '@babel/helper-validator-identifier': 7.29.7 '@babel/traverse': 7.29.7 @@ -18739,15 +18691,6 @@ snapshots: transitivePeerDependencies: - supports-color - '@babel/helper-replace-supers@7.29.7(@babel/core@7.29.0)': - dependencies: - '@babel/core': 7.29.0(supports-color@7.2.0) - '@babel/helper-member-expression-to-functions': 7.29.7 - '@babel/helper-optimise-call-expression': 7.29.7 - '@babel/traverse': 7.29.7 - transitivePeerDependencies: - - supports-color - '@babel/helper-replace-supers@7.29.7(@babel/core@7.29.7)': dependencies: '@babel/core': 7.29.7 @@ -18811,7 +18754,7 @@ snapshots: '@babel/parser@7.29.0': dependencies: - '@babel/types': 7.29.0 + '@babel/types': 7.29.7 '@babel/parser@7.29.7': dependencies: @@ -18861,21 +18804,11 @@ snapshots: '@babel/core': 7.28.5(supports-color@7.2.0) '@babel/helper-plugin-utils': 7.29.7 - '@babel/plugin-syntax-jsx@7.27.1(@babel/core@7.29.0)': - dependencies: - '@babel/core': 7.29.0(supports-color@7.2.0) - '@babel/helper-plugin-utils': 7.29.7 - '@babel/plugin-syntax-jsx@7.27.1(@babel/core@7.29.7)': dependencies: '@babel/core': 7.29.7 '@babel/helper-plugin-utils': 7.29.7 - '@babel/plugin-syntax-jsx@7.29.7(@babel/core@7.29.0)': - dependencies: - '@babel/core': 7.29.0(supports-color@7.2.0) - '@babel/helper-plugin-utils': 7.29.7 - '@babel/plugin-syntax-jsx@7.29.7(@babel/core@7.29.7)': dependencies: '@babel/core': 7.29.7 @@ -18896,11 +18829,6 @@ snapshots: '@babel/core': 7.28.5(supports-color@7.2.0) '@babel/helper-plugin-utils': 7.29.7 - '@babel/plugin-syntax-typescript@7.27.1(@babel/core@7.29.0)': - dependencies: - '@babel/core': 7.29.0(supports-color@7.2.0) - '@babel/helper-plugin-utils': 7.29.7 - '@babel/plugin-syntax-typescript@7.27.1(@babel/core@7.29.7)': dependencies: '@babel/core': 7.29.7 @@ -19011,14 +18939,6 @@ snapshots: transitivePeerDependencies: - supports-color - '@babel/plugin-transform-modules-commonjs@7.27.1(@babel/core@7.29.0)': - dependencies: - '@babel/core': 7.29.0(supports-color@7.2.0) - '@babel/helper-module-transforms': 7.28.3(@babel/core@7.29.0) - '@babel/helper-plugin-utils': 7.27.1 - transitivePeerDependencies: - - supports-color - '@babel/plugin-transform-modules-commonjs@7.27.1(@babel/core@7.29.7)': dependencies: '@babel/core': 7.29.7 @@ -19167,17 +19087,6 @@ snapshots: transitivePeerDependencies: - supports-color - '@babel/plugin-transform-typescript@7.28.5(@babel/core@7.29.0)': - dependencies: - '@babel/core': 7.29.0(supports-color@7.2.0) - '@babel/helper-annotate-as-pure': 7.29.7 - '@babel/helper-create-class-features-plugin': 7.29.7(@babel/core@7.29.0) - '@babel/helper-plugin-utils': 7.29.7 - '@babel/helper-skip-transparent-expression-wrappers': 7.27.1 - '@babel/plugin-syntax-typescript': 7.27.1(@babel/core@7.29.0) - transitivePeerDependencies: - - supports-color - '@babel/plugin-transform-typescript@7.28.5(@babel/core@7.29.7)': dependencies: '@babel/core': 7.29.7 @@ -19213,17 +19122,6 @@ snapshots: transitivePeerDependencies: - supports-color - '@babel/preset-typescript@7.28.5(@babel/core@7.29.0)': - dependencies: - '@babel/core': 7.29.0(supports-color@7.2.0) - '@babel/helper-plugin-utils': 7.27.1 - '@babel/helper-validator-option': 7.27.1 - '@babel/plugin-syntax-jsx': 7.27.1(@babel/core@7.29.0) - '@babel/plugin-transform-modules-commonjs': 7.27.1(@babel/core@7.29.0) - '@babel/plugin-transform-typescript': 7.28.5(@babel/core@7.29.0) - transitivePeerDependencies: - - supports-color - '@babel/preset-typescript@7.28.5(@babel/core@7.29.7)': dependencies: '@babel/core': 7.29.7 @@ -19246,12 +19144,6 @@ snapshots: '@babel/runtime@7.29.2': {} - '@babel/template@7.27.2': - dependencies: - '@babel/code-frame': 7.29.7 - '@babel/parser': 7.29.7 - '@babel/types': 7.29.7 - '@babel/template@7.29.7': dependencies: '@babel/code-frame': 7.29.7 @@ -19264,8 +19156,8 @@ snapshots: '@babel/generator': 7.28.5 '@babel/helper-globals': 7.28.0 '@babel/parser': 7.28.5 - '@babel/template': 7.27.2 - '@babel/types': 7.28.5 + '@babel/template': 7.29.7 + '@babel/types': 7.29.7 debug: 4.4.3(supports-color@7.2.0) transitivePeerDependencies: - supports-color @@ -19294,11 +19186,6 @@ snapshots: transitivePeerDependencies: - supports-color - '@babel/types@7.28.5': - dependencies: - '@babel/helper-string-parser': 7.29.7 - '@babel/helper-validator-identifier': 7.29.7 - '@babel/types@7.29.0': dependencies: '@babel/helper-string-parser': 7.27.1 @@ -20367,7 +20254,7 @@ snapshots: '@expo/metro-config@56.0.13(expo@56.0.5)(typescript@5.9.3)': dependencies: '@babel/code-frame': 7.29.0 - '@babel/core': 7.29.0(supports-color@7.2.0) + '@babel/core': 7.29.7 '@babel/generator': 7.29.1 '@expo/config': 56.0.9(typescript@5.9.3) '@expo/env': 2.3.0 @@ -20565,6 +20452,19 @@ snapshots: - supports-color - utf-8-validate + '@google/genai@2.10.0(@modelcontextprotocol/sdk@1.29.0(zod@4.5.4))': + dependencies: + google-auth-library: 10.5.0 + p-retry: 4.6.2 + protobufjs: 7.6.4 + ws: 8.21.0 + optionalDependencies: + '@modelcontextprotocol/sdk': 1.29.0(zod@4.5.4) + transitivePeerDependencies: + - bufferutil + - supports-color + - utf-8-validate + '@grpc/grpc-js@1.14.4': dependencies: '@grpc/proto-loader': 0.8.1 @@ -21021,6 +20921,29 @@ snapshots: transitivePeerDependencies: - supports-color + '@modelcontextprotocol/sdk@1.29.0(zod@4.5.4)': + dependencies: + '@hono/node-server': 1.19.14(hono@4.12.23) + ajv: 8.20.0 + ajv-formats: 3.0.1(ajv@8.20.0) + content-type: 1.0.5 + cors: 2.8.6 + cross-spawn: 7.0.6 + eventsource: 3.0.7 + eventsource-parser: 3.1.0 + express: 5.2.1 + express-rate-limit: 8.5.2(express@5.2.1) + hono: 4.12.23 + jose: 6.2.3 + json-schema-typed: 8.0.2 + pkce-challenge: 5.0.1 + raw-body: 3.0.2 + zod: 4.5.4 + zod-to-json-schema: 3.25.2(zod@4.5.4) + transitivePeerDependencies: + - supports-color + optional: true + '@msgpack/msgpack@3.1.3': {} '@msgpackr-extract/msgpackr-extract-darwin-arm64@3.0.4': @@ -21202,8 +21125,6 @@ snapshots: '@nodelib/fs.scandir': 2.1.5 fastq: 1.19.1 - '@nothing-but/utils@0.17.0': {} - '@nx/nx-darwin-arm64@23.1.1': optional: true @@ -24348,8 +24269,6 @@ snapshots: '@rolldown/pluginutils@1.0.0-beta.27': {} - '@rolldown/pluginutils@1.0.0-beta.40': {} - '@rolldown/pluginutils@1.0.0-beta.53': {} '@rolldown/pluginutils@1.0.0-rc.3': {} @@ -24689,48 +24608,6 @@ snapshots: '@smithy/util-buffer-from': 2.2.0 tslib: 2.8.1 - '@solid-devtools/debugger@0.28.1(solid-js@1.9.10)': - dependencies: - '@nothing-but/utils': 0.17.0 - '@solid-devtools/shared': 0.20.0(solid-js@1.9.10) - '@solid-primitives/bounds': 0.1.3(solid-js@1.9.10) - '@solid-primitives/event-listener': 2.4.3(solid-js@1.9.10) - '@solid-primitives/keyboard': 1.3.3(solid-js@1.9.10) - '@solid-primitives/rootless': 1.5.2(solid-js@1.9.10) - '@solid-primitives/scheduled': 1.5.2(solid-js@1.9.10) - '@solid-primitives/static-store': 0.1.2(solid-js@1.9.10) - '@solid-primitives/utils': 6.3.2(solid-js@1.9.10) - solid-js: 1.9.10 - - '@solid-devtools/logger@0.9.11(solid-js@1.9.10)': - dependencies: - '@nothing-but/utils': 0.17.0 - '@solid-devtools/debugger': 0.28.1(solid-js@1.9.10) - '@solid-devtools/shared': 0.20.0(solid-js@1.9.10) - '@solid-primitives/utils': 6.3.2(solid-js@1.9.10) - solid-js: 1.9.10 - - '@solid-devtools/shared@0.20.0(solid-js@1.9.10)': - dependencies: - '@nothing-but/utils': 0.17.0 - '@solid-primitives/event-listener': 2.4.3(solid-js@1.9.10) - '@solid-primitives/media': 2.3.3(solid-js@1.9.10) - '@solid-primitives/refs': 1.1.2(solid-js@1.9.10) - '@solid-primitives/rootless': 1.5.2(solid-js@1.9.10) - '@solid-primitives/scheduled': 1.5.2(solid-js@1.9.10) - '@solid-primitives/static-store': 0.1.2(solid-js@1.9.10) - '@solid-primitives/styles': 0.1.2(solid-js@1.9.10) - '@solid-primitives/utils': 6.3.2(solid-js@1.9.10) - solid-js: 1.9.10 - - '@solid-primitives/bounds@0.1.3(solid-js@1.9.10)': - dependencies: - '@solid-primitives/event-listener': 2.4.3(solid-js@1.9.10) - '@solid-primitives/resize-observer': 2.1.3(solid-js@1.9.10) - '@solid-primitives/static-store': 0.1.2(solid-js@1.9.10) - '@solid-primitives/utils': 6.3.2(solid-js@1.9.10) - solid-js: 1.9.10 - '@solid-primitives/event-listener@2.4.3(solid-js@1.9.10)': dependencies: '@solid-primitives/utils': 6.3.2(solid-js@1.9.10) @@ -24743,14 +24620,6 @@ snapshots: '@solid-primitives/utils': 6.3.2(solid-js@1.9.10) solid-js: 1.9.10 - '@solid-primitives/media@2.3.3(solid-js@1.9.10)': - dependencies: - '@solid-primitives/event-listener': 2.4.3(solid-js@1.9.10) - '@solid-primitives/rootless': 1.5.2(solid-js@1.9.10) - '@solid-primitives/static-store': 0.1.2(solid-js@1.9.10) - '@solid-primitives/utils': 6.3.2(solid-js@1.9.10) - solid-js: 1.9.10 - '@solid-primitives/refs@1.1.2(solid-js@1.9.10)': dependencies: '@solid-primitives/utils': 6.3.2(solid-js@1.9.10) @@ -24769,21 +24638,11 @@ snapshots: '@solid-primitives/utils': 6.3.2(solid-js@1.9.10) solid-js: 1.9.10 - '@solid-primitives/scheduled@1.5.2(solid-js@1.9.10)': - dependencies: - solid-js: 1.9.10 - '@solid-primitives/static-store@0.1.2(solid-js@1.9.10)': dependencies: '@solid-primitives/utils': 6.3.2(solid-js@1.9.10) solid-js: 1.9.10 - '@solid-primitives/styles@0.1.2(solid-js@1.9.10)': - dependencies: - '@solid-primitives/rootless': 1.5.2(solid-js@1.9.10) - '@solid-primitives/utils': 6.3.2(solid-js@1.9.10) - solid-js: 1.9.10 - '@solid-primitives/utils@6.3.2(solid-js@1.9.10)': dependencies: solid-js: 1.9.10 @@ -25115,6 +24974,8 @@ snapshots: '@tanstack/history@1.154.14': {} + '@tanstack/history@1.162.1': {} + '@tanstack/nitro-v2-vite-plugin@1.155.0(@electric-sql/pglite@0.4.3)(aws4fetch@1.0.20)(better-sqlite3@12.11.1)(drizzle-orm@0.45.2(@cloudflare/workers-types@4.20260317.1)(@electric-sql/pglite@0.4.3)(@opentelemetry/api@1.9.1)(@prisma/client@7.9.0(prisma@7.9.0(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(better-sqlite3@12.11.1)(magicast@0.5.2)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(typescript@5.9.3))(typescript@5.9.3))(better-sqlite3@12.11.1)(bun-types@1.3.14)(mysql2@3.15.3)(postgres@3.4.7)(prisma@7.9.0(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(better-sqlite3@12.11.1)(magicast@0.5.2)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(typescript@5.9.3)))(mysql2@3.15.3)(rolldown@1.2.4)(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0))': dependencies: nitropack: 2.13.1(@electric-sql/pglite@0.4.3)(aws4fetch@1.0.20)(better-sqlite3@12.11.1)(drizzle-orm@0.45.2(@cloudflare/workers-types@4.20260317.1)(@electric-sql/pglite@0.4.3)(@opentelemetry/api@1.9.1)(@prisma/client@7.9.0(prisma@7.9.0(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(better-sqlite3@12.11.1)(magicast@0.5.2)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(typescript@5.9.3))(typescript@5.9.3))(better-sqlite3@12.11.1)(bun-types@1.3.14)(mysql2@3.15.3)(postgres@3.4.7)(prisma@7.9.0(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(better-sqlite3@12.11.1)(magicast@0.5.2)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(typescript@5.9.3)))(mysql2@3.15.3)(rolldown@1.2.4) @@ -25237,23 +25098,23 @@ snapshots: '@tanstack/query-core': 5.90.12 react: 19.2.3 - '@tanstack/react-router-devtools@1.159.5(@tanstack/react-router@1.159.5(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(@tanstack/router-core@1.159.4)(csstype@3.2.3)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': + '@tanstack/react-router-devtools@1.167.1(@tanstack/react-router@1.170.32(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(@tanstack/router-core@1.171.27)(csstype@3.2.3)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': dependencies: - '@tanstack/react-router': 1.159.5(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@tanstack/router-devtools-core': 1.159.4(@tanstack/router-core@1.159.4)(csstype@3.2.3) + '@tanstack/react-router': 1.170.32(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@tanstack/router-devtools-core': 1.168.1(@tanstack/router-core@1.171.27)(csstype@3.2.3) react: 19.2.3 react-dom: 19.2.3(react@19.2.3) optionalDependencies: - '@tanstack/router-core': 1.159.4 + '@tanstack/router-core': 1.171.27 transitivePeerDependencies: - csstype - '@tanstack/react-router-ssr-query@1.159.5(@tanstack/query-core@5.90.12)(@tanstack/react-query@5.90.12(react@19.2.3))(@tanstack/react-router@1.159.5(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(@tanstack/router-core@1.159.4)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': + '@tanstack/react-router-ssr-query@1.167.2(@tanstack/query-core@5.90.12)(@tanstack/react-query@5.90.12(react@19.2.3))(@tanstack/react-router@1.170.32(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(@tanstack/router-core@1.171.27)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': dependencies: '@tanstack/query-core': 5.90.12 '@tanstack/react-query': 5.90.12(react@19.2.3) - '@tanstack/react-router': 1.159.5(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@tanstack/router-ssr-query-core': 1.159.4(@tanstack/query-core@5.90.12)(@tanstack/router-core@1.159.4) + '@tanstack/react-router': 1.170.32(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@tanstack/router-ssr-query-core': 1.169.2(@tanstack/query-core@5.90.12)(@tanstack/router-core@1.171.27) react: 19.2.3 react-dom: 19.2.3(react@19.2.3) transitivePeerDependencies: @@ -25270,16 +25131,14 @@ snapshots: tiny-invariant: 1.3.3 tiny-warning: 1.0.3 - '@tanstack/react-router@1.159.5(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': + '@tanstack/react-router@1.170.32(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': dependencies: - '@tanstack/history': 1.154.14 - '@tanstack/react-store': 0.8.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@tanstack/router-core': 1.159.4 + '@tanstack/history': 1.162.1 + '@tanstack/react-store': 0.9.3(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@tanstack/router-core': 1.171.27 isbot: 5.1.32 react: 19.2.3 react-dom: 19.2.3(react@19.2.3) - tiny-invariant: 1.3.3 - tiny-warning: 1.0.3 '@tanstack/react-start-client@1.141.1(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': dependencies: @@ -25291,19 +25150,17 @@ snapshots: tiny-invariant: 1.3.3 tiny-warning: 1.0.3 - '@tanstack/react-start-client@1.159.5(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': + '@tanstack/react-start-client@1.168.30(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': dependencies: - '@tanstack/react-router': 1.159.5(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@tanstack/router-core': 1.159.4 - '@tanstack/start-client-core': 1.159.4 + '@tanstack/react-router': 1.170.32(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@tanstack/router-core': 1.171.27 + '@tanstack/start-client-core': 1.170.27 react: 19.2.3 react-dom: 19.2.3(react@19.2.3) - tiny-invariant: 1.3.3 - tiny-warning: 1.0.3 - '@tanstack/react-start-plugin@1.131.50(e7a157c953e155a2765d901b34df38b3)': + '@tanstack/react-start-plugin@1.131.50(5e76e58f58fcdc553da46eb093ac388b)': dependencies: - '@tanstack/start-plugin-core': 1.131.50(1a1cdd8b9c2c533357f243540b1932ef) + '@tanstack/start-plugin-core': 1.131.50(b114ec7757aa79b8f316a176b0457a25) '@vitejs/plugin-react': 4.7.0(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)) pathe: 2.0.3 vite: 8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0) @@ -25393,6 +25250,32 @@ snapshots: - xml2js - yaml + '@tanstack/react-start-rsc@0.1.48(crossws@0.4.6(srvx@0.11.17))(esbuild@0.28.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(rolldown@1.2.4)(rollup@4.60.1)(vite-plugin-solid@2.11.14(solid-js@1.9.10)(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)))(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0))': + dependencies: + '@tanstack/react-router': 1.170.32(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@tanstack/router-core': 1.171.27 + '@tanstack/router-utils': 1.162.2 + '@tanstack/start-client-core': 1.170.27 + '@tanstack/start-fn-stubs': 1.162.0 + '@tanstack/start-plugin-core': 1.171.39(@tanstack/react-router@1.170.32(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(crossws@0.4.6(srvx@0.11.17))(esbuild@0.28.1)(rolldown@1.2.4)(rollup@4.60.1)(vite-plugin-solid@2.11.14(solid-js@1.9.10)(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)))(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)) + '@tanstack/start-storage-context': 1.167.29 + pathe: 2.0.3 + react: 19.2.3 + react-dom: 19.2.3(react@19.2.3) + transitivePeerDependencies: + - '@farmfe/core' + - '@rsbuild/core' + - bun-types-no-globals + - crossws + - esbuild + - rolldown + - rollup + - supports-color + - unloader + - vite + - vite-plugin-solid + - webpack + '@tanstack/react-start-server@1.141.1(crossws@0.4.6(srvx@0.11.17))(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': dependencies: '@tanstack/history': 1.141.0 @@ -25405,38 +25288,52 @@ snapshots: transitivePeerDependencies: - crossws - '@tanstack/react-start-server@1.159.5(crossws@0.4.6(srvx@0.11.17))(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': + '@tanstack/react-start-server@1.167.37(crossws@0.4.6(srvx@0.11.17))(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': dependencies: - '@tanstack/history': 1.154.14 - '@tanstack/react-router': 1.159.5(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@tanstack/router-core': 1.159.4 - '@tanstack/start-client-core': 1.159.4 - '@tanstack/start-server-core': 1.159.4(crossws@0.4.6(srvx@0.11.17)) + '@tanstack/react-router': 1.170.32(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@tanstack/router-core': 1.171.27 + '@tanstack/start-server-core': 1.169.31(crossws@0.4.6(srvx@0.11.17)) react: 19.2.3 react-dom: 19.2.3(react@19.2.3) transitivePeerDependencies: - crossws - '@tanstack/react-start@1.159.5(crossws@0.4.6(srvx@0.11.17))(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(vite-plugin-solid@2.11.14(solid-js@1.9.10)(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)))(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0))': + '@tanstack/react-start@1.168.49(crossws@0.4.6(srvx@0.11.17))(esbuild@0.28.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(rolldown@1.2.4)(rollup@4.60.1)(vite-plugin-solid@2.11.14(solid-js@1.9.10)(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)))(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0))': dependencies: - '@tanstack/react-router': 1.159.5(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@tanstack/react-start-client': 1.159.5(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@tanstack/react-start-server': 1.159.5(crossws@0.4.6(srvx@0.11.17))(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@tanstack/router-utils': 1.158.0 - '@tanstack/start-client-core': 1.159.4 - '@tanstack/start-plugin-core': 1.159.5(@tanstack/react-router@1.159.5(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(crossws@0.4.6(srvx@0.11.17))(vite-plugin-solid@2.11.14(solid-js@1.9.10)(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)))(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)) - '@tanstack/start-server-core': 1.159.4(crossws@0.4.6(srvx@0.11.17)) + '@tanstack/react-router': 1.170.32(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@tanstack/react-start-client': 1.168.30(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@tanstack/react-start-rsc': 0.1.48(crossws@0.4.6(srvx@0.11.17))(esbuild@0.28.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(rolldown@1.2.4)(rollup@4.60.1)(vite-plugin-solid@2.11.14(solid-js@1.9.10)(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)))(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)) + '@tanstack/react-start-server': 1.167.37(crossws@0.4.6(srvx@0.11.17))(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@tanstack/router-utils': 1.162.2 + '@tanstack/start-client-core': 1.170.27 + '@tanstack/start-plugin-core': 1.171.39(@tanstack/react-router@1.170.32(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(crossws@0.4.6(srvx@0.11.17))(esbuild@0.28.1)(rolldown@1.2.4)(rollup@4.60.1)(vite-plugin-solid@2.11.14(solid-js@1.9.10)(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)))(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)) + '@tanstack/start-server-core': 1.169.31(crossws@0.4.6(srvx@0.11.17)) pathe: 2.0.3 react: 19.2.3 react-dom: 19.2.3(react@19.2.3) + optionalDependencies: vite: 8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0) transitivePeerDependencies: - - '@rsbuild/core' + - '@farmfe/core' + - '@rspack/core' + - bun-types-no-globals - crossws + - esbuild + - react-server-dom-rspack + - rolldown + - rollup - supports-color + - unloader - vite-plugin-solid - webpack + '@tanstack/react-store@0.11.1(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': + dependencies: + '@tanstack/store': 0.11.1 + react: 19.2.3 + react-dom: 19.2.3(react@19.2.3) + use-sync-external-store: 1.6.0(react@19.2.3) + '@tanstack/react-store@0.8.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': dependencies: '@tanstack/store': 0.8.0 @@ -25444,6 +25341,13 @@ snapshots: react-dom: 19.2.3(react@19.2.3) use-sync-external-store: 1.6.0(react@19.2.3) + '@tanstack/react-store@0.9.3(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': + dependencies: + '@tanstack/store': 0.9.3 + react: 19.2.3 + react-dom: 19.2.3(react@19.2.3) + use-sync-external-store: 1.6.0(react@19.2.3) + '@tanstack/router-core@1.131.50': dependencies: '@tanstack/history': 1.131.2 @@ -25474,22 +25378,18 @@ snapshots: tiny-invariant: 1.3.3 tiny-warning: 1.0.3 - '@tanstack/router-devtools-core@1.141.1(@tanstack/router-core@1.159.4)(csstype@3.2.3)(solid-js@1.9.10)': + '@tanstack/router-core@1.171.27': dependencies: - '@tanstack/router-core': 1.159.4 - clsx: 2.1.1 - goober: 2.1.18(csstype@3.2.3) - solid-js: 1.9.10 - tiny-invariant: 1.3.3 - optionalDependencies: - csstype: 3.2.3 + '@tanstack/history': 1.162.1 + cookie-es: 3.1.1 + seroval: 1.6.4 + seroval-plugins: 1.6.4(seroval@1.6.4) - '@tanstack/router-devtools-core@1.159.4(@tanstack/router-core@1.159.4)(csstype@3.2.3)': + '@tanstack/router-devtools-core@1.168.1(@tanstack/router-core@1.171.27)(csstype@3.2.3)': dependencies: - '@tanstack/router-core': 1.159.4 + '@tanstack/router-core': 1.171.27 clsx: 2.1.1 goober: 2.1.18(csstype@3.2.3) - tiny-invariant: 1.3.3 optionalDependencies: csstype: 3.2.3 @@ -25506,11 +25406,11 @@ snapshots: transitivePeerDependencies: - supports-color - '@tanstack/router-generator@1.141.1': + '@tanstack/router-generator@1.159.4': dependencies: - '@tanstack/router-core': 1.141.1 - '@tanstack/router-utils': 1.141.0 - '@tanstack/virtual-file-routes': 1.141.0 + '@tanstack/router-core': 1.159.4 + '@tanstack/router-utils': 1.158.0 + '@tanstack/virtual-file-routes': 1.154.7 prettier: 3.7.4 recast: 0.23.11 source-map: 0.7.6 @@ -25519,20 +25419,20 @@ snapshots: transitivePeerDependencies: - supports-color - '@tanstack/router-generator@1.159.4': + '@tanstack/router-generator@1.167.33': dependencies: - '@tanstack/router-core': 1.159.4 - '@tanstack/router-utils': 1.158.0 - '@tanstack/virtual-file-routes': 1.154.7 + '@babel/types': 7.29.7 + '@tanstack/router-core': 1.171.27 + '@tanstack/router-utils': 1.162.2 + '@tanstack/virtual-file-routes': 1.162.0 + jiti: 2.7.0 + magic-string: 0.30.21 prettier: 3.7.4 - recast: 0.23.11 - source-map: 0.7.6 - tsx: 4.21.0 - zod: 3.25.76 + zod: 4.5.4 transitivePeerDependencies: - supports-color - '@tanstack/router-plugin@1.131.50(@tanstack/react-router@1.159.5(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(vite-plugin-solid@2.11.14(solid-js@1.9.10)(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)))(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0))': + '@tanstack/router-plugin@1.131.50(@tanstack/react-router@1.170.32(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(vite-plugin-solid@2.11.14(solid-js@1.9.10)(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)))(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0))': dependencies: '@babel/core': 7.29.7 '@babel/plugin-syntax-jsx': 7.29.7(@babel/core@7.29.7) @@ -25549,66 +25449,41 @@ snapshots: unplugin: 2.3.11 zod: 3.25.76 optionalDependencies: - '@tanstack/react-router': 1.159.5(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@tanstack/react-router': 1.170.32(react-dom@19.2.3(react@19.2.3))(react@19.2.3) vite: 8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0) vite-plugin-solid: 2.11.14(solid-js@1.9.10)(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)) transitivePeerDependencies: - supports-color - '@tanstack/router-plugin@1.141.1(@tanstack/react-router@1.159.5(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(vite-plugin-solid@2.11.14(solid-js@1.9.10)(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)))(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0))': + '@tanstack/router-plugin@1.168.35(@tanstack/react-router@1.170.32(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(esbuild@0.28.1)(rolldown@1.2.4)(rollup@4.60.1)(vite-plugin-solid@2.11.14(solid-js@1.9.10)(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)))(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0))': dependencies: '@babel/core': 7.29.7 - '@babel/plugin-syntax-jsx': 7.29.7(@babel/core@7.29.7) - '@babel/plugin-syntax-typescript': 7.27.1(@babel/core@7.29.7) '@babel/template': 7.29.7 - '@babel/traverse': 7.29.7 '@babel/types': 7.29.7 - '@tanstack/router-core': 1.141.1 - '@tanstack/router-generator': 1.141.1 - '@tanstack/router-utils': 1.141.0 - '@tanstack/virtual-file-routes': 1.141.0 - babel-dead-code-elimination: 1.0.10 - chokidar: 3.6.0 - unplugin: 2.3.11 - zod: 3.25.76 - optionalDependencies: - '@tanstack/react-router': 1.159.5(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - vite: 8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0) - vite-plugin-solid: 2.11.14(solid-js@1.9.10)(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)) - transitivePeerDependencies: - - supports-color - - '@tanstack/router-plugin@1.159.5(@tanstack/react-router@1.159.5(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(supports-color@7.2.0)(vite-plugin-solid@2.11.14(solid-js@1.9.10)(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)))(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0))': - dependencies: - '@babel/core': 7.29.0(supports-color@7.2.0) - '@babel/plugin-syntax-jsx': 7.29.7(@babel/core@7.29.0) - '@babel/plugin-syntax-typescript': 7.27.1(@babel/core@7.29.0) - '@babel/template': 7.29.7 - '@babel/traverse': 7.29.7 - '@babel/types': 7.29.7 - '@tanstack/router-core': 1.159.4 - '@tanstack/router-generator': 1.159.4 - '@tanstack/router-utils': 1.158.0 - '@tanstack/virtual-file-routes': 1.154.7 - chokidar: 3.6.0 - unplugin: 2.3.11 - zod: 3.25.76 + '@tanstack/router-core': 1.171.27 + '@tanstack/router-generator': 1.167.33 + '@tanstack/router-utils': 1.162.2 + chokidar: 5.0.0 + unplugin: 3.3.0(esbuild@0.28.1)(rolldown@1.2.4)(rollup@4.60.1)(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)) + zod: 4.5.4 optionalDependencies: - '@tanstack/react-router': 1.159.5(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@tanstack/react-router': 1.170.32(react-dom@19.2.3(react@19.2.3))(react@19.2.3) vite: 8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0) vite-plugin-solid: 2.11.14(solid-js@1.9.10)(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)) transitivePeerDependencies: + - '@farmfe/core' + - '@rspack/core' + - bun-types-no-globals + - esbuild + - rolldown + - rollup - supports-color + - unloader - '@tanstack/router-ssr-query-core@1.141.1(@tanstack/query-core@5.90.12)(@tanstack/router-core@1.159.4)': + '@tanstack/router-ssr-query-core@1.169.2(@tanstack/query-core@5.90.12)(@tanstack/router-core@1.171.27)': dependencies: '@tanstack/query-core': 5.90.12 - '@tanstack/router-core': 1.159.4 - - '@tanstack/router-ssr-query-core@1.159.4(@tanstack/query-core@5.90.12)(@tanstack/router-core@1.159.4)': - dependencies: - '@tanstack/query-core': 5.90.12 - '@tanstack/router-core': 1.159.4 + '@tanstack/router-core': 1.171.27 '@tanstack/router-utils@1.131.2': dependencies: @@ -25636,7 +25511,20 @@ snapshots: '@tanstack/router-utils@1.158.0': dependencies: - '@babel/core': 7.29.0(supports-color@7.2.0) + '@babel/core': 7.29.7 + '@babel/generator': 7.29.7 + '@babel/parser': 7.29.7 + '@babel/types': 7.29.7 + ansis: 4.2.0 + babel-dead-code-elimination: 1.0.12 + diff: 8.0.2 + pathe: 2.0.3 + tinyglobby: 0.2.17 + transitivePeerDependencies: + - supports-color + + '@tanstack/router-utils@1.162.2': + dependencies: '@babel/generator': 7.29.7 '@babel/parser': 7.29.7 '@babel/types': 7.29.7 @@ -25694,86 +25582,80 @@ snapshots: '@tanstack/query-core': 5.90.12 solid-js: 1.9.10 - '@tanstack/solid-router-devtools@1.141.1(@tanstack/router-core@1.159.4)(@tanstack/solid-router@1.141.1(solid-js@1.9.10))(csstype@3.2.3)(solid-js@1.9.10)': + '@tanstack/solid-router-devtools@1.167.1(@tanstack/router-core@1.171.27)(@tanstack/solid-router@1.170.30(solid-js@1.9.10))(csstype@3.2.3)(solid-js@1.9.10)': dependencies: - '@tanstack/router-devtools-core': 1.141.1(@tanstack/router-core@1.159.4)(csstype@3.2.3)(solid-js@1.9.10) - '@tanstack/solid-router': 1.141.1(solid-js@1.9.10) + '@tanstack/router-devtools-core': 1.168.1(@tanstack/router-core@1.171.27)(csstype@3.2.3) + '@tanstack/solid-router': 1.170.30(solid-js@1.9.10) solid-js: 1.9.10 optionalDependencies: - '@tanstack/router-core': 1.159.4 + '@tanstack/router-core': 1.171.27 transitivePeerDependencies: - csstype - '@tanstack/solid-router-ssr-query@1.141.1(@tanstack/query-core@5.90.12)(@tanstack/router-core@1.159.4)(@tanstack/solid-query@5.90.15(solid-js@1.9.10))(@tanstack/solid-router@1.141.1(solid-js@1.9.10))(eslint@9.39.4(jiti@2.7.0))(solid-js@1.9.10)(supports-color@7.2.0)(typescript@5.9.3)': + '@tanstack/solid-router-ssr-query@1.167.2(@tanstack/query-core@5.90.12)(@tanstack/router-core@1.171.27)(@tanstack/solid-query@5.90.15(solid-js@1.9.10))(@tanstack/solid-router@1.170.30(solid-js@1.9.10))(solid-js@1.9.10)': dependencies: '@tanstack/query-core': 5.90.12 - '@tanstack/router-ssr-query-core': 1.141.1(@tanstack/query-core@5.90.12)(@tanstack/router-core@1.159.4) + '@tanstack/router-ssr-query-core': 1.169.2(@tanstack/query-core@5.90.12)(@tanstack/router-core@1.171.27) '@tanstack/solid-query': 5.90.15(solid-js@1.9.10) - '@tanstack/solid-router': 1.141.1(solid-js@1.9.10) - eslint-plugin-solid: 0.14.5(eslint@9.39.4(jiti@2.7.0))(supports-color@7.2.0)(typescript@5.9.3) + '@tanstack/solid-router': 1.170.30(solid-js@1.9.10) solid-js: 1.9.10 transitivePeerDependencies: - '@tanstack/router-core' - - eslint - - supports-color - - typescript - '@tanstack/solid-router@1.141.1(solid-js@1.9.10)': + '@tanstack/solid-router@1.170.30(solid-js@1.9.10)': dependencies: - '@solid-devtools/logger': 0.9.11(solid-js@1.9.10) '@solid-primitives/refs': 1.1.2(solid-js@1.9.10) '@solidjs/meta': 0.29.4(solid-js@1.9.10) - '@tanstack/history': 1.141.0 - '@tanstack/router-core': 1.141.1 - '@tanstack/solid-store': 0.8.0(solid-js@1.9.10) + '@tanstack/history': 1.162.1 + '@tanstack/router-core': 1.171.27 isbot: 5.1.32 solid-js: 1.9.10 - tiny-invariant: 1.3.3 - tiny-warning: 1.0.3 - '@tanstack/solid-start-client@1.141.1(solid-js@1.9.10)': + '@tanstack/solid-start-client@1.168.29(solid-js@1.9.10)': dependencies: - '@tanstack/router-core': 1.141.1 - '@tanstack/solid-router': 1.141.1(solid-js@1.9.10) - '@tanstack/start-client-core': 1.141.1 + '@tanstack/router-core': 1.171.27 + '@tanstack/solid-router': 1.170.30(solid-js@1.9.10) + '@tanstack/start-client-core': 1.170.27 solid-js: 1.9.10 - tiny-invariant: 1.3.3 - tiny-warning: 1.0.3 - '@tanstack/solid-start-server@1.141.1(crossws@0.4.6(srvx@0.11.17))(solid-js@1.9.10)': + '@tanstack/solid-start-server@1.167.36(crossws@0.4.6(srvx@0.11.17))(solid-js@1.9.10)': dependencies: - '@solidjs/meta': 0.29.4(solid-js@1.9.10) - '@tanstack/history': 1.141.0 - '@tanstack/router-core': 1.141.1 - '@tanstack/solid-router': 1.141.1(solid-js@1.9.10) - '@tanstack/start-client-core': 1.141.1 - '@tanstack/start-server-core': 1.141.1(crossws@0.4.6(srvx@0.11.17)) + '@tanstack/router-core': 1.171.27 + '@tanstack/solid-router': 1.170.30(solid-js@1.9.10) + '@tanstack/start-server-core': 1.169.31(crossws@0.4.6(srvx@0.11.17)) solid-js: 1.9.10 transitivePeerDependencies: - crossws - '@tanstack/solid-start@1.141.1(@tanstack/react-router@1.159.5(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(crossws@0.4.6(srvx@0.11.17))(solid-js@1.9.10)(vite-plugin-solid@2.11.14(solid-js@1.9.10)(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)))(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0))': + '@tanstack/solid-start@1.168.47(@tanstack/react-router@1.170.32(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(crossws@0.4.6(srvx@0.11.17))(esbuild@0.28.1)(rolldown@1.2.4)(rollup@4.60.1)(solid-js@1.9.10)(vite-plugin-solid@2.11.14(solid-js@1.9.10)(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)))(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0))': dependencies: - '@tanstack/solid-router': 1.141.1(solid-js@1.9.10) - '@tanstack/solid-start-client': 1.141.1(solid-js@1.9.10) - '@tanstack/solid-start-server': 1.141.1(crossws@0.4.6(srvx@0.11.17))(solid-js@1.9.10) - '@tanstack/start-client-core': 1.141.1 - '@tanstack/start-plugin-core': 1.141.1(@tanstack/react-router@1.159.5(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(crossws@0.4.6(srvx@0.11.17))(vite-plugin-solid@2.11.14(solid-js@1.9.10)(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)))(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)) - '@tanstack/start-server-core': 1.141.1(crossws@0.4.6(srvx@0.11.17)) + '@tanstack/solid-router': 1.170.30(solid-js@1.9.10) + '@tanstack/solid-start-client': 1.168.29(solid-js@1.9.10) + '@tanstack/solid-start-server': 1.167.36(crossws@0.4.6(srvx@0.11.17))(solid-js@1.9.10) + '@tanstack/start-client-core': 1.170.27 + '@tanstack/start-plugin-core': 1.171.39(@tanstack/react-router@1.170.32(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(crossws@0.4.6(srvx@0.11.17))(esbuild@0.28.1)(rolldown@1.2.4)(rollup@4.60.1)(vite-plugin-solid@2.11.14(solid-js@1.9.10)(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)))(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)) + '@tanstack/start-server-core': 1.169.31(crossws@0.4.6(srvx@0.11.17)) pathe: 2.0.3 solid-js: 1.9.10 + optionalDependencies: vite: 8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0) transitivePeerDependencies: - - '@rsbuild/core' + - '@farmfe/core' + - '@rspack/core' - '@tanstack/react-router' + - bun-types-no-globals - crossws + - esbuild + - rolldown + - rollup - supports-color + - unloader - vite-plugin-solid - webpack - '@tanstack/solid-store@0.8.0(solid-js@1.9.10)': + '@tanstack/solid-store@0.11.1(solid-js@1.9.10)': dependencies: - '@tanstack/store': 0.8.0 + '@tanstack/store': 0.11.1 solid-js: 1.9.10 '@tanstack/start-api-routes@1.120.19(91e012b4b7f2d471a11b1e1ea02d5103)': @@ -25852,12 +25734,19 @@ snapshots: tiny-invariant: 1.3.3 tiny-warning: 1.0.3 - '@tanstack/start-config@1.120.20(340eefabdbae5b0c948fd6f8943277d1)': + '@tanstack/start-client-core@1.170.27': + dependencies: + '@tanstack/router-core': 1.171.27 + '@tanstack/start-fn-stubs': 1.162.0 + '@tanstack/start-storage-context': 1.167.29 + seroval: 1.6.4 + + '@tanstack/start-config@1.120.20(c688c64811f9265f6bbbab232e625bf6)': dependencies: - '@tanstack/react-router': 1.159.5(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@tanstack/react-start-plugin': 1.131.50(e7a157c953e155a2765d901b34df38b3) + '@tanstack/react-router': 1.170.32(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@tanstack/react-start-plugin': 1.131.50(5e76e58f58fcdc553da46eb093ac388b) '@tanstack/router-generator': 1.159.4 - '@tanstack/router-plugin': 1.159.5(@tanstack/react-router@1.159.5(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(supports-color@7.2.0)(vite-plugin-solid@2.11.14(solid-js@1.9.10)(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)))(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)) + '@tanstack/router-plugin': 1.168.35(@tanstack/react-router@1.170.32(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(esbuild@0.28.1)(rolldown@1.2.4)(rollup@4.60.1)(vite-plugin-solid@2.11.14(solid-js@1.9.10)(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)))(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)) '@tanstack/server-functions-plugin': 1.141.0(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)) '@tanstack/start-server-functions-handler': 1.120.19(crossws@0.4.6(srvx@0.11.17)) '@vitejs/plugin-react': 4.7.0(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)) @@ -25879,10 +25768,12 @@ snapshots: - '@capacitor/preferences' - '@deno/kv' - '@electric-sql/pglite' + - '@farmfe/core' - '@libsql/client' - '@netlify/blobs' - '@planetscale/database' - '@rsbuild/core' + - '@rspack/core' - '@types/node' - '@upstash/redis' - '@vercel/blob' @@ -25891,11 +25782,13 @@ snapshots: - aws4fetch - bare-abort-controller - better-sqlite3 + - bun-types-no-globals - crossws - db0 - debug - drizzle-orm - encoding + - esbuild - idb-keyval - ioredis - jiti @@ -25904,6 +25797,7 @@ snapshots: - mysql2 - react-native-b4a - rolldown + - rollup - sass - sass-embedded - sqlite3 @@ -25912,6 +25806,7 @@ snapshots: - supports-color - terser - tsx + - unloader - uploadthing - vite-plugin-solid - webpack @@ -25920,14 +25815,16 @@ snapshots: '@tanstack/start-fn-stubs@1.154.7': {} - '@tanstack/start-plugin-core@1.131.50(1a1cdd8b9c2c533357f243540b1932ef)': + '@tanstack/start-fn-stubs@1.162.0': {} + + '@tanstack/start-plugin-core@1.131.50(b114ec7757aa79b8f316a176b0457a25)': dependencies: '@babel/code-frame': 7.26.2 '@babel/core': 7.29.7 '@babel/types': 7.29.7 '@tanstack/router-core': 1.131.50 '@tanstack/router-generator': 1.131.50 - '@tanstack/router-plugin': 1.131.50(@tanstack/react-router@1.159.5(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(vite-plugin-solid@2.11.14(solid-js@1.9.10)(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)))(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)) + '@tanstack/router-plugin': 1.131.50(@tanstack/react-router@1.170.32(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(vite-plugin-solid@2.11.14(solid-js@1.9.10)(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)))(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)) '@tanstack/router-utils': 1.131.2 '@tanstack/server-functions-plugin': 1.131.2(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)) '@tanstack/start-server-core': 1.131.50 @@ -25940,7 +25837,7 @@ snapshots: pathe: 2.0.3 ufo: 1.6.3 vite: 8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0) - vitefu: 1.1.1(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)) + vitefu: 1.1.3(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)) xmlbuilder2: 3.1.1 zod: 3.25.76 transitivePeerDependencies: @@ -25978,65 +25875,41 @@ snapshots: - webpack - xml2js - '@tanstack/start-plugin-core@1.141.1(@tanstack/react-router@1.159.5(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(crossws@0.4.6(srvx@0.11.17))(vite-plugin-solid@2.11.14(solid-js@1.9.10)(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)))(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0))': - dependencies: - '@babel/code-frame': 7.26.2 - '@babel/core': 7.29.0(supports-color@7.2.0) - '@babel/types': 7.29.0 - '@rolldown/pluginutils': 1.0.0-beta.40 - '@tanstack/router-core': 1.141.1 - '@tanstack/router-generator': 1.141.1 - '@tanstack/router-plugin': 1.141.1(@tanstack/react-router@1.159.5(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(vite-plugin-solid@2.11.14(solid-js@1.9.10)(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)))(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)) - '@tanstack/router-utils': 1.141.0 - '@tanstack/server-functions-plugin': 1.141.0(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)) - '@tanstack/start-client-core': 1.141.1 - '@tanstack/start-server-core': 1.141.1(crossws@0.4.6(srvx@0.11.17)) - babel-dead-code-elimination: 1.0.10 - cheerio: 1.1.2 - exsolve: 1.0.8 - pathe: 2.0.3 - srvx: 0.8.16 - tinyglobby: 0.2.17 - ufo: 1.6.1 - vite: 8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0) - vitefu: 1.1.1(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)) - xmlbuilder2: 4.0.3 - zod: 3.25.76 - transitivePeerDependencies: - - '@rsbuild/core' - - '@tanstack/react-router' - - crossws - - supports-color - - vite-plugin-solid - - webpack - - '@tanstack/start-plugin-core@1.159.5(@tanstack/react-router@1.159.5(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(crossws@0.4.6(srvx@0.11.17))(vite-plugin-solid@2.11.14(solid-js@1.9.10)(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)))(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0))': + '@tanstack/start-plugin-core@1.171.39(@tanstack/react-router@1.170.32(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(crossws@0.4.6(srvx@0.11.17))(esbuild@0.28.1)(rolldown@1.2.4)(rollup@4.60.1)(vite-plugin-solid@2.11.14(solid-js@1.9.10)(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)))(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0))': dependencies: '@babel/code-frame': 7.27.1 - '@babel/core': 7.29.0(supports-color@7.2.0) + '@babel/core': 7.29.7 '@babel/types': 7.29.7 - '@rolldown/pluginutils': 1.0.0-beta.40 - '@tanstack/router-core': 1.159.4 - '@tanstack/router-generator': 1.159.4 - '@tanstack/router-plugin': 1.159.5(@tanstack/react-router@1.159.5(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(supports-color@7.2.0)(vite-plugin-solid@2.11.14(solid-js@1.9.10)(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)))(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)) - '@tanstack/router-utils': 1.158.0 - '@tanstack/start-client-core': 1.159.4 - '@tanstack/start-server-core': 1.159.4(crossws@0.4.6(srvx@0.11.17)) - cheerio: 1.1.2 + '@tanstack/router-core': 1.171.27 + '@tanstack/router-generator': 1.167.33 + '@tanstack/router-plugin': 1.168.35(@tanstack/react-router@1.170.32(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(esbuild@0.28.1)(rolldown@1.2.4)(rollup@4.60.1)(vite-plugin-solid@2.11.14(solid-js@1.9.10)(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)))(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)) + '@tanstack/router-utils': 1.162.2 + '@tanstack/start-server-core': 1.169.31(crossws@0.4.6(srvx@0.11.17)) exsolve: 1.0.8 + lightningcss: 1.33.0 pathe: 2.0.3 + picomatch: 4.0.5 + seroval: 1.6.4 + source-map: 0.7.6 srvx: 0.11.17 tinyglobby: 0.2.17 ufo: 1.6.3 - vite: 8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0) - vitefu: 1.1.1(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)) + vitefu: 1.1.3(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)) xmlbuilder2: 4.0.3 - zod: 3.25.76 + zod: 4.5.4 + optionalDependencies: + vite: 8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0) transitivePeerDependencies: - - '@rsbuild/core' + - '@farmfe/core' + - '@rspack/core' - '@tanstack/react-router' + - bun-types-no-globals - crossws + - esbuild + - rolldown + - rollup - supports-color + - unloader - vite-plugin-solid - webpack @@ -26076,6 +25949,18 @@ snapshots: transitivePeerDependencies: - crossws + '@tanstack/start-server-core@1.169.31(crossws@0.4.6(srvx@0.11.17))': + dependencies: + '@tanstack/history': 1.162.1 + '@tanstack/router-core': 1.171.27 + '@tanstack/start-client-core': 1.170.27 + '@tanstack/start-storage-context': 1.167.29 + fetchdts: 0.1.7 + h3-v2: h3@2.0.1-rc.20(crossws@0.4.6(srvx@0.11.17)) + seroval: 1.6.4 + transitivePeerDependencies: + - crossws + '@tanstack/start-server-functions-client@1.131.50(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0))': dependencies: '@tanstack/server-functions-plugin': 1.131.2(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)) @@ -26130,13 +26015,17 @@ snapshots: dependencies: '@tanstack/router-core': 1.159.4 - '@tanstack/start@1.120.20(340eefabdbae5b0c948fd6f8943277d1)': + '@tanstack/start-storage-context@1.167.29': + dependencies: + '@tanstack/router-core': 1.171.27 + + '@tanstack/start@1.120.20(c688c64811f9265f6bbbab232e625bf6)': dependencies: '@tanstack/react-start-client': 1.141.1(react-dom@19.2.3(react@19.2.3))(react@19.2.3) '@tanstack/react-start-router-manifest': 1.120.19(e2865e417d15aa2efdac89fcc0288f0b) '@tanstack/react-start-server': 1.141.1(crossws@0.4.6(srvx@0.11.17))(react-dom@19.2.3(react@19.2.3))(react@19.2.3) '@tanstack/start-api-routes': 1.120.19(91e012b4b7f2d471a11b1e1ea02d5103) - '@tanstack/start-config': 1.120.20(340eefabdbae5b0c948fd6f8943277d1) + '@tanstack/start-config': 1.120.20(c688c64811f9265f6bbbab232e625bf6) '@tanstack/start-server-functions-client': 1.131.50(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)) '@tanstack/start-server-functions-handler': 1.120.19(crossws@0.4.6(srvx@0.11.17)) '@tanstack/start-server-functions-server': 1.131.2(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)) @@ -26151,10 +26040,12 @@ snapshots: - '@capacitor/preferences' - '@deno/kv' - '@electric-sql/pglite' + - '@farmfe/core' - '@libsql/client' - '@netlify/blobs' - '@planetscale/database' - '@rsbuild/core' + - '@rspack/core' - '@types/node' - '@upstash/redis' - '@vercel/blob' @@ -26163,11 +26054,13 @@ snapshots: - aws4fetch - bare-abort-controller - better-sqlite3 + - bun-types-no-globals - crossws - db0 - debug - drizzle-orm - encoding + - esbuild - idb-keyval - ioredis - jiti @@ -26178,6 +26071,7 @@ snapshots: - react-dom - react-native-b4a - rolldown + - rollup - sass - sass-embedded - sqlite3 @@ -26186,6 +26080,7 @@ snapshots: - supports-color - terser - tsx + - unloader - uploadthing - vite - vite-plugin-solid @@ -26199,6 +26094,8 @@ snapshots: '@tanstack/store@0.8.0': {} + '@tanstack/store@0.9.3': {} + '@tanstack/typedoc-config@0.3.4': dependencies: typedoc: 0.28.20(@typescript/typescript6@6.0.2) @@ -26208,10 +26105,10 @@ snapshots: '@tanstack/virtual-file-routes@1.131.2': {} - '@tanstack/virtual-file-routes@1.141.0': {} - '@tanstack/virtual-file-routes@1.154.7': {} + '@tanstack/virtual-file-routes@1.162.0': {} + '@tanstack/vite-config@0.6.0(@microsoft/api-extractor@7.47.7(@types/node@24.10.3))(esbuild@0.28.1)(rolldown@1.1.5)(rollup@4.60.1)(supports-color@7.2.0)(typescript@7.0.2)(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0))': dependencies: vite: 8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0) @@ -26229,9 +26126,9 @@ snapshots: - typescript - webpack - '@tanstack/zod-adapter@1.166.9(@tanstack/react-router@1.159.5(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(zod@4.3.6)': + '@tanstack/zod-adapter@1.166.9(@tanstack/react-router@1.170.32(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(zod@4.3.6)': dependencies: - '@tanstack/react-router': 1.159.5(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@tanstack/react-router': 1.170.32(react-dom@19.2.3(react@19.2.3))(react@19.2.3) zod: 4.3.6 '@testing-library/dom@10.4.1': @@ -26566,15 +26463,6 @@ snapshots: - supports-color optional: true - '@typescript-eslint/project-service@8.49.0(supports-color@7.2.0)(typescript@5.9.3)': - dependencies: - '@typescript-eslint/tsconfig-utils': 8.49.0(typescript@5.9.3) - '@typescript-eslint/types': 8.59.4 - debug: 4.4.3(supports-color@7.2.0) - typescript: 5.9.3 - transitivePeerDependencies: - - supports-color - '@typescript-eslint/project-service@8.59.4(typescript@7.0.2)': dependencies: '@typescript-eslint/tsconfig-utils': 8.59.4(typescript@7.0.2) @@ -26585,21 +26473,12 @@ snapshots: - supports-color optional: true - '@typescript-eslint/scope-manager@8.49.0': - dependencies: - '@typescript-eslint/types': 8.49.0 - '@typescript-eslint/visitor-keys': 8.49.0 - '@typescript-eslint/scope-manager@8.59.4': dependencies: '@typescript-eslint/types': 8.59.4 '@typescript-eslint/visitor-keys': 8.59.4 optional: true - '@typescript-eslint/tsconfig-utils@8.49.0(typescript@5.9.3)': - dependencies: - typescript: 5.9.3 - '@typescript-eslint/tsconfig-utils@8.59.4(typescript@7.0.2)': dependencies: typescript: 7.0.2 @@ -26618,25 +26497,8 @@ snapshots: - supports-color optional: true - '@typescript-eslint/types@8.49.0': {} - '@typescript-eslint/types@8.59.4': {} - '@typescript-eslint/typescript-estree@8.49.0(supports-color@7.2.0)(typescript@5.9.3)': - dependencies: - '@typescript-eslint/project-service': 8.49.0(supports-color@7.2.0)(typescript@5.9.3) - '@typescript-eslint/tsconfig-utils': 8.49.0(typescript@5.9.3) - '@typescript-eslint/types': 8.49.0 - '@typescript-eslint/visitor-keys': 8.49.0 - debug: 4.4.3(supports-color@7.2.0) - minimatch: 9.0.5 - semver: 7.8.4 - tinyglobby: 0.2.17 - ts-api-utils: 2.1.0(typescript@5.9.3) - typescript: 5.9.3 - transitivePeerDependencies: - - supports-color - '@typescript-eslint/typescript-estree@8.59.4(typescript@7.0.2)': dependencies: '@typescript-eslint/project-service': 8.59.4(typescript@7.0.2) @@ -26653,17 +26515,6 @@ snapshots: - supports-color optional: true - '@typescript-eslint/utils@8.49.0(eslint@9.39.4(jiti@2.7.0))(supports-color@7.2.0)(typescript@5.9.3)': - dependencies: - '@eslint-community/eslint-utils': 4.9.1(eslint@9.39.4(jiti@2.7.0)) - '@typescript-eslint/scope-manager': 8.49.0 - '@typescript-eslint/types': 8.49.0 - '@typescript-eslint/typescript-estree': 8.49.0(supports-color@7.2.0)(typescript@5.9.3) - eslint: 9.39.4(jiti@2.7.0) - typescript: 5.9.3 - transitivePeerDependencies: - - supports-color - '@typescript-eslint/utils@8.59.4(eslint@9.39.4(jiti@2.7.0))(typescript@7.0.2)': dependencies: '@eslint-community/eslint-utils': 4.9.1(eslint@9.39.4(jiti@2.7.0)) @@ -26676,11 +26527,6 @@ snapshots: - supports-color optional: true - '@typescript-eslint/visitor-keys@8.49.0': - dependencies: - '@typescript-eslint/types': 8.49.0 - eslint-visitor-keys: 4.2.1 - '@typescript-eslint/visitor-keys@8.59.4': dependencies: '@typescript-eslint/types': 8.59.4 @@ -27413,15 +27259,6 @@ snapshots: transitivePeerDependencies: - supports-color - babel-plugin-jsx-dom-expressions@0.40.3(@babel/core@7.29.0): - dependencies: - '@babel/core': 7.29.0(supports-color@7.2.0) - '@babel/helper-module-imports': 7.18.6 - '@babel/plugin-syntax-jsx': 7.29.7(@babel/core@7.29.0) - '@babel/types': 7.29.7 - html-entities: 2.3.3 - parse5: 7.3.0 - babel-plugin-jsx-dom-expressions@0.40.3(@babel/core@7.29.7): dependencies: '@babel/core': 7.29.7 @@ -27575,13 +27412,6 @@ snapshots: - '@babel/core' - supports-color - babel-preset-solid@1.9.10(@babel/core@7.29.0)(solid-js@1.9.10): - dependencies: - '@babel/core': 7.29.0(supports-color@7.2.0) - babel-plugin-jsx-dom-expressions: 0.40.3(@babel/core@7.29.0) - optionalDependencies: - solid-js: 1.9.10 - babel-preset-solid@1.9.10(@babel/core@7.29.7)(solid-js@1.9.10): dependencies: '@babel/core': 7.29.7 @@ -28172,6 +28002,8 @@ snapshots: cookie-es@2.0.1: {} + cookie-es@3.1.1: {} + cookie-signature@1.2.2: {} cookie@0.6.0: {} @@ -28767,9 +28599,9 @@ snapshots: esbuild-plugin-solid@0.5.0(esbuild@0.28.1)(solid-js@1.9.10): dependencies: - '@babel/core': 7.29.0(supports-color@7.2.0) - '@babel/preset-typescript': 7.28.5(@babel/core@7.29.0) - babel-preset-solid: 1.9.10(@babel/core@7.29.0)(solid-js@1.9.10) + '@babel/core': 7.29.7 + '@babel/preset-typescript': 7.28.5(@babel/core@7.29.7) + babel-preset-solid: 1.9.10(@babel/core@7.29.7)(solid-js@1.9.10) esbuild: 0.28.1 solid-js: 1.9.10 transitivePeerDependencies: @@ -28906,19 +28738,6 @@ snapshots: optionalDependencies: source-map: 0.6.1 - eslint-plugin-solid@0.14.5(eslint@9.39.4(jiti@2.7.0))(supports-color@7.2.0)(typescript@5.9.3): - dependencies: - '@typescript-eslint/utils': 8.49.0(eslint@9.39.4(jiti@2.7.0))(supports-color@7.2.0)(typescript@5.9.3) - eslint: 9.39.4(jiti@2.7.0) - estraverse: 5.3.0 - is-html: 2.0.0 - kebab-case: 1.0.2 - known-css-properties: 0.30.0 - style-to-object: 1.0.14 - typescript: 5.9.3 - transitivePeerDependencies: - - supports-color - eslint-plugin-unused-imports@4.3.0(@typescript-eslint/eslint-plugin@8.59.4(@typescript-eslint/parser@8.59.4(eslint@9.39.4(jiti@2.7.0))(typescript@7.0.2))(eslint@9.39.4(jiti@2.7.0))(typescript@7.0.2))(eslint@9.39.4(jiti@2.7.0)): dependencies: eslint: 9.39.4(jiti@2.7.0) @@ -29762,6 +29581,13 @@ snapshots: optionalDependencies: crossws: 0.4.6(srvx@0.11.17) + h3@2.0.1-rc.20(crossws@0.4.6(srvx@0.11.17)): + dependencies: + rou3: 0.8.1 + srvx: 0.11.17 + optionalDependencies: + crossws: 0.4.6(srvx@0.11.17) + h3@2.0.1-rc.22(crossws@0.4.6(srvx@0.11.17)): dependencies: rou3: 0.8.1 @@ -29938,8 +29764,6 @@ snapshots: dependencies: cheerio: 1.1.2 - html-tags@3.3.1: {} - html-url-attributes@3.0.1: {} html-void-elements@3.0.0: {} @@ -30168,10 +29992,6 @@ snapshots: is-hexadecimal@2.0.1: {} - is-html@2.0.0: - dependencies: - html-tags: 3.3.1 - is-inside-container@1.0.0: dependencies: is-docker: 3.0.0 @@ -30536,8 +30356,6 @@ snapshots: jwa: 2.0.1 safe-buffer: 5.2.1 - kebab-case@1.0.2: {} - keyv@4.5.4: dependencies: json-buffer: 3.0.1 @@ -30579,8 +30397,6 @@ snapshots: knitwork@1.3.0: {} - known-css-properties@0.30.0: {} - kolorist@1.8.0: {} lan-network@0.2.1: {} @@ -31206,7 +31022,7 @@ snapshots: metro-source-map@0.84.4: dependencies: '@babel/traverse': 7.29.0 - '@babel/types': 7.29.0 + '@babel/types': 7.29.7 flow-enums-runtime: 0.0.6 invariant: 2.2.4 metro-symbolicate: 0.84.4 @@ -33883,7 +33699,7 @@ snapshots: dependencies: '@babel/generator': 7.28.5 '@babel/parser': 7.29.0 - '@babel/types': 7.29.0 + '@babel/types': 7.29.7 ast-kit: 2.2.0 birpc: 3.0.0 dts-resolver: 2.1.3(oxc-resolver@11.21.3) @@ -34220,12 +34036,18 @@ snapshots: dependencies: seroval: 1.5.0 + seroval-plugins@1.6.4(seroval@1.6.4): + dependencies: + seroval: 1.6.4 + seroval@1.3.2: {} seroval@1.4.0: {} seroval@1.5.0: {} + seroval@1.6.4: {} + serve-placeholder@2.0.2: dependencies: defu: 6.1.4 @@ -34882,10 +34704,6 @@ snapshots: ts-algebra@2.0.0: {} - ts-api-utils@2.1.0(typescript@5.9.3): - dependencies: - typescript: 5.9.3 - ts-api-utils@2.5.0(typescript@7.0.2): dependencies: typescript: 7.0.2 @@ -35278,6 +35096,17 @@ snapshots: picomatch: 4.0.5 webpack-virtual-modules: 0.6.2 + unplugin@3.3.0(esbuild@0.28.1)(rolldown@1.2.4)(rollup@4.60.1)(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)): + dependencies: + '@jridgewell/remapping': 2.3.5 + picomatch: 4.0.5 + webpack-virtual-modules: 0.6.2 + optionalDependencies: + esbuild: 0.28.1 + rolldown: 1.2.4 + rollup: 4.60.1 + vite: 8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0) + unrun@0.2.19(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.1): dependencies: rolldown: 1.0.0-beta.53(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.1) @@ -35673,10 +35502,6 @@ snapshots: tsx: 4.23.12 yaml: 2.9.0 - vitefu@1.1.1(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)): - optionalDependencies: - vite: 8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0) - vitefu@1.1.3(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)): optionalDependencies: vite: 8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0) @@ -36094,6 +35919,11 @@ snapshots: dependencies: zod: 4.3.6 + zod-to-json-schema@3.25.2(zod@4.5.4): + dependencies: + zod: 4.5.4 + optional: true + zod@3.25.76: {} zod@4.0.0: {} @@ -36102,6 +35932,8 @@ snapshots: zod@4.3.6: {} + zod@4.5.4: {} + zone.js@0.15.1: {} zwitch@2.0.4: {} diff --git a/testing/e2e/package.json b/testing/e2e/package.json index a6d86fa5ec..cd6729fe1e 100644 --- a/testing/e2e/package.json +++ b/testing/e2e/package.json @@ -47,8 +47,8 @@ "@tanstack/devtools-event-bus": "^0.4.1", "@tanstack/nitro-v2-vite-plugin": "^1.155.0", "@tanstack/react-ai-devtools": "workspace:*", - "@tanstack/react-router": "^1.158.4", - "@tanstack/react-start": "^1.159.0", + "@tanstack/react-router": "^1.170.32", + "@tanstack/react-start": "^1.168.49", "arktype": "^2.1.28", "react": "^19.2.3", "react-dom": "^19.2.3", diff --git a/testing/e2e/vite.config.ts b/testing/e2e/vite.config.ts index a6db58d789..47dad6f737 100644 --- a/testing/e2e/vite.config.ts +++ b/testing/e2e/vite.config.ts @@ -14,13 +14,7 @@ const config = defineConfig({ // option only affects the SSR build, where we want the SDK resolved at // runtime via require() instead of inlined into the rollup chunk. ssr: { - external: ['@elevenlabs/elevenlabs-js', '@tanstack/store'], - }, - // Router 1.159 calls `new Store(state, { onUpdate })` (Store 0.8). - // ai-client uses Store 0.11 `createAtom`. Vite prebundling them into one - // `@tanstack_store.js` makes hydration throw `actionsFactory is not a function`. - optimizeDeps: { - exclude: ['@tanstack/store'], + external: ['@elevenlabs/elevenlabs-js'], }, resolve: { tsconfigPaths: true }, plugins: [ diff --git a/testing/panel/package.json b/testing/panel/package.json index f51fa0b379..320270b00b 100644 --- a/testing/panel/package.json +++ b/testing/panel/package.json @@ -28,8 +28,8 @@ "@tanstack/nitro-v2-vite-plugin": "^1.155.0", "@tanstack/react-ai-devtools": "workspace:*", "@tanstack/react-devtools": "^0.9.10", - "@tanstack/react-router": "^1.158.4", - "@tanstack/react-start": "^1.159.0", + "@tanstack/react-router": "^1.170.32", + "@tanstack/react-start": "^1.168.49", "@tanstack/start": "^1.120.20", "highlight.js": "^11.11.1", "lucide-react": "^0.561.0", From 47ea59cda6effbd65b61ff0fdee4025aae342ee4 Mon Sep 17 00:00:00 2001 From: Tom Beckenham <34339192+tombeckenham@users.noreply.github.com> Date: Thu, 3 Sep 2026 17:31:13 +1000 Subject: [PATCH 7/8] test(ai-vertex): mock Gemini adapters in factory tests The @google/genai constructor spy does not intercept across the @tanstack/ai-gemini package boundary, so Vertex factory tests assert the options passed into Gemini adapters instead. --- packages/ai-vertex/package.json | 1 - packages/ai-vertex/tests/factories.test.ts | 86 +++++++++++++++++----- pnpm-lock.yaml | 44 ----------- 3 files changed, 66 insertions(+), 65 deletions(-) diff --git a/packages/ai-vertex/package.json b/packages/ai-vertex/package.json index 0fead1cade..f5d635271c 100644 --- a/packages/ai-vertex/package.json +++ b/packages/ai-vertex/package.json @@ -58,7 +58,6 @@ "@tanstack/ai": "workspace:^" }, "devDependencies": { - "@google/genai": "^2.10.0", "@tanstack/ai": "workspace:*", "@vitest/coverage-v8": "4.1.10", "vite": "^8.2.1" diff --git a/packages/ai-vertex/tests/factories.test.ts b/packages/ai-vertex/tests/factories.test.ts index 54c9c86b84..c21f6c0d5e 100644 --- a/packages/ai-vertex/tests/factories.test.ts +++ b/packages/ai-vertex/tests/factories.test.ts @@ -11,22 +11,35 @@ import { const mocks = vi.hoisted(() => { return { - constructorSpy: vi.fn<(options: Record) => void>(), + constructorSpy: + vi.fn< + (kind: string, options: Record, model: string) => void + >(), } }) -vi.mock('@google/genai', async (importOriginal) => { - const actual = await importOriginal() +vi.mock('@tanstack/ai-gemini', async (importOriginal) => { + const actual = await importOriginal() + const adapterClass = (kind: string) => { + return class { + readonly name = 'gemini' + readonly model: string - class MockGoogleGenAI { - constructor(options: Record) { - mocks.constructorSpy(options) + constructor(options: Record, model: string) { + this.model = model + mocks.constructorSpy(kind, options, model) + } } } return { ...actual, - GoogleGenAI: MockGoogleGenAI, + GeminiTextAdapter: adapterClass('text'), + GeminiImageAdapter: adapterClass('image'), + GeminiEmbeddingAdapter: adapterClass('embedding'), + GeminiTTSAdapter: adapterClass('speech'), + GeminiAudioAdapter: adapterClass('audio'), + GeminiVideoAdapter: adapterClass('video'), } }) @@ -49,11 +62,15 @@ describe('vertex factories', () => { expect(adapter.name).toBe('gemini') expect(adapter.model).toBe('gemini-3.7-flash') - expect(mocks.constructorSpy).toHaveBeenCalledExactlyOnceWith({ - project: 'my-project', - location: 'europe-west1', - vertexai: true, - }) + expect(mocks.constructorSpy).toHaveBeenCalledExactlyOnceWith( + 'text', + { + project: 'my-project', + location: 'europe-west1', + vertexai: true, + }, + 'gemini-3.7-flash', + ) }) it('builds summarize, image, embedding, speech, audio, and video adapters', () => { @@ -66,13 +83,42 @@ describe('vertex factories', () => { expect(vertexAudio('lyria-3-pro-preview', auth).name).toBe('gemini') expect(vertexVideo('veo-3.1-generate-preview', auth).name).toBe('gemini') - expect(mocks.constructorSpy).toHaveBeenCalledTimes(6) - for (const call of mocks.constructorSpy.mock.calls) { - expect(call[0]).toMatchObject({ - project: 'my-project', - location: 'europe-west1', - vertexai: true, - }) - } + expect(mocks.constructorSpy.mock.calls).toEqual([ + [ + 'text', + { project: 'my-project', location: 'europe-west1', vertexai: true }, + 'gemini-3.7-flash', + ], + [ + 'image', + { project: 'my-project', location: 'europe-west1', vertexai: true }, + 'gemini-3.1-flash-image', + ], + [ + 'embedding', + { project: 'my-project', location: 'europe-west1', vertexai: true }, + 'gemini-embedding-001', + ], + [ + 'speech', + { project: 'my-project', location: 'europe-west1', vertexai: true }, + 'gemini-3.1-flash-tts-preview', + ], + [ + 'audio', + { project: 'my-project', location: 'europe-west1', vertexai: true }, + 'lyria-3-pro-preview', + ], + [ + 'video', + { + project: 'my-project', + location: 'europe-west1', + vertexai: true, + allowUrlFetch: undefined, + }, + 'veo-3.1-generate-preview', + ], + ]) }) }) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 8b051ac1f7..f056ed5d3b 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -2913,9 +2913,6 @@ importers: specifier: workspace:^ version: link:../ai-gemini devDependencies: - '@google/genai': - specifier: ^2.10.0 - version: 2.10.0(@modelcontextprotocol/sdk@1.29.0(zod@4.5.4)) '@tanstack/ai': specifier: workspace:* version: link:../ai @@ -20452,19 +20449,6 @@ snapshots: - supports-color - utf-8-validate - '@google/genai@2.10.0(@modelcontextprotocol/sdk@1.29.0(zod@4.5.4))': - dependencies: - google-auth-library: 10.5.0 - p-retry: 4.6.2 - protobufjs: 7.6.4 - ws: 8.21.0 - optionalDependencies: - '@modelcontextprotocol/sdk': 1.29.0(zod@4.5.4) - transitivePeerDependencies: - - bufferutil - - supports-color - - utf-8-validate - '@grpc/grpc-js@1.14.4': dependencies: '@grpc/proto-loader': 0.8.1 @@ -20921,29 +20905,6 @@ snapshots: transitivePeerDependencies: - supports-color - '@modelcontextprotocol/sdk@1.29.0(zod@4.5.4)': - dependencies: - '@hono/node-server': 1.19.14(hono@4.12.23) - ajv: 8.20.0 - ajv-formats: 3.0.1(ajv@8.20.0) - content-type: 1.0.5 - cors: 2.8.6 - cross-spawn: 7.0.6 - eventsource: 3.0.7 - eventsource-parser: 3.1.0 - express: 5.2.1 - express-rate-limit: 8.5.2(express@5.2.1) - hono: 4.12.23 - jose: 6.2.3 - json-schema-typed: 8.0.2 - pkce-challenge: 5.0.1 - raw-body: 3.0.2 - zod: 4.5.4 - zod-to-json-schema: 3.25.2(zod@4.5.4) - transitivePeerDependencies: - - supports-color - optional: true - '@msgpack/msgpack@3.1.3': {} '@msgpackr-extract/msgpackr-extract-darwin-arm64@3.0.4': @@ -35919,11 +35880,6 @@ snapshots: dependencies: zod: 4.3.6 - zod-to-json-schema@3.25.2(zod@4.5.4): - dependencies: - zod: 4.5.4 - optional: true - zod@3.25.76: {} zod@4.0.0: {} From 399c8ce3ed413716daafaa6f23af74be8533452b Mon Sep 17 00:00:00 2001 From: "autofix-ci[bot]" <114827586+autofix-ci[bot]@users.noreply.github.com> Date: Fri, 4 Sep 2026 06:13:54 +0000 Subject: [PATCH 8/8] ci: apply automated fixes --- .../src/routes/_database-demo/api.database-demo.ts | 4 +--- .../src/routes/_execute-prompt/api.execute-prompt.ts | 4 +--- .../src/routes/_execute-prompt/api.realtime-token.ts | 4 +--- 3 files changed, 3 insertions(+), 9 deletions(-) diff --git a/examples/ts-code-mode-web/src/routes/_database-demo/api.database-demo.ts b/examples/ts-code-mode-web/src/routes/_database-demo/api.database-demo.ts index f74be7c6c9..4258f9ceb3 100644 --- a/examples/ts-code-mode-web/src/routes/_database-demo/api.database-demo.ts +++ b/examples/ts-code-mode-web/src/routes/_database-demo/api.database-demo.ts @@ -226,9 +226,7 @@ function wrapWithTimingEvents( })() } -export const Route = createFileRoute( - '/_database-demo/api/database-demo', -)({ +export const Route = createFileRoute('/_database-demo/api/database-demo')({ server: { handlers: { POST: async ({ request }) => { diff --git a/examples/ts-code-mode-web/src/routes/_execute-prompt/api.execute-prompt.ts b/examples/ts-code-mode-web/src/routes/_execute-prompt/api.execute-prompt.ts index 6c9a6149a4..f49ecf5a4f 100644 --- a/examples/ts-code-mode-web/src/routes/_execute-prompt/api.execute-prompt.ts +++ b/examples/ts-code-mode-web/src/routes/_execute-prompt/api.execute-prompt.ts @@ -33,9 +33,7 @@ async function getDriver(): Promise { return cachedDriver } -export const Route = createFileRoute( - '/_execute-prompt/api/execute-prompt', -)({ +export const Route = createFileRoute('/_execute-prompt/api/execute-prompt')({ server: { handlers: { POST: async ({ request }) => { diff --git a/examples/ts-code-mode-web/src/routes/_execute-prompt/api.realtime-token.ts b/examples/ts-code-mode-web/src/routes/_execute-prompt/api.realtime-token.ts index 5cfcd1157e..5b7ab96876 100644 --- a/examples/ts-code-mode-web/src/routes/_execute-prompt/api.realtime-token.ts +++ b/examples/ts-code-mode-web/src/routes/_execute-prompt/api.realtime-token.ts @@ -2,9 +2,7 @@ import { createFileRoute } from '@tanstack/react-router' import { realtimeToken } from '@tanstack/ai' import { openaiRealtimeToken } from '@tanstack/ai-openai' -export const Route = createFileRoute( - '/_execute-prompt/api/realtime-token', -)({ +export const Route = createFileRoute('/_execute-prompt/api/realtime-token')({ server: { handlers: { POST: async () => {