@tanstack/react-start-client 1.20.3-alpha.1

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.
Files changed (51) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +9 -0
  3. package/dist/cjs/Meta.cjs +14 -0
  4. package/dist/cjs/Meta.cjs.map +1 -0
  5. package/dist/cjs/Meta.d.cts +1 -0
  6. package/dist/cjs/Scripts.cjs +12 -0
  7. package/dist/cjs/Scripts.cjs.map +1 -0
  8. package/dist/cjs/Scripts.d.cts +1 -0
  9. package/dist/cjs/StartClient.cjs +24 -0
  10. package/dist/cjs/StartClient.cjs.map +1 -0
  11. package/dist/cjs/StartClient.d.cts +4 -0
  12. package/dist/cjs/index.cjs +54 -0
  13. package/dist/cjs/index.cjs.map +1 -0
  14. package/dist/cjs/index.d.cts +7 -0
  15. package/dist/cjs/renderRSC.cjs +29 -0
  16. package/dist/cjs/renderRSC.cjs.map +1 -0
  17. package/dist/cjs/renderRSC.d.cts +2 -0
  18. package/dist/cjs/tests/createServerFn.test-d.d.cts +1 -0
  19. package/dist/cjs/tests/setupTests.d.cts +0 -0
  20. package/dist/cjs/useServerFn.cjs +24 -0
  21. package/dist/cjs/useServerFn.cjs.map +1 -0
  22. package/dist/cjs/useServerFn.d.cts +1 -0
  23. package/dist/esm/Meta.d.ts +1 -0
  24. package/dist/esm/Meta.js +14 -0
  25. package/dist/esm/Meta.js.map +1 -0
  26. package/dist/esm/Scripts.d.ts +1 -0
  27. package/dist/esm/Scripts.js +12 -0
  28. package/dist/esm/Scripts.js.map +1 -0
  29. package/dist/esm/StartClient.d.ts +4 -0
  30. package/dist/esm/StartClient.js +24 -0
  31. package/dist/esm/StartClient.js.map +1 -0
  32. package/dist/esm/index.d.ts +7 -0
  33. package/dist/esm/index.js +24 -0
  34. package/dist/esm/index.js.map +1 -0
  35. package/dist/esm/renderRSC.d.ts +2 -0
  36. package/dist/esm/renderRSC.js +29 -0
  37. package/dist/esm/renderRSC.js.map +1 -0
  38. package/dist/esm/tests/createServerFn.test-d.d.ts +1 -0
  39. package/dist/esm/tests/setupTests.d.ts +0 -0
  40. package/dist/esm/useServerFn.d.ts +1 -0
  41. package/dist/esm/useServerFn.js +24 -0
  42. package/dist/esm/useServerFn.js.map +1 -0
  43. package/package.json +68 -0
  44. package/src/Meta.tsx +10 -0
  45. package/src/Scripts.tsx +8 -0
  46. package/src/StartClient.tsx +21 -0
  47. package/src/index.tsx +68 -0
  48. package/src/renderRSC.tsx +89 -0
  49. package/src/tests/createServerFn.test-d.tsx +15 -0
  50. package/src/tests/setupTests.tsx +1 -0
  51. package/src/useServerFn.ts +27 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2021-present Tanner Linsley
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,9 @@
1
+ <img src="https://static.scarf.sh/a.png?x-pxid=d988eb79-b0fc-4a2b-8514-6a1ab932d188" />
2
+
3
+ # TanStack React Start - Client
4
+
5
+ This package is not meant to be used directly. It is a dependency of [`@tanstack/react-start`](https://www.npmjs.com/package/@tanstack/react-start).
6
+
7
+ TanStack React Start is a fullstack-framework made for SSR, Streaming, Server Functions, API Routes, bundling and more powered by [TanStack Router](https://tanstack.com/router).
8
+
9
+ Head over to [tanstack.com/start](https://tanstack.com/start) for more information about getting started.
@@ -0,0 +1,14 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
+ const jsxRuntime = require("react/jsx-runtime");
4
+ const reactRouter = require("@tanstack/react-router");
5
+ const Meta = () => {
6
+ if (process.env.NODE_ENV === "development") {
7
+ console.warn(
8
+ "The Meta component is deprecated. Use `HeadContent` from `@tanstack/react-router` instead."
9
+ );
10
+ }
11
+ return /* @__PURE__ */ jsxRuntime.jsx(reactRouter.HeadContent, {});
12
+ };
13
+ exports.Meta = Meta;
14
+ //# sourceMappingURL=Meta.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Meta.cjs","sources":["../../src/Meta.tsx"],"sourcesContent":["import { HeadContent } from '@tanstack/react-router'\n\nexport const Meta = () => {\n if (process.env.NODE_ENV === 'development') {\n console.warn(\n 'The Meta component is deprecated. Use `HeadContent` from `@tanstack/react-router` instead.',\n )\n }\n return <HeadContent />\n}\n"],"names":["HeadContent"],"mappings":";;;;AAEO,MAAM,OAAO,MAAM;AACpB,MAAA,QAAQ,IAAI,aAAa,eAAe;AAClC,YAAA;AAAA,MACN;AAAA,IACF;AAAA,EAAA;AAEF,wCAAQA,YAAY,aAAA,EAAA;AACtB;;"}
@@ -0,0 +1 @@
1
+ export declare const Meta: () => import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,12 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
+ const jsxRuntime = require("react/jsx-runtime");
4
+ const reactRouter = require("@tanstack/react-router");
5
+ const Scripts = () => {
6
+ if (process.env.NODE_ENV === "development") {
7
+ console.warn("The Scripts component was moved to `@tanstack/react-router`");
8
+ }
9
+ return /* @__PURE__ */ jsxRuntime.jsx(reactRouter.Scripts, {});
10
+ };
11
+ exports.Scripts = Scripts;
12
+ //# sourceMappingURL=Scripts.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Scripts.cjs","sources":["../../src/Scripts.tsx"],"sourcesContent":["import { Scripts as RouterScripts } from '@tanstack/react-router'\n\nexport const Scripts = () => {\n if (process.env.NODE_ENV === 'development') {\n console.warn('The Scripts component was moved to `@tanstack/react-router`')\n }\n return <RouterScripts />\n}\n"],"names":["RouterScripts"],"mappings":";;;;AAEO,MAAM,UAAU,MAAM;AACvB,MAAA,QAAQ,IAAI,aAAa,eAAe;AAC1C,YAAQ,KAAK,6DAA6D;AAAA,EAAA;AAE5E,wCAAQA,YAAc,SAAA,EAAA;AACxB;;"}
@@ -0,0 +1 @@
1
+ export declare const Scripts: () => import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,24 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
+ const jsxRuntime = require("react/jsx-runtime");
4
+ const reactRouter = require("@tanstack/react-router");
5
+ const startClientCore = require("@tanstack/start-client-core");
6
+ let hydrationPromise;
7
+ function StartClient(props) {
8
+ if (!hydrationPromise) {
9
+ if (!props.router.state.matches.length) {
10
+ hydrationPromise = startClientCore.hydrate(props.router);
11
+ } else {
12
+ hydrationPromise = Promise.resolve();
13
+ }
14
+ }
15
+ return /* @__PURE__ */ jsxRuntime.jsx(
16
+ reactRouter.Await,
17
+ {
18
+ promise: hydrationPromise,
19
+ children: () => /* @__PURE__ */ jsxRuntime.jsx(reactRouter.RouterProvider, { router: props.router })
20
+ }
21
+ );
22
+ }
23
+ exports.StartClient = StartClient;
24
+ //# sourceMappingURL=StartClient.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"StartClient.cjs","sources":["../../src/StartClient.tsx"],"sourcesContent":["import { Await, RouterProvider } from '@tanstack/react-router'\nimport { hydrate } from '@tanstack/start-client-core'\nimport type { AnyRouter } from '@tanstack/router-core'\n\nlet hydrationPromise: Promise<void | Array<Array<void>>> | undefined\n\nexport function StartClient(props: { router: AnyRouter }) {\n if (!hydrationPromise) {\n if (!props.router.state.matches.length) {\n hydrationPromise = hydrate(props.router)\n } else {\n hydrationPromise = Promise.resolve()\n }\n }\n return (\n <Await\n promise={hydrationPromise}\n children={() => <RouterProvider router={props.router} />}\n />\n )\n}\n"],"names":["hydrate","jsx","Await","RouterProvider"],"mappings":";;;;;AAIA,IAAI;AAEG,SAAS,YAAY,OAA8B;AACxD,MAAI,CAAC,kBAAkB;AACrB,QAAI,CAAC,MAAM,OAAO,MAAM,QAAQ,QAAQ;AACnB,yBAAAA,gBAAAA,QAAQ,MAAM,MAAM;AAAA,IAAA,OAClC;AACL,yBAAmB,QAAQ,QAAQ;AAAA,IAAA;AAAA,EACrC;AAGA,SAAAC,2BAAA;AAAA,IAACC,YAAA;AAAA,IAAA;AAAA,MACC,SAAS;AAAA,MACT,UAAU,MAAMD,2BAAAA,IAACE,YAAAA,gBAAe,EAAA,QAAQ,MAAM,OAAQ,CAAA;AAAA,IAAA;AAAA,EACxD;AAEJ;;"}
@@ -0,0 +1,4 @@
1
+ import { AnyRouter } from '@tanstack/router-core';
2
+ export declare function StartClient(props: {
3
+ router: AnyRouter;
4
+ }): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,54 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
+ const startClientCore = require("@tanstack/start-client-core");
4
+ const Meta = require("./Meta.cjs");
5
+ const Scripts = require("./Scripts.cjs");
6
+ const StartClient = require("./StartClient.cjs");
7
+ const renderRSC = require("./renderRSC.cjs");
8
+ const useServerFn = require("./useServerFn.cjs");
9
+ Object.defineProperty(exports, "clientOnly", {
10
+ enumerable: true,
11
+ get: () => startClientCore.clientOnly
12
+ });
13
+ Object.defineProperty(exports, "createIsomorphicFn", {
14
+ enumerable: true,
15
+ get: () => startClientCore.createIsomorphicFn
16
+ });
17
+ Object.defineProperty(exports, "createMiddleware", {
18
+ enumerable: true,
19
+ get: () => startClientCore.createMiddleware
20
+ });
21
+ Object.defineProperty(exports, "createServerFn", {
22
+ enumerable: true,
23
+ get: () => startClientCore.createServerFn
24
+ });
25
+ Object.defineProperty(exports, "globalMiddleware", {
26
+ enumerable: true,
27
+ get: () => startClientCore.globalMiddleware
28
+ });
29
+ Object.defineProperty(exports, "json", {
30
+ enumerable: true,
31
+ get: () => startClientCore.json
32
+ });
33
+ Object.defineProperty(exports, "mergeHeaders", {
34
+ enumerable: true,
35
+ get: () => startClientCore.mergeHeaders
36
+ });
37
+ Object.defineProperty(exports, "registerGlobalMiddleware", {
38
+ enumerable: true,
39
+ get: () => startClientCore.registerGlobalMiddleware
40
+ });
41
+ Object.defineProperty(exports, "serverOnly", {
42
+ enumerable: true,
43
+ get: () => startClientCore.serverOnly
44
+ });
45
+ Object.defineProperty(exports, "startSerializer", {
46
+ enumerable: true,
47
+ get: () => startClientCore.startSerializer
48
+ });
49
+ exports.Meta = Meta.Meta;
50
+ exports.Scripts = Scripts.Scripts;
51
+ exports.StartClient = StartClient.StartClient;
52
+ exports.renderRsc = renderRSC.renderRsc;
53
+ exports.useServerFn = useServerFn.useServerFn;
54
+ //# sourceMappingURL=index.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.cjs","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -0,0 +1,7 @@
1
+ export { mergeHeaders, startSerializer, createIsomorphicFn, createServerFn, createMiddleware, registerGlobalMiddleware, globalMiddleware, serverOnly, clientOnly, json, } from '@tanstack/start-client-core';
2
+ export { type DehydratedRouter, type ClientExtractedBaseEntry, type StartSsrGlobal, type ClientExtractedEntry, type SsrMatch, type ClientExtractedPromise, type ClientExtractedStream, type ResolvePromiseState, type IsomorphicFn, type ServerOnlyFn, type ClientOnlyFn, type IsomorphicFnBase, type ServerFn as FetchFn, type ServerFnCtx as FetchFnCtx, type CompiledFetcherFnOptions, type CompiledFetcherFn, type Fetcher, type RscStream, type FetcherData, type FetcherBaseOptions, type ServerFn, type ServerFnCtx, type ServerFnResponseType, type JsonResponse, type IntersectAllValidatorInputs, type IntersectAllValidatorOutputs, type FunctionMiddlewareServerFn, type AnyFunctionMiddleware, type FunctionMiddlewareOptions, type FunctionMiddlewareWithTypes, type FunctionMiddlewareValidator, type FunctionMiddlewareServer, type FunctionMiddlewareAfterClient, type FunctionMiddlewareAfterServer, type FunctionMiddleware, type FunctionMiddlewareClientFnOptions, type FunctionMiddlewareClientFnResult, type FunctionMiddlewareClientNextFn, type FunctionClientResultWithContext, type AssignAllClientContextBeforeNext, type AssignAllMiddleware, type AssignAllServerContext, type FunctionMiddlewareAfterValidator, type FunctionMiddlewareClientFn, type FunctionMiddlewareServerFnResult, type FunctionMiddlewareClient, type FunctionMiddlewareServerFnOptions, type FunctionMiddlewareServerNextFn, type FunctionServerResultWithContext, } from '@tanstack/start-client-core';
3
+ export { Meta } from './Meta.cjs';
4
+ export { Scripts } from './Scripts.cjs';
5
+ export { StartClient } from './StartClient.cjs';
6
+ export { renderRsc } from './renderRSC.cjs';
7
+ export { useServerFn } from './useServerFn.cjs';
@@ -0,0 +1,29 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
+ const react = require("react");
4
+ const invariant = require("tiny-invariant");
5
+ function renderRsc(input) {
6
+ if (react.isValidElement(input)) {
7
+ return input;
8
+ }
9
+ if (typeof input === "object" && !input.state) {
10
+ input.state = {
11
+ status: "pending",
12
+ promise: Promise.resolve().then(() => {
13
+ invariant(false, "renderRSC() is coming soon!");
14
+ }).then((element) => {
15
+ input.state.value = element;
16
+ input.state.status = "success";
17
+ }).catch((err) => {
18
+ input.state.status = "error";
19
+ input.state.error = err;
20
+ })
21
+ };
22
+ }
23
+ if (input.state.status === "pending") {
24
+ throw input.state.promise;
25
+ }
26
+ return input.state.value;
27
+ }
28
+ exports.renderRsc = renderRsc;
29
+ //# sourceMappingURL=renderRSC.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"renderRSC.cjs","sources":["../../src/renderRSC.tsx"],"sourcesContent":["// TODO: RSCs\nimport { isValidElement } from 'react'\nimport invariant from 'tiny-invariant'\nimport type React from 'react'\n\nexport function renderRsc(input: any): React.JSX.Element {\n if (isValidElement(input)) {\n return input\n }\n\n if (typeof input === 'object' && !input.state) {\n input.state = {\n status: 'pending',\n promise: Promise.resolve()\n .then(() => {\n let element\n\n // We're in node\n // TODO: RSCs\n // if (reactDom.createFromNodeStream) {\n // const stream = await import('node:stream')\n\n // let body: any = input\n\n // // Unwrap the response\n // if (input instanceof Response) {\n // body = input.body\n // }\n\n // // Convert ReadableStream to NodeJS stream.Readable\n // if (body instanceof ReadableStream) {\n // body = stream.Readable.fromWeb(body as any)\n // }\n\n // if (stream.Readable.isReadable(body)) {\n // // body = copyStreamToRaw(body)\n // } else if (input.text) {\n // // create a readable stream by awaiting the text method\n // body = new stream.Readable({\n // async read() {\n // input.text().then((value: any) => {\n // this.push(value)\n // this.push(null)\n // })\n // },\n // })\n // } else {\n // console.error('input', input)\n // throw new Error('Unexpected rsc input type 👆')\n // }\n\n // element = await reactDom.createFromNodeStream(body)\n // } else {\n // // We're in the browser\n // if (input.body instanceof ReadableStream) {\n // input = input.body\n // }\n\n // if (input instanceof ReadableStream) {\n // element = await reactDom.createFromReadableStream(input)\n // }\n\n // if (input instanceof Response) {\n // // copy to the response body to cache the raw data\n // element = await reactDom.createFromFetch(input)\n // }\n // }\n\n // return element\n\n invariant(false, 'renderRSC() is coming soon!')\n })\n .then((element) => {\n input.state.value = element\n input.state.status = 'success'\n })\n .catch((err) => {\n input.state.status = 'error'\n input.state.error = err\n }),\n }\n }\n\n if (input.state.status === 'pending') {\n throw input.state.promise\n }\n\n return input.state.value\n}\n"],"names":["isValidElement"],"mappings":";;;;AAKO,SAAS,UAAU,OAA+B;AACnD,MAAAA,MAAAA,eAAe,KAAK,GAAG;AAClB,WAAA;AAAA,EAAA;AAGT,MAAI,OAAO,UAAU,YAAY,CAAC,MAAM,OAAO;AAC7C,UAAM,QAAQ;AAAA,MACZ,QAAQ;AAAA,MACR,SAAS,QAAQ,QAAQ,EACtB,KAAK,MAAM;AAwDV,kBAAU,OAAO,6BAA6B;AAAA,MAAA,CAC/C,EACA,KAAK,CAAC,YAAY;AACjB,cAAM,MAAM,QAAQ;AACpB,cAAM,MAAM,SAAS;AAAA,MAAA,CACtB,EACA,MAAM,CAAC,QAAQ;AACd,cAAM,MAAM,SAAS;AACrB,cAAM,MAAM,QAAQ;AAAA,MACrB,CAAA;AAAA,IACL;AAAA,EAAA;AAGE,MAAA,MAAM,MAAM,WAAW,WAAW;AACpC,UAAM,MAAM,MAAM;AAAA,EAAA;AAGpB,SAAO,MAAM,MAAM;AACrB;;"}
@@ -0,0 +1,2 @@
1
+ import { default as React } from 'react';
2
+ export declare function renderRsc(input: any): React.JSX.Element;
@@ -0,0 +1 @@
1
+ export {};
File without changes
@@ -0,0 +1,24 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
+ const routerCore = require("@tanstack/router-core");
4
+ const reactRouter = require("@tanstack/react-router");
5
+ function useServerFn(serverFn) {
6
+ const router = reactRouter.useRouter();
7
+ return async (...args) => {
8
+ try {
9
+ const res = await serverFn(...args);
10
+ if (routerCore.isRedirect(res)) {
11
+ throw res;
12
+ }
13
+ return res;
14
+ } catch (err) {
15
+ if (routerCore.isRedirect(err)) {
16
+ err.options._fromLocation = router.state.location;
17
+ return router.navigate(router.resolveRedirect(err).options);
18
+ }
19
+ throw err;
20
+ }
21
+ };
22
+ }
23
+ exports.useServerFn = useServerFn;
24
+ //# sourceMappingURL=useServerFn.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useServerFn.cjs","sources":["../../src/useServerFn.ts"],"sourcesContent":["import { isRedirect } from '@tanstack/router-core'\nimport { useRouter } from '@tanstack/react-router'\n\nexport function useServerFn<T extends (...deps: Array<any>) => Promise<any>>(\n serverFn: T,\n): (...args: Parameters<T>) => ReturnType<T> {\n const router = useRouter()\n\n return (async (...args: Array<any>) => {\n try {\n const res = await serverFn(...args)\n\n if (isRedirect(res)) {\n throw res\n }\n\n return res\n } catch (err) {\n if (isRedirect(err)) {\n err.options._fromLocation = router.state.location\n return router.navigate(router.resolveRedirect(err).options)\n }\n\n throw err\n }\n }) as any\n}\n"],"names":["useRouter","isRedirect"],"mappings":";;;;AAGO,SAAS,YACd,UAC2C;AAC3C,QAAM,SAASA,YAAAA,UAAU;AAEzB,SAAQ,UAAU,SAAqB;AACjC,QAAA;AACF,YAAM,MAAM,MAAM,SAAS,GAAG,IAAI;AAE9B,UAAAC,WAAAA,WAAW,GAAG,GAAG;AACb,cAAA;AAAA,MAAA;AAGD,aAAA;AAAA,aACA,KAAK;AACR,UAAAA,WAAAA,WAAW,GAAG,GAAG;AACf,YAAA,QAAQ,gBAAgB,OAAO,MAAM;AACzC,eAAO,OAAO,SAAS,OAAO,gBAAgB,GAAG,EAAE,OAAO;AAAA,MAAA;AAGtD,YAAA;AAAA,IAAA;AAAA,EAEV;AACF;;"}
@@ -0,0 +1 @@
1
+ export declare function useServerFn<T extends (...deps: Array<any>) => Promise<any>>(serverFn: T): (...args: Parameters<T>) => ReturnType<T>;
@@ -0,0 +1 @@
1
+ export declare const Meta: () => import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,14 @@
1
+ import { jsx } from "react/jsx-runtime";
2
+ import { HeadContent } from "@tanstack/react-router";
3
+ const Meta = () => {
4
+ if (process.env.NODE_ENV === "development") {
5
+ console.warn(
6
+ "The Meta component is deprecated. Use `HeadContent` from `@tanstack/react-router` instead."
7
+ );
8
+ }
9
+ return /* @__PURE__ */ jsx(HeadContent, {});
10
+ };
11
+ export {
12
+ Meta
13
+ };
14
+ //# sourceMappingURL=Meta.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Meta.js","sources":["../../src/Meta.tsx"],"sourcesContent":["import { HeadContent } from '@tanstack/react-router'\n\nexport const Meta = () => {\n if (process.env.NODE_ENV === 'development') {\n console.warn(\n 'The Meta component is deprecated. Use `HeadContent` from `@tanstack/react-router` instead.',\n )\n }\n return <HeadContent />\n}\n"],"names":[],"mappings":";;AAEO,MAAM,OAAO,MAAM;AACpB,MAAA,QAAQ,IAAI,aAAa,eAAe;AAClC,YAAA;AAAA,MACN;AAAA,IACF;AAAA,EAAA;AAEF,6BAAQ,aAAY,EAAA;AACtB;"}
@@ -0,0 +1 @@
1
+ export declare const Scripts: () => import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,12 @@
1
+ import { jsx } from "react/jsx-runtime";
2
+ import { Scripts as Scripts$1 } from "@tanstack/react-router";
3
+ const Scripts = () => {
4
+ if (process.env.NODE_ENV === "development") {
5
+ console.warn("The Scripts component was moved to `@tanstack/react-router`");
6
+ }
7
+ return /* @__PURE__ */ jsx(Scripts$1, {});
8
+ };
9
+ export {
10
+ Scripts
11
+ };
12
+ //# sourceMappingURL=Scripts.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Scripts.js","sources":["../../src/Scripts.tsx"],"sourcesContent":["import { Scripts as RouterScripts } from '@tanstack/react-router'\n\nexport const Scripts = () => {\n if (process.env.NODE_ENV === 'development') {\n console.warn('The Scripts component was moved to `@tanstack/react-router`')\n }\n return <RouterScripts />\n}\n"],"names":["RouterScripts"],"mappings":";;AAEO,MAAM,UAAU,MAAM;AACvB,MAAA,QAAQ,IAAI,aAAa,eAAe;AAC1C,YAAQ,KAAK,6DAA6D;AAAA,EAAA;AAE5E,6BAAQA,WAAc,EAAA;AACxB;"}
@@ -0,0 +1,4 @@
1
+ import { AnyRouter } from '@tanstack/router-core';
2
+ export declare function StartClient(props: {
3
+ router: AnyRouter;
4
+ }): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,24 @@
1
+ import { jsx } from "react/jsx-runtime";
2
+ import { Await, RouterProvider } from "@tanstack/react-router";
3
+ import { hydrate } from "@tanstack/start-client-core";
4
+ let hydrationPromise;
5
+ function StartClient(props) {
6
+ if (!hydrationPromise) {
7
+ if (!props.router.state.matches.length) {
8
+ hydrationPromise = hydrate(props.router);
9
+ } else {
10
+ hydrationPromise = Promise.resolve();
11
+ }
12
+ }
13
+ return /* @__PURE__ */ jsx(
14
+ Await,
15
+ {
16
+ promise: hydrationPromise,
17
+ children: () => /* @__PURE__ */ jsx(RouterProvider, { router: props.router })
18
+ }
19
+ );
20
+ }
21
+ export {
22
+ StartClient
23
+ };
24
+ //# sourceMappingURL=StartClient.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"StartClient.js","sources":["../../src/StartClient.tsx"],"sourcesContent":["import { Await, RouterProvider } from '@tanstack/react-router'\nimport { hydrate } from '@tanstack/start-client-core'\nimport type { AnyRouter } from '@tanstack/router-core'\n\nlet hydrationPromise: Promise<void | Array<Array<void>>> | undefined\n\nexport function StartClient(props: { router: AnyRouter }) {\n if (!hydrationPromise) {\n if (!props.router.state.matches.length) {\n hydrationPromise = hydrate(props.router)\n } else {\n hydrationPromise = Promise.resolve()\n }\n }\n return (\n <Await\n promise={hydrationPromise}\n children={() => <RouterProvider router={props.router} />}\n />\n )\n}\n"],"names":[],"mappings":";;;AAIA,IAAI;AAEG,SAAS,YAAY,OAA8B;AACxD,MAAI,CAAC,kBAAkB;AACrB,QAAI,CAAC,MAAM,OAAO,MAAM,QAAQ,QAAQ;AACnB,yBAAA,QAAQ,MAAM,MAAM;AAAA,IAAA,OAClC;AACL,yBAAmB,QAAQ,QAAQ;AAAA,IAAA;AAAA,EACrC;AAGA,SAAA;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,SAAS;AAAA,MACT,UAAU,MAAM,oBAAC,gBAAe,EAAA,QAAQ,MAAM,OAAQ,CAAA;AAAA,IAAA;AAAA,EACxD;AAEJ;"}
@@ -0,0 +1,7 @@
1
+ export { mergeHeaders, startSerializer, createIsomorphicFn, createServerFn, createMiddleware, registerGlobalMiddleware, globalMiddleware, serverOnly, clientOnly, json, } from '@tanstack/start-client-core';
2
+ export { type DehydratedRouter, type ClientExtractedBaseEntry, type StartSsrGlobal, type ClientExtractedEntry, type SsrMatch, type ClientExtractedPromise, type ClientExtractedStream, type ResolvePromiseState, type IsomorphicFn, type ServerOnlyFn, type ClientOnlyFn, type IsomorphicFnBase, type ServerFn as FetchFn, type ServerFnCtx as FetchFnCtx, type CompiledFetcherFnOptions, type CompiledFetcherFn, type Fetcher, type RscStream, type FetcherData, type FetcherBaseOptions, type ServerFn, type ServerFnCtx, type ServerFnResponseType, type JsonResponse, type IntersectAllValidatorInputs, type IntersectAllValidatorOutputs, type FunctionMiddlewareServerFn, type AnyFunctionMiddleware, type FunctionMiddlewareOptions, type FunctionMiddlewareWithTypes, type FunctionMiddlewareValidator, type FunctionMiddlewareServer, type FunctionMiddlewareAfterClient, type FunctionMiddlewareAfterServer, type FunctionMiddleware, type FunctionMiddlewareClientFnOptions, type FunctionMiddlewareClientFnResult, type FunctionMiddlewareClientNextFn, type FunctionClientResultWithContext, type AssignAllClientContextBeforeNext, type AssignAllMiddleware, type AssignAllServerContext, type FunctionMiddlewareAfterValidator, type FunctionMiddlewareClientFn, type FunctionMiddlewareServerFnResult, type FunctionMiddlewareClient, type FunctionMiddlewareServerFnOptions, type FunctionMiddlewareServerNextFn, type FunctionServerResultWithContext, } from '@tanstack/start-client-core';
3
+ export { Meta } from './Meta.js';
4
+ export { Scripts } from './Scripts.js';
5
+ export { StartClient } from './StartClient.js';
6
+ export { renderRsc } from './renderRSC.js';
7
+ export { useServerFn } from './useServerFn.js';
@@ -0,0 +1,24 @@
1
+ import { clientOnly, createIsomorphicFn, createMiddleware, createServerFn, globalMiddleware, json, mergeHeaders, registerGlobalMiddleware, serverOnly, startSerializer } from "@tanstack/start-client-core";
2
+ import { Meta } from "./Meta.js";
3
+ import { Scripts } from "./Scripts.js";
4
+ import { StartClient } from "./StartClient.js";
5
+ import { renderRsc } from "./renderRSC.js";
6
+ import { useServerFn } from "./useServerFn.js";
7
+ export {
8
+ Meta,
9
+ Scripts,
10
+ StartClient,
11
+ clientOnly,
12
+ createIsomorphicFn,
13
+ createMiddleware,
14
+ createServerFn,
15
+ globalMiddleware,
16
+ json,
17
+ mergeHeaders,
18
+ registerGlobalMiddleware,
19
+ renderRsc,
20
+ serverOnly,
21
+ startSerializer,
22
+ useServerFn
23
+ };
24
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;"}
@@ -0,0 +1,2 @@
1
+ import { default as React } from 'react';
2
+ export declare function renderRsc(input: any): React.JSX.Element;
@@ -0,0 +1,29 @@
1
+ import { isValidElement } from "react";
2
+ import invariant from "tiny-invariant";
3
+ function renderRsc(input) {
4
+ if (isValidElement(input)) {
5
+ return input;
6
+ }
7
+ if (typeof input === "object" && !input.state) {
8
+ input.state = {
9
+ status: "pending",
10
+ promise: Promise.resolve().then(() => {
11
+ invariant(false, "renderRSC() is coming soon!");
12
+ }).then((element) => {
13
+ input.state.value = element;
14
+ input.state.status = "success";
15
+ }).catch((err) => {
16
+ input.state.status = "error";
17
+ input.state.error = err;
18
+ })
19
+ };
20
+ }
21
+ if (input.state.status === "pending") {
22
+ throw input.state.promise;
23
+ }
24
+ return input.state.value;
25
+ }
26
+ export {
27
+ renderRsc
28
+ };
29
+ //# sourceMappingURL=renderRSC.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"renderRSC.js","sources":["../../src/renderRSC.tsx"],"sourcesContent":["// TODO: RSCs\nimport { isValidElement } from 'react'\nimport invariant from 'tiny-invariant'\nimport type React from 'react'\n\nexport function renderRsc(input: any): React.JSX.Element {\n if (isValidElement(input)) {\n return input\n }\n\n if (typeof input === 'object' && !input.state) {\n input.state = {\n status: 'pending',\n promise: Promise.resolve()\n .then(() => {\n let element\n\n // We're in node\n // TODO: RSCs\n // if (reactDom.createFromNodeStream) {\n // const stream = await import('node:stream')\n\n // let body: any = input\n\n // // Unwrap the response\n // if (input instanceof Response) {\n // body = input.body\n // }\n\n // // Convert ReadableStream to NodeJS stream.Readable\n // if (body instanceof ReadableStream) {\n // body = stream.Readable.fromWeb(body as any)\n // }\n\n // if (stream.Readable.isReadable(body)) {\n // // body = copyStreamToRaw(body)\n // } else if (input.text) {\n // // create a readable stream by awaiting the text method\n // body = new stream.Readable({\n // async read() {\n // input.text().then((value: any) => {\n // this.push(value)\n // this.push(null)\n // })\n // },\n // })\n // } else {\n // console.error('input', input)\n // throw new Error('Unexpected rsc input type 👆')\n // }\n\n // element = await reactDom.createFromNodeStream(body)\n // } else {\n // // We're in the browser\n // if (input.body instanceof ReadableStream) {\n // input = input.body\n // }\n\n // if (input instanceof ReadableStream) {\n // element = await reactDom.createFromReadableStream(input)\n // }\n\n // if (input instanceof Response) {\n // // copy to the response body to cache the raw data\n // element = await reactDom.createFromFetch(input)\n // }\n // }\n\n // return element\n\n invariant(false, 'renderRSC() is coming soon!')\n })\n .then((element) => {\n input.state.value = element\n input.state.status = 'success'\n })\n .catch((err) => {\n input.state.status = 'error'\n input.state.error = err\n }),\n }\n }\n\n if (input.state.status === 'pending') {\n throw input.state.promise\n }\n\n return input.state.value\n}\n"],"names":[],"mappings":";;AAKO,SAAS,UAAU,OAA+B;AACnD,MAAA,eAAe,KAAK,GAAG;AAClB,WAAA;AAAA,EAAA;AAGT,MAAI,OAAO,UAAU,YAAY,CAAC,MAAM,OAAO;AAC7C,UAAM,QAAQ;AAAA,MACZ,QAAQ;AAAA,MACR,SAAS,QAAQ,QAAQ,EACtB,KAAK,MAAM;AAwDV,kBAAU,OAAO,6BAA6B;AAAA,MAAA,CAC/C,EACA,KAAK,CAAC,YAAY;AACjB,cAAM,MAAM,QAAQ;AACpB,cAAM,MAAM,SAAS;AAAA,MAAA,CACtB,EACA,MAAM,CAAC,QAAQ;AACd,cAAM,MAAM,SAAS;AACrB,cAAM,MAAM,QAAQ;AAAA,MACrB,CAAA;AAAA,IACL;AAAA,EAAA;AAGE,MAAA,MAAM,MAAM,WAAW,WAAW;AACpC,UAAM,MAAM,MAAM;AAAA,EAAA;AAGpB,SAAO,MAAM,MAAM;AACrB;"}
@@ -0,0 +1 @@
1
+ export {};
File without changes
@@ -0,0 +1 @@
1
+ export declare function useServerFn<T extends (...deps: Array<any>) => Promise<any>>(serverFn: T): (...args: Parameters<T>) => ReturnType<T>;
@@ -0,0 +1,24 @@
1
+ import { isRedirect } from "@tanstack/router-core";
2
+ import { useRouter } from "@tanstack/react-router";
3
+ function useServerFn(serverFn) {
4
+ const router = useRouter();
5
+ return async (...args) => {
6
+ try {
7
+ const res = await serverFn(...args);
8
+ if (isRedirect(res)) {
9
+ throw res;
10
+ }
11
+ return res;
12
+ } catch (err) {
13
+ if (isRedirect(err)) {
14
+ err.options._fromLocation = router.state.location;
15
+ return router.navigate(router.resolveRedirect(err).options);
16
+ }
17
+ throw err;
18
+ }
19
+ };
20
+ }
21
+ export {
22
+ useServerFn
23
+ };
24
+ //# sourceMappingURL=useServerFn.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useServerFn.js","sources":["../../src/useServerFn.ts"],"sourcesContent":["import { isRedirect } from '@tanstack/router-core'\nimport { useRouter } from '@tanstack/react-router'\n\nexport function useServerFn<T extends (...deps: Array<any>) => Promise<any>>(\n serverFn: T,\n): (...args: Parameters<T>) => ReturnType<T> {\n const router = useRouter()\n\n return (async (...args: Array<any>) => {\n try {\n const res = await serverFn(...args)\n\n if (isRedirect(res)) {\n throw res\n }\n\n return res\n } catch (err) {\n if (isRedirect(err)) {\n err.options._fromLocation = router.state.location\n return router.navigate(router.resolveRedirect(err).options)\n }\n\n throw err\n }\n }) as any\n}\n"],"names":[],"mappings":";;AAGO,SAAS,YACd,UAC2C;AAC3C,QAAM,SAAS,UAAU;AAEzB,SAAQ,UAAU,SAAqB;AACjC,QAAA;AACF,YAAM,MAAM,MAAM,SAAS,GAAG,IAAI;AAE9B,UAAA,WAAW,GAAG,GAAG;AACb,cAAA;AAAA,MAAA;AAGD,aAAA;AAAA,aACA,KAAK;AACR,UAAA,WAAW,GAAG,GAAG;AACf,YAAA,QAAQ,gBAAgB,OAAO,MAAM;AACzC,eAAO,OAAO,SAAS,OAAO,gBAAgB,GAAG,EAAE,OAAO;AAAA,MAAA;AAGtD,YAAA;AAAA,IAAA;AAAA,EAEV;AACF;"}
package/package.json ADDED
@@ -0,0 +1,68 @@
1
+ {
2
+ "name": "@tanstack/react-start-client",
3
+ "version": "1.20.3-alpha.1",
4
+ "description": "Modern and scalable routing for React applications",
5
+ "author": "Tanner Linsley",
6
+ "license": "MIT",
7
+ "repository": {
8
+ "type": "git",
9
+ "url": "https://github.com/TanStack/router.git",
10
+ "directory": "packages/react-start-client"
11
+ },
12
+ "homepage": "https://tanstack.com/start",
13
+ "funding": {
14
+ "type": "github",
15
+ "url": "https://github.com/sponsors/tannerlinsley"
16
+ },
17
+ "keywords": [
18
+ "react",
19
+ "location",
20
+ "router",
21
+ "routing",
22
+ "async",
23
+ "async router",
24
+ "typescript"
25
+ ],
26
+ "type": "module",
27
+ "types": "dist/esm/index.d.ts",
28
+ "exports": {
29
+ ".": {
30
+ "import": {
31
+ "types": "./dist/esm/index.d.ts",
32
+ "default": "./dist/esm/index.js"
33
+ },
34
+ "require": {
35
+ "types": "./dist/cjs/index.d.cts",
36
+ "default": "./dist/cjs/index.cjs"
37
+ }
38
+ },
39
+ "./package.json": "./package.json"
40
+ },
41
+ "sideEffects": false,
42
+ "files": [
43
+ "dist",
44
+ "src"
45
+ ],
46
+ "engines": {
47
+ "node": ">=12"
48
+ },
49
+ "dependencies": {
50
+ "cookie-es": "^1.2.2",
51
+ "jsesc": "^3.1.0",
52
+ "tiny-invariant": "^1.3.3",
53
+ "tiny-warning": "^1.0.3",
54
+ "@tanstack/react-router": "^1.20.3-alpha.1",
55
+ "@tanstack/router-core": "^1.20.3-alpha.1",
56
+ "@tanstack/start-client-core": "^1.20.3-alpha.1"
57
+ },
58
+ "devDependencies": {
59
+ "@testing-library/react": "^16.2.0",
60
+ "@types/jsesc": "^3.0.3",
61
+ "@vitejs/plugin-react": "^4.3.4"
62
+ },
63
+ "peerDependencies": {
64
+ "react": ">=18.0.0 || >=19.0.0",
65
+ "react-dom": ">=18.0.0 || >=19.0.0"
66
+ },
67
+ "scripts": {}
68
+ }
package/src/Meta.tsx ADDED
@@ -0,0 +1,10 @@
1
+ import { HeadContent } from '@tanstack/react-router'
2
+
3
+ export const Meta = () => {
4
+ if (process.env.NODE_ENV === 'development') {
5
+ console.warn(
6
+ 'The Meta component is deprecated. Use `HeadContent` from `@tanstack/react-router` instead.',
7
+ )
8
+ }
9
+ return <HeadContent />
10
+ }
@@ -0,0 +1,8 @@
1
+ import { Scripts as RouterScripts } from '@tanstack/react-router'
2
+
3
+ export const Scripts = () => {
4
+ if (process.env.NODE_ENV === 'development') {
5
+ console.warn('The Scripts component was moved to `@tanstack/react-router`')
6
+ }
7
+ return <RouterScripts />
8
+ }
@@ -0,0 +1,21 @@
1
+ import { Await, RouterProvider } from '@tanstack/react-router'
2
+ import { hydrate } from '@tanstack/start-client-core'
3
+ import type { AnyRouter } from '@tanstack/router-core'
4
+
5
+ let hydrationPromise: Promise<void | Array<Array<void>>> | undefined
6
+
7
+ export function StartClient(props: { router: AnyRouter }) {
8
+ if (!hydrationPromise) {
9
+ if (!props.router.state.matches.length) {
10
+ hydrationPromise = hydrate(props.router)
11
+ } else {
12
+ hydrationPromise = Promise.resolve()
13
+ }
14
+ }
15
+ return (
16
+ <Await
17
+ promise={hydrationPromise}
18
+ children={() => <RouterProvider router={props.router} />}
19
+ />
20
+ )
21
+ }
package/src/index.tsx ADDED
@@ -0,0 +1,68 @@
1
+ export {
2
+ mergeHeaders,
3
+ startSerializer,
4
+ createIsomorphicFn,
5
+ createServerFn,
6
+ createMiddleware,
7
+ registerGlobalMiddleware,
8
+ globalMiddleware,
9
+ serverOnly,
10
+ clientOnly,
11
+ json,
12
+ } from '@tanstack/start-client-core'
13
+ export {
14
+ type DehydratedRouter,
15
+ type ClientExtractedBaseEntry,
16
+ type StartSsrGlobal,
17
+ type ClientExtractedEntry,
18
+ type SsrMatch,
19
+ type ClientExtractedPromise,
20
+ type ClientExtractedStream,
21
+ type ResolvePromiseState,
22
+ type IsomorphicFn,
23
+ type ServerOnlyFn,
24
+ type ClientOnlyFn,
25
+ type IsomorphicFnBase,
26
+ type ServerFn as FetchFn,
27
+ type ServerFnCtx as FetchFnCtx,
28
+ type CompiledFetcherFnOptions,
29
+ type CompiledFetcherFn,
30
+ type Fetcher,
31
+ type RscStream,
32
+ type FetcherData,
33
+ type FetcherBaseOptions,
34
+ type ServerFn,
35
+ type ServerFnCtx,
36
+ type ServerFnResponseType,
37
+ type JsonResponse,
38
+ type IntersectAllValidatorInputs,
39
+ type IntersectAllValidatorOutputs,
40
+ type FunctionMiddlewareServerFn,
41
+ type AnyFunctionMiddleware,
42
+ type FunctionMiddlewareOptions,
43
+ type FunctionMiddlewareWithTypes,
44
+ type FunctionMiddlewareValidator,
45
+ type FunctionMiddlewareServer,
46
+ type FunctionMiddlewareAfterClient,
47
+ type FunctionMiddlewareAfterServer,
48
+ type FunctionMiddleware,
49
+ type FunctionMiddlewareClientFnOptions,
50
+ type FunctionMiddlewareClientFnResult,
51
+ type FunctionMiddlewareClientNextFn,
52
+ type FunctionClientResultWithContext,
53
+ type AssignAllClientContextBeforeNext,
54
+ type AssignAllMiddleware,
55
+ type AssignAllServerContext,
56
+ type FunctionMiddlewareAfterValidator,
57
+ type FunctionMiddlewareClientFn,
58
+ type FunctionMiddlewareServerFnResult,
59
+ type FunctionMiddlewareClient,
60
+ type FunctionMiddlewareServerFnOptions,
61
+ type FunctionMiddlewareServerNextFn,
62
+ type FunctionServerResultWithContext,
63
+ } from '@tanstack/start-client-core'
64
+ export { Meta } from './Meta'
65
+ export { Scripts } from './Scripts'
66
+ export { StartClient } from './StartClient'
67
+ export { renderRsc } from './renderRSC'
68
+ export { useServerFn } from './useServerFn'
@@ -0,0 +1,89 @@
1
+ // TODO: RSCs
2
+ import { isValidElement } from 'react'
3
+ import invariant from 'tiny-invariant'
4
+ import type React from 'react'
5
+
6
+ export function renderRsc(input: any): React.JSX.Element {
7
+ if (isValidElement(input)) {
8
+ return input
9
+ }
10
+
11
+ if (typeof input === 'object' && !input.state) {
12
+ input.state = {
13
+ status: 'pending',
14
+ promise: Promise.resolve()
15
+ .then(() => {
16
+ let element
17
+
18
+ // We're in node
19
+ // TODO: RSCs
20
+ // if (reactDom.createFromNodeStream) {
21
+ // const stream = await import('node:stream')
22
+
23
+ // let body: any = input
24
+
25
+ // // Unwrap the response
26
+ // if (input instanceof Response) {
27
+ // body = input.body
28
+ // }
29
+
30
+ // // Convert ReadableStream to NodeJS stream.Readable
31
+ // if (body instanceof ReadableStream) {
32
+ // body = stream.Readable.fromWeb(body as any)
33
+ // }
34
+
35
+ // if (stream.Readable.isReadable(body)) {
36
+ // // body = copyStreamToRaw(body)
37
+ // } else if (input.text) {
38
+ // // create a readable stream by awaiting the text method
39
+ // body = new stream.Readable({
40
+ // async read() {
41
+ // input.text().then((value: any) => {
42
+ // this.push(value)
43
+ // this.push(null)
44
+ // })
45
+ // },
46
+ // })
47
+ // } else {
48
+ // console.error('input', input)
49
+ // throw new Error('Unexpected rsc input type 👆')
50
+ // }
51
+
52
+ // element = await reactDom.createFromNodeStream(body)
53
+ // } else {
54
+ // // We're in the browser
55
+ // if (input.body instanceof ReadableStream) {
56
+ // input = input.body
57
+ // }
58
+
59
+ // if (input instanceof ReadableStream) {
60
+ // element = await reactDom.createFromReadableStream(input)
61
+ // }
62
+
63
+ // if (input instanceof Response) {
64
+ // // copy to the response body to cache the raw data
65
+ // element = await reactDom.createFromFetch(input)
66
+ // }
67
+ // }
68
+
69
+ // return element
70
+
71
+ invariant(false, 'renderRSC() is coming soon!')
72
+ })
73
+ .then((element) => {
74
+ input.state.value = element
75
+ input.state.status = 'success'
76
+ })
77
+ .catch((err) => {
78
+ input.state.status = 'error'
79
+ input.state.error = err
80
+ }),
81
+ }
82
+ }
83
+
84
+ if (input.state.status === 'pending') {
85
+ throw input.state.promise
86
+ }
87
+
88
+ return input.state.value
89
+ }
@@ -0,0 +1,15 @@
1
+ import { expectTypeOf, test } from 'vitest'
2
+ import { createServerFn } from '@tanstack/start-client-core'
3
+
4
+ test('createServerFn returns RSC', () => {
5
+ const fn = createServerFn().handler(() => ({
6
+ rscs: [
7
+ <div key="0">I'm an RSC</div>,
8
+ <div key="1">I'm an RSC</div>,
9
+ ] as const,
10
+ }))
11
+
12
+ expectTypeOf(fn()).toEqualTypeOf<
13
+ Promise<{ rscs: readonly [ReadableStream, ReadableStream] }>
14
+ >()
15
+ })
@@ -0,0 +1 @@
1
+ import '@testing-library/react'
@@ -0,0 +1,27 @@
1
+ import { isRedirect } from '@tanstack/router-core'
2
+ import { useRouter } from '@tanstack/react-router'
3
+
4
+ export function useServerFn<T extends (...deps: Array<any>) => Promise<any>>(
5
+ serverFn: T,
6
+ ): (...args: Parameters<T>) => ReturnType<T> {
7
+ const router = useRouter()
8
+
9
+ return (async (...args: Array<any>) => {
10
+ try {
11
+ const res = await serverFn(...args)
12
+
13
+ if (isRedirect(res)) {
14
+ throw res
15
+ }
16
+
17
+ return res
18
+ } catch (err) {
19
+ if (isRedirect(err)) {
20
+ err.options._fromLocation = router.state.location
21
+ return router.navigate(router.resolveRedirect(err).options)
22
+ }
23
+
24
+ throw err
25
+ }
26
+ }) as any
27
+ }