Thanks to visit codestin.com
Credit goes to github.com

Skip to content
Open
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
113 changes: 110 additions & 3 deletions e2e/react-start/serialization-adapters/src/data.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -46,11 +46,95 @@ export const carAdapter = createSerializationAdapter({
makeCar(value),
})

export function makeData() {
function makeFoo(suffix: string = '') {
return new Foo(typeof window === 'undefined' ? 'server' : 'client' + suffix)
export class AsyncFoo {
private readonly internalValue: string
constructor(value: string) {
this.internalValue = value
}

get valueAsync() {
return new Promise<[string]>((resolve) => {
setTimeout(() => {
resolve([this.internalValue])
}, 1000)
})
}

get value() {
return this.internalValue
}

public echo() {
return { message: `echo`, value: this.internalValue }
}
}

export const asyncFooAdapter = createSerializationAdapter({
key: 'asyncFoo',
test: (value) => value instanceof AsyncFoo,
toSerializable: (foo) => foo.value,
toSerializableAsync: (foo) => foo.valueAsync,
fromSerializable: (value) =>
new AsyncFoo(typeof value === 'string' ? value : value[0]),
})

export interface AsyncCar {
__type: 'asynccar'
make: string
model: string
year: number
honk: () => { message: string; make: string; model: string; year: number }
}

export function makeAsyncCar(opts: {
make: string
model: string
year: number
}): AsyncCar {
return {
...opts,
__type: 'asynccar',
honk: () => {
return { message: `Asynchronous Car Honk!`, ...opts }
},
}
}

export const asyncCarAdapter = createSerializationAdapter({
key: 'asyncCar',
test: (value: any): value is AsyncCar =>
'__type' in (value as AsyncCar) && value.__type === 'asynccar',
toSerializable: (car) => ({
make: car.make,
model: car.model,
year: car.year,
}),
fromSerializable: (value: { make: string; model: string; year: number }) =>
makeAsyncCar(value),
})

export function makeAsyncFoo(suffix: string = '') {
return new AsyncFoo(
(typeof window === 'undefined' ? 'server' : 'client') + '-async' + suffix,
)
}

export function makeFoo(suffix: string = '') {
return new Foo(typeof window === 'undefined' ? 'server' : 'client' + suffix)
}

export function makeData() {
return {
asyncFoo: {
singleInstance: makeAsyncFoo(),
},
asyncCar: {
singleInstance: makeAsyncCar({
make: 'Toyota',
model: 'Camry',
year: 2020,
}),
},
foo: {
singleInstance: makeFoo(),
array: [makeFoo('0'), makeFoo('1'), makeFoo('2')],
Expand Down Expand Up @@ -148,12 +232,35 @@ export function RenderData({
year: data.car.singleInstance.year,
})}
</div>
<h3>Async Car</h3>
<h4>expected</h4>
<div data-testid={`${id}-async-car-expected`}>
{JSON.stringify({
make: localData.asyncCar.singleInstance.make,
model: localData.asyncCar.singleInstance.model,
year: localData.asyncCar.singleInstance.year,
})}
</div>
<h4>actual</h4>
<div data-testid={`${id}-async-car-actual`}>
{JSON.stringify({
make: data.asyncCar.singleInstance.make,
model: data.asyncCar.singleInstance.model,
year: data.asyncCar.singleInstance.year,
})}
</div>
<b>Foo</b>
<div data-testid={`${id}-foo`}>
{JSON.stringify({
value: data.foo.singleInstance.value,
})}
</div>
<b>Async Foo</b>
<div data-testid={`${id}-async-foo`}>
{JSON.stringify({
value: data.asyncFoo.singleInstance.value,
})}
</div>
</div>
)
}
Expand Down
22 changes: 22 additions & 0 deletions e2e/react-start/serialization-adapters/src/routeTree.gen.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import { Route as SsrNestedRouteImport } from './routes/ssr/nested'
import { Route as SsrDataOnlyRouteImport } from './routes/ssr/data-only'
import { Route as ServerFunctionNestedRouteImport } from './routes/server-function/nested'
import { Route as ServerFunctionCustomErrorRouteImport } from './routes/server-function/custom-error'
import { Route as ServerFunctionClassInstanceRouteImport } from './routes/server-function/class-instance'

const IndexRoute = IndexRouteImport.update({
id: '/',
Expand Down Expand Up @@ -47,9 +48,16 @@ const ServerFunctionCustomErrorRoute =
path: '/server-function/custom-error',
getParentRoute: () => rootRouteImport,
} as any)
const ServerFunctionClassInstanceRoute =
ServerFunctionClassInstanceRouteImport.update({
id: '/server-function/class-instance',
path: '/server-function/class-instance',
getParentRoute: () => rootRouteImport,
} as any)

export interface FileRoutesByFullPath {
'/': typeof IndexRoute
'/server-function/class-instance': typeof ServerFunctionClassInstanceRoute
'/server-function/custom-error': typeof ServerFunctionCustomErrorRoute
'/server-function/nested': typeof ServerFunctionNestedRoute
'/ssr/data-only': typeof SsrDataOnlyRoute
Expand All @@ -58,6 +66,7 @@ export interface FileRoutesByFullPath {
}
export interface FileRoutesByTo {
'/': typeof IndexRoute
'/server-function/class-instance': typeof ServerFunctionClassInstanceRoute
'/server-function/custom-error': typeof ServerFunctionCustomErrorRoute
'/server-function/nested': typeof ServerFunctionNestedRoute
'/ssr/data-only': typeof SsrDataOnlyRoute
Expand All @@ -67,6 +76,7 @@ export interface FileRoutesByTo {
export interface FileRoutesById {
__root__: typeof rootRouteImport
'/': typeof IndexRoute
'/server-function/class-instance': typeof ServerFunctionClassInstanceRoute
'/server-function/custom-error': typeof ServerFunctionCustomErrorRoute
'/server-function/nested': typeof ServerFunctionNestedRoute
'/ssr/data-only': typeof SsrDataOnlyRoute
Expand All @@ -77,6 +87,7 @@ export interface FileRouteTypes {
fileRoutesByFullPath: FileRoutesByFullPath
fullPaths:
| '/'
| '/server-function/class-instance'
| '/server-function/custom-error'
| '/server-function/nested'
| '/ssr/data-only'
Expand All @@ -85,6 +96,7 @@ export interface FileRouteTypes {
fileRoutesByTo: FileRoutesByTo
to:
| '/'
| '/server-function/class-instance'
| '/server-function/custom-error'
| '/server-function/nested'
| '/ssr/data-only'
Expand All @@ -93,6 +105,7 @@ export interface FileRouteTypes {
id:
| '__root__'
| '/'
| '/server-function/class-instance'
| '/server-function/custom-error'
| '/server-function/nested'
| '/ssr/data-only'
Expand All @@ -102,6 +115,7 @@ export interface FileRouteTypes {
}
export interface RootRouteChildren {
IndexRoute: typeof IndexRoute
ServerFunctionClassInstanceRoute: typeof ServerFunctionClassInstanceRoute
ServerFunctionCustomErrorRoute: typeof ServerFunctionCustomErrorRoute
ServerFunctionNestedRoute: typeof ServerFunctionNestedRoute
SsrDataOnlyRoute: typeof SsrDataOnlyRoute
Expand Down Expand Up @@ -153,11 +167,19 @@ declare module '@tanstack/react-router' {
preLoaderRoute: typeof ServerFunctionCustomErrorRouteImport
parentRoute: typeof rootRouteImport
}
'/server-function/class-instance': {
id: '/server-function/class-instance'
path: '/server-function/class-instance'
fullPath: '/server-function/class-instance'
preLoaderRoute: typeof ServerFunctionClassInstanceRouteImport
parentRoute: typeof rootRouteImport
}
}
}

const rootRouteChildren: RootRouteChildren = {
IndexRoute: IndexRoute,
ServerFunctionClassInstanceRoute: ServerFunctionClassInstanceRoute,
ServerFunctionCustomErrorRoute: ServerFunctionCustomErrorRoute,
ServerFunctionNestedRoute: ServerFunctionNestedRoute,
SsrDataOnlyRoute: SsrDataOnlyRoute,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import { createFileRoute } from '@tanstack/react-router'
import { createServerFn } from '@tanstack/react-start'
import { useState } from 'react'
import { makeAsyncFoo, makeFoo } from '~/data'

const serverFn = createServerFn().handler(() => {
return {
asyncFoo: makeAsyncFoo('-serverFn'),
foo: makeFoo('-serverFn'),
}
})

export const Route = createFileRoute('/server-function/class-instance')({
component: RouteComponent,
})

function RouteComponent() {
const [resp, setResp] = useState<null | Awaited<ReturnType<typeof serverFn>>>(
null,
)

return (
<div>
<button
data-testid="server-function-btn"
onClick={() => serverFn().then(setResp)}
>
trigger serverFn
</button>
<div data-testid="server-function-foo-response">
{JSON.stringify(resp?.foo?.value)}
</div>
<div data-testid="server-function-async-foo-response">
{JSON.stringify(resp?.asyncFoo?.echo())}
</div>
</div>
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,20 @@ export const Route = createFileRoute('/ssr/data-only')({

const honkState = loaderData.car.singleInstance.honk()

const expectedAsyncHonkState = localData.asyncCar.singleInstance.honk()
const asyncHonkState = loaderData.asyncCar.singleInstance.honk()

return (
<div data-testid="data-only-container">
<h2 data-testid="data-only-heading">data-only</h2>
<div>
context: <RenderData id="context" data={context} />
</div>
<hr />
<div>
loader: <RenderData id="loader" data={loaderData} />
</div>
<hr />
<div data-testid="honk-container">
<h3>honk</h3>
<div>
Expand All @@ -43,6 +48,21 @@ export const Route = createFileRoute('/ssr/data-only')({
</div>
</div>
<hr />
<div data-testid="async-honk-container">
<h3>async car honk</h3>
<div>
expected:{' '}
<div data-testid="async-honk-expected-state">
{JSON.stringify(expectedAsyncHonkState)}
</div>
</div>
<div>
actual:{' '}
<div data-testid="async-honk-actual-state">
{JSON.stringify(asyncHonkState)}
</div>
</div>
</div>
<Outlet />
</div>
)
Expand Down
10 changes: 9 additions & 1 deletion e2e/react-start/serialization-adapters/src/start.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
import { createStart } from '@tanstack/react-start'
import { carAdapter, fooAdapter, nestedOuterAdapter } from './data'
import {
asyncCarAdapter,
asyncFooAdapter,
carAdapter,
fooAdapter,
nestedOuterAdapter,
} from './data'
import { customErrorAdapter } from './CustomError'

export const startInstance = createStart(() => {
Expand All @@ -11,6 +17,8 @@ export const startInstance = createStart(() => {
customErrorAdapter,
// only register nestedOuterAdapter here, nestedInnerAdapter is registered as an "extends" of nestedOuterAdapter
nestedOuterAdapter,
asyncCarAdapter,
asyncFooAdapter,
],
}
})
Loading
Loading