Skip to content

Commit

Permalink
defineClientLoader and defineClientAction
Browse files Browse the repository at this point in the history
  • Loading branch information
pcattori committed May 8, 2024
1 parent ab4a44d commit 1eb88a9
Show file tree
Hide file tree
Showing 7 changed files with 51 additions and 28 deletions.
2 changes: 2 additions & 0 deletions packages/remix-cloudflare/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,9 @@ export {
createRequestHandler,
createSession,
unstable_defineLoader,
unstable_defineClientLoader,
unstable_defineAction,
unstable_defineClientAction,
defer,
broadcastDevReady,
logDevReady,
Expand Down
2 changes: 2 additions & 0 deletions packages/remix-deno/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,9 @@ export {
broadcastDevReady,
createSession,
unstable_defineLoader,
unstable_defineClientLoader,
unstable_defineAction,
unstable_defineClientAction,
defer,
isCookie,
isSession,
Expand Down
2 changes: 2 additions & 0 deletions packages/remix-node/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,9 @@ export {
createRequestHandler,
createSession,
unstable_defineLoader,
unstable_defineClientLoader,
unstable_defineAction,
unstable_defineClientAction,
defer,
broadcastDevReady,
logDevReady,
Expand Down
18 changes: 3 additions & 15 deletions packages/remix-react/future/single-fetch.d.ts
Original file line number Diff line number Diff line change
@@ -1,26 +1,14 @@
import type { MetaArgs, UIMatch, UNSAFE_MetaMatch } from "@remix-run/react";
import type {
Loader,
Action,
SerializeFrom,
TypedDeferredData,
TypedResponse,
unstable_Loader as Loader,
unstable_Action as Action,
unstable_Serialize as Serialize,
} from "@remix-run/server-runtime";
import type {
useFetcher as useFetcherRR,
FetcherWithComponents,
} from "react-router-dom";

// Backwards-compatible type for Remix v2 where json/defer still use the old types,
// and only non-json/defer returns use the new types. This allows for incremental
// 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
type Serialize<T extends Loader | Action> =
Awaited<ReturnType<T>> extends TypedDeferredData<infer D> ? D :
Awaited<ReturnType<T>> extends TypedResponse<Record<string, unknown>> ? SerializeFrom<T> :
Awaited<ReturnType<T>>;

declare module "@remix-run/react" {
export function useLoaderData<T extends Loader>(): Serialize<T>;

Expand Down
19 changes: 12 additions & 7 deletions packages/remix-server-runtime/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,22 @@ export {
parseMultipartFormData as unstable_parseMultipartFormData,
} from "./formData";
export { defer, json, redirect, redirectDocument } from "./responses";

export {
SingleFetchRedirectSymbol as UNSAFE_SingleFetchRedirectSymbol,
defineLoader as unstable_defineLoader,
defineClientLoader as unstable_defineClientLoader,
defineAction as unstable_defineAction,
defineClientAction as unstable_defineClientAction,
} from "./single-fetch";
export type {
Loader,
Action,
Loader as unstable_Loader,
Action as unstable_Action,
Serialize as unstable_Serialize,
SingleFetchResult as UNSAFE_SingleFetchResult,
SingleFetchResults as UNSAFE_SingleFetchResults,
} from "./single-fetch";
export { SingleFetchRedirectSymbol as UNSAFE_SingleFetchRedirectSymbol } from "./single-fetch";

export { createRequestHandler } from "./server";
export {
createSession,
Expand Down Expand Up @@ -87,7 +96,3 @@ export type {
UploadHandler,
UploadHandlerPart,
} from "./reexport";
export {
defineLoader as unstable_defineLoader,
defineAction as unstable_defineAction,
} from "./reexport";
2 changes: 0 additions & 2 deletions packages/remix-server-runtime/reexport.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,5 +61,3 @@ export type {
SessionStorage,
FlashSessionData,
} from "./sessions";

export { defineLoader, defineAction } from "./single-fetch";
34 changes: 30 additions & 4 deletions packages/remix-server-runtime/single-fetch.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import type {
import { ResponseStubOperationsSymbol } from "./routeModules";
import type { TypedDeferredData, TypedResponse } from "./responses";
import { isDeferredData, isRedirectStatusCode, isResponse } from "./responses";
import type { SerializeFrom } from "./serialize";

export const SingleFetchRedirectSymbol = Symbol("SingleFetchRedirect");
const ResponseStubActionSymbol = Symbol("ResponseStubAction");
Expand Down Expand Up @@ -533,25 +534,50 @@ type DataFunctionReturnValue =
| TypedDeferredData<Record<string, unknown>>
| TypedResponse<Record<string, unknown>>;

// Backwards-compatible type for Remix v2 where json/defer still use the old types,
// and only non-json/defer returns use the new types. This allows for incremental
// 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<T extends Loader | ClientLoader | Action | ClientAction> =
Awaited<ReturnType<T>> extends TypedDeferredData<infer D> ? D :
Awaited<ReturnType<T>> extends TypedResponse<Record<string, unknown>> ? SerializeFrom<T> :
Awaited<ReturnType<T>>;

// loader
type LoaderArgs = RRLoaderArgs<AppLoadContext> & {
// Context is always provided in Remix, and typed for module augmentation support.
context: AppLoadContext;
response: ResponseStub;
};

export type Loader = (
args: LoaderArgs
) => MaybePromise<DataFunctionReturnValue>;
export let defineLoader = <T extends Loader>(loader: T): T => loader;

// clientLoader
type ClientLoaderArgs = RRLoaderArgs<undefined> & {
serverLoader: <T extends Loader>() => Promise<Serialize<T>>;
};
type ClientLoader = (args: ClientLoaderArgs) => MaybePromise<Serializable>;
export let defineClientLoader = <T extends ClientLoader>(clientLoader: T): T =>
clientLoader;

// action
type ActionArgs = RRActionArgs<AppLoadContext> & {
// Context is always provided in Remix, and typed for module augmentation support.
context: AppLoadContext;
response: ResponseStub;
};

export type Action = (
args: ActionArgs
) => MaybePromise<DataFunctionReturnValue>;

export let defineLoader = <T extends Loader>(loader: T): T => loader;
export let defineAction = <T extends Action>(action: T): T => action;

// clientAction
type ClientActionArgs = RRActionArgs<undefined> & {
serverAction: <T extends Action>() => Promise<Serialize<T>>;
};
type ClientAction = (args: ClientActionArgs) => MaybePromise<Serializable>;
export let defineClientAction = <T extends ClientAction>(clientAction: T): T =>
clientAction;

0 comments on commit 1eb88a9

Please sign in to comment.