# make-synchronized

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

Latest version **0.8.0** (published 2025-06-08) · MIT license · 0 weekly downloads

## Install

```sh
npm install make-synchronized
pnpm add make-synchronized
yarn add make-synchronized
bun add make-synchronized
```

## Health

**Score 50/100 (C)** — status: stable.

Positive: has types; esm support; no vulnerabilities; high quality score.

Warnings: low downloads; pre 1.0.

Negative: stale.

## Facts

| | |
|---|---|
| Version | 0.8.0 |
| Published | 2025-06-08 |
| First published | 2022-08-18 |
| Weekly downloads | 0 |
| License | MIT |
| TypeScript types | bundled |
| Module format | ESM + CommonJS |
| Dependencies | 0 |
| Unpacked size | 68 KB |
| Known vulnerabilities | 0 |
| Install scripts | no |
| GitHub stars | 28 |
| Author | fisker Cheung |
| Maintainers | fisker |

## Links

- npm: https://www.npmjs.com/package/make-synchronized
- Repository: https://github.com/fisker/make-synchronized
- Homepage: https://github.com/fisker/make-synchronized#readme
- Issues: https://github.com/fisker/make-synchronized/issues
- Funding: https://github.com/fisker/make-synchronized?sponsor=1
- npm.io page: https://npm.io/package/make-synchronized

## Recent versions

- 0.8.0 (latest) — 2025-06-08
- 0.7.2 — 2025-03-26
- 0.7.1 — 2025-03-26
- 0.7.0 — 2025-03-26
- 0.6.0 — 2025-03-25
- 0.5.2 — 2025-03-25
- 0.5.1 — 2025-03-25
- 0.5.0 — 2025-03-25
- 0.4.2 — 2025-03-24
- 0.4.1 — 2025-03-24
- 0.4.0 — 2025-03-24
- 0.3.1 — 2025-03-22
- 0.3.0 — 2025-03-22
- 0.2.10 — 2025-03-19
- 0.2.9 — 2024-04-17
- … 14 more at https://npm.io/package/make-synchronized/versions

## README

# 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.

## Install

```bash
yarn add make-synchronized
```

## Usage

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'))
   ```

## Named exports

```js
import {
  makeSynchronized, // Same as the default export
  makeDefaultExportSynchronized,
  makeModuleSynchronized,
  makeSynchronizedFunction,
  makeSynchronizedFunctions,
  makeInlineFunctionSynchronized,
} from 'make-synchronized'
```

## Limitation

This module uses [`MessagePort#postMessage`](https://nodejs.org/api/worker_threads.html#portpostmessagevalue-transferlist) to transfer arguments, return values, errors between the main thread and the [worker](https://nodejs.org/api/worker_threads.html#class-worker). Please make sure the arguments and return values are serializable by [the structured clone algorithm](https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Structured_clone_algorithm).

## API

### `makeSynchronized(module: string | URL | ImportMeta)`

> 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"
  ```

  [Example](./examples/make-default-export-function-synchronized.js)

- 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"
  ```

  [Example](./examples/make-module-specifiers-synchronized.js)

### `makeSynchronized(module: string | URL | ImportMeta, implementation: function | object)`

> 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](./examples/use-module-synchronized-as-default.js)

- 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](./examples/use-module-synchronized-as-default.js)

### `makeSynchronized(implementation: function)`

```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](./examples/use-inline-function.js)

### `makeSynchronizedFunction(module: string | URL | ImportMeta, implementation: function, specifier?: string)`

> 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',
)
```

### `makeSynchronizedFunctions(module: string | URL | ImportMeta, implementation: object)`

> 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',
})
```

### `makeDefaultExportSynchronized(module: string | URL | ImportMeta)`

> 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.
```

### `makeModuleSynchronized(module: string | URL | ImportMeta)`

> 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.
```

### `makeInlineFunctionSynchronized(implementOrCode: function | string)`

> 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)
})
```

---
_Source: https://npm.io/package/make-synchronized · Machine-readable twin of the npm.io package page. Health data is recomputed on every publish._
