Skip to content

feat(runtime): finish the move to the new JavaScript evaluation API for 0.21 - #660

Closed
route wants to merge 2 commits into
feat/js-api-compatfrom
feat/js-api-finish
Closed

route wants to merge 2 commits into
feat/js-api-compatfrom
feat/js-api-finish

Conversation

@route

@route route commented Oct 19, 2026

Copy link
Copy Markdown
Member

Second step after #659, for 0.21. It's based on #659's branch, so this diff shows only the removal.

Removed

  • Frame::Runtime::Legacy: the old evaluation path, its change detection, and evaluate_async, evaluate_func and evaluate_on.
  • Utils::Deprecate and FERRUM_DEPRECATION_WARNINGS.
  • Frame::Script helpers that only the old path used.

Behavior in 0.21

Each of these was warned about in 0.20:

  • A returned promise or thenable is awaited, and a rejection raises.
  • Keywords are always named parameters, and mixing them with positional arguments raises ArgumentError.
  • A script of several statements raises SyntaxError. A script after a leading line break runs.
  • A thrown value that isn't an Error raises JavaScriptError.
  • Node#evaluate resolves nodes and dates instead of returning {}.

Positional arguments keep working through arguments[n].

route added 2 commits October 22, 2026 19:28
…keeping the old one with warnings

`#evaluate`, `#evaluate_async`, `#execute`, `#evaluate_func` and `#evaluate_on` had four argument conventions and three
return semantics between them, and scripts reached their arguments through `arguments[0]`. This adds one convention for
all of them, without changing what any existing call returns.

New: keyword arguments become the script's parameters, `page.evaluate("a + b", a: 1, b: 2)`, bound by name when the
script is a function declaration. A script may be a function or arrow declaration, used as-is, and may `await`; promises
it returns are awaited, bounded by `timeout:` and raising `ScriptTimeoutError`, now a `TimeoutError`. Added
`#evaluate_handle`, returning a `Ferrum::RemoteObject`, and `Node#execute`/`Node#evaluate_handle`. Scripts are read by a
small scanner, `Frame::Script`, that skips strings, template literals, regular expressions and comments.

Compatible: a call that doesn't use any of that runs exactly as before, through `Runtime::Legacy`, which also keeps
`#evaluate_async`, `#evaluate_func` and `#evaluate_on`. Positional arguments keep working. What 0.21 will do differently
is detected and warned about with a rewrite, pointing at the first caller outside installed gems: keywords read through
`arguments`, mixed positional and keyword arguments, scripts of several statements or that never run, promises and
thenables that will be awaited, thrown non-Errors that will raise, and nodes `Node#evaluate` will resolve.
`FERRUM_DEPRECATION_WARNINGS=raise` turns the warnings into errors, `0` silences them.
…or 0.21

Removes `Runtime::Legacy`, which kept old-style scripts running as before and warned about what changes here, along with
`#evaluate_async`, `#evaluate_func`, `#evaluate_on` and `Utils::Deprecate`. Every call now takes the new path:

- a returned promise or thenable is awaited, and a rejection raises
- keywords are always named parameters, and mixing them with positional arguments raises `ArgumentError`
- a script of several statements raises `SyntaxError`, and one after a leading line break runs
- a thrown value that isn't an `Error` raises `JavaScriptError`
- `Node#evaluate` resolves nodes and dates instead of returning `{}`

Positional arguments keep working through `arguments[n]`.
@route

route commented Oct 22, 2026

Copy link
Copy Markdown
Member Author

Replaced by #659, which now ships the new API behind a js_api switch: 0.21 flips the default and 0.22 removes the legacy code.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant