@tanstack/router-core 1.121.33 → 1.121.39
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/index.d.cts +1 -1
- package/dist/cjs/router.cjs +5 -0
- package/dist/cjs/router.cjs.map +1 -1
- package/dist/cjs/router.d.cts +2 -2
- package/dist/cjs/scroll-restoration.cjs +1 -1
- package/dist/cjs/scroll-restoration.cjs.map +1 -1
- package/dist/cjs/serializer.cjs +146 -0
- package/dist/cjs/serializer.cjs.map +1 -0
- package/dist/cjs/serializer.d.cts +7 -1
- package/dist/cjs/ssr/client.cjs +12 -0
- package/dist/cjs/ssr/client.cjs.map +1 -0
- package/dist/cjs/ssr/client.d.cts +6 -0
- package/dist/cjs/ssr/createRequestHandler.cjs +50 -0
- package/dist/cjs/ssr/createRequestHandler.cjs.map +1 -0
- package/dist/cjs/ssr/createRequestHandler.d.cts +9 -0
- package/dist/cjs/ssr/handlerCallback.cjs +7 -0
- package/dist/cjs/ssr/handlerCallback.cjs.map +1 -0
- package/dist/cjs/ssr/handlerCallback.d.cts +9 -0
- package/dist/cjs/ssr/headers.cjs +39 -0
- package/dist/cjs/ssr/headers.cjs.map +1 -0
- package/dist/cjs/ssr/headers.d.cts +5 -0
- package/dist/cjs/ssr/json.cjs +14 -0
- package/dist/cjs/ssr/json.cjs.map +1 -0
- package/dist/cjs/ssr/json.d.cts +4 -0
- package/dist/cjs/ssr/server.cjs +17 -0
- package/dist/cjs/ssr/server.cjs.map +1 -0
- package/dist/cjs/ssr/server.d.cts +8 -0
- package/dist/cjs/ssr/ssr-client.cjs +131 -0
- package/dist/cjs/ssr/ssr-client.cjs.map +1 -0
- package/dist/cjs/ssr/ssr-client.d.cts +68 -0
- package/dist/cjs/ssr/ssr-server.cjs +248 -0
- package/dist/cjs/ssr/ssr-server.cjs.map +1 -0
- package/dist/cjs/ssr/ssr-server.d.cts +32 -0
- package/dist/cjs/ssr/transformStreamWithRouter.cjs +183 -0
- package/dist/cjs/ssr/transformStreamWithRouter.cjs.map +1 -0
- package/dist/cjs/ssr/transformStreamWithRouter.d.cts +6 -0
- package/dist/cjs/ssr/tsrScript.cjs +4 -0
- package/dist/cjs/ssr/tsrScript.cjs.map +1 -0
- package/dist/cjs/ssr/tsrScript.d.cts +1 -0
- package/dist/esm/index.d.ts +1 -1
- package/dist/esm/router.d.ts +2 -2
- package/dist/esm/router.js +5 -0
- package/dist/esm/router.js.map +1 -1
- package/dist/esm/scroll-restoration.js +1 -1
- package/dist/esm/scroll-restoration.js.map +1 -1
- package/dist/esm/serializer.d.ts +7 -1
- package/dist/esm/serializer.js +146 -0
- package/dist/esm/serializer.js.map +1 -0
- package/dist/esm/ssr/client.d.ts +6 -0
- package/dist/esm/ssr/client.js +12 -0
- package/dist/esm/ssr/client.js.map +1 -0
- package/dist/esm/ssr/createRequestHandler.d.ts +9 -0
- package/dist/esm/ssr/createRequestHandler.js +50 -0
- package/dist/esm/ssr/createRequestHandler.js.map +1 -0
- package/dist/esm/ssr/handlerCallback.d.ts +9 -0
- package/dist/esm/ssr/handlerCallback.js +7 -0
- package/dist/esm/ssr/handlerCallback.js.map +1 -0
- package/dist/esm/ssr/headers.d.ts +5 -0
- package/dist/esm/ssr/headers.js +39 -0
- package/dist/esm/ssr/headers.js.map +1 -0
- package/dist/esm/ssr/json.d.ts +4 -0
- package/dist/esm/ssr/json.js +14 -0
- package/dist/esm/ssr/json.js.map +1 -0
- package/dist/esm/ssr/server.d.ts +8 -0
- package/dist/esm/ssr/server.js +17 -0
- package/dist/esm/ssr/server.js.map +1 -0
- package/dist/esm/ssr/ssr-client.d.ts +68 -0
- package/dist/esm/ssr/ssr-client.js +131 -0
- package/dist/esm/ssr/ssr-client.js.map +1 -0
- package/dist/esm/ssr/ssr-server.d.ts +32 -0
- package/dist/esm/ssr/ssr-server.js +248 -0
- package/dist/esm/ssr/ssr-server.js.map +1 -0
- package/dist/esm/ssr/transformStreamWithRouter.d.ts +6 -0
- package/dist/esm/ssr/transformStreamWithRouter.js +183 -0
- package/dist/esm/ssr/transformStreamWithRouter.js.map +1 -0
- package/dist/esm/ssr/tsrScript.d.ts +1 -0
- package/dist/esm/ssr/tsrScript.js +5 -0
- package/dist/esm/ssr/tsrScript.js.map +1 -0
- package/package.json +29 -2
- package/src/index.ts +1 -0
- package/src/router.ts +8 -5
- package/src/scroll-restoration.ts +1 -1
- package/src/serializer.ts +174 -1
- package/src/ssr/client.ts +15 -0
- package/src/ssr/createRequestHandler.ts +74 -0
- package/src/ssr/handlerCallback.ts +15 -0
- package/src/ssr/headers.ts +51 -0
- package/src/ssr/json.ts +18 -0
- package/src/ssr/server.ts +23 -0
- package/src/ssr/ssr-client.ts +244 -0
- package/src/ssr/ssr-server.ts +345 -0
- package/src/ssr/transformStreamWithRouter.ts +258 -0
- package/src/ssr/tsrScript.ts +91 -0
- package/src/vite-env.d.ts +4 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"transformStreamWithRouter.js","sources":["../../../src/ssr/transformStreamWithRouter.ts"],"sourcesContent":["import { ReadableStream } from 'node:stream/web'\nimport { Readable } from 'node:stream'\nimport { createControlledPromise } from '../utils'\nimport type { AnyRouter } from '../router'\n\nexport function transformReadableStreamWithRouter(\n router: AnyRouter,\n routerStream: ReadableStream,\n) {\n return transformStreamWithRouter(router, routerStream)\n}\n\nexport function transformPipeableStreamWithRouter(\n router: AnyRouter,\n routerStream: Readable,\n) {\n return Readable.fromWeb(\n transformStreamWithRouter(router, Readable.toWeb(routerStream)),\n )\n}\n\n// regex pattern for matching closing body and html tags\nconst patternBodyStart = /(<body)/\nconst patternBodyEnd = /(<\\/body>)/\nconst patternHtmlEnd = /(<\\/html>)/\nconst patternHeadStart = /(<head.*?>)/\n// regex pattern for matching closing tags\nconst patternClosingTag = /(<\\/[a-zA-Z][\\w:.-]*?>)/g\n\nconst textDecoder = new TextDecoder()\n\ntype ReadablePassthrough = {\n stream: ReadableStream\n write: (chunk: string) => void\n end: (chunk?: string) => void\n destroy: (error: unknown) => void\n destroyed: boolean\n}\n\nfunction createPassthrough() {\n let controller: ReadableStreamDefaultController<any>\n const encoder = new TextEncoder()\n const stream = new ReadableStream({\n start(c) {\n controller = c\n },\n })\n\n const res: ReadablePassthrough = {\n stream,\n write: (chunk) => {\n controller.enqueue(encoder.encode(chunk))\n },\n end: (chunk) => {\n if (chunk) {\n controller.enqueue(encoder.encode(chunk))\n }\n controller.close()\n res.destroyed = true\n },\n destroy: (error) => {\n controller.error(error)\n },\n destroyed: false,\n }\n\n return res\n}\n\nasync function readStream(\n stream: ReadableStream,\n opts: {\n onData?: (chunk: ReadableStreamReadValueResult<any>) => void\n onEnd?: () => void\n onError?: (error: unknown) => void\n },\n) {\n try {\n const reader = stream.getReader()\n let chunk\n while (!(chunk = await reader.read()).done) {\n opts.onData?.(chunk)\n }\n opts.onEnd?.()\n } catch (error) {\n opts.onError?.(error)\n }\n}\n\nexport function transformStreamWithRouter(\n router: AnyRouter,\n appStream: ReadableStream,\n) {\n const finalPassThrough = createPassthrough()\n\n let isAppRendering = true as boolean\n let routerStreamBuffer = ''\n let pendingClosingTags = ''\n let bodyStarted = false as boolean\n let headStarted = false as boolean\n let leftover = ''\n let leftoverHtml = ''\n\n function getBufferedRouterStream() {\n const html = routerStreamBuffer\n routerStreamBuffer = ''\n return html\n }\n\n function decodeChunk(chunk: unknown): string {\n if (chunk instanceof Uint8Array) {\n return textDecoder.decode(chunk)\n }\n return String(chunk)\n }\n\n const injectedHtmlDonePromise = createControlledPromise<void>()\n\n let processingCount = 0\n\n // Process any already-injected HTML\n router.serverSsr!.injectedHtml.forEach((promise) => {\n handleInjectedHtml(promise)\n })\n\n // Listen for any new injected HTML\n const stopListeningToInjectedHtml = router.subscribe(\n 'onInjectedHtml',\n (e) => {\n handleInjectedHtml(e.promise)\n },\n )\n\n function handleInjectedHtml(promise: Promise<string>) {\n processingCount++\n\n promise\n .then((html) => {\n if (!bodyStarted) {\n routerStreamBuffer += html\n } else {\n finalPassThrough.write(html)\n }\n })\n .catch(injectedHtmlDonePromise.reject)\n .finally(() => {\n processingCount--\n\n if (!isAppRendering && processingCount === 0) {\n stopListeningToInjectedHtml()\n injectedHtmlDonePromise.resolve()\n }\n })\n }\n\n injectedHtmlDonePromise\n .then(() => {\n const finalHtml =\n leftoverHtml + getBufferedRouterStream() + pendingClosingTags\n\n finalPassThrough.end(finalHtml)\n })\n .catch((err) => {\n console.error('Error reading routerStream:', err)\n finalPassThrough.destroy(err)\n })\n\n // Transform the appStream\n readStream(appStream, {\n onData: (chunk) => {\n const text = decodeChunk(chunk.value)\n\n let chunkString = leftover + text\n const bodyEndMatch = chunkString.match(patternBodyEnd)\n const htmlEndMatch = chunkString.match(patternHtmlEnd)\n\n if (!bodyStarted) {\n const bodyStartMatch = chunkString.match(patternBodyStart)\n if (bodyStartMatch) {\n bodyStarted = true\n }\n }\n\n if (!headStarted) {\n const headStartMatch = chunkString.match(patternHeadStart)\n if (headStartMatch) {\n headStarted = true\n const index = headStartMatch.index!\n const headTag = headStartMatch[0]\n const remaining = chunkString.slice(index + headTag.length)\n finalPassThrough.write(\n chunkString.slice(0, index) + headTag + getBufferedRouterStream(),\n )\n // make sure to only write `remaining` until the next closing tag\n chunkString = remaining\n }\n }\n\n if (!bodyStarted) {\n finalPassThrough.write(chunkString)\n leftover = ''\n return\n }\n\n // If either the body end or html end is in the chunk,\n // We need to get all of our data in asap\n if (\n bodyEndMatch &&\n htmlEndMatch &&\n bodyEndMatch.index! < htmlEndMatch.index!\n ) {\n const bodyEndIndex = bodyEndMatch.index!\n pendingClosingTags = chunkString.slice(bodyEndIndex)\n\n finalPassThrough.write(\n chunkString.slice(0, bodyEndIndex) + getBufferedRouterStream(),\n )\n\n leftover = ''\n return\n }\n\n let result: RegExpExecArray | null\n let lastIndex = 0\n while ((result = patternClosingTag.exec(chunkString)) !== null) {\n lastIndex = result.index + result[0].length\n }\n\n if (lastIndex > 0) {\n const processed =\n chunkString.slice(0, lastIndex) +\n getBufferedRouterStream() +\n leftoverHtml\n\n finalPassThrough.write(processed)\n leftover = chunkString.slice(lastIndex)\n } else {\n leftover = chunkString\n leftoverHtml += getBufferedRouterStream()\n }\n },\n onEnd: () => {\n // Mark the app as done rendering\n isAppRendering = false\n\n // If there are no pending promises, resolve the injectedHtmlDonePromise\n if (processingCount === 0) {\n injectedHtmlDonePromise.resolve()\n }\n },\n onError: (error) => {\n console.error('Error reading appStream:', error)\n finalPassThrough.destroy(error)\n },\n })\n\n return finalPassThrough.stream\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
const minifiedTsrBootStrapScript = 'const __TSR_SSR__={matches:[],streamedValues:{},initMatch:o=>(__TSR_SSR__.matches.push(o),o.extracted?.forEach(l=>{if(l.type==="stream"){let r;l.value=new ReadableStream({start(e){r={enqueue:t=>{try{e.enqueue(t)}catch{}},close:()=>{try{e.close()}catch{}}}}}),l.value.controller=r}else{let r,e;l.value=new Promise((t,n)=>{e=n,r=t}),l.value.reject=e,l.value.resolve=r}}),!0),resolvePromise:({matchId:o,id:l,promiseState:r})=>{const e=__TSR_SSR__.matches.find(t=>t.id===o);if(e){const t=e.extracted?.[l];if(t&&t.type==="promise"&&t.value&&r.status==="success")return t.value.resolve(r.data),!0}return!1},injectChunk:({matchId:o,id:l,chunk:r})=>{const e=__TSR_SSR__.matches.find(t=>t.id===o);if(e){const t=e.extracted?.[l];if(t&&t.type==="stream"&&t.value?.controller)return t.value.controller.enqueue(new TextEncoder().encode(r.toString())),!0}return!1},closeStream:({matchId:o,id:l})=>{const r=__TSR_SSR__.matches.find(e=>e.id===o);if(r){const e=r.extracted?.[l];if(e&&e.type==="stream"&&e.value?.controller)return e.value.controller.close(),!0}return!1},cleanScripts:()=>{document.querySelectorAll(".tsr-once").forEach(o=>{o.remove()})}};window.__TSR_SSR__=__TSR_SSR__;\n';
|
|
2
|
+
export {
|
|
3
|
+
minifiedTsrBootStrapScript as default
|
|
4
|
+
};
|
|
5
|
+
//# sourceMappingURL=tsrScript.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tsrScript.js","sources":["../../../src/ssr/tsrScript.ts?script-string"],"sourcesContent":["import type { ControllablePromise } from '../router'\nimport type { TsrSsrGlobal } from './ssr-client'\n\nconst __TSR_SSR__: TsrSsrGlobal = {\n matches: [],\n streamedValues: {},\n initMatch: (match) => {\n __TSR_SSR__.matches.push(match)\n\n match.extracted?.forEach((ex) => {\n if (ex.type === 'stream') {\n let controller\n ex.value = new ReadableStream({\n start(c) {\n controller = {\n enqueue: (chunk: unknown) => {\n try {\n c.enqueue(chunk)\n } catch {}\n },\n close: () => {\n try {\n c.close()\n } catch {}\n },\n }\n },\n })\n ex.value.controller = controller\n } else {\n let resolve: ControllablePromise['reject'] | undefined\n let reject: ControllablePromise['reject'] | undefined\n\n ex.value = new Promise((_resolve, _reject) => {\n reject = _reject\n resolve = _resolve\n }) as ControllablePromise\n ex.value.reject = reject!\n ex.value.resolve = resolve!\n }\n })\n\n return true\n },\n resolvePromise: ({ matchId, id, promiseState }) => {\n const match = __TSR_SSR__.matches.find((m) => m.id === matchId)\n if (match) {\n const ex = match.extracted?.[id]\n if (\n ex &&\n ex.type === 'promise' &&\n ex.value &&\n promiseState.status === 'success'\n ) {\n ex.value.resolve(promiseState.data)\n return true\n }\n }\n return false\n },\n injectChunk: ({ matchId, id, chunk }) => {\n const match = __TSR_SSR__.matches.find((m) => m.id === matchId)\n\n if (match) {\n const ex = match.extracted?.[id]\n if (ex && ex.type === 'stream' && ex.value?.controller) {\n ex.value.controller.enqueue(new TextEncoder().encode(chunk.toString()))\n return true\n }\n }\n return false\n },\n closeStream: ({ matchId, id }) => {\n const match = __TSR_SSR__.matches.find((m) => m.id === matchId)\n if (match) {\n const ex = match.extracted?.[id]\n if (ex && ex.type === 'stream' && ex.value?.controller) {\n ex.value.controller.close()\n return true\n }\n }\n return false\n },\n cleanScripts: () => {\n document.querySelectorAll('.tsr-once').forEach((el) => {\n el.remove()\n })\n },\n}\n\nwindow.__TSR_SSR__ = __TSR_SSR__\n"],"names":[],"mappings":"AAAA,MAAA,6BAAe;"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tanstack/router-core",
|
|
3
|
-
"version": "1.121.
|
|
3
|
+
"version": "1.121.39",
|
|
4
4
|
"description": "Modern and scalable routing for React applications",
|
|
5
5
|
"author": "Tanner Linsley",
|
|
6
6
|
"license": "MIT",
|
|
@@ -33,6 +33,26 @@
|
|
|
33
33
|
"default": "./dist/cjs/index.cjs"
|
|
34
34
|
}
|
|
35
35
|
},
|
|
36
|
+
"./ssr/server": {
|
|
37
|
+
"import": {
|
|
38
|
+
"types": "./dist/esm/ssr/server.d.ts",
|
|
39
|
+
"default": "./dist/esm/ssr/server.js"
|
|
40
|
+
},
|
|
41
|
+
"require": {
|
|
42
|
+
"types": "./dist/cjs/ssr/server.d.cts",
|
|
43
|
+
"default": "./dist/cjs/ssr/server.cjs"
|
|
44
|
+
}
|
|
45
|
+
},
|
|
46
|
+
"./ssr/client": {
|
|
47
|
+
"import": {
|
|
48
|
+
"types": "./dist/esm/ssr/client.d.ts",
|
|
49
|
+
"default": "./dist/esm/ssr/client.js"
|
|
50
|
+
},
|
|
51
|
+
"require": {
|
|
52
|
+
"types": "./dist/cjs/ssr/client.d.cts",
|
|
53
|
+
"default": "./dist/cjs/ssr/client.cjs"
|
|
54
|
+
}
|
|
55
|
+
},
|
|
36
56
|
"./package.json": "./package.json"
|
|
37
57
|
},
|
|
38
58
|
"sideEffects": false,
|
|
@@ -45,8 +65,15 @@
|
|
|
45
65
|
},
|
|
46
66
|
"dependencies": {
|
|
47
67
|
"@tanstack/store": "^0.7.0",
|
|
68
|
+
"cookie-es": "^1.2.2",
|
|
69
|
+
"jsesc": "^3.1.0",
|
|
48
70
|
"tiny-invariant": "^1.3.3",
|
|
49
|
-
"
|
|
71
|
+
"tiny-warning": "^1.0.3",
|
|
72
|
+
"@tanstack/history": "1.121.34"
|
|
73
|
+
},
|
|
74
|
+
"devDependencies": {
|
|
75
|
+
"@types/jsesc": "^3.0.3",
|
|
76
|
+
"esbuild": "^0.25.0"
|
|
50
77
|
},
|
|
51
78
|
"scripts": {}
|
|
52
79
|
}
|
package/src/index.ts
CHANGED
package/src/router.ts
CHANGED
|
@@ -77,7 +77,7 @@ import type {
|
|
|
77
77
|
NavigateFn,
|
|
78
78
|
} from './RouterProvider'
|
|
79
79
|
import type { Manifest } from './manifest'
|
|
80
|
-
import type {
|
|
80
|
+
import type { TsrSerializer } from './serializer'
|
|
81
81
|
import type { AnySchema, AnyValidator } from './validators'
|
|
82
82
|
import type { NavigateOptions, ResolveRelativePath, ToOptions } from './link'
|
|
83
83
|
import type { NotFoundError } from './not-found'
|
|
@@ -1016,7 +1016,8 @@ export class RouterCore<
|
|
|
1016
1016
|
if (__tempLocation && (!__tempKey || __tempKey === this.tempLocationKey)) {
|
|
1017
1017
|
// Sync up the location keys
|
|
1018
1018
|
const parsedTempLocation = parse(__tempLocation) as any
|
|
1019
|
-
parsedTempLocation.state.key = location.state.key
|
|
1019
|
+
parsedTempLocation.state.key = location.state.key // TODO: Remove in v2 - use __TSR_key instead
|
|
1020
|
+
parsedTempLocation.state.__TSR_key = location.state.__TSR_key
|
|
1020
1021
|
|
|
1021
1022
|
delete parsedTempLocation.state.__tempLocation
|
|
1022
1023
|
|
|
@@ -1616,7 +1617,8 @@ export class RouterCore<
|
|
|
1616
1617
|
// temporarily add the previous values to the next state so they don't affect
|
|
1617
1618
|
// the comparison
|
|
1618
1619
|
const ignoredProps = [
|
|
1619
|
-
'key',
|
|
1620
|
+
'key', // TODO: Remove in v2 - use __TSR_key instead
|
|
1621
|
+
'__TSR_key',
|
|
1620
1622
|
'__TSR_index',
|
|
1621
1623
|
'__hashScrollIntoViewOptions',
|
|
1622
1624
|
] as const
|
|
@@ -1657,7 +1659,8 @@ export class RouterCore<
|
|
|
1657
1659
|
...nextHistory.state,
|
|
1658
1660
|
__tempKey: undefined!,
|
|
1659
1661
|
__tempLocation: undefined!,
|
|
1660
|
-
|
|
1662
|
+
__TSR_key: undefined!,
|
|
1663
|
+
key: undefined!, // TODO: Remove in v2 - use __TSR_key instead
|
|
1661
1664
|
},
|
|
1662
1665
|
},
|
|
1663
1666
|
},
|
|
@@ -2854,7 +2857,7 @@ export class RouterCore<
|
|
|
2854
2857
|
|
|
2855
2858
|
ssr?: {
|
|
2856
2859
|
manifest: Manifest | undefined
|
|
2857
|
-
serializer:
|
|
2860
|
+
serializer: TsrSerializer
|
|
2858
2861
|
}
|
|
2859
2862
|
|
|
2860
2863
|
serverSsr?: {
|
|
@@ -79,7 +79,7 @@ export const scrollRestorationCache = createScrollRestorationCache()
|
|
|
79
79
|
*/
|
|
80
80
|
|
|
81
81
|
export const defaultGetScrollRestorationKey = (location: ParsedLocation) => {
|
|
82
|
-
return location.state.
|
|
82
|
+
return location.state.__TSR_key! || location.href
|
|
83
83
|
}
|
|
84
84
|
|
|
85
85
|
export function getCssSelector(el: any): string {
|
package/src/serializer.ts
CHANGED
|
@@ -1,10 +1,17 @@
|
|
|
1
|
-
|
|
1
|
+
import { isPlainObject } from './utils'
|
|
2
|
+
|
|
3
|
+
export interface TsrSerializer {
|
|
2
4
|
stringify: (obj: unknown) => string
|
|
3
5
|
parse: (str: string) => unknown
|
|
4
6
|
encode: <T>(value: T) => T
|
|
5
7
|
decode: <T>(value: T) => T
|
|
6
8
|
}
|
|
7
9
|
|
|
10
|
+
/**
|
|
11
|
+
* @deprecated This is re-export of TsrSerializer which is the generic Router serializer interface. Going forward StartSerializer will be used specifically as a Tanstack Start serializer interface.
|
|
12
|
+
*/
|
|
13
|
+
export interface StartSerializer extends TsrSerializer {}
|
|
14
|
+
|
|
8
15
|
export type SerializerStringifyBy<T, TSerializable> = T extends TSerializable
|
|
9
16
|
? T
|
|
10
17
|
: T extends (...args: Array<any>) => any
|
|
@@ -30,3 +37,169 @@ export type Serializable = Date | undefined | Error | FormData | bigint
|
|
|
30
37
|
export type SerializerStringify<T> = SerializerStringifyBy<T, Serializable>
|
|
31
38
|
|
|
32
39
|
export type SerializerParse<T> = SerializerParseBy<T, Serializable>
|
|
40
|
+
export const tsrSerializer: TsrSerializer = {
|
|
41
|
+
stringify: (value: any) =>
|
|
42
|
+
JSON.stringify(value, function replacer(key, val) {
|
|
43
|
+
const ogVal = this[key]
|
|
44
|
+
const serializer = serializers.find((t) => t.stringifyCondition(ogVal))
|
|
45
|
+
|
|
46
|
+
if (serializer) {
|
|
47
|
+
return serializer.stringify(ogVal)
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
return val
|
|
51
|
+
}),
|
|
52
|
+
parse: (value: string) =>
|
|
53
|
+
JSON.parse(value, function parser(key, val) {
|
|
54
|
+
const ogVal = this[key]
|
|
55
|
+
if (isPlainObject(ogVal)) {
|
|
56
|
+
const serializer = serializers.find((t) => t.parseCondition(ogVal))
|
|
57
|
+
|
|
58
|
+
if (serializer) {
|
|
59
|
+
return serializer.parse(ogVal)
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
return val
|
|
64
|
+
}),
|
|
65
|
+
encode: (value: any) => {
|
|
66
|
+
// When encoding, dive first
|
|
67
|
+
if (Array.isArray(value)) {
|
|
68
|
+
return value.map((v) => tsrSerializer.encode(v))
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
if (isPlainObject(value)) {
|
|
72
|
+
return Object.fromEntries(
|
|
73
|
+
Object.entries(value).map(([key, v]) => [key, tsrSerializer.encode(v)]),
|
|
74
|
+
)
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
const serializer = serializers.find((t) => t.stringifyCondition(value))
|
|
78
|
+
if (serializer) {
|
|
79
|
+
return serializer.stringify(value)
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
return value
|
|
83
|
+
},
|
|
84
|
+
decode: (value: any) => {
|
|
85
|
+
// Attempt transform first
|
|
86
|
+
if (isPlainObject(value)) {
|
|
87
|
+
const serializer = serializers.find((t) => t.parseCondition(value))
|
|
88
|
+
if (serializer) {
|
|
89
|
+
return serializer.parse(value)
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
if (Array.isArray(value)) {
|
|
94
|
+
return value.map((v) => tsrSerializer.decode(v))
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
if (isPlainObject(value)) {
|
|
98
|
+
return Object.fromEntries(
|
|
99
|
+
Object.entries(value).map(([key, v]) => [key, tsrSerializer.decode(v)]),
|
|
100
|
+
)
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
return value
|
|
104
|
+
},
|
|
105
|
+
}
|
|
106
|
+
const createSerializer = <TKey extends string, TInput, TSerialized>(
|
|
107
|
+
key: TKey,
|
|
108
|
+
check: (value: any) => value is TInput,
|
|
109
|
+
toValue: (value: TInput) => TSerialized,
|
|
110
|
+
fromValue: (value: TSerialized) => TInput,
|
|
111
|
+
) => ({
|
|
112
|
+
key,
|
|
113
|
+
stringifyCondition: check,
|
|
114
|
+
stringify: (value: any) => ({ [`$${key}`]: toValue(value) }),
|
|
115
|
+
parseCondition: (value: any) => Object.hasOwn(value, `$${key}`),
|
|
116
|
+
parse: (value: any) => fromValue(value[`$${key}`]),
|
|
117
|
+
})
|
|
118
|
+
// Keep these ordered by predicted frequency
|
|
119
|
+
// Make sure to keep DefaultSerializable in sync with these serializers
|
|
120
|
+
// Also, make sure that they are unit tested in serializer.test.tsx
|
|
121
|
+
const serializers = [
|
|
122
|
+
createSerializer(
|
|
123
|
+
// Key
|
|
124
|
+
'undefined',
|
|
125
|
+
// Check
|
|
126
|
+
(v): v is undefined => v === undefined,
|
|
127
|
+
// To
|
|
128
|
+
() => 0,
|
|
129
|
+
// From
|
|
130
|
+
() => undefined,
|
|
131
|
+
),
|
|
132
|
+
createSerializer(
|
|
133
|
+
// Key
|
|
134
|
+
'date',
|
|
135
|
+
// Check
|
|
136
|
+
(v): v is Date => v instanceof Date,
|
|
137
|
+
// To
|
|
138
|
+
(v) => v.toISOString(),
|
|
139
|
+
// From
|
|
140
|
+
(v) => new Date(v),
|
|
141
|
+
),
|
|
142
|
+
createSerializer(
|
|
143
|
+
// Key
|
|
144
|
+
'error',
|
|
145
|
+
// Check
|
|
146
|
+
(v): v is Error => v instanceof Error,
|
|
147
|
+
// To
|
|
148
|
+
(v) => ({
|
|
149
|
+
...v,
|
|
150
|
+
message: v.message,
|
|
151
|
+
stack: process.env.NODE_ENV === 'development' ? v.stack : undefined,
|
|
152
|
+
cause: v.cause,
|
|
153
|
+
}),
|
|
154
|
+
// From
|
|
155
|
+
(v) => Object.assign(new Error(v.message), v),
|
|
156
|
+
),
|
|
157
|
+
createSerializer(
|
|
158
|
+
// Key
|
|
159
|
+
'formData',
|
|
160
|
+
// Check
|
|
161
|
+
(v): v is FormData => v instanceof FormData,
|
|
162
|
+
// To
|
|
163
|
+
(v) => {
|
|
164
|
+
const entries: Record<
|
|
165
|
+
string,
|
|
166
|
+
Array<FormDataEntryValue> | FormDataEntryValue
|
|
167
|
+
> = {}
|
|
168
|
+
v.forEach((value, key) => {
|
|
169
|
+
const entry = entries[key]
|
|
170
|
+
if (entry !== undefined) {
|
|
171
|
+
if (Array.isArray(entry)) {
|
|
172
|
+
entry.push(value)
|
|
173
|
+
} else {
|
|
174
|
+
entries[key] = [entry, value]
|
|
175
|
+
}
|
|
176
|
+
} else {
|
|
177
|
+
entries[key] = value
|
|
178
|
+
}
|
|
179
|
+
})
|
|
180
|
+
return entries
|
|
181
|
+
},
|
|
182
|
+
// From
|
|
183
|
+
(v) => {
|
|
184
|
+
const formData = new FormData()
|
|
185
|
+
Object.entries(v).forEach(([key, value]) => {
|
|
186
|
+
if (Array.isArray(value)) {
|
|
187
|
+
value.forEach((val) => formData.append(key, val))
|
|
188
|
+
} else {
|
|
189
|
+
formData.append(key, value)
|
|
190
|
+
}
|
|
191
|
+
})
|
|
192
|
+
return formData
|
|
193
|
+
},
|
|
194
|
+
),
|
|
195
|
+
createSerializer(
|
|
196
|
+
// Key
|
|
197
|
+
'bigint',
|
|
198
|
+
// Check
|
|
199
|
+
(v): v is bigint => typeof v === 'bigint',
|
|
200
|
+
// To
|
|
201
|
+
(v) => v.toString(),
|
|
202
|
+
// From
|
|
203
|
+
(v) => BigInt(v),
|
|
204
|
+
),
|
|
205
|
+
] as const
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export { mergeHeaders, headersInitToObject } from './headers'
|
|
2
|
+
export { json } from './json'
|
|
3
|
+
export type { JsonResponse } from './json'
|
|
4
|
+
export { hydrate } from './ssr-client'
|
|
5
|
+
export type {
|
|
6
|
+
DehydratedRouter,
|
|
7
|
+
ClientExtractedBaseEntry,
|
|
8
|
+
TsrSsrGlobal,
|
|
9
|
+
ClientExtractedEntry,
|
|
10
|
+
SsrMatch,
|
|
11
|
+
ClientExtractedPromise,
|
|
12
|
+
ClientExtractedStream,
|
|
13
|
+
ResolvePromiseState,
|
|
14
|
+
} from './ssr-client'
|
|
15
|
+
export { tsrSerializer } from '../serializer'
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import { createMemoryHistory } from '@tanstack/history'
|
|
2
|
+
import { mergeHeaders } from './headers'
|
|
3
|
+
import { attachRouterServerSsrUtils, dehydrateRouter } from './ssr-server'
|
|
4
|
+
import type { HandlerCallback } from './handlerCallback'
|
|
5
|
+
import type { AnyRouter } from '../router'
|
|
6
|
+
import type { Manifest } from '../manifest'
|
|
7
|
+
|
|
8
|
+
export type RequestHandler<TRouter extends AnyRouter> = (
|
|
9
|
+
cb: HandlerCallback<TRouter>,
|
|
10
|
+
) => Promise<Response>
|
|
11
|
+
|
|
12
|
+
export function createRequestHandler<TRouter extends AnyRouter>({
|
|
13
|
+
createRouter,
|
|
14
|
+
request,
|
|
15
|
+
getRouterManifest,
|
|
16
|
+
}: {
|
|
17
|
+
createRouter: () => TRouter
|
|
18
|
+
request: Request
|
|
19
|
+
getRouterManifest?: () => Manifest | Promise<Manifest>
|
|
20
|
+
}): RequestHandler<TRouter> {
|
|
21
|
+
return async (cb) => {
|
|
22
|
+
const router = createRouter()
|
|
23
|
+
|
|
24
|
+
attachRouterServerSsrUtils(router, await getRouterManifest?.())
|
|
25
|
+
|
|
26
|
+
const url = new URL(request.url, 'http://localhost')
|
|
27
|
+
|
|
28
|
+
const href = url.href.replace(url.origin, '')
|
|
29
|
+
|
|
30
|
+
// Create a history for the router
|
|
31
|
+
const history = createMemoryHistory({
|
|
32
|
+
initialEntries: [href],
|
|
33
|
+
})
|
|
34
|
+
|
|
35
|
+
// Update the router with the history and context
|
|
36
|
+
router.update({
|
|
37
|
+
history,
|
|
38
|
+
})
|
|
39
|
+
|
|
40
|
+
await router.load()
|
|
41
|
+
|
|
42
|
+
dehydrateRouter(router)
|
|
43
|
+
|
|
44
|
+
const responseHeaders = getRequestHeaders({
|
|
45
|
+
router,
|
|
46
|
+
})
|
|
47
|
+
|
|
48
|
+
return cb({
|
|
49
|
+
request,
|
|
50
|
+
router,
|
|
51
|
+
responseHeaders,
|
|
52
|
+
} as any)
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
function getRequestHeaders(opts: { router: AnyRouter }): Headers {
|
|
57
|
+
let headers = mergeHeaders(
|
|
58
|
+
{
|
|
59
|
+
'Content-Type': 'text/html; charset=UTF-8',
|
|
60
|
+
},
|
|
61
|
+
...opts.router.state.matches.map((match) => {
|
|
62
|
+
return match.headers
|
|
63
|
+
}),
|
|
64
|
+
)
|
|
65
|
+
|
|
66
|
+
// Handle Redirects
|
|
67
|
+
const { redirect } = opts.router.state
|
|
68
|
+
|
|
69
|
+
if (redirect) {
|
|
70
|
+
headers = mergeHeaders(headers, redirect.headers)
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
return headers
|
|
74
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { AnyRouter } from '../router'
|
|
2
|
+
|
|
3
|
+
export interface HandlerCallback<TRouter extends AnyRouter> {
|
|
4
|
+
(ctx: {
|
|
5
|
+
request: Request
|
|
6
|
+
router: TRouter
|
|
7
|
+
responseHeaders: Headers
|
|
8
|
+
}): Response | Promise<Response>
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export function defineHandlerCallback<TRouter extends AnyRouter>(
|
|
12
|
+
handler: HandlerCallback<TRouter>,
|
|
13
|
+
): HandlerCallback<TRouter> {
|
|
14
|
+
return handler
|
|
15
|
+
}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { splitSetCookieString } from 'cookie-es'
|
|
2
|
+
import type { OutgoingHttpHeaders } from 'node:http2'
|
|
3
|
+
|
|
4
|
+
// A utility function to turn HeadersInit into an object
|
|
5
|
+
export function headersInitToObject(
|
|
6
|
+
headers: HeadersInit,
|
|
7
|
+
): Record<keyof OutgoingHttpHeaders, string> {
|
|
8
|
+
const obj: Record<keyof OutgoingHttpHeaders, string> = {}
|
|
9
|
+
const headersInstance = new Headers(headers)
|
|
10
|
+
for (const [key, value] of headersInstance.entries()) {
|
|
11
|
+
obj[key] = value
|
|
12
|
+
}
|
|
13
|
+
return obj
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
type AnyHeaders =
|
|
17
|
+
| Headers
|
|
18
|
+
| HeadersInit
|
|
19
|
+
| Record<string, string>
|
|
20
|
+
| Array<[string, string]>
|
|
21
|
+
| OutgoingHttpHeaders
|
|
22
|
+
| undefined
|
|
23
|
+
|
|
24
|
+
// Helper function to convert various HeaderInit types to a Headers instance
|
|
25
|
+
function toHeadersInstance(init: AnyHeaders) {
|
|
26
|
+
if (init instanceof Headers) {
|
|
27
|
+
return new Headers(init)
|
|
28
|
+
} else if (Array.isArray(init)) {
|
|
29
|
+
return new Headers(init)
|
|
30
|
+
} else if (typeof init === 'object') {
|
|
31
|
+
return new Headers(init as HeadersInit)
|
|
32
|
+
} else {
|
|
33
|
+
return new Headers()
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
// Function to merge headers with proper overrides
|
|
38
|
+
export function mergeHeaders(...headers: Array<AnyHeaders>) {
|
|
39
|
+
return headers.reduce((acc: Headers, header) => {
|
|
40
|
+
const headersInstance = toHeadersInstance(header)
|
|
41
|
+
for (const [key, value] of headersInstance.entries()) {
|
|
42
|
+
if (key === 'set-cookie') {
|
|
43
|
+
const splitCookies = splitSetCookieString(value)
|
|
44
|
+
splitCookies.forEach((cookie) => acc.append('set-cookie', cookie))
|
|
45
|
+
} else {
|
|
46
|
+
acc.set(key, value)
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
return acc
|
|
50
|
+
}, new Headers())
|
|
51
|
+
}
|
package/src/ssr/json.ts
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { mergeHeaders } from './headers'
|
|
2
|
+
|
|
3
|
+
export interface JsonResponse<TData> extends Response {
|
|
4
|
+
json: () => Promise<TData>
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
export function json<TData>(
|
|
8
|
+
payload: TData,
|
|
9
|
+
init?: ResponseInit,
|
|
10
|
+
): JsonResponse<TData> {
|
|
11
|
+
return new Response(JSON.stringify(payload), {
|
|
12
|
+
...init,
|
|
13
|
+
headers: mergeHeaders(
|
|
14
|
+
{ 'content-type': 'application/json' },
|
|
15
|
+
init?.headers,
|
|
16
|
+
),
|
|
17
|
+
})
|
|
18
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
export { createRequestHandler } from './createRequestHandler'
|
|
2
|
+
export type { RequestHandler } from './createRequestHandler'
|
|
3
|
+
export { defineHandlerCallback } from './handlerCallback'
|
|
4
|
+
export type { HandlerCallback } from './handlerCallback'
|
|
5
|
+
export {
|
|
6
|
+
transformPipeableStreamWithRouter,
|
|
7
|
+
transformStreamWithRouter,
|
|
8
|
+
transformReadableStreamWithRouter,
|
|
9
|
+
} from './transformStreamWithRouter'
|
|
10
|
+
export {
|
|
11
|
+
attachRouterServerSsrUtils,
|
|
12
|
+
dehydrateRouter,
|
|
13
|
+
extractAsyncLoaderData,
|
|
14
|
+
onMatchSettled,
|
|
15
|
+
replaceBy,
|
|
16
|
+
} from './ssr-server'
|
|
17
|
+
export type {
|
|
18
|
+
ServerExtractedBaseEntry,
|
|
19
|
+
ServerExtractedEntry,
|
|
20
|
+
ServerExtractedPromise,
|
|
21
|
+
ServerExtractedStream,
|
|
22
|
+
} from './ssr-server'
|
|
23
|
+
export * from './tsrScript'
|