eyeglass
Version:
Sass modules for npm.
65 lines • 2.38 kB
JavaScript
/**
* Custom function wrapper to ensure sync/async compatibility
* ---
* In the docs for render() and renderSync(), custom functions behave
* differently. However, we want eyeglass custom functions to act just like
* importers, always receiving an optional `done()` argument at the end. A
* developer can either asynchronously call `done()` or they can return a
* value in a synchronous manner.
*
* To make this work, we rely on the `deasync` library to turn an event loop
* while holding a C level `sleep()` open. This allows an async function to
* resolve without having to run a fiber through the entire node-sass project.
*
* The original problem and solution can be found on stack overflow:
* http://stackoverflow.com/questions/21819858/how-to-wrap-async-function-
* calls-into-a-sync-function-in-node-js-or-javascript
*/
;
Object.defineProperty(exports, "__esModule", { value: true });
const makeSync = function (fn) {
return function () {
let result;
let args = new Array(...arguments);
let last = args[args.length - 1];
// last arg is a function (async capture)
if (typeof last === "function") {
return fn.apply(this, args);
}
// last arg is not a function (synchronous mode)
// for some reason, there is a bridge object that shouldn't be on the args
// replace it with our custom callback
// turn the loop once, and then begin blocking until we resolve
function cb(res) {
setTimeout(function () {
result = res;
}, 0);
}
args.pop(); // bridge object BAD
args.push(cb); // capture callback GOOD
result = fn.apply(this, args);
if (result !== undefined) {
return result;
}
try {
const deasync = require('deasync');
while (result === undefined) {
deasync.runLoopOnce();
}
return result;
}
catch (ex) {
throw new Error('deasync is required to make async functions synchronous');
}
};
};
function all(obj) {
let syncAll = {};
for (let name in obj) {
syncAll[name] = sync(obj[name]);
}
return syncAll;
}
const sync = Object.assign(makeSync, { all });
exports.default = sync;
//# sourceMappingURL=sync.js.map