All Projects → nikersify → Jay

nikersify / Jay

Licence: mit
😎 Supercharged JavaScript REPL

Programming Languages

javascript
184084 projects - #8 most used programming language
typescript
32286 projects

Projects that are alternatives of or similar to Jay

Lua Resty Repl
Interactive console (REPL) for Openresty and luajit code
Stars: ✭ 165 (-82.99%)
Mutual labels:  cli, readline, repl
fancyline
Readline-esque library with fancy features
Stars: ✭ 72 (-92.58%)
Mutual labels:  repl, readline
Vsh
vsh - HashiCorp Vault interactive shell and cli tool
Stars: ✭ 209 (-78.45%)
Mutual labels:  cli, repl
Cliffy
NodeJS Framework for Interactive CLIs
Stars: ✭ 263 (-72.89%)
Mutual labels:  cli, repl
Bull Repl
Bull / BullMQ queue command line REPL
Stars: ✭ 121 (-87.53%)
Mutual labels:  cli, repl
Alive Progress
A new kind of Progress Bar, with real-time throughput, ETA, and very cool animations!
Stars: ✭ 2,940 (+203.09%)
Mutual labels:  cli, repl
PrettyPrompt
A cross-platform command line prompt library that provides syntax highlighting, autocompletion, history and multi-line input.
Stars: ✭ 45 (-95.36%)
Mutual labels:  repl, readline
Flask Konch
An improved shell command for the Flask CLI
Stars: ✭ 65 (-93.3%)
Mutual labels:  cli, repl
Lev
The complete REPL & CLI for managing LevelDB instances.
Stars: ✭ 295 (-69.59%)
Mutual labels:  cli, repl
Racket Rash
The Reckless Racket Shell
Stars: ✭ 358 (-63.09%)
Mutual labels:  cli, repl
Readline Sync
Synchronous Readline for interactively running to have a conversation with the user via a console(TTY).
Stars: ✭ 601 (-38.04%)
Mutual labels:  readline, repl
Psysh
A REPL for PHP
Stars: ✭ 9,161 (+844.43%)
Mutual labels:  cli, repl
Radian
A 21 century R console
Stars: ✭ 878 (-9.48%)
Mutual labels:  cli, repl
Ldb
A C++ REPL / CLI for LevelDB
Stars: ✭ 201 (-79.28%)
Mutual labels:  cli, repl
Repl
🐚 an instant REPL for any command
Stars: ✭ 71 (-92.68%)
Mutual labels:  cli, repl
repline
Haskeline wrapper for GHCi-like REPL interfaces
Stars: ✭ 98 (-89.9%)
Mutual labels:  repl, readline
Baapan
✨ Super Cool NPM Playground right on the Node REPL ✨
Stars: ✭ 60 (-93.81%)
Mutual labels:  cli, repl
Ishell
Library for creating interactive cli applications.
Stars: ✭ 1,127 (+16.19%)
Mutual labels:  cli, readline
Croissant
🥐 A Lua REPL and debugger
Stars: ✭ 285 (-70.62%)
Mutual labels:  cli, repl
Age
A simple, modern and secure encryption tool (and Go library) with small explicit keys, no config options, and UNIX-style composability.
Stars: ✭ 9,409 (+870%)
Mutual labels:  cli, modern

Jay Build Status npm

Supercharged JavaScript REPL 😎

Jay is a terminal-based JavaScript REPL focused on increasing prototyping speed and productivity. It's packed with modern REPL features, whilst also striving to maintain a familiar REPL vibe.

Here are the most important features that differentiate Jay from other REPL's:

  • require modules directly from the registry
  • Eager eval (requires node >= 12.3.0)
  • Top level await
  • Typeahead + dropdown menu-style completion

Plus some necessities:

  • Colored input
  • Bracket/quote pair completion
  • Fresh require
  • Full readline keybindings support
  • Lazy loaded built-in modules
  • _ variable

Why

Jay was created with two goals in mind:

  1. To bring modern JavaScript REPL features to the terminal, like eager eval, top level await and typeahead code completion
  2. To create a super quick environment for prototyping/running npm dependent JavaScript code.

It would probably make sense to split Jay into separate packages (just the REPL into one, and the smart require into another) in the future, to allow better reusability of the REPL components.

Examples

Basic web scraping

Let's say that for some reason we want to scrape all of the titles and links from the hacker news front page.

To accomplish that, we can use Jay (obviously), got (http client) and cheerio (jQuery-esque API for server-side).

Let's begin by running Jay and getting the necessary dependencies:

$ jay
> const got = require('got')
> const cheerio = require('cheerio')

Then, we download the page and load the HTML into cheerio:

> const {body} = await got('https://news.ycombinator.com')
> const $ = cheerio.load(body)

$ behaves pretty much like jQuery, we can use the following simple one-liner to get our result:

> $('a.storylink').map((i, el) => ({text: $(el).text(), link: $(el).attr('href')})).get()
[
	{
		text: 'National Park Typeface',
		link: 'https://nationalparktypeface.com'
	},
	...
]

After running the previous line, we can store the result in a named variable via _ - which caches the result of the last evaluation - as follows:

> const result = _
> result.length // 30

If you find an interesting example to put in this section, a PR is more than welcome!

Install

Jay expects itself to be installed globally:

$ npm install -g jay-repl

Then simply run it by typing jay in the terminal:

$ jay

Alternatively, Jay can be directly run with Node builtin npx:

$ npx -p jay-repl jay

FAQ

How does the smart require function work?

After pressing enter in the prompt, Jay parses the entered input into an AST using acorn and looks for all CallExpression's whose names are equal to require.

This triggers the "asker" system to ask the user whether they actually want to install a given require'd module. If the user decides to install the module, Jay starts a "global" npm install in its cache directory. If they don't, nothing happens and the evaluation will most likely result in an "module not found" error.

Either way, after all of the above is complete, the control is handed back to the evaluator which only now actually executes the entered line.

How does Jay's require differ from the normal one?

The normal require only looks for modules within two places:

  • locally, if the module id is prefixed with things like . or ../ - e.g. require('./index.js')
  • in node_modules - e.g. require('express')

Jay's require in addition to the above also looks within its global cache (but only if the local & node_modules resolutions fail). This, in addition to parsing the input and looking for require calls, allows for importing any module that's on the registry, automatically installing it if needed.

The require also is also a "fresh require".

What does "fresh require" mean?

The require function in Jay doesn't use the standard node's cache and always reads the files from disk upon importing them. Consider the following example:

Let's say we have a file called greet.js with the following contents:

module.exports = x => 'hello '.repeat(x)

Start up node's repl, require it, and we get the expected output:

$ node
> greet = require('./greet')
> greet(2)
// 'hello hello '

Now, without closing the session, we change the file into:

-module.exports = x => 'hello '.repeat(x)
+module.exports = x => 'hi '.repeat(x)

Requiring the file again will, unfortunately, not change the output:

> greet = require('./greet')
> greet(3)
// 'hello hello hello '

Jay, as beforementioned, doesn't cache modules. Repeating the steps yields the result we actually want in this case:

$ jay
$ echo "module.exports = x => 'hello '.repeat(x) > greet.js"
> greet = require('./greet')
> greet(2)
// 'hello hello '
$ sed -i 's/hello/hi/' greet.js
// (in the same Jay session)
> greet = require('./greet')
> greet(3)
// 'hi hi hi '

This also works analogically with modules in node_modules, Jay's cache, JSON files, etc.

Where does Jay store the cached modules?

Jay uses env-paths to determine the cache's location:

  • MacOS - ~/Library/Caches/jay-repl-nodejs/packages
  • Linux - ~/.cache/jay-repl-nodejs
  • Windows - ~/

You can see the exact location of the cache by simply running the following line in Jay:

> require('env-paths')('jay-repl').cache

Contributing

  1. Fork & clone the repository
  2. Start the Typescript watch script:
$ npm run build:watch
  1. Make your changes
  2. Try out your changes on your local build
$ node dist/cli.js
  1. Run the tests:
$ npm test
  1. Commit & PR!

This repository uses Git LFS for storing readme's gifs, if you want to view them locally you will need to install and set up the Git LFS extension on your machine.

License

MIT © nikersify

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].