async-off
v1.2.0
Published
Make asynchronous TypeScript code synchronous
Downloads
3
Readme
async-off
: make asynchronous TypeScript code synchronous
Installation
Using without installation:
npx async-off path/to/file.ts
Installation:
npm install -g async-off
Usage
async-off path/to/file.ts
cat path/to/file.ts | async-off
async-off --help
async-off -h
async-off
converts asynchronous TypeScript code to synchronous code by:
- Removing the keyword
await
in expressions and infor-await-of
loops. - Removing the keyword
async
. - Changing
Promise<X>
toX
. - Changing
AsyncIterable<X>
toIterable<X>
andAsyncIterator<X>
toIterator<X>
.
More changes can be configured (see below).
What would I use this command for?
async-off
’s approach only works for very simple code. Then you can avoid writing very similar code twice – once asynchronously and once synchronously. Examples of such code include:
- Helper functions for iterables:
map()
,filter()
, etc. (see next section) - A Markdown parser that can be used both asynchronously (with asynchronous iterables as input) and synchronously (with strings or normal iterables as input).
Example
Input:
async function* map<In, Out>(
mapperFn: (x: In) => Out,
iterable: AsyncOrSyncIterable<In>
): AsyncIterable<Out> {
for await (const x of iterable) {
yield mapperFn(x);
}
}
//<async>
type AsyncOrSyncIterable<Item> = AsyncIterable<Item> | Iterable<Item>;
//</async>
//<async-off-config>
// {
// "renameType": {
// "AsyncOrSyncIterable": "Iterable"
// }
// }
//</async-off-config>
Output:
function* map<In, Out>(
mapperFn: (x: In) => Out,
iterable: Iterable<In>
): Iterable<Out> {
for (const x of iterable) {
yield mapperFn(x);
}
}
Configuration
async-off
is configured via embedded JSON (see previous section). The following properties are supported:
interface ConfigJson {
/**
* Removes a function call wrapped around a value.
* Use case – unit testing:
*
* ```ts
* processAsyncData(toAsyncIterable(['a', 'b', 'c']));
* processSyncData(['a', 'b', 'c']);
* ```
*
* Note: (processAsyncData() is renamed separately.)
*/
unwrapFunctionCall?: Array<string>;
/**
* Included by default: `"Promise"`
*/
unwrapParamerizedType?: Array<string>;
renameVariable?: Record<string, string>;
/**
* Included by default: `{"AsyncIterable": "Iterable", "AsyncIterator": "Iterator"}`
*/
renameType?: Record<string, string>;
}
Tips
Different names for exports
const Functions = {
map,
filter,
};
//<async>
export {Functions as AsyncIterable};
//</async>
//<sync>
// export {Functions as Iterable};
//</sync>
Resources
- For syntax transformations,
async-off
uses the libraryts-morph
- The TypeScript AST Viewer helps with exploring how TypeScript code is represented as abstract syntax trees.