node icon indicating copy to clipboard operation
node copied to clipboard

repl: integrate experimental repl

Open redyetidev opened this issue 10 months ago • 25 comments

Summary

This PR introduces an overhauled REPL for Node.js, inspired by the groundwork laid by @devsnek and their team on nodejs/repl. While significant changes have been made to the team's prototype REPL, credit for the concept belongs to them for their initial codebase.

Modifications

Technical

  • Class This REPL uses an ECMAScript class, rather than the REPLServer function prototype
  • Execution Context Contrary to the current REPL, which uses a mix of an inspector session and a virtual context, and the prototype REPL, which uses child_process and an inspector session, this REPL uses only a virtual context.

General

  • Syntax Highlighting Using the a custom implementation, syntax highlighting (in real-time) is now a feature of this REPL
  • (Coming Soon) Annotations Function annotations are under development
  • Runtime Variables Differing from the typical _ and _error variables, this REPL has an _X variable (where X is any line number)

Upcoming Features

These features are under development but are not included in this integration (as they are incomplete)

  • Anotations An annotations system, similar to that of the prototype REPL is under development

Usage

To try out this experimental REPL, users must enable it with the --experimental-repl CLI flag; otherwise, the stable REPL remains unaffected.

Limitations

While this iteration shows promise, it comes with certain limitations due to its experimental nature:

  1. Annotations is a work in progress. Although there's a prototype implementation, it heavily relies on 'requires'. I aim for a more dynamic approach, avoiding the generated one.
  2. Top-level await is unsupported

Why?

The Node.js REPL has remained unchanged for years, and it's time for a makeover.

[!CAUTION] This REPL is highly experimental, and its use may lead to unintended side effects.

redyetidev avatar Apr 19 '24 15:04 redyetidev

Note that a few 'little' bugs have been patched locally, but I don't want to force push for a little bit (so I can fix and test even more :-) )

redyetidev avatar Apr 19 '24 15:04 redyetidev

Primordials are not used in active runtime places, as they are speed bottlenecks.

REPL is a place where reliability is more important than speed, so definitely a part of the codebase where we'd want to avoid prototype pollution as much as possible. A solution that have been suggested was to run user code on a different realm, so the UI and user code can't interfere with one another. I think this is going to be a necessary condition before we can replace the current REPL and/or call it stable.

Additionally, the lack of primordials will help with the (possible) removal of them entirely.

(Off topic, but removal of primordials is not realistic nor desirable any time soon IMO. Anyways, let's not discuss that here)

aduh95 avatar Apr 19 '24 16:04 aduh95

REPL is a place where reliability is more important than speed, so definitely a part of the codebase where we'd want to avoid prototype pollution as much as possible. A solution that have been suggested was to run user code on a different realm, so the UI and user code can't interfere with one another. I think this is going to be a necessary condition before we can replace the current REPL and/or call it stable.

Currently, I have this REPL running in it's own vm context.

(Off topic, but removal of primordials is not realistic nor desirable any time soon IMO. Anyways, let's not discuss that here)

Oh! I must've heard wrong information, I'll add primordials

redyetidev avatar Apr 19 '24 16:04 redyetidev

Oh! I must've heard wrong information, I'll add primordials

More accurately, you heard a different opinion :) It doesn't mean that my opinion is the correct one / the other opinion you heard is "wrong", deciding if primordials are worth it is subjective, so it should not be surprising there's no consensus on how/if they should be used. In the end, you are free to do as you please as long as the linter is happy (and the code is not on an error path / does not introduce perf regression).

aduh95 avatar Apr 19 '24 17:04 aduh95

[!NOTE] In my latest commit, I changed the test-cli-options-doc.js file. There was a bug in the file, that prevented the tests from passing (and a few errors in my documentation, which I also resolved). The check was --no<option>, when it should have been `--no<option>`

redyetidev avatar Apr 19 '24 19:04 redyetidev

ERROR: Coverage for lines (94.96%) does not meet global threshold (95%)

Well... I have my work cut out for me

redyetidev avatar Apr 20 '24 01:04 redyetidev

All tests passed!

CCing @nodejs/repl for review

redyetidev avatar Apr 21 '24 00:04 redyetidev

Requesting a CI test so verify all is in working order

redyetidev avatar Apr 21 '24 15:04 redyetidev

CI: https://ci.nodejs.org/job/node-test-pull-request/58574/

nodejs-github-bot avatar Apr 21 '24 15:04 nodejs-github-bot

@aduh95 So far, I think the failed CI tests are unrelated to this change, WDYT?

redyetidev avatar Apr 21 '24 16:04 redyetidev

The latest changes to the Node.js repo were merged into this PR. This will not affect this PR but will prevent a merge conflict.

I will update the code with the latest lint changes.

redyetidev avatar Apr 21 '24 19:04 redyetidev

No longer blocked.

redyetidev avatar Apr 24 '24 19:04 redyetidev

Any more things I need to update, @aduh95? I'm still not sure what to do about dependencies if they aren't going there.

redyetidev avatar Apr 26 '24 20:04 redyetidev

By the way, currently the Markdown linter doesn't like the use of await in a JS code block, is there a way to disable it without adding a comment into the actual code block?

redyetidev avatar Apr 27 '24 14:04 redyetidev

By the way, currently the Markdown linter doesn't like the use of await in a JS code block, is there a way to disable it without adding a comment into the actual code block?

If you search for use of await in the doc/api folder, you can find example of how to use that keyword in a way that keeps the linter happy. Disabling the linter is (almost?) never the correct solution.

aduh95 avatar Apr 27 '24 16:04 aduh95

@aduh95 WDYT can be done about the dependencies?

redyetidev avatar May 02 '24 22:05 redyetidev

@aduh95 WDYT can be done about the dependencies?

Like I said, it needs to be moved to deps/, and the update process would need to be automated (which should happen on a separate PR that would need to land first). I reckon it does require more work, if you are not interested in doing that work, you could remove syntax highlighting from this PR, it can always be added later.

aduh95 avatar May 03 '24 12:05 aduh95

Sure thing! I'll move the dependencies today :-)

redyetidev avatar May 03 '24 12:05 redyetidev

Once local linting and building is complete, I'll update the PR. Adding dependencies label preemptively.

redyetidev avatar May 03 '24 13:05 redyetidev

Added labels based on what the would've been if this PR opened with these changes.

redyetidev avatar May 03 '24 15:05 redyetidev

Sorry if you missed it, but like I said in my other comment, the censoring should happen in a separate PR so we can discuss whether we’re OK with taking a new dependency.

aduh95 avatar May 03 '24 16:05 aduh95

Sorry if you missed it, but like I said in my other comment, the censoring should happen in a separate PR so we can discuss whether we’re OK with taking a new dependency.

Got it.

redyetidev avatar May 03 '24 16:05 redyetidev

I'll open a PR shortly, which will block this, so I added the 'blocked' label.

redyetidev avatar May 03 '24 16:05 redyetidev

@aduh95 I've implemented a basic syntax highlighter (I haven't decided on colors, right now it's all inspect.colors.special (unless inspect.styles.X exists)

redyetidev avatar May 09 '24 23:05 redyetidev

The ReGexes used are inspired from a variety of sources, so I need to condense them a bit

redyetidev avatar May 09 '24 23:05 redyetidev

[re-opened due to merge conflicts]

redyetidev avatar May 12 '24 14:05 redyetidev