@benjavicente/start-client-core 1.167.9

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 (94) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +12 -0
  3. package/bin/intent.js +25 -0
  4. package/dist/esm/client/ServerFunctionSerializationAdapter.d.ts +7 -0
  5. package/dist/esm/client/ServerFunctionSerializationAdapter.js +18 -0
  6. package/dist/esm/client/ServerFunctionSerializationAdapter.js.map +1 -0
  7. package/dist/esm/client/hydrateStart.d.ts +2 -0
  8. package/dist/esm/client/hydrateStart.js +31 -0
  9. package/dist/esm/client/hydrateStart.js.map +1 -0
  10. package/dist/esm/client/index.d.ts +2 -0
  11. package/dist/esm/client/index.js +2 -0
  12. package/dist/esm/client-rpc/createClientRpc.d.ts +6 -0
  13. package/dist/esm/client-rpc/createClientRpc.js +21 -0
  14. package/dist/esm/client-rpc/createClientRpc.js.map +1 -0
  15. package/dist/esm/client-rpc/frame-decoder.d.ts +23 -0
  16. package/dist/esm/client-rpc/frame-decoder.js +231 -0
  17. package/dist/esm/client-rpc/frame-decoder.js.map +1 -0
  18. package/dist/esm/client-rpc/index.d.ts +1 -0
  19. package/dist/esm/client-rpc/index.js +2 -0
  20. package/dist/esm/client-rpc/serverFnFetcher.d.ts +1 -0
  21. package/dist/esm/client-rpc/serverFnFetcher.js +231 -0
  22. package/dist/esm/client-rpc/serverFnFetcher.js.map +1 -0
  23. package/dist/esm/constants.d.ts +53 -0
  24. package/dist/esm/constants.js +46 -0
  25. package/dist/esm/constants.js.map +1 -0
  26. package/dist/esm/createMiddleware.d.ts +195 -0
  27. package/dist/esm/createMiddleware.js +26 -0
  28. package/dist/esm/createMiddleware.js.map +1 -0
  29. package/dist/esm/createServerFn.d.ts +131 -0
  30. package/dist/esm/createServerFn.js +200 -0
  31. package/dist/esm/createServerFn.js.map +1 -0
  32. package/dist/esm/createStart.d.ts +50 -0
  33. package/dist/esm/createStart.js +29 -0
  34. package/dist/esm/createStart.js.map +1 -0
  35. package/dist/esm/fake-start-entry.d.ts +2 -0
  36. package/dist/esm/fake-start-entry.js +7 -0
  37. package/dist/esm/fake-start-entry.js.map +1 -0
  38. package/dist/esm/getDefaultSerovalPlugins.d.ts +1 -0
  39. package/dist/esm/getDefaultSerovalPlugins.js +10 -0
  40. package/dist/esm/getDefaultSerovalPlugins.js.map +1 -0
  41. package/dist/esm/getGlobalStartContext.d.ts +3 -0
  42. package/dist/esm/getGlobalStartContext.js +12 -0
  43. package/dist/esm/getGlobalStartContext.js.map +1 -0
  44. package/dist/esm/getRouterInstance.d.ts +2 -0
  45. package/dist/esm/getRouterInstance.js +8 -0
  46. package/dist/esm/getRouterInstance.js.map +1 -0
  47. package/dist/esm/getStartContextServerOnly.d.ts +2 -0
  48. package/dist/esm/getStartContextServerOnly.js +8 -0
  49. package/dist/esm/getStartContextServerOnly.js.map +1 -0
  50. package/dist/esm/getStartOptions.d.ts +2 -0
  51. package/dist/esm/getStartOptions.js +8 -0
  52. package/dist/esm/getStartOptions.js.map +1 -0
  53. package/dist/esm/global.d.ts +7 -0
  54. package/dist/esm/index.d.ts +20 -0
  55. package/dist/esm/index.js +12 -0
  56. package/dist/esm/safeObjectMerge.d.ts +10 -0
  57. package/dist/esm/safeObjectMerge.js +30 -0
  58. package/dist/esm/safeObjectMerge.js.map +1 -0
  59. package/dist/esm/serverRoute.d.ts +65 -0
  60. package/dist/esm/startEntry.d.ts +8 -0
  61. package/dist/esm/tests/createServerFn.test-d.d.ts +1 -0
  62. package/dist/esm/tests/createServerMiddleware.test-d.d.ts +1 -0
  63. package/package.json +98 -0
  64. package/skills/start-core/SKILL.md +210 -0
  65. package/skills/start-core/deployment/SKILL.md +306 -0
  66. package/skills/start-core/execution-model/SKILL.md +302 -0
  67. package/skills/start-core/middleware/SKILL.md +365 -0
  68. package/skills/start-core/server-functions/SKILL.md +335 -0
  69. package/skills/start-core/server-routes/SKILL.md +280 -0
  70. package/src/client/ServerFunctionSerializationAdapter.ts +16 -0
  71. package/src/client/hydrateStart.ts +43 -0
  72. package/src/client/index.ts +2 -0
  73. package/src/client-rpc/createClientRpc.ts +20 -0
  74. package/src/client-rpc/frame-decoder.ts +389 -0
  75. package/src/client-rpc/index.ts +1 -0
  76. package/src/client-rpc/serverFnFetcher.ts +416 -0
  77. package/src/constants.ts +90 -0
  78. package/src/createMiddleware.ts +824 -0
  79. package/src/createServerFn.ts +813 -0
  80. package/src/createStart.ts +166 -0
  81. package/src/fake-start-entry.ts +2 -0
  82. package/src/getDefaultSerovalPlugins.ts +17 -0
  83. package/src/getGlobalStartContext.ts +18 -0
  84. package/src/getRouterInstance.ts +8 -0
  85. package/src/getStartContextServerOnly.ts +4 -0
  86. package/src/getStartOptions.ts +8 -0
  87. package/src/global.ts +9 -0
  88. package/src/index.tsx +119 -0
  89. package/src/safeObjectMerge.ts +38 -0
  90. package/src/serverRoute.ts +509 -0
  91. package/src/start-entry.d.ts +11 -0
  92. package/src/startEntry.ts +10 -0
  93. package/src/tests/createServerFn.test-d.ts +866 -0
  94. package/src/tests/createServerMiddleware.test-d.ts +810 -0
@@ -0,0 +1,8 @@
1
+ import { createServerOnlyFn } from "@benjavicente/start-fn-stubs";
2
+ import { getStartContext } from "@benjavicente/start-storage-context";
3
+ //#region src/getStartContextServerOnly.ts
4
+ var getStartContextServerOnly = createServerOnlyFn(getStartContext);
5
+ //#endregion
6
+ export { getStartContextServerOnly };
7
+
8
+ //# sourceMappingURL=getStartContextServerOnly.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"getStartContextServerOnly.js","names":[],"sources":["../../src/getStartContextServerOnly.ts"],"sourcesContent":["import { getStartContext } from '@benjavicente/start-storage-context'\nimport { createServerOnlyFn } from '@benjavicente/start-fn-stubs'\n\nexport const getStartContextServerOnly = createServerOnlyFn(getStartContext)\n"],"mappings":";;;AAGA,IAAa,4BAA4B,mBAAmB,gBAAgB"}
@@ -0,0 +1,2 @@
1
+ import { AnyStartInstanceOptions } from './createStart.js';
2
+ export declare const getStartOptions: () => AnyStartInstanceOptions | undefined;
@@ -0,0 +1,8 @@
1
+ import { createIsomorphicFn } from "@benjavicente/start-fn-stubs";
2
+ import { getStartContext } from "@benjavicente/start-storage-context";
3
+ //#region src/getStartOptions.ts
4
+ var getStartOptions = createIsomorphicFn().client(() => window.__TSS_START_OPTIONS__).server(() => getStartContext().startOptions);
5
+ //#endregion
6
+ export { getStartOptions };
7
+
8
+ //# sourceMappingURL=getStartOptions.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"getStartOptions.js","names":[],"sources":["../../src/getStartOptions.ts"],"sourcesContent":["import { getStartContext } from '@benjavicente/start-storage-context'\nimport { createIsomorphicFn } from '@benjavicente/start-fn-stubs'\nimport type { AnyStartInstanceOptions } from './createStart'\n\nexport const getStartOptions: () => AnyStartInstanceOptions | undefined =\n createIsomorphicFn()\n .client(() => window.__TSS_START_OPTIONS__)\n .server(() => getStartContext().startOptions)\n"],"mappings":";;;AAIA,IAAa,kBACX,oBAAoB,CACjB,aAAa,OAAO,sBAAsB,CAC1C,aAAa,iBAAiB,CAAC,aAAa"}
@@ -0,0 +1,7 @@
1
+ import { AnyStartInstanceOptions } from './createStart.js';
2
+ declare global {
3
+ interface Window {
4
+ __TSS_START_OPTIONS__?: AnyStartInstanceOptions;
5
+ }
6
+ }
7
+ export {};
@@ -0,0 +1,20 @@
1
+ export type { JsonResponse } from '@benjavicente/router-core/ssr/client';
2
+ export { hydrate, json, mergeHeaders } from '@benjavicente/router-core/ssr/client';
3
+ export { RawStream } from '@benjavicente/router-core';
4
+ export type { OnRawStreamCallback } from '@benjavicente/router-core';
5
+ export { createIsomorphicFn, createServerOnlyFn, createClientOnlyFn, type IsomorphicFn, type ServerOnlyFn, type ClientOnlyFn, type IsomorphicFnBase, } from '@benjavicente/start-fn-stubs';
6
+ export { createServerFn } from './createServerFn.js';
7
+ export { createMiddleware, type IntersectAllValidatorInputs, type IntersectAllValidatorOutputs, type FunctionMiddlewareServerFn, type AnyFunctionMiddleware, type FunctionMiddlewareOptions, type FunctionMiddlewareWithTypes, type FunctionMiddlewareValidator, type FunctionMiddlewareServer, type FunctionMiddlewareAfterClient, type FunctionMiddlewareAfterServer, type FunctionMiddleware, type FunctionMiddlewareAfterMiddleware, type FunctionMiddlewareClientFnOptions, type FunctionMiddlewareClientFnResult, type FunctionMiddlewareClientNextFn, type FunctionClientResultWithContext, type AssignAllClientContextBeforeNext, type AssignAllMiddleware, type FunctionMiddlewareAfterValidator, type FunctionMiddlewareClientFn, type FunctionMiddlewareServerFnResult, type FunctionMiddlewareClient, type FunctionMiddlewareServerFnOptions, type FunctionMiddlewareServerNextFn, type FunctionServerResultWithContext, type AnyRequestMiddleware, type RequestMiddlewareOptions, type RequestMiddlewareWithTypes, type RequestMiddlewareServer, type RequestMiddlewareAfterServer, type RequestMiddleware, type RequestMiddlewareAfterMiddleware, type RequestServerFn, type RequestMiddlewareServerFnResult, type RequestServerOptions, type RequestServerNextFn, type RequestServerNextFnOptions, type RequestServerResult, } from './createMiddleware.js';
8
+ export type { CompiledFetcherFnOptions, CompiledFetcherFn, CustomFetch, Fetcher, RscStream, FetcherBaseOptions, ServerFn, ServerFnCtx, MiddlewareFn, ServerFnMiddlewareOptions, ServerFnMiddlewareResult, ServerFnBuilder, ServerFnBaseOptions, NextFn, Method, OptionalFetcher, RequiredFetcher, } from './createServerFn.js';
9
+ export { execValidator, flattenMiddlewares, executeMiddleware, } from './createServerFn.js';
10
+ export { TSS_FORMDATA_CONTEXT, TSS_SERVER_FUNCTION, TSS_CONTENT_TYPE_FRAMED, TSS_CONTENT_TYPE_FRAMED_VERSIONED, TSS_FRAMED_PROTOCOL_VERSION, FrameType, FRAME_HEADER_SIZE, X_TSS_SERIALIZED, X_TSS_RAW_RESPONSE, X_TSS_CONTEXT, validateFramedProtocolVersion, } from './constants.js';
11
+ export type { FrameType as FrameTypeValue, ClientFnMeta, ServerFnMeta, } from './constants.js';
12
+ export type * from './serverRoute.js';
13
+ export type * from './startEntry.js';
14
+ export { createStart } from './createStart.js';
15
+ export type { AnyStartInstance, AnyStartInstanceOptions, StartInstance, StartInstanceOptions, } from './createStart.js';
16
+ export type { Register } from '@benjavicente/router-core';
17
+ export { getRouterInstance } from './getRouterInstance.js';
18
+ export { getDefaultSerovalPlugins } from './getDefaultSerovalPlugins.js';
19
+ export { getGlobalStartContext } from './getGlobalStartContext.js';
20
+ export { safeObjectMerge, createNullProtoObject } from './safeObjectMerge.js';
@@ -0,0 +1,12 @@
1
+ import { FRAME_HEADER_SIZE, FrameType, TSS_CONTENT_TYPE_FRAMED, TSS_CONTENT_TYPE_FRAMED_VERSIONED, TSS_FORMDATA_CONTEXT, TSS_FRAMED_PROTOCOL_VERSION, TSS_SERVER_FUNCTION, X_TSS_CONTEXT, X_TSS_RAW_RESPONSE, X_TSS_SERIALIZED, validateFramedProtocolVersion } from "./constants.js";
2
+ import { createNullProtoObject, safeObjectMerge } from "./safeObjectMerge.js";
3
+ import { createServerFn, execValidator, executeMiddleware, flattenMiddlewares } from "./createServerFn.js";
4
+ import { createMiddleware } from "./createMiddleware.js";
5
+ import { createStart } from "./createStart.js";
6
+ import { getRouterInstance } from "./getRouterInstance.js";
7
+ import { getDefaultSerovalPlugins } from "./getDefaultSerovalPlugins.js";
8
+ import { getGlobalStartContext } from "./getGlobalStartContext.js";
9
+ import { hydrate, json, mergeHeaders } from "@benjavicente/router-core/ssr/client";
10
+ import { RawStream } from "@benjavicente/router-core";
11
+ import { createClientOnlyFn, createIsomorphicFn, createServerOnlyFn } from "@benjavicente/start-fn-stubs";
12
+ export { FRAME_HEADER_SIZE, FrameType, RawStream, TSS_CONTENT_TYPE_FRAMED, TSS_CONTENT_TYPE_FRAMED_VERSIONED, TSS_FORMDATA_CONTEXT, TSS_FRAMED_PROTOCOL_VERSION, TSS_SERVER_FUNCTION, X_TSS_CONTEXT, X_TSS_RAW_RESPONSE, X_TSS_SERIALIZED, createClientOnlyFn, createIsomorphicFn, createMiddleware, createNullProtoObject, createServerFn, createServerOnlyFn, createStart, execValidator, executeMiddleware, flattenMiddlewares, getDefaultSerovalPlugins, getGlobalStartContext, getRouterInstance, hydrate, json, mergeHeaders, safeObjectMerge, validateFramedProtocolVersion };
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Merge target and source into a new null-proto object, filtering dangerous keys.
3
+ */
4
+ export declare function safeObjectMerge<T extends Record<string, unknown>>(target: T | undefined, source: Record<string, unknown> | null | undefined): T;
5
+ /**
6
+ * Create a null-prototype object, optionally copying from source.
7
+ */
8
+ export declare function createNullProtoObject<T extends object>(source?: T): {
9
+ [K in keyof T]: T[K];
10
+ };
@@ -0,0 +1,30 @@
1
+ //#region src/safeObjectMerge.ts
2
+ function isSafeKey(key) {
3
+ return key !== "__proto__" && key !== "constructor" && key !== "prototype";
4
+ }
5
+ /**
6
+ * Merge target and source into a new null-proto object, filtering dangerous keys.
7
+ */
8
+ function safeObjectMerge(target, source) {
9
+ const result = Object.create(null);
10
+ if (target) {
11
+ for (const key of Object.keys(target)) if (isSafeKey(key)) result[key] = target[key];
12
+ }
13
+ if (source && typeof source === "object") {
14
+ for (const key of Object.keys(source)) if (isSafeKey(key)) result[key] = source[key];
15
+ }
16
+ return result;
17
+ }
18
+ /**
19
+ * Create a null-prototype object, optionally copying from source.
20
+ */
21
+ function createNullProtoObject(source) {
22
+ if (!source) return Object.create(null);
23
+ const obj = Object.create(null);
24
+ for (const key of Object.keys(source)) if (isSafeKey(key)) obj[key] = source[key];
25
+ return obj;
26
+ }
27
+ //#endregion
28
+ export { createNullProtoObject, safeObjectMerge };
29
+
30
+ //# sourceMappingURL=safeObjectMerge.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"safeObjectMerge.js","names":[],"sources":["../../src/safeObjectMerge.ts"],"sourcesContent":["function isSafeKey(key: string): boolean {\n return key !== '__proto__' && key !== 'constructor' && key !== 'prototype'\n}\n\n/**\n * Merge target and source into a new null-proto object, filtering dangerous keys.\n */\nexport function safeObjectMerge<T extends Record<string, unknown>>(\n target: T | undefined,\n source: Record<string, unknown> | null | undefined,\n): T {\n const result = Object.create(null) as T\n if (target) {\n for (const key of Object.keys(target)) {\n if (isSafeKey(key)) result[key as keyof T] = target[key] as T[keyof T]\n }\n }\n if (source && typeof source === 'object') {\n for (const key of Object.keys(source)) {\n if (isSafeKey(key)) result[key as keyof T] = source[key] as T[keyof T]\n }\n }\n return result\n}\n\n/**\n * Create a null-prototype object, optionally copying from source.\n */\nexport function createNullProtoObject<T extends object>(\n source?: T,\n): { [K in keyof T]: T[K] } {\n if (!source) return Object.create(null)\n const obj = Object.create(null)\n for (const key of Object.keys(source)) {\n if (isSafeKey(key)) obj[key] = (source as Record<string, unknown>)[key]\n }\n return obj\n}\n"],"mappings":";AAAA,SAAS,UAAU,KAAsB;AACvC,QAAO,QAAQ,eAAe,QAAQ,iBAAiB,QAAQ;;;;;AAMjE,SAAgB,gBACd,QACA,QACG;CACH,MAAM,SAAS,OAAO,OAAO,KAAK;AAClC,KAAI;OACG,MAAM,OAAO,OAAO,KAAK,OAAO,CACnC,KAAI,UAAU,IAAI,CAAE,QAAO,OAAkB,OAAO;;AAGxD,KAAI,UAAU,OAAO,WAAW;OACzB,MAAM,OAAO,OAAO,KAAK,OAAO,CACnC,KAAI,UAAU,IAAI,CAAE,QAAO,OAAkB,OAAO;;AAGxD,QAAO;;;;;AAMT,SAAgB,sBACd,QAC0B;AAC1B,KAAI,CAAC,OAAQ,QAAO,OAAO,OAAO,KAAK;CACvC,MAAM,MAAM,OAAO,OAAO,KAAK;AAC/B,MAAK,MAAM,OAAO,OAAO,KAAK,OAAO,CACnC,KAAI,UAAU,IAAI,CAAE,KAAI,OAAQ,OAAmC;AAErE,QAAO"}
@@ -0,0 +1,65 @@
1
+ import { AnyContext, AnyRoute, Assign, Constrain, Expand, ResolveAllParamsFromParent, UnionToIntersection } from '@benjavicente/router-core';
2
+ import { AnyRequestMiddleware, AssignAllServerRequestContext } from './createMiddleware.js';
3
+ declare module '@benjavicente/router-core' {
4
+ interface FilebaseRouteOptionsInterface<TRegister, TParentRoute extends AnyRoute = AnyRoute, TId extends string = string, TPath extends string = string, TSearchValidator = undefined, TParams = {}, TLoaderDeps extends Record<string, any> = {}, TLoaderFn = undefined, TRouterContext = {}, TRouteContextFn = AnyContext, TBeforeLoadFn = AnyContext, TRemountDepsFn = AnyContext, TSSR = unknown, TServerMiddlewares = unknown, THandlers = undefined> {
5
+ server?: RouteServerOptions<TRegister, TParentRoute, TPath, TParams, TLoaderDeps, TLoaderFn, TRouterContext, TRouteContextFn, TBeforeLoadFn, TServerMiddlewares, THandlers>;
6
+ }
7
+ interface RouteTypes<in out TRegister, in out TParentRoute extends AnyRoute, in out TPath extends string, in out TFullPath extends string, in out TCustomId extends string, in out TId extends string, in out TSearchValidator, in out TParams, in out TRouterContext, in out TRouteContextFn, in out TBeforeLoadFn, in out TLoaderDeps, in out TLoaderFn, in out TChildren, in out TFileRouteTypes, in out TSSR, in out TServerMiddlewares, in out THandlers> {
8
+ middleware: TServerMiddlewares;
9
+ allServerContext: ResolveAllServerContext<TRegister, TParentRoute, TServerMiddlewares>;
10
+ }
11
+ interface BeforeLoadContextOptionsExtensions<in out TRegister, in out TParentRoute extends AnyRoute, in out TSearchValidator, in out TParams, in out TRouterContext, in out TRouteContextFn, in out TRouteId, in out TServerMiddlewares, in out THandlers> {
12
+ serverContext?: Expand<Assign<ResolveAllServerContext<TRegister, TParentRoute, TServerMiddlewares>, ExtractHandlersContext<THandlers>>>;
13
+ }
14
+ interface LoaderFnContextExtensions<in out TRegister, in out TParentRoute extends AnyRoute = AnyRoute, in out TId extends string = string, in out TParams = {}, in out TLoaderDeps = {}, in out TRouterContext = {}, in out TRouteContextFn = AnyContext, in out TBeforeLoadFn = AnyContext, in out TServerMiddlewares = unknown, in out THandlers = undefined> {
15
+ serverContext?: Expand<Assign<ResolveAllServerContext<TRegister, TParentRoute, TServerMiddlewares>, ExtractHandlersContext<THandlers>>>;
16
+ }
17
+ }
18
+ type ExtractHandlersContext<THandlers> = THandlers extends (...args: any) => CustomHandlerFunctionsRecord<any, any, any, any, any, any, infer TServerContext> ? UnionToIntersection<TServerContext> : THandlers extends Record<string, RouteMethodHandler<any, any, any, any, any, any, infer TServerContext>> ? UnionToIntersection<TServerContext> : undefined;
19
+ export interface RouteServerOptions<TRegister, TParentRoute extends AnyRoute, TFullPath extends string, TParams, TLoaderDeps, TLoaderFn, TRouterContext, TRouteContextFn, TBeforeLoadFn, TServerMiddlewares, THandlers> {
20
+ middleware?: Constrain<TServerMiddlewares, ReadonlyArray<AnyRequestMiddleware>>;
21
+ handlers?: Constrain<THandlers, Partial<Record<RouteMethod, RouteMethodHandlerFn<TRegister, TParentRoute, TFullPath, TParams, TServerMiddlewares, any, any>>> | ((opts: HandlersFnOpts<TRegister, TParentRoute, TFullPath, TParams, TServerMiddlewares>) => CustomHandlerFunctionsRecord<TRegister, TParentRoute, TFullPath, TParams, TServerMiddlewares, any, any>)>;
22
+ }
23
+ declare const createHandlersSymbol: unique symbol;
24
+ type CustomHandlerFunctionsRecord<TRegister, TParentRoute extends AnyRoute, TFullPath extends string, TParams, TServerMiddlewares, TMethodMiddlewares, TServerContext> = {
25
+ [createHandlersSymbol]: true;
26
+ } & Partial<Record<RouteMethod, RouteMethodHandler<TRegister, TParentRoute, TFullPath, TParams, TServerMiddlewares, TMethodMiddlewares, TServerContext>>>;
27
+ export interface HandlersFnOpts<TRegister, TParentRoute extends AnyRoute, TFullPath extends string, TParams, TServerMiddlewares> {
28
+ createHandlers: CreateHandlersFn<TRegister, TParentRoute, TFullPath, TParams, TServerMiddlewares>;
29
+ }
30
+ export type CreateHandlersFn<TRegister, TParentRoute extends AnyRoute, TFullPath extends string, TParams, TServerMiddlewares> = <const TMethodAllMiddlewares, const TMethodGetMiddlewares, const TMethodPostMiddlewares, const TMethodPutMiddlewares, const TMethodPatchMiddlewares, const TMethodDeleteMiddlewares, const TMethodOptionsMiddlewares, const TMethodHeadMiddlewares, TServerContext>(opts: CreateMethodFnOpts<TRegister, TParentRoute, TFullPath, TParams, TServerMiddlewares, TMethodAllMiddlewares, TMethodGetMiddlewares, TMethodPostMiddlewares, TMethodPutMiddlewares, TMethodPatchMiddlewares, TMethodDeleteMiddlewares, TMethodOptionsMiddlewares, TMethodHeadMiddlewares, TServerContext>) => CustomHandlerFunctionsRecord<TRegister, TParentRoute, TFullPath, TParams, TServerMiddlewares, any, TServerContext>;
31
+ export interface CreateMethodFnOpts<TRegister, TParentRoute extends AnyRoute, TFullPath extends string, TParams, TServerMiddlewares, TMethodAllMiddlewares, TMethodGetMiddlewares, TMethodPostMiddlewares, TMethodPutMiddlewares, TMethodPatchMiddlewares, TMethodDeleteMiddlewares, TMethodOptionsMiddlewares, TMethodHeadMiddlewares, TServerContext> {
32
+ ANY?: RouteMethodHandler<TRegister, TParentRoute, TFullPath, TParams, TServerMiddlewares, TMethodAllMiddlewares, TServerContext>;
33
+ GET?: RouteMethodHandler<TRegister, TParentRoute, TFullPath, TParams, TServerMiddlewares, TMethodGetMiddlewares, TServerContext>;
34
+ POST?: RouteMethodHandler<TRegister, TParentRoute, TFullPath, TParams, TServerMiddlewares, TMethodPostMiddlewares, TServerContext>;
35
+ PUT?: RouteMethodHandler<TRegister, TParentRoute, TFullPath, TParams, TServerMiddlewares, TMethodPutMiddlewares, TServerContext>;
36
+ PATCH?: RouteMethodHandler<TRegister, TParentRoute, TFullPath, TParams, TServerMiddlewares, TMethodPatchMiddlewares, TServerContext>;
37
+ DELETE?: RouteMethodHandler<TRegister, TParentRoute, TFullPath, TParams, TServerMiddlewares, TMethodDeleteMiddlewares, TServerContext>;
38
+ OPTIONS?: RouteMethodHandler<TRegister, TParentRoute, TFullPath, TParams, TServerMiddlewares, TMethodOptionsMiddlewares, TServerContext>;
39
+ HEAD?: RouteMethodHandler<TRegister, TParentRoute, TFullPath, TParams, TServerMiddlewares, TMethodHeadMiddlewares, TServerContext>;
40
+ }
41
+ export type RouteMethodHandler<TRegister, TParentRoute extends AnyRoute, TFullPath extends string, TParams, TServerMiddlewares, TMethodMiddlewares, TServerContext> = RouteMethodHandlerFn<TRegister, TParentRoute, TFullPath, TParams, TServerMiddlewares, TMethodMiddlewares, TServerContext> | RouteMethodBuilderOptions<TRegister, TParentRoute, TFullPath, TParams, TServerMiddlewares, TMethodMiddlewares, TServerContext>;
42
+ export interface RouteMethodBuilderOptions<TRegister, TParentRoute extends AnyRoute, TFullPath extends string, TParams, TServerMiddlewares, TMethodMiddlewares, TResponse> {
43
+ handler?: RouteMethodHandlerFn<TRegister, TParentRoute, TFullPath, TParams, TServerMiddlewares, TMethodMiddlewares, TResponse>;
44
+ middleware?: Constrain<TMethodMiddlewares, ReadonlyArray<AnyRequestMiddleware>>;
45
+ }
46
+ export type ResolveAllServerContext<TRegister, TParentRoute extends AnyRoute, TServerMiddlewares> = unknown extends TParentRoute ? AssignAllServerRequestContext<TRegister, TServerMiddlewares, {}> : Assign<TParentRoute['types']['allServerContext'], AssignAllServerRequestContext<TRegister, TServerMiddlewares, {}>>;
47
+ export type RouteMethod = 'ANY' | 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE' | 'OPTIONS' | 'HEAD';
48
+ export type RouteMethodHandlerFn<TRegister, TParentRoute extends AnyRoute, TFullPath extends string, TParams, TServerMiddlewares, TMethodMiddlewares, TServerContext> = (ctx: RouteMethodHandlerCtx<TRegister, TParentRoute, TFullPath, TParams, TServerMiddlewares, TMethodMiddlewares>) => RouteMethodResult<TServerContext> | Promise<RouteMethodResult<TServerContext>>;
49
+ export type RouteMethodResult<TContext> = Response | undefined | RouteMethodNextResult<TContext>;
50
+ export type RouteMethodNextResult<TContext> = {
51
+ isNext: true;
52
+ context: TContext;
53
+ };
54
+ export interface RouteMethodHandlerCtx<in out TRegister, in out TParentRoute extends AnyRoute, in out TFullPath extends string, in out TParams, in out TServerMiddlewares, in out TMethodMiddlewares> {
55
+ context: Expand<AssignAllMethodContext<TRegister, TParentRoute, TServerMiddlewares, TMethodMiddlewares>>;
56
+ request: Request;
57
+ params: Expand<ResolveAllParamsFromParent<TParentRoute, TParams>>;
58
+ pathname: TFullPath;
59
+ next: <TContext = undefined>(options?: {
60
+ context?: TContext;
61
+ }) => RouteMethodNextResult<TContext>;
62
+ }
63
+ export type MergeMethodMiddlewares<TServerMiddlewares, TMethodMiddlewares> = TServerMiddlewares extends ReadonlyArray<any> ? TMethodMiddlewares extends ReadonlyArray<any> ? readonly [...TServerMiddlewares, ...TMethodMiddlewares] : TServerMiddlewares : TMethodMiddlewares;
64
+ export type AssignAllMethodContext<TRegister, TParentRoute extends AnyRoute, TServerMiddlewares, TMethodMiddlewares> = ResolveAllServerContext<TRegister, TParentRoute, MergeMethodMiddlewares<TServerMiddlewares, TMethodMiddlewares>>;
65
+ export {};
@@ -0,0 +1,8 @@
1
+ import { AnyRouter, Awaitable } from '@benjavicente/router-core';
2
+ import { AnyStartInstance } from './createStart.js';
3
+ export interface StartEntry {
4
+ startInstance: AnyStartInstance | undefined;
5
+ }
6
+ export interface RouterEntry {
7
+ getRouter: () => Awaitable<AnyRouter>;
8
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export {};
package/package.json ADDED
@@ -0,0 +1,98 @@
1
+ {
2
+ "name": "@benjavicente/start-client-core",
3
+ "version": "1.167.9",
4
+ "description": "Modern and scalable routing for React applications",
5
+ "author": "Tanner Linsley",
6
+ "license": "MIT",
7
+ "repository": {
8
+ "type": "git",
9
+ "url": "git+https://github.com/TanStack/router.git",
10
+ "directory": "packages/start-client-core"
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
+ },
35
+ "./client": {
36
+ "import": {
37
+ "types": "./dist/esm/client/index.d.ts",
38
+ "default": "./dist/esm/client/index.js"
39
+ }
40
+ },
41
+ "./client-rpc": {
42
+ "import": {
43
+ "types": "./dist/esm/client-rpc/index.d.ts",
44
+ "default": "./dist/esm/client-rpc/index.js"
45
+ }
46
+ },
47
+ "./package.json": "./package.json"
48
+ },
49
+ "imports": {
50
+ "#tanstack-start-entry": {
51
+ "default": "./dist/esm/fake-start-entry.js"
52
+ },
53
+ "#tanstack-router-entry": {
54
+ "default": "./dist/esm/fake-start-entry.js"
55
+ }
56
+ },
57
+ "sideEffects": false,
58
+ "files": [
59
+ "dist",
60
+ "src",
61
+ "skills",
62
+ "bin",
63
+ "!skills/_artifacts"
64
+ ],
65
+ "engines": {
66
+ "node": ">=22.12.0"
67
+ },
68
+ "dependencies": {
69
+ "seroval": "^1.4.2",
70
+ "@benjavicente/router-core": "1.168.9",
71
+ "@benjavicente/start-fn-stubs": "1.161.6",
72
+ "@benjavicente/start-storage-context": "1.166.23"
73
+ },
74
+ "devDependencies": {
75
+ "@tanstack/intent": "^0.0.14",
76
+ "vite": "*",
77
+ "@types/node": ">=20"
78
+ },
79
+ "bin": {
80
+ "intent": "./bin/intent.js"
81
+ },
82
+ "scripts": {
83
+ "clean": "rimraf ./dist && rimraf ./coverage",
84
+ "test": "pnpm test:eslint && pnpm test:types && pnpm test:build && pnpm test:unit",
85
+ "test:unit": "vitest",
86
+ "test:unit:dev": "vitest --watch",
87
+ "test:eslint": "eslint ./src",
88
+ "test:types": "pnpm run \"/^test:types:ts[0-9]{2}$/\"",
89
+ "test:types:ts55": "node ../../node_modules/typescript55/lib/tsc.js",
90
+ "test:types:ts56": "node ../../node_modules/typescript56/lib/tsc.js",
91
+ "test:types:ts57": "node ../../node_modules/typescript57/lib/tsc.js",
92
+ "test:types:ts58": "node ../../node_modules/typescript58/lib/tsc.js",
93
+ "test:types:ts59": "node ../../node_modules/typescript59/lib/tsc.js",
94
+ "test:types:ts60": "tsc",
95
+ "test:build": "publint --strict && attw --ignore-rules no-resolution --pack .",
96
+ "build": "vite build"
97
+ }
98
+ }
@@ -0,0 +1,210 @@
1
+ ---
2
+ name: start-core
3
+ description: >-
4
+ Core overview for TanStack Start: tanstackStart() Vite plugin,
5
+ getRouter() factory, root route document shell (HeadContent,
6
+ Scripts, Outlet), client/server entry points, routeTree.gen.ts,
7
+ tsconfig configuration. Entry point for all Start skills.
8
+ type: core
9
+ library: tanstack-start
10
+ library_version: '1.166.2'
11
+ sources:
12
+ - TanStack/router:docs/start/framework/react/build-from-scratch.md
13
+ - TanStack/router:docs/start/framework/react/quick-start.md
14
+ - TanStack/router:docs/start/framework/react/guide/routing.md
15
+ ---
16
+
17
+ # TanStack Start Core
18
+
19
+ TanStack Start is a full-stack React framework built on TanStack Router and Vite. It adds SSR, streaming, server functions (type-safe RPCs), middleware, server routes, and universal deployment.
20
+
21
+ > **CRITICAL**: All code in TanStack Start is ISOMORPHIC by default — it runs in BOTH server and client environments. Loaders run on both server AND client. To run code exclusively on the server, use `createServerFn`. This is the #1 AI agent mistake.
22
+ > **CRITICAL**: TanStack Start is NOT Next.js. Do not generate `getServerSideProps`, `"use server"` directives, `app/layout.tsx`, or any Next.js/Remix patterns. Use `createServerFn` for server-only code.
23
+ > **CRITICAL**: Types are FULLY INFERRED. Never cast, never annotate inferred values.
24
+
25
+ ## Sub-Skills
26
+
27
+ | Task | Sub-Skill |
28
+ | -------------------------------------------- | ------------------------------------------------------------------- |
29
+ | Type-safe RPCs, data fetching, mutations | [start-core/server-functions/SKILL.md](./server-functions/SKILL.md) |
30
+ | Request/function middleware, context, auth | [start-core/middleware/SKILL.md](./middleware/SKILL.md) |
31
+ | Isomorphic execution, environment boundaries | [start-core/execution-model/SKILL.md](./execution-model/SKILL.md) |
32
+ | REST API endpoints alongside app routes | [start-core/server-routes/SKILL.md](./server-routes/SKILL.md) |
33
+ | Hosting, SSR modes, prerendering, SEO | [start-core/deployment/SKILL.md](./deployment/SKILL.md) |
34
+
35
+ ## Quick Decision Tree
36
+
37
+ ```text
38
+ Need to run code exclusively on the server (DB, secrets)?
39
+ → start-core/server-functions
40
+
41
+ Need auth checks, logging, or shared logic across server functions?
42
+ → start-core/middleware
43
+
44
+ Need to understand where code runs (server vs client)?
45
+ → start-core/execution-model
46
+
47
+ Need a REST API endpoint (GET/POST/PUT/DELETE)?
48
+ → start-core/server-routes
49
+
50
+ Need to deploy, configure SSR, or prerender?
51
+ → start-core/deployment
52
+ ```
53
+
54
+ ## Project Setup
55
+
56
+ ### 1. Install Dependencies
57
+
58
+ ```bash
59
+ npm i @benjavicente/react-start @benjavicente/react-router react react-dom
60
+ npm i -D vite @vitejs/plugin-react typescript
61
+ ```
62
+
63
+ ### 2. Configure Vite
64
+
65
+ ```ts
66
+ // vite.config.ts
67
+ import { defineConfig } from 'vite'
68
+ import { tanstackStart } from '@benjavicente/react-start/plugin/vite'
69
+ import viteReact from '@vitejs/plugin-react'
70
+
71
+ export default defineConfig({
72
+ plugins: [
73
+ // MUST come before react()
74
+ tanstackStart(),
75
+ viteReact(),
76
+ ],
77
+ })
78
+ ```
79
+
80
+ ### 3. Create Router Factory
81
+
82
+ ```tsx
83
+ // src/router.tsx
84
+ import { createRouter } from '@benjavicente/react-router'
85
+ import { routeTree } from './routeTree.gen'
86
+
87
+ export function getRouter() {
88
+ const router = createRouter({
89
+ routeTree,
90
+ scrollRestoration: true,
91
+ })
92
+
93
+ return router
94
+ }
95
+ ```
96
+
97
+ ### 4. Create Root Route with Document Shell
98
+
99
+ ```tsx
100
+ // src/routes/__root.tsx
101
+ import type { ReactNode } from 'react'
102
+ import {
103
+ Outlet,
104
+ createRootRoute,
105
+ HeadContent,
106
+ Scripts,
107
+ } from '@benjavicente/react-router'
108
+
109
+ export const Route = createRootRoute({
110
+ head: () => ({
111
+ meta: [
112
+ { charSet: 'utf-8' },
113
+ { name: 'viewport', content: 'width=device-width, initial-scale=1' },
114
+ { title: 'My App' },
115
+ ],
116
+ }),
117
+ component: RootComponent,
118
+ })
119
+
120
+ function RootComponent() {
121
+ return (
122
+ <html>
123
+ <head>
124
+ <HeadContent />
125
+ </head>
126
+ <body>
127
+ <Outlet />
128
+ <Scripts />
129
+ </body>
130
+ </html>
131
+ )
132
+ }
133
+ ```
134
+
135
+ ### 5. Create Index Route with Server Function
136
+
137
+ ```tsx
138
+ // src/routes/index.tsx
139
+ import { createFileRoute } from '@benjavicente/react-router'
140
+ import { createServerFn } from '@benjavicente/react-start'
141
+
142
+ const getGreeting = createServerFn({ method: 'GET' }).handler(async () => {
143
+ return { message: 'Hello from the server!' }
144
+ })
145
+
146
+ export const Route = createFileRoute('/')({
147
+ loader: () => getGreeting(),
148
+ component: HomePage,
149
+ })
150
+
151
+ function HomePage() {
152
+ const data = Route.useLoaderData()
153
+ return <h1>{data.message}</h1>
154
+ }
155
+ ```
156
+
157
+ ## Common Mistakes
158
+
159
+ ### 1. CRITICAL: React plugin before Start plugin in Vite config
160
+
161
+ ```ts
162
+ // WRONG — route generation and server function compilation fail
163
+ plugins: [react(), tanstackStart()]
164
+
165
+ // CORRECT — Start plugin must come first
166
+ plugins: [tanstackStart(), react()]
167
+ ```
168
+
169
+ ### 2. HIGH: Enabling verbatimModuleSyntax in tsconfig
170
+
171
+ `verbatimModuleSyntax` causes server bundles to leak into client bundles. Keep it disabled.
172
+
173
+ ### 3. HIGH: Missing Scripts component in root route
174
+
175
+ The `<Scripts />` component must be rendered in the `<body>` of the root route. Without it, client-side JavaScript does not load and hydration fails.
176
+
177
+ ```tsx
178
+ // WRONG — no Scripts
179
+ function RootComponent() {
180
+ return (
181
+ <html>
182
+ <head>
183
+ <HeadContent />
184
+ </head>
185
+ <body>
186
+ <Outlet />
187
+ </body>
188
+ </html>
189
+ )
190
+ }
191
+
192
+ // CORRECT — Scripts in body
193
+ function RootComponent() {
194
+ return (
195
+ <html>
196
+ <head>
197
+ <HeadContent />
198
+ </head>
199
+ <body>
200
+ <Outlet />
201
+ <Scripts />
202
+ </body>
203
+ </html>
204
+ )
205
+ }
206
+ ```
207
+
208
+ ## Version Note
209
+
210
+ This skill targets `@benjavicente/react-start` v1.166.2 and `@benjavicente/start-client-core` v1.166.2.