quadratic icon indicating copy to clipboard operation
quadratic copied to clipboard

Javascript

Open davidfig opened this issue 10 months ago • 29 comments

  • [x] basic javascript computation
  • [x] typescript support using esbuild-wasm
  • [x] allow async operations in javascript
  • [x] getCell/getCells in javascript (requires await)
  • [x] map errors to proper line number (for execution errors)
  • [x] show an error when trying to import modules
  • [x] ensure good errors during esbuild transform
  • [x] add code highlighting and language server support (comes out of the box with monaco for typescript)
  • [x] add output type information to results
  • [x] getPos and get relative cells
  • [x] JS logo in code editor
  • [x] add icons/prettify UI
  • [x] better console.log support for formatting Objects, Arrays, DateTime, and boolean
  • [x] return line numbers
  • [x] handle Infinity and NaN
  • [x] import ESM modules
  • [x] reimplement return line numbers
  • [x] output png from OffscreenCanvas
  • [x] merge conflicts with main
  • [x] corner resize
  • [x] return Canvas instead of Blob to make it easier on user
  • [x] tests for getCells without y1
  • [x] Address Jim & Luke's comments
  • [x] Better handling of import errors (it fails silently w/o reporting the error)
  • [ ] CodeRunning cell indicator

Out of scope for this PR

  • Typescript support (requires a bit of work around packaging)
  • better console colors/highlighting
  • cancel JS / better UI around controlling what GC is doing--especially around code runs

davidfig avatar Apr 09 '24 15:04 davidfig

The latest updates on your projects. Learn more about Vercel for Git ↗︎

Name Status Preview Updated (UTC)
quadratic ✅ Ready (Inspect) Visit Preview Jun 27, 2024 8:57pm

vercel[bot] avatar Apr 09 '24 15:04 vercel[bot]

Codecov Report

Attention: Patch coverage is 95.79580% with 42 lines in your changes missing coverage. Please review.

Project coverage is 90.71%. Comparing base (553e95f) to head (a6fc7ce).

Files Patch % Lines
...atic-core/src/controller/execution/run_code/mod.rs 71.42% 18 Missing :warning:
quadratic-core/src/grid/file/current.rs 0.00% 6 Missing :warning:
quadratic-core/src/values/cellvalue.rs 80.76% 5 Missing :warning:
quadratic-core/src/controller/send_render.rs 91.17% 3 Missing :warning:
quadratic-core/src/grid/sheet/rendering.rs 95.83% 3 Missing :warning:
quadratic-core/src/values/convert.rs 0.00% 2 Missing :warning:
...rc/controller/execution/run_code/run_javascript.rs 99.81% 1 Missing :warning:
quadratic-core/src/controller/transaction_types.rs 88.88% 1 Missing :warning:
quadratic-core/src/formulas/criteria.rs 0.00% 1 Missing :warning:
quadratic-core/src/grid/sheet/bounds.rs 97.05% 1 Missing :warning:
... and 1 more
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #1273      +/-   ##
==========================================
+ Coverage   90.54%   90.71%   +0.16%     
==========================================
  Files         178      179       +1     
  Lines       32966    33869     +903     
==========================================
+ Hits        29849    30724     +875     
- Misses       3117     3145      +28     

:umbrella: View full report in Codecov by Sentry.
:loudspeaker: Have feedback on the report? Share it here.

codecov[bot] avatar Apr 09 '24 16:04 codecov[bot]

Review

Blocking items

  • [x] No errors As described, bug of having no errors in my console
  • [ ] Add d3.js Visualizations, data wrangling, etc.
  • [ ] Make sure getCells() is sufficiently similar to Python
  • [x] Arrays in console As image shows https://github.com/quadratichq/quadratic/assets/146771258/9945aaf9-cc27-49b3-aca6-d7b191f6ad6a
  • [x] Objects should be output in console and sheet https://github.com/quadratichq/quadratic/assets/146771258/5ca53213-cf56-4a53-ab77-ab859b015ea6
  • [ ] Code snippets Let's make sure we create code snippets that sufficiently cover the base use-cases so we know the minimal stuff actually works
  • [x] Press '/' to code should disappear Not recognizing js currently
  • [ ] Freezing by trying to pick other code editor To recreate select other code cells from currently open code cell, you'll brick the sheet
  • [x] JS image For cell type selection and top left of editor use following image https://github.com/quadratichq/quadratic/assets/146771258/bd8fc2cb-5a84-4b38-b486-a8127b1204a7
  • [ ] AI assistant for JavaScript @davidkircos presumably a near clone for Python, @luke-quadratic will provide text file of docs for fine-tuning
  • [ ] Basic docs Add docs
  • [x] Mark experimental In cell type selector put (experimental) or some other indicator that some bugs should be expected for first month or so of users

luke-quadratic avatar Apr 16 '24 19:04 luke-quadratic

This code is bad (its incorrectly using Object.entries())

let res = await fetch("https://jsonplaceholder.typicode.com/todos/1");
let json = await res.json();

let data = Object.entries((key, value) => {
    console.log([key, value]);
    return [key, value];
});

return data

If you try to run that, it will result in an error that makes the code editor become unresponsive to running code. You can still type and it looks like you're running it, but you're not. Only once you open the console do you see you got stuck

This is the proper code that should run

let res = await fetch("https://jsonplaceholder.typicode.com/todos/1");
let json = await res.json();

let data = Object.entries(json).map((key, value) => {
    console.log([key, value]);
    return [key, value];
});

return data

CleanShot 2024-04-16 at 13 22 54@2x

jimniels avatar Apr 16 '24 19:04 jimniels

JavaScript needs first class support as a cell type in the app (e.g. in the cell type menu not looking disabled, as well as a matching icon in the code editor for the "JS" code type)

CleanShot 2024-04-16 at 13 27 28@2x

CleanShot 2024-04-16 at 13 27 39@2x

I can assign this to @jimniels to do

jimniels avatar Apr 16 '24 19:04 jimniels

Nice-to-have: prettier that formats the code when you save/run any code cell changes

jimniels avatar Apr 16 '24 19:04 jimniels

CleanShot 2024-04-16 at 13 31 42@2x

jimniels avatar Apr 16 '24 19:04 jimniels

Using console.log produces unexpected results for primitive data types in javascript, e.g. logging and object just shows [object Object] and logging an array (or nested array) doesn't show the values as being in an array ([1,2,3] logs as 1,2,3)

See screenshot for basic example discrepancies

CleanShot 2024-04-16 at 13 36 14@2x

jimniels avatar Apr 16 '24 19:04 jimniels

The UI that indicates what is being returned is different in javascript than it is in Python.

For example, here's the UI for a javascript cell that returns a string

CleanShot 2024-04-16 at 13 53 16@2x

And here's a cell that returns a string in python

CleanShot 2024-04-16 at 13 52 49@2x

Note that 1) the line number is missing, and 2) the data type isn't highlighted

jimniels avatar Apr 16 '24 19:04 jimniels

People are probably going to forget await a lot and encounter an issue like this:

CleanShot 2024-04-25 at 13 50 20@2x

And there's no help that all they need to do is add await. Even the console says it's an object:

CleanShot 2024-04-25 at 13 50 49@2x

Would be great if we could throw a warning and tell people that what that is is a promise

jimniels avatar Apr 25 '24 19:04 jimniels

Minor: some of the UI has the return statement as a sentence with full punctuation (like this JS cell with a period)

CleanShot 2024-04-25 at 13 55 33@2x

While others do not (like this python output with no period)

CleanShot 2024-04-25 at 13 55 38@2x

Whatever we do, we should be consistent. I’d probably lean towards not making them full sentences (so leave off the trailing period)

jimniels avatar Apr 25 '24 19:04 jimniels

Updating the range of getCells when using JavaSrcript doesn't seem to update the dashed outline on the grid (whereas it does if you're using python — once you run the code anyway, would be nice if it would live update but that's a separate issue)

https://github.com/quadratichq/quadratic/assets/1316441/d0236fea-949b-4153-9cb1-6fd4b1321336

Edit: it appears this is because cell range highlighting doesn't work at all in javascript. The reason you still see it in this video recording is because you had the python cell open and it just didn't clear.

jimniels avatar Apr 25 '24 20:04 jimniels

Logging a new line results in a quote mark?

CleanShot 2024-04-25 at 14 30 40@2x

Edit Oh I see, logging something actually puts it in quotes

CleanShot 2024-04-25 at 14 32 56@2x

Do we want that? Python doesn't do that. CleanShot 2024-04-25 at 14 34 11@2x

Neither do consoles like the one in the browser CleanShot 2024-04-25 at 14 33 40@2x

jimniels avatar Apr 25 '24 20:04 jimniels

Not passing a third arg to the getCells function still works. The function signature says that third param is required, but if you don't provide it, everything still works.

// This is wrong, 3 params are required, it should throw an error or something
const oneCell = await getCells(0,0)

CleanShot 2024-04-25 at 14 49 35@2x

jimniels avatar Apr 25 '24 20:04 jimniels

Feels a bit weird that things logged in the same console.log end up separate by a line break in the console

CleanShot 2024-04-25 at 15 54 16@2x

Whereas python doesn't do this:

CleanShot 2024-04-25 at 15 17 09@2x

Neither does the browser console:

CleanShot 2024-04-25 at 15 16 36@2x

jimniels avatar Apr 25 '24 21:04 jimniels

Why is the output of this not 1?

CleanShot 2024-04-25 at 16 03 56@2x

luke-quadratic avatar Apr 25 '24 22:04 luke-quadratic

Need parity with Python across the board - in the case of references this means not just getCell and getCells should be supported Should also support cell, c, and cells.

CleanShot 2024-04-25 at 16 05 41@2x

luke-quadratic avatar Apr 25 '24 22:04 luke-quadratic

For getCellsWithHeadings you get back an array of objects with keys for the headings, but you can't just return them right back to the sheet untouched. This feels a bit...strange.

For example, if you use getCellsWithHeadings to get some data like this:

[{foo: 1, bar: 2 }, {foo: 10, bar: 20}]

You can't return that back to the sheet.

To return data like that, you'd have to do an array of arrays, e.g.

[['foo', 'bar'], [1, 2], [10, 20]]

CleanShot 2024-04-25 at 16 54 13@2x

Not sure if we want to standardize something where if you return an array of objects, it'll try to put that on the sheet with the keys as col headings, e.g.

return [{foo: 1, bar: 2 }, {foo: 10, bar: 20}]

would result in

CleanShot 2024-04-25 at 16 58 03@2x

jimniels avatar Apr 25 '24 22:04 jimniels

for chart let's just call it returned a chart, user is indifferent/doesn't know what a blob is, image, etc.

CleanShot 2024-04-30 at 09 46 56@2x

luke-quadratic avatar Apr 30 '24 15:04 luke-quadratic

Seemed like @jimniels was experiencing this as well but the app regularly just stops working, as in you can move about the sheet but you can't open the editor, can't run things, etc.

This happens after a minute or two of playing around usually.

luke-quadratic avatar Apr 30 '24 16:04 luke-quadratic

Should this match Python? rel_cell vs relCell CleanShot 2024-04-30 at 10 46 38@2x

luke-quadratic avatar Apr 30 '24 16:04 luke-quadratic

rogue arrows in editor

CleanShot 2024-04-30 at 11 34 59@2x

luke-quadratic avatar Apr 30 '24 17:04 luke-quadratic

This is how cell ranges are treated, shouldn't it just be like this when it's 1-D:

array: [ 0: value1 1: value2 2: value3 ]

when it's 2D array: [ 0: value1 1: value 2 etc ], [ 0: value1 etc. ]

CleanShot 2024-05-01 at 09 22 49@2x

luke-quadratic avatar May 01 '24 15:05 luke-quadratic

Arrays with non-uniform data don't work

CleanShot 2024-05-01 at 09 41 01@2x

luke-quadratic avatar May 01 '24 15:05 luke-quadratic

I'm assuming this is a known thing, but the default chart that gets generated is low resolution on my MacBook display.

CleanShot 2024-05-03 at 16 05 01@2x

Can we control the image that gets generated? can we make it 2x? e.g. draw it at 800x600 but size it to 400x300

jimniels avatar May 03 '24 22:05 jimniels

I know mis-typed imports are an issue. You know enough to display a generic error in the code cell, can you do the same for the console? Same as you display other known error messages, this one is just a generic one? At least then it's clear there’s some kind of error.

CleanShot 2024-05-03 at 16 08 22@2x

jimniels avatar May 03 '24 22:05 jimniels

JS is lacking the same mechanisms as Python for inspecting your code cell run, e.g. cancelling a run, seeing that it's in progress, etc. The "play" button doesn't even go disabled while code is executing.

This is fine for a lot of synchronous code, but when you start doing async stuff (like fetching modules over the network) it feels really weird that there's no feedback that something is happening.

In this example, I slowed down the network, but you can see how I hit "Play", the button remains enabled, there's no indication that anything is happening, and then after a few seconds the module gets loaded, the code executes, and you see the new value show up in the sheet (and the new output in the console)

https://github.com/quadratichq/quadratic/assets/1316441/bad439ac-fd28-4c3d-bdf4-4623c2996b64

Are we ok just shipping this like this? without the same mechanisms we have in python for cancelling execution, showing when something is executing, etc.?

jimniels avatar May 03 '24 22:05 jimniels

Minor: any occurrence of "Javascript" in the UI should be represented as "JavaScript"

CleanShot 2024-05-03 at 16 37 09@2x

I fixed it in the cell type menu, but if there are others you know of...

jimniels avatar May 03 '24 22:05 jimniels

We should update the cell type menu for JavaScript so it reads like the others and includes a link to the JS docs

Example:

CleanShot 2024-05-03 at 16 45 46@2x

jimniels avatar May 03 '24 22:05 jimniels

CleanShot 2024-06-26 at 19 13 37@2x

luke-quadratic avatar Jun 27 '24 01:06 luke-quadratic