npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

using.macro

v1.0.5

Published

babel-plugin-macro for automatic try-finally blocks and C++ like RAII resource management

Downloads

273

Readme

using.macro

Npm

Babel Macro Build Status Coverage Status TypeScript

Just plain old C++ RAII (or C# using declaration) implementation for TypeScipt via '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.

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, 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):

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

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':

// 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<Fn>(createUsingMacro(createFunctionCallFactory('free')));

// Pass this noop function type to createMacro<>() for TypeScript support.
type Fn = <T>(val: T) => T;

and use it in your code this way:

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:

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 and upvote this proposition to it.

This macro was originally created for simplifying the usage of 'embind' C++ object handles