Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ const middleware = createMiddleware({ type: 'function' }).client(
async ({ next }) => {
return next({
sendContext: {
serverFn: barFn as any,
serverFn: barFn,
},
})
},
Expand Down
3 changes: 3 additions & 0 deletions packages/router-core/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -420,6 +420,9 @@ export type {
SerializerExtensions,
ValidateSerializable,
RegisteredSerializableInput,
SerializableExtensions,
DefaultSerializable,
Serializable,
} from './ssr/serializer/transformer'

export {
Expand Down
21 changes: 13 additions & 8 deletions packages/router-core/src/ssr/serializer/transformer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,19 @@ import type {
import type { LooseReturnType } from '../../utils'
import type { AnyRoute, ResolveAllSSR } from '../../route'

export type Serializable =
| number
| string
| boolean
| null
| undefined
| bigint
| Date
export interface DefaultSerializable {
number: number
string: string
boolean: boolean
null: null
undefined: undefined
bigint: bigint
Date: Date
}

export interface SerializableExtensions extends DefaultSerializable {}

export type Serializable = SerializableExtensions[keyof SerializableExtensions]

export function createSerializationAdapter<
TInput = unknown,
Expand Down
2 changes: 2 additions & 0 deletions packages/start-client-core/src/createServerFn.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { mergeHeaders } from '@tanstack/router-core/ssr/client'
import { TSS_SERVER_FUNCTION_FACTORY } from './constants'
import { getServerContextAfterGlobalMiddlewares } from './getServerContextAfterGlobalMiddlewares'
import { getStartOptions } from './getStartOptions'
import type { TSS_SERVER_FUNCTION } from './constants'
import type {
AnyValidator,
Constrain,
Expand Down Expand Up @@ -248,6 +249,7 @@ export type Fetcher<TRegister, TMiddlewares, TInputValidator, TResponse> =
: RequiredFetcher<TRegister, TMiddlewares, TInputValidator, TResponse>

export interface FetcherBase {
[TSS_SERVER_FUNCTION]: true
url: string
__executeServer: (opts: {
method: Method
Expand Down
5 changes: 3 additions & 2 deletions packages/start-client-core/src/createStart.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { createMiddleware } from './createMiddleware'
import type { TSS_SERVER_FUNCTION } from './constants'
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

Import TSS_SERVER_FUNCTION as a value so the computed property type-checks.

import type removes the runtime symbol, so when this module augmentation evaluates [TSS_SERVER_FUNCTION] there is no corresponding value and the file fails to compile ('TSS_SERVER_FUNCTION' only refers to a type, but is being used as a value here.). Pull the symbol in as a normal import (and keep using it in the ambient declaration) so the unique symbol is available.

-import type { TSS_SERVER_FUNCTION } from './constants'
+import { TSS_SERVER_FUNCTION } from './constants'

Also applies to: 120-122

🤖 Prompt for AI Agents
In packages/start-client-core/src/createStart.ts around lines 2 and also lines
120-122, the symbol TSS_SERVER_FUNCTION is currently imported with "import type"
so it is erased at runtime and the module augmentation that uses
[TSS_SERVER_FUNCTION] fails to compile; change the import to a normal value
import (remove the "type" qualifier) so the unique symbol/value is present at
runtime and keep using that same identifier in the ambient declaration to allow
the computed property to type-check and compile.

import type {
AnyFunctionMiddleware,
AnyRequestMiddleware,
Expand Down Expand Up @@ -116,7 +117,7 @@ export type AnyStartInstance = StartInstance<any, any, any, any>
export type AnyStartInstanceOptions = StartInstanceOptions<any, any, any, any>

declare module '@tanstack/router-core' {
interface Register {
ssr: true
interface SerializableExtensions {
serverFn: { [TSS_SERVER_FUNCTION]: true }
}
}
12 changes: 12 additions & 0 deletions packages/start-client-core/src/tests/createServerFn.test-d.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { describe, expectTypeOf, test } from 'vitest'
import { createMiddleware } from '../createMiddleware'
import { createServerFn } from '../createServerFn'
import { TSS_SERVER_FUNCTION } from '../constants'
import type { Constrain, Register, Validator } from '@tanstack/router-core'
import type { ConstrainValidator } from '../createServerFn'

Expand Down Expand Up @@ -586,3 +587,14 @@ test('createServerFn with inputValidator and request middleware', () => {
Promise<string>
>()
})

test('createServerFn has TSS_SERVER_FUNCTION symbol set', () => {
const fn = createServerFn().handler(() => ({}))
expectTypeOf(fn).toHaveProperty(TSS_SERVER_FUNCTION)
expectTypeOf(fn[TSS_SERVER_FUNCTION]).toEqualTypeOf<true>()
})

test('createServerFn fetcher itself is serializable', () => {
const fn1 = createServerFn().handler(() => ({}))
const fn2 = createServerFn().handler(() => fn1)
})
Loading