// a function that can have different implementations on the client and server. // implementations not provided will default to a no-op function. export type IsomorphicFn< TArgs extends Array = [], TServer = undefined, TClient = undefined, > = (...args: TArgs) => TServer | TClient export interface ServerOnlyFn, TServer> extends IsomorphicFn { client: ( clientImpl: (...args: TArgs) => TClient, ) => IsomorphicFn } export interface ClientOnlyFn, TClient> extends IsomorphicFn { server: ( serverImpl: (...args: TArgs) => TServer, ) => IsomorphicFn } export interface IsomorphicFnBase extends IsomorphicFn { server: , TServer>( serverImpl: (...args: TArgs) => TServer, ) => ServerOnlyFn client: , TClient>( clientImpl: (...args: TArgs) => TClient, ) => ClientOnlyFn } // this is a dummy function, it will be replaced by the transformer // if we use `createIsomorphicFn` in this library itself, vite tries to execute it before the transformer runs // therefore we must return a dummy function that allows calling `server` and `client` method chains. export function createIsomorphicFn(): IsomorphicFnBase { return { server: () => ({ client: () => () => {} }), client: () => ({ server: () => () => {} }), } as any }