Skip to content

Use TypeScript decorators to bind to native libraries

License

Notifications You must be signed in to change notification settings

timfish/ffi-decorators

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

12 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

ffi-decorators

Use node-ffi-napi via decorators.

It got tiresome maintaining separate type declarations and mappings for all our node-ffi-napi code. This library has made things a little less painful so hopefully it can be useful to others.

It gives you:

  • Typed calls to native libraries
  • Automatic 'promisifcation' using the ffi async feature
  • Automatic handling of callback pointer lifetime

Only tested in TypeScript where you'll need these options enabling in your tsconfig.json:

  "compilerOptions": {
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true,
  }

Note: ffi-napi is a peer dependency so you'll need to install a version which is compatible with your node version.

import { Callback, Library, Method, never } from 'ffi-decorators';

@Library({ libPath: 'libmylibrary' })
class MyLibrary {
  constructor(path?: string) { }

  @Method({ types: ['double', ['double', 'int']] })
  do_some_number_fudging(a: number, b: number): number {
    return never();
  }

  @Method({ types: ['double', ['double', 'int']] })
  do_long_running_thing(input: number, length: number): Promise<number> {
    return never();
  }

  @Method({ types: ['void', ['short', 'pointer']] })
  something_with_callback(
    handle: number,
    @Callback({ types: ['void', ['int']] })
    cb: (result: number) => void
  ): void {
    return never();
  }

  @Method({ nativeName: 'specific_name', types: ['double', ['double']] })
  whateverYouLike(a: number): number {
    return never();
  }
}

// Create a class instance and native calls are proxied
const myLib = new MyLibrary();
myLib.do_some_number_fudging(10, 546);

// do_long_running_thing returns a promise so 
// this automatically uses the ffi async feature
const result = await myLib.do_long_running_thing(95, 9);

// Callback pointers are cached to avoid GC
myLib.something_with_callback(5, (res) => {
  console.log(res);
})

// This will actually call specific_name
myLib.whateverYouLike(16);

// Optionally supply the full path to your library
const myLib = new MyLibrary('path/to/libmylibrary');

About

Use TypeScript decorators to bind to native libraries

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published