Last active
January 9, 2021 09:20
-
-
Save princejwesley/a66d514d86ea174270210561c44b71ba to your computer and use it in GitHub Desktop.
REPL with standalone await + babel transform
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const repl = require('repl'); | |
const babel = require('babel-core'); | |
function preprocess(input) { | |
const awaitMatcher = /^(?:\s*(?:(?:let|var|const)\s)?\s*([^=]+)=\s*|^\s*)(await\s[\s\S]*)/; | |
const asyncWrapper = (code, binder) => { | |
let assign = binder ? `global.${binder} = ` : ''; | |
return `(function(){ async function _wrap() { return ${assign}${code} } return _wrap();})()`; | |
}; | |
// match & transform | |
const match = input.match(awaitMatcher); | |
if (match) { | |
input = `${asyncWrapper(match[2], match[1])}`; | |
} | |
return input; | |
} | |
function myEval(cmd, context, filename, callback) { | |
const code = babel.transform(preprocess(cmd), { | |
presets: ['es2015', 'stage-3'], | |
plugins: [ | |
["transform-runtime", { | |
"regenerator": true | |
}] | |
] | |
}).code; | |
_eval(code, context, filename, callback); | |
} | |
const replInstance = repl.start({ prompt: '> ' }); | |
const _eval = replInstance.eval; | |
replInstance.eval = myEval; |
@christophemarois I installed the latest node (it has native async function support), but it's REPL still does not understand await. Top level await support was never supported by node... I tried with your code and it gives back the promise, it does not wait it out. I tried with this:
const timeout = function (delay) {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve()
}, delay)
})
}
await Promise.resolve(timeout(3000));
Currently there is a discussion about REPL await support here: nodejs/node#13209 If there is a way to make the REPL hang, then it is possible to implement this. Probably it is possible with a while(1) + break, I'll try it out later.
Can't hang with while(1) because it hangs the event loop and so it does not let the promise to be fulfilled.
function syncAwait(condition, timeout){
let expirationTime = Date.now() + timeout;
while(1){
if (condition())
return "awaited";
if (Date.now() > expirationTime)
return "expired";
}
}
var i = false;
setTimeout(function (){
i = true;
}, 2000);
syncAwait(function (){
return i;
}, 50000);
This returns only expired because the setTimeout can't run until the while loop is finished.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
By running the latest stable node version with the
--harmony
flag, you can remove the need for babel altogether. Just replace functionmyEval
by:and run
node --harmony await-babel-repl.js