@mcesystems/nbind
Version:
Magical headers that make your C++ library accessible from JavaScript
156 lines (155 loc) • 5.62 kB
JavaScript
;
// This file is part of nbind, copyright (C) 2014-2016 BusFaster Ltd.
// Released under the MIT license, see LICENSE.
Object.defineProperty(exports, "__esModule", { value: true });
var path = require('path'); // tslint:disable-line:no-var-requires
var Binding = /** @class */ (function () {
function Binding() {
}
return Binding;
}());
exports.Binding = Binding;
/** Default callback that throws any error given to it. */
function rethrow(err, result) {
if (err)
throw (err);
}
/** Make list of possible paths for a single compiled output file name. */
function makeModulePathList(root, name) {
return ([
// Binary copied using copyasm
[root, name],
// node-gyp's linked version in the "build" dir
[root, 'build', name],
// node-waf and gyp_addon (a.k.a node-gyp)
[root, 'build', 'Debug', name],
[root, 'build', 'Release', name],
// Debug files, for development (legacy behavior, remove for node v0.9)
[root, 'out', 'Debug', name],
[root, 'Debug', name],
// Release files, but manually compiled (legacy behavior, remove for node v0.9)
[root, 'out', 'Release', name],
[root, 'Release', name],
// Legacy from node-waf, node <= 0.4.x
[root, 'build', 'default', name],
[
root,
process.env['NODE_BINDINGS_COMPILED_DIR'] || 'compiled',
process.versions.node,
process.platform,
process.arch,
name
]
]);
}
function findCompiledModule(basePath, specList, callback) {
var resolvedList = [];
var ext = path.extname(basePath);
/** If basePath has a known extension, check if it's a loadable module. */
for (var _i = 0, specList_1 = specList; _i < specList_1.length; _i++) {
var spec = specList_1[_i];
if (ext == spec.ext) {
try {
spec.path = require.resolve(basePath);
// Stop if a module was found.
callback(null, spec);
return (spec);
}
catch (err) {
resolvedList.push(basePath);
}
}
}
/** Try all possible subdirectories of basePath. */
for (var _a = 0, specList_2 = specList; _a < specList_2.length; _a++) {
var spec = specList_2[_a];
// Check if any possible path contains a loadable module,
// and store unsuccessful attempts.
for (var _b = 0, _c = makeModulePathList(basePath, spec.name); _b < _c.length; _b++) {
var pathParts = _c[_b];
var resolvedPath = path.resolve.apply(path, pathParts);
try {
spec.path = require.resolve(resolvedPath);
}
catch (err) {
resolvedList.push(resolvedPath);
continue;
}
// Stop if a module was found.
callback(null, spec);
return (spec);
}
}
var err = new Error('Could not locate the bindings file. Tried:\n' +
resolvedList.join('\n'));
err.tries = resolvedList;
callback(err);
return (null);
}
function find(basePath, cb) {
var callback = arguments[arguments.length - 1];
if (typeof (callback) != 'function')
callback = rethrow;
return (findCompiledModule((basePath != callback && basePath) || process.cwd(), [
{ ext: '.node', name: 'nbind.node', type: 'node' },
{ ext: '.js', name: 'nbind.js', type: 'emcc' }
], callback));
}
exports.find = find;
function init(basePath, lib, cb) {
var callback = arguments[arguments.length - 1];
if (typeof (callback) != 'function')
callback = rethrow;
var binding = new Binding();
find(basePath != callback && basePath, function (err, binary) {
if (err) {
callback(err);
return;
}
binding.binary = binary;
binding.lib = (lib != callback && lib) || {};
if (binary.type == 'emcc') {
initAsm(binding, callback);
}
else {
initNode(binding, callback);
}
});
return (binding);
}
exports.init = init;
/** Initialize asm.js module. */
function initAsm(binding, callback) {
var lib = binding.lib;
lib.locateFile = lib.locateFile || function (name) {
return (path.resolve(path.dirname(binding.binary.path), name));
};
// Load the Asm.js module.
require(binding.binary.path)(lib, function (err, parts) {
if (!err) {
for (var _i = 0, _a = Object.keys(parts); _i < _a.length; _i++) {
var key = _a[_i];
binding[key] = parts[key];
}
}
callback(err, binding);
});
}
/** Initialize native Node.js addon. */
function initNode(binding, callback) {
// Load the compiled addon.
var lib = require(binding.binary.path);
if (!lib || typeof (lib) != 'object') {
callback(new Error('Error loading addon'));
return;
}
binding.bind = lib.NBind.bind_value;
binding.reflect = lib.NBind.reflect;
binding.queryType = lib.NBind.queryType;
binding.toggleLightGC = function (enable) { }; // tslint:disable-line:no-empty
// using keyof ExportType instead of string to avoid 'string cannot index ExportType'
Object.keys(lib).forEach(function (key) {
binding.lib[key] = lib[key];
});
callback(null, binding);
}