[![Coverage][codecov_badge]][codecov_link] [![Npm Version][package_version_badge]][package_link] [![MIT License][license_badge]][license_link]
npm install make-synchronized[![Coverage][codecov_badge]][codecov_link]
[![Npm Version][package_version_badge]][package_link]
[![MIT License][license_badge]][license_link]
[codecov_badge]: https://img.shields.io/codecov/c/github/fisker/make-synchronized?style=flat-square
[codecov_link]: https://codecov.io/gh/fisker/make-synchronized
[license_badge]: https://img.shields.io/npm/l/make-synchronized.svg?style=flat-square
[license_link]: https://github.com/fisker/make-synchronized/blob/main/license
[package_version_badge]: https://img.shields.io/npm/v/make-synchronized.svg?style=flat-square
[package_link]: https://www.npmjs.com/package/make-synchronized
> Make synchronized functions.
``bash`
yarn add make-synchronized
This module mainly to support three kinds of different purpose of usage:
1. Make asynchronous functions in an existing module into synchronized
`js
import makeSynchronized from 'make-synchronized'
const synchronized = makeSynchronized(
new URL('./my-asynchronous-function-module.js', import.meta.url),
)
`
1. Make a module that turns asynchronous function into synchronized
`js
import makeSynchronized from 'make-synchronized'
export default makeSynchronized(import.meta, myAsynchronousFunction)
`
1. Make an inline asynchronous function into synchronized
`js
import makeSynchronized from 'make-synchronized'
const synchronized = makeSynchronized(() => Promise.resolve('foo'))
`
`js`
import {
makeSynchronized, // Same as the default export
makeDefaultExportSynchronized,
makeModuleSynchronized,
makeSynchronizedFunction,
makeSynchronizedFunctions,
makeInlineFunctionSynchronized,
} from 'make-synchronized'
This module uses MessagePort#postMessage to transfer arguments, return values, errors between the main thread and the worker. Please make sure the arguments and return values are serializable by the structured clone algorithm.
> Make asynchronous functions in an existing module to be synchronized to call.
- If the passing module is a module that contains a function type default export, returns a Proxy function, with other specifiers attached.
`js`
// foo.js
export default () => Promise.resolve('default export called')
export const foo = 'foo'
export const bar = () => Promise.resolve('bar called')
`js
const synchronized = makeSynchronized(new URL('./foo.js', import.meta.url))
synchronized()
// -> "default export called"
synchronized.foo
// -> "foo"
// This function also synchronized.
synchronized.bar()
// -> "bar called"
`
- If the passing module is a module without default export or default export is not a function, a Module object will be returned with all specifiers.
`js`
// foo.js
export const foo = 'foo'
export const bar = () => Promise.resolve('bar called')
`js
import makeSynchronized from 'make-synchronized'
const module = makeSynchronized(new URL('./foo.js', import.meta.url))
module
// [Object: null prototype] [Module] { bar: [Getter], foo: [Getter] }
module.foo
// -> "foo"
module.bar()
// -> "bar called"
`
> Make asynchronous functions to be synchronized for export.
- If implementation is a function, returns a synchronized version of the passed function.
> [!IMPORTANT]
>
> It MUST be used as the default export
`js
// foo.js
import makeSynchronized from 'make-synchronized'
export default makeSynchronized(import.meta, () => Promise.resolve('foo'))
`
`js
import foo from './foo.js'
foo()
// -> foo
`
- Example
- If implementation is a object with multiple functions, returns a Proxy object with synchronized functions attached.
> [!IMPORTANT]
>
> Functions MUST exported as the same name as the key in implementation object.
`js
// foo-and-bar.js
import makeSynchronized from 'make-synchronized'
export const {foo, bar} = makeSynchronized(import.meta, {
async foo() {
return 'foo'
},
async bar() {
return 'bar'
},
})
`
`js
import {foo, bar} from './foo-and-bar.js'
foo()
// -> foo
bar()
// -> bar
`
- Example
`js
import makeSynchronized from 'make-synchronized'
const foo = makeSynchronized(() => Promise.resolve('foo'))
foo()
// -> foo
`
> [!IMPORTANT]
>
> The given function is executed in a separate environment, so you cannot use any variables/imports from outside the scope of the function. You can pass in arguments to the function. To import dependencies, use await import(…) in the function body.
- Example
> Make a synchronized function for export.
Explicit version of makeSynchronized(module, implementation) that returns the synchronized function for export.
`js
import {makeSynchronizedFunction} from 'make-synchronized'
export default makeSynchronizedFunction(
import.meta,
async () => 'default export called',
)
export const foo = makeSynchronizedFunction(
import.meta,
async () => 'foo export called',
'foo',
)
`
> Make synchronized functions for export.
Explicit version of makeSynchronized(module, implementation) that only returns Proxy with synchronized functions for export.
`js
import {makeSynchronizedFunctions} from 'make-synchronized'
export const {
// MUST match the key in second argument
foo,
bar,
} = makeSynchronizedFunctions(import.meta, {
foo: async () => 'foo export called',
bar: async () => 'bar export called',
})
`
> Make an existing module's default export to be a synchronized function.
Explicit version of makeSynchronized(module) that only returns the synchronized default export.
`js
import {makeDefaultExportSynchronized} from 'make-synchronized'
const foo = makeModuleSynchronized('foo')
foo()
// -> default export of foo module is called.`
> Make an existing module's exports to be synchronized functions.
Synchronize version of import(module), always returns a Module.
`diff`
- const {default: foo} = await import('foo')
+ const {default: foo} = makeModuleSynchronized('foo')
`js
import {makeModuleSynchronized} from 'make-synchronized'
const {default: foo, bar} = makeModuleSynchronized('foo')
foo()
// -> default export of foo module is called.
bar()
// -> bar function from foo module is called.`
> Make an inline asynchronous function into synchronized.
> [!IMPORTANT]
>
> The given function is executed in a separate environment, so you cannot use any variables/imports from outside the scope of the function. You can pass in arguments to the function. To import dependencies, use await import(…) in the function body.
Explicit version of makeSynchronized(function).
`js
import makeSynchronized from 'make-synchronized'
const foo = makeSynchronized(() => Promise.resolve('foo'))
foo()
// -> foo
`
`js
import makeSynchronized from 'make-synchronized'
const foo = makeSynchronized(
() => ${someOtherCode})
foo()
`
`js
import makeSynchronized from 'make-synchronized'
const sleep = makeSynchronized((delay) =>
process.getBuiltinModule('node:timers/promises').setTimeout(delay),
)
`
`js
import makeSynchronized from 'make-synchronized'
const sleep = makeSynchronized(async (delay) => {
const {setTimeout} = await import('node:timers/promises')
await setTimeout(delay)
})
``