import { AppLoadContext, ServerBuild } from '@netlify/remix-runtime';
import { Context } from '@netlify/edge-functions';

type LoadContext = AppLoadContext & Context;
/**
 * A function that returns the value to use as `context` in route `loader` and
 * `action` functions.
 *
 * You can think of this as an escape hatch that allows you to pass
 * environment/platform-specific values through to your loader/action.
 */
type GetLoadContextFunction = (request: Request, context: Context) => Promise<LoadContext> | LoadContext;
type RequestHandler = (request: Request, context: LoadContext) => Promise<Response | void>;
/**
 * See https://remix.run/docs/en/main/other-api/adapter.
 * This returns a Netlify Edge Function handler: https://docs.netlify.com/edge-functions/overview/.
 */
declare function createRequestHandler({ build, mode, getLoadContext, }: {
    build: ServerBuild;
    mode?: string;
    getLoadContext?: GetLoadContextFunction;
}): RequestHandler;

/**
 * The base Hydrogen templates expect a globally defined `ExecutionContext` type, which by default
 * comes from Oxygen:
 * https://github.com/Shopify/hydrogen/blob/92a53c477540ee22cc273e7f3cbd2fd0582c815f/templates/skeleton/env.d.ts#L3.
 * We do the same thing to minimize differences.
 */
declare global {
    interface ExecutionContext {
        waitUntil(promise: Promise<unknown>): void;
    }
}
/**
 * For convenience, this matches the function signature that Hydrogen includes by default in its templates:
 * https://github.com/Shopify/hydrogen/blob/92a53c477540ee22cc273e7f3cbd2fd0582c815f/templates/skeleton/app/lib/context.ts.
 *
 * Remix expects the user to use module augmentation to modify their exported `AppLoadContext` type. See
 * https://github.com/remix-run/remix/blob/5dc3b67dc31f3df7b1b0298ae4e9cac9c5ae1c06/packages/remix-server-runtime/data.ts#L15-L23
 * Hydrogen follows this pattern. However, because of the way TypeScript module augmentation works,
 * we can't access the final user-augmented type here, so we have to do this dance with generic types.
 */
type CreateAppLoadContext<E extends {}, C extends {}> = (request: Request, env: E, executionContext: ExecutionContext) => Promise<C>;
declare const createHydrogenAppLoadContext: <E extends {}, C extends {}>(request: Request, netlifyContext: Context, createAppLoadContext: CreateAppLoadContext<E, C>) => Promise<Context & C & Record<string, unknown>>;

export { type GetLoadContextFunction, type RequestHandler, createHydrogenAppLoadContext, createRequestHandler };
