From 6a4350749e0b56f7e2ffe7c6260f3d69895bf61b Mon Sep 17 00:00:00 2001 From: Pedro Cattori Date: Tue, 20 Aug 2024 17:32:33 -0400 Subject: [PATCH] trigger single-fetch types via `future` interface merging --- packages/remix-cloudflare/index.ts | 1 + packages/remix-deno/index.ts | 1 + packages/remix-node/index.ts | 1 + packages/remix-server-runtime/future.ts | 1 + packages/remix-server-runtime/index.ts | 2 +- packages/remix-server-runtime/reexport.ts | 2 + packages/remix-server-runtime/serialize.ts | 12 ++++++ packages/remix-server-runtime/single-fetch.ts | 43 ++++++++++++++++--- 8 files changed, 55 insertions(+), 8 deletions(-) create mode 100644 packages/remix-server-runtime/future.ts diff --git a/packages/remix-cloudflare/index.ts b/packages/remix-cloudflare/index.ts index ec5fa2a0dc6..f79e1b9d3be 100644 --- a/packages/remix-cloudflare/index.ts +++ b/packages/remix-cloudflare/index.ts @@ -40,6 +40,7 @@ export type { DataFunctionArgs, EntryContext, ErrorResponse, + Future, HandleDataRequestFunction, HandleDocumentRequestFunction, HeadersArgs, diff --git a/packages/remix-deno/index.ts b/packages/remix-deno/index.ts index c82e1b0ae6d..3a16591712e 100644 --- a/packages/remix-deno/index.ts +++ b/packages/remix-deno/index.ts @@ -43,6 +43,7 @@ export type { DataFunctionArgs, EntryContext, ErrorResponse, + Future, HandleDataRequestFunction, HandleDocumentRequestFunction, HandleErrorFunction, diff --git a/packages/remix-node/index.ts b/packages/remix-node/index.ts index 960d3bad3e7..bccdb246f7d 100644 --- a/packages/remix-node/index.ts +++ b/packages/remix-node/index.ts @@ -52,6 +52,7 @@ export type { DataFunctionArgs, EntryContext, ErrorResponse, + Future, HandleDataRequestFunction, HandleDocumentRequestFunction, HeadersArgs, diff --git a/packages/remix-server-runtime/future.ts b/packages/remix-server-runtime/future.ts new file mode 100644 index 00000000000..3dd46a2bce1 --- /dev/null +++ b/packages/remix-server-runtime/future.ts @@ -0,0 +1 @@ +export interface Future {} diff --git a/packages/remix-server-runtime/index.ts b/packages/remix-server-runtime/index.ts index aa1fc78cdc7..a615a9deeb3 100644 --- a/packages/remix-server-runtime/index.ts +++ b/packages/remix-server-runtime/index.ts @@ -11,7 +11,6 @@ export { data as unstable_data, } from "./single-fetch"; export type { - Serialize as unstable_Serialize, SingleFetchResult as UNSAFE_SingleFetchResult, SingleFetchResults as UNSAFE_SingleFetchResults, } from "./single-fetch"; @@ -60,6 +59,7 @@ export type { EntryContext, ErrorResponse, FlashSessionData, + Future, HandleDataRequestFunction, HandleDocumentRequestFunction, HeadersArgs, diff --git a/packages/remix-server-runtime/reexport.ts b/packages/remix-server-runtime/reexport.ts index cc7fc46f507..27770979f3e 100644 --- a/packages/remix-server-runtime/reexport.ts +++ b/packages/remix-server-runtime/reexport.ts @@ -28,6 +28,8 @@ export type { AppLoadContext } from "./data"; export type { EntryContext } from "./entry"; +export type { Future } from "./future"; + export type { HtmlLinkDescriptor, LinkDescriptor, diff --git a/packages/remix-server-runtime/serialize.ts b/packages/remix-server-runtime/serialize.ts index c3d4822f498..6f2280661f6 100644 --- a/packages/remix-server-runtime/serialize.ts +++ b/packages/remix-server-runtime/serialize.ts @@ -6,6 +6,14 @@ import type { } from "./routeModules"; import { expectType } from "./typecheck"; import { type Expect, type Equal } from "./typecheck"; +import { type SerializeFrom as SingleFetch_SerializeFrom } from "./single-fetch"; +import type { Future } from "./future"; + +type SingleFetchEnabled = Future extends { + singleFetch: infer T extends boolean; +} + ? T + : false; // prettier-ignore /** @@ -17,6 +25,10 @@ import { type Expect, type Equal } from "./typecheck"; * `type LoaderData = SerializeFrom` */ export type SerializeFrom = + SingleFetchEnabled extends true ? + T extends (...args: []) => unknown ? SingleFetch_SerializeFrom : + never + : T extends (...args: any[]) => infer Output ? Parameters extends [ClientLoaderFunctionArgs | ClientActionFunctionArgs] ? // Client data functions may not serialize diff --git a/packages/remix-server-runtime/single-fetch.ts b/packages/remix-server-runtime/single-fetch.ts index 6757fd256be..4bb631fbdaa 100644 --- a/packages/remix-server-runtime/single-fetch.ts +++ b/packages/remix-server-runtime/single-fetch.ts @@ -17,9 +17,9 @@ import type { AppLoadContext } from "./data"; import { sanitizeError, sanitizeErrors } from "./errors"; import { getDocumentHeaders } from "./headers"; import { ServerMode } from "./mode"; -import type { TypedDeferredData, TypedResponse } from "./responses"; +import type { TypedResponse } from "./responses"; import { isRedirectStatusCode, isResponse } from "./responses"; -import type { SerializeFrom } from "./serialize"; +import type { Jsonify } from "./jsonify"; export const SingleFetchRedirectSymbol = Symbol("SingleFetchRedirect"); @@ -379,6 +379,36 @@ type Serializable = | Set | Promise; +// prettier-ignore +type Serialize = + T extends void ? undefined : + + // First, let type stay as-is if its already serializable... + T extends Serializable ? T : + + // ...then don't allow functions to be serialized... + T extends (...args: any[]) => unknown ? undefined : + + // ...lastly handle inner types for all container types allowed by `turbo-stream` + + // Promise + T extends Promise ? Promise> : + + // Map & Set + T extends Map ? Map, Serialize> : + T extends Set ? Set> : + + // Array + T extends [] ? [] : + T extends readonly [infer F, ...infer R] ? [Serialize, ...Serialize] : + T extends Array ? Array> : + T extends readonly unknown[] ? readonly Serialize[] : + + // Record + T extends Record ? {[K in keyof T]: Serialize} : + + undefined + type Fn = (...args: any[]) => unknown; // Backwards-compatible type for Remix v2 where json/defer still use the old types, @@ -386,8 +416,7 @@ type Fn = (...args: any[]) => unknown; // migration of loaders to return naked objects. In the next major version, // json/defer will be removed so everything will use the new simplified typings. // prettier-ignore -export type Serialize = - Awaited> extends TypedDeferredData ? D : - Awaited> extends TypedResponse> ? SerializeFrom : - Awaited> extends DataWithResponseInit ? D : - Awaited>; +export type SerializeFrom = + Awaited> extends TypedResponse> ? Jsonify : + Awaited> extends DataWithResponseInit ? Serialize : + Serialize>>;