Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/Veetaha/using.macro
babel-plugin-macro for automatic try-finally blocks and C++ RAII style - like resource management.
https://github.com/Veetaha/using.macro
Last synced: 2 months ago
JSON representation
babel-plugin-macro for automatic try-finally blocks and C++ RAII style - like resource management.
- Host: GitHub
- URL: https://github.com/Veetaha/using.macro
- Owner: Veetaha
- License: mit
- Created: 2019-10-01T21:44:01.000Z (over 5 years ago)
- Default Branch: master
- Last Pushed: 2023-01-04T11:59:15.000Z (about 2 years ago)
- Last Synced: 2024-11-15T04:42:01.055Z (2 months ago)
- Language: TypeScript
- Size: 492 KB
- Stars: 12
- Watchers: 1
- Forks: 0
- Open Issues: 10
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# using.macro
[![Npm](https://img.shields.io/npm/v/using.macro?label=npm%20package&logo=logos&style=for-the-badge)](https://www.npmjs.com/package/using.macro)
[![Babel Macro](https://img.shields.io/badge/babel--macro-%F0%9F%8E%A3-f5da55.svg?style=flat-square)](https://github.com/kentcdodds/babel-plugin-macros)
[![Build Status](https://travis-ci.com/Veetaha/using.macro.svg?branch=master)](https://travis-ci.com/Veetaha/using.macro)
[![Coverage Status](https://coveralls.io/repos/github/Veetaha/using.macro/badge.svg?branch=master)](https://coveralls.io/github/Veetaha/using.macro?branch=master)
[![TypeScript](https://img.shields.io/badge/%3C%2F%3E-TypeScript-%230074c1.svg)](https://www.typescriptlang.org/)Just plain old C++ RAII (or C# `using` declaration) implementation for TypeScipt via [`'babel-plugin-macros'`](https://github.com/kentcdodds/babel-plugin-macros).
## :zap: Rationale
Suppose you have a local resource handle that you must manually release in the same
scope.With this plugin the cleanup is done automatically for you.
```ts
import using from 'using.macro';const resource = using (new Resource());
using (new AutoVarResource());
doStuffWithResource(resource);↓ ↓ ↓ ↓ ↓ ↓
const resource = new Resource();
try {
const _handle = new AutoVarResource(); // variable is created for you
try {
doStuffWithResource(resource);
} finally {
_handle.delete(); // this part is fully customizable!
}
} finally {
resource.delete(); // this part is fully customizable!
}
```## :dvd: Installation
Make sure [`babel-plugin-macros`](https://github.com/kentcdodds/babel-plugin-macros),
is added as `"macros"` item in `"plugins"` array of your babel config file.Afterwards just install this package **as dev dependency** and use it in your code:
```
npm i -D using.macro
```## :sunglasses: Syntax
The way you import this macro doesn't matter (as long as TypeScript eats it):
```ts
import using from 'using.macro';
import kek from 'using.macro';
import { using } from 'using.macro';
import { using as kek } from 'using.macro';
```There are only two options for invoking this macro:
* Near variable declaration `var/let/const varId = using(expresssion);`
* As a single expression statement ` using(expression);` so that a variable will be created automatically to release it for you.## :hammer: Customize
By default when you do
```ts
import using from 'using.macro';
```
you get `.delete()` method called on your handles.If you want to change this behaviour to e.g. call `free()` function on your handle,
you can wrap this macro with your own via `createUsingMacro()` from `'using.macro/create'`:
```ts
// using-ptr.macro.ts # .macro extension matters! See babel-plugin-macros docs
import { createMacro } from 'babel-plugin-macros';
import { createUsingMacro, createFunctionCallFactory } from 'using.macro/create';export default createMacro(createUsingMacro(createFunctionCallFactory('free')));
// Pass this noop function type to createMacro<>() for TypeScript support.
type Fn = (val: T) => T;
```
and use it in your code this way:
```ts
import usingPtr from './using-ptr.macro';const ptr = usingPtr (malloc(42));
// stuff↓ ↓ ↓ ↓ ↓ ↓
const ptr = malloc(42);
try {
// stuff
} finally {
free(ptr);
}
````create[Function/Method]CallFactory()` are simply two helper
functions. You can actually pass your own destructor codegen function instead:
```ts
import * as T from '@babel/types'; // default import is not supported by babel!createUsingMacro(garbageVariableIdentifier => {
// you may return a simple expression or a statement or an array of statements here
return T.callExpression(T.identifier('free'), [garbageVariableIdentifier.node]);
})
```## :warning: Caveats
Unfortunately `'babel-plugin-macros'` doesn't natively support TypeScript macros
in runtime, so you need to build your custom `*.macro.ts` to `*.macro.js` file,
and put in the same directory as `ts` file.## :arrow_upper_right: References
If you are looking for a native `using` binding syntax, please support [this stage 2 proposal](https://github.com/tc39/proposal-explicit-resource-management) and upvote
this [proposition](https://github.com/tc39/proposal-explicit-resource-management/issues/15#issuecomment-511255293) to it.This macro was originally created for simplifying the usage of
[`'embind'`](https://emscripten.org/docs/porting/connecting_cpp_and_javascript/embind.html) C++ object
handles