UNPKG

make-synchronized

Version:

[![Coverage][codecov_badge]][codecov_link] [![Npm Version][package_version_badge]][package_link] [![MIT License][license_badge]][license_link]

246 lines (198 loc) 7.24 kB
type Module = | string // `URL` and duck type | URL | {href: string} // `ImportMeta` and duck type with `url` | ImportMeta | {url: string} | {filename: string} type NormalizedPropertyPath = string[] type PropertyPath = undefined | string | NormalizedPropertyPath type AnyFunction = (...argumentsList: any[]) => any type AsynchronousFunction = (...argumentsList: any[]) => Promise<any> type ObjectWithFunctions = Record<string, any> type ModuleExportImplementation = ObjectWithFunctions | AnyFunction type SynchronizedFunction< InputAsynchronousFunction extends AnyFunction = AnyFunction, > = ( ...argumentsList: Parameters<InputAsynchronousFunction> ) => Awaited<ReturnType<InputAsynchronousFunction>> type SynchronizedObject< InputObject extends ObjectWithFunctions = ObjectWithFunctions, > = { [Key in keyof InputObject]: InputObject[Key] extends AsynchronousFunction ? SynchronizedFunction<InputObject[Key]> : Awaited<InputObject[Key]> } type SynchronizedModule<InputNodeModule = Record<string, any>> = { [Key in keyof InputNodeModule]: InputNodeModule[Key] extends AsynchronousFunction ? SynchronizedFunction<InputNodeModule[Key]> : Awaited<InputNodeModule[Key]> } type NodeModule = Record<string, any> type NodeModuleWithFunctionDefaultExport = NodeModule & { default: AnyFunction } type SynchronizedDefaultExportProxy< InputNodeModule extends NodeModuleWithFunctionDefaultExport = NodeModuleWithFunctionDefaultExport, > = SynchronizedFunction<InputNodeModule['default']> & SynchronizedModule<InputNodeModule> // Main function /** Make an inline asynchronous function into synchronized. @param {function} implementation - function to be synchronized @example ```js import makeSynchronized from 'make-synchronized' const synchronizedFoo = makeSynchronized(() => Promise.resolve(foo)) ``` */ export function makeSynchronized< InputFunction extends AnyFunction = AnyFunction, >(implementation: InputFunction): SynchronizedFunction<InputFunction> /** Make functions in a module synchronized. @param {string | URL | ImportMeta} module - module to be synchronized @example ```js import makeSynchronized from 'make-synchronized' const synchronizedFoo = makeSynchronized<typeof import('foo')>('foo') const {bar: synchronizedBar} = makeSynchronized<typeof import('foo')>('foo') ``` */ export function makeSynchronized<InputNodeModule = Record<string, any>>( module: Module, ): InputNodeModule extends NodeModuleWithFunctionDefaultExport ? SynchronizedDefaultExportProxy<InputNodeModule> : SynchronizedModule<InputNodeModule> /** Make a function synchronized for default export. @param {string | URL | ImportMeta} module - current module @param {function | Record<string, any>} implementation - current module implementation @example ```js import makeSynchronized from 'make-synchronized' export default makeSynchronized(import.meta, myAsynchronousFunction) ``` */ export function makeSynchronized< InputImplementation extends ModuleExportImplementation, >( module: Module, implementation: InputImplementation, ): InputImplementation extends AnyFunction ? SynchronizedFunction<InputImplementation> : InputImplementation extends ObjectWithFunctions ? SynchronizedObject<InputImplementation> : never // For modules /** Make default export asynchronous function of module synchronized. @param {string | URL | ImportMeta} module - module to be synchronized @example ```js import {makeDefaultExportSynchronized} from 'make-synchronized' const synchronizedFoo = makeSynchronized<typeof import('foo')>('foo') ``` */ export function makeDefaultExportSynchronized< InputNodeModule extends NodeModuleWithFunctionDefaultExport = NodeModuleWithFunctionDefaultExport, >(module: Module): SynchronizedFunction<InputNodeModule['default']> /** Make functions of module synchronized. @param {string | URL | ImportMeta} module - module to be synchronized @example ```js import {makeDefaultExportSynchronized} from 'make-synchronized' const {default: synchronizedFoo, bar: synchronizedBar} = makeSynchronized<typeof import('foo')>('foo') ``` */ export function makeModuleSynchronized< InputNodeModule extends NodeModule = NodeModule, >(module: Module): SynchronizedModule<InputNodeModule> // For exports /** Make an asynchronous function synchronized for default export. @param {string | URL | ImportMeta} module - current module location @param {AsynchronousFunction} implementation - asynchronous function implementation @example ```js import {makeSynchronizedFunction} from 'make-synchronized' export default makeSynchronizedFunction(import.meta, myAsynchronousFunction) ``` */ export function makeSynchronizedFunction< InputFunction extends AsynchronousFunction = AsynchronousFunction, >( module: Module, implementation: InputFunction, ): SynchronizedFunction<InputFunction> /** Make an asynchronous function synchronized for named export. @param {string | URL | ImportMeta} module - current module location @param {AsynchronousFunction} implementation - asynchronous function implementation @param {string | string[]} specifier - function access path, MUST match the export specifier @example ```js import {makeSynchronizedFunction} from 'make-synchronized' export const mySynchronousFunction = makeSynchronizedFunction(import.meta, myAsynchronousFunction, 'mySynchronousFunction') ``` */ export function makeSynchronizedFunction< InputFunction extends AsynchronousFunction = AsynchronousFunction, >( module: Module, implementation: InputFunction, specifier?: PropertyPath, ): SynchronizedFunction<InputFunction> /** Make a group of asynchronous functions synchronized to export. @param {string | URL | ImportMeta} module - current module location @param {ObjectWithFunctions} implementation - asynchronous function implementations @example ```js import {makeSynchronizedFunctions} from 'make-synchronized' export const { foo, bar, } = makeSynchronizedFunctions(import.meta, { foo: myAsynchronousFunctionFoo, bar: myAsynchronousFunctionBar, }) ``` */ export function makeSynchronizedFunctions< InputObjectWithFunctions extends ObjectWithFunctions = ObjectWithFunctions, >( module: Module, implementation: InputObjectWithFunctions, ): SynchronizedObject<InputObjectWithFunctions> export default makeSynchronized // For inline functions /** Make an inline asynchronous function into synchronized. @param {function} implementation - function to be synchronized @example ```js import {makeInlineFunctionSynchronized} from 'make-synchronized' const synchronizedFoo = makeSynchronized(() => Promise.resolve(foo)) ``` */ export function makeInlineFunctionSynchronized< InputFunction extends AnyFunction = AnyFunction, >(implementation: InputFunction): SynchronizedFunction<InputFunction> /** Make an inline asynchronous function into synchronized. @param {string} implementation - function to be synchronized @example ```js import {makeInlineFunctionSynchronized} from 'make-synchronized' const synchronizedFoo = makeSynchronized(() => Promise.resolve(foo)) ``` */ export function makeInlineFunctionSynchronized< T extends AnyFunction = AnyFunction, >(implementation: string): SynchronizedFunction<T>