Skip to content

Instantly share code, notes, and snippets.

@bguiz
Last active August 22, 2017 13:04
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save bguiz/bf72f2abcc872f60ea3a8298126d219a to your computer and use it in GitHub Desktop.
Save bguiz/bf72f2abcc872f60ea3a8298126d219a to your computer and use it in GitHub Desktop.
Custom NodeJs REPL

Custom NodeJs REPLs

A way to create read-eval-print-loops for your own projects, with a per-instance history, rather than a global history.

Sample Usage

const customRepl = require('./custom-repl.js');

/**
 * Add context to the REPL: 
 * What things are accessible from the prompt?
 */

const foobarRepl = customRepl('foobar');
  
function syncThing (x) {
    return `sync ${x}`;    
}

function asyncThing (x) {
    return `async ${x}`;    
}

// add synchronous context
fooBarRepl.addContext(syncThing);

// add asynchronous context
setTimeout(() => {
    foobarRepl.addContext(asyncThing);
}, 5000);
  • You may run syncThing() immediately
  • You need to wait five seconds before you may run asyncThing()
    • IRL, you would do this to wait for something that is asynchronous to finish loading, or similar
const fs = require('fs');
const repl = require('repl');
module.exports = customRepl;
function customRepl (name, options = {}) {
const historyFilePath =
options.historyFilePath ||
`${process.env.HOME}/.custom_repl/${name}_repl_history`;
let historyFileExists = false;
try {
// ensure history file exists
fs.statSync(historyFilePath);
historyFileExists = true;
} catch (ex) {
// Do nothing
}
let historyLines;
if (historyFileExists) {
// load command history
console.log(`${name}: Loading your history...`);
historyLines = fs.readFileSync(historyFilePath)
.toString()
.split('\n')
.reverse()
// Discard empty lines
.filter((line) => (line.trim().length > 0));
} else {
historyLines = [];
}
const replServer = repl.start({
prompt: `${name}> `,
});
historyLines.forEach((line) => replServer.history.push(line));
replServer.on('exit', () => {
console.log(`${name}: Saving your history...`);
const lines = replServer.lines;
fs.appendFileSync(
historyFilePath,
`${lines.join('\n')}\n`);
console.log(`${name}: Bye!`);
process.exit();
});
function addContext (property, value) {
if (typeof property === 'function') {
value = property;
property = value.name;
}
if (typeof replServer.context[property] !== 'undefined') {
throw `context already exists: ${property}`;
}
replServer.context[property] = value;
}
return {
addContext,
};
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment