@piglovesyou/to-sync
v0.2.0
Published
synchronously execute asynchronous functions
Downloads
4
Maintainers
Readme
to-sync
A forked version of do-sync, also for babel-plugin-macros developers.
$ npm install @piglovesyou/to-sync
$ yarn add @piglovesyou/to-sync
Features
- Enable lexical scope in a target async function for more flexible use
- Typings for a generated sync function without generics parameters
import toSync from '@piglovesyou/to-sync'
export async function myAsyncFunc(a: string): Promise<string> {
// ...
}
// Typed as `string => string` 😎
export const mySyncFunction = toSync(myAsyncFunc);
Caveats
- Export your async function. Otherwise the child process cannot find it.
- Call
toSync
next to your async function. If you can't, pass{ filename }
option to it. - This is slow naturally, as it launches a new process and communicate through serialized data. Try to avoid using it.
do-sync
do-sync
is a small library that allows certian kinds of async functions to be executed synchronously in node.
Why Though? Isn't this a terrible idea?
babel-plugin-macros
does not support asynchrony in macros1, but many vital libraries like sharp
require asynchrony to function -- and, in fact do not support synchronous usage.
Example
import { doSync, AsyncFn, JSONObject } from 'do-sync';
interface resizeOpts extends JSONObject {
width: number, height: number
}
interface resizeRet extends JSONObject {
width: number, height: number, blob: string,
}
const resize = doSync(async (target: string, { width, height, ...jpegOpions }: resizeOpts): Promise<resizeRet> => {
const sharp = require('sharp');
const blob =
(await sharp(Buffer.from(target, 'base64'))
.resize(width, height)
.jpeg(jpegOpions)
.toBuffer()).toString('base64');
return { blob, width, height };
})
const myImage = resize('cool.png', {
width: 10, height: 10
})
This package is used to implement image.macro, which dynamically resizes high-resolution images to multiple sizes at compilation time for use with webpack. It's a little rough around the edges, but works well and should provide some more concrete usage examples:
Limitations
- The function will be completely extracted from its scope context. It is run as though it was on its own, in its own file.
- Only JSON serializible parameters and response values are allowed.
- Typescript will enforce JSON serializibility, but as a result
pure
Object
s passed into functions, or returned by functions must extend or implement JSONObject. - If the process throws an error, properties that cannot be serialized to JSON will not cross the process boundary.
Footguns
ENOBUFS
do-sync
uses a node subprocess and writes all code to STDIN. child_process.spawnSync
has a default limit on STDIN input which can, if large JSON is transiting STDIN make your program explode. doSync
takes an optional second parameter, opts
, which has the same options as spawnSync
-- the value is already very large (1GB), but you can set maxBuffer to something bigger if you encounter issues:
doSync(myFunc, {
maxBuffer: 1024 * 1024 * 1024
})