quansync
Create sync/async APIs with usable logic.
Quantum + Sync - "Superposition" between sync and async.
- Typesafe
- ESM, modern JavaScript
- Zero dependencies
Heavily inspired by genasync by @loganfsmyth.
Why & How
Please refer to Anthony's blog post: Async, Sync, in Between.
Usage
pnpm i quansync
import fs from 'node:fs'
import { quansync } from 'quansync'
// Create a quansync function by providing `sync` and `async` implementations
const readFile = quansync({
sync: (path: string) => fs.readFileSync(path),
async: (path: string) => fs.promises.readFile(path),
})
// Create a quansync function by providing a generator function
const myFunction = quansync(function* (filename) {
// Use `yield*` to call another quansync function
const code = yield* readFile(filename, 'utf8')
return `// some custom prefix\n${code}`
})
// Use it as a sync function
const result = myFunction.sync('./some-file.js')
// Use it as an async function
const asyncResult = await myFunction.async('./some-file.js')
getIsAsync
Returns a boolean indicating whether the current execution is in async mode.
import { getIsAsync, quansync } from 'quansync'
const fn = quansync(function* () {
const isAsync: boolean = yield* getIsAsync()
console.log(isAsync)
})
fn.sync() // false
await fn() // true
await fn.async() // true
Build-time Macro
If you don't like the function* and yield* syntax, we also provide a build-time macro via unplugin-quansync allowing you use quansync with async/await syntax, while still able to get the sync version out of that.
Here is an example:
import fs from 'node:fs'
import { quansync } from 'quansync/macro'
// Create a quansync function by providing `sync` and `async` implementations
const readFile = quansync({
sync: (path: string) => fs.readFileSync(path),
async: (path: string) => fs.promises.readFile(path),
})
// Create a quansync function by providing an **async** function
const myFunction = quansync(async (filename) => {
// Use `await` to call another quansync function
const code = await readFile(filename, 'utf8')
return `// some custom prefix\n${code}`
})
// Use it as a sync function
const result = myFunction.sync('./some-file.js')
// Use it as an async function
const asyncResult = await myFunction.async('./some-file.js')
For more details on usage, refer to unplugin-quansync's docs.
Benchmark
Run the following command to benchmark the performance of quansync:
pnpm run build && pnpm run benchmark
Benchmark results indicate that each yield incurs an overhead of
approximately 150 ns, comparable to that of await sync(). (On Apple M1 Max)
Sponsors
License
MIT License Anthony Fu and Kevin Deng