Repository navigation
Conversation
A function that is not an arrow gets strict-mode this: the object of a method call, undefined for a plain call, and the receiver call, apply and bind pass, never boxed. An arrow sees the this of the function it is written in. At the top level this is undefined, since there is no global object. Host functions and intrinsics still receive no this. Constructors and prototypes stay unsupported.
every, filter, find, findIndex, findLast, findLastIndex, flatMap, forEach, map, some, Array.from and the forEach of Map and Set call their callback with the thisArg as this. Every other built-in callback keeps undefined.
A reviver no longer receives the holder as a third argument; it is this instead, as in JavaScript. Use this where a reviver read the third argument.
A function replacer is called with the object holding the key as this, and with a fresh object around the value at the top level, as in JavaScript.
measure-run parses the context once, before any run, so both engines receive a plain object as a host's run call does. A second loop without forced collections reports median, min and max time, and a closing line says how many times faster or slower Maple is than js-interpreter. A synthetic contact record (46 flat fields, address, 450 activities, 300 custom fields) with three small scripts replaces context.json and demo-script.js as the default fixture. runJsInterpreter takes parsed data; the Benchmark worker parses inside its timed runs, as before.
A JSON string is no longer parsed as data, and run types data as object. A host that holds JSON text parses it first; the playground's workers now do, and the Benchmark worker parses once, outside the timed runs, for both engines.
When nothing on the chain answers to a key, assignment creates the same own data property as defineProperty, and no setter can run, so defineOwn assigns directly; every other key, __proto__ and inherited names included, keeps defineProperty. Copying the 75 KB contact record into a run drops from about 0.77 to 0.34 ms and from 1.22 to 0.85 MB allocated, and a 2,000-item filter/map/reduce from 8.0 to 5.6 ms.
Each top-level key of data that holds an object, array or function is copied when the script first reads it, at most once per run; primitives are bound at once. All keys of a run share one conversion, so shared values and cycles stay intact. An unsupported value inside a key now ends the run with INTERNAL_ERROR at the read instead of a TypeError before the run, and one the script never reads goes unnoticed. A one-key read of the 75 KB contact record drops from 0.34 to 0.04 ms and from 0.87 to 0.09 MB allocated.
new Maple({ astCache: true }) keeps the syntax trees of up to 200 scripts,
keyed by their source text, so a script that runs again is not parsed again;
{ maxEntries } sets another limit, the least recently used script is dropped
when full, and maple.clearAstCache() empties it. Trees are deep-frozen before
they are kept, code that does not parse is not kept, and nested runs share the
cache. measure-run gains --ast-cache, which reuses one instance: a one-line
script drops from 0.017 to 0.008 ms, a 10-line script from 0.55 to 0.51 ms.
contact-summary.js builds a CRM summary from the contact fixture and reads every key, activities and customFields included, so it measures a run in which nothing is left unread.
parseContext refused only what is not an object at all and left an array to Maple, which rejects it, while js-interpreter exposed its indexes, so the Benchmark tab reported two outcomes instead of one input error. From the same review: astCache.maxEntries of null is rejected instead of silently taking the default, the boundary doc's sentence on host mutations is completed, an ast-cache test name gets its article, and the measure-run usage line spells pnpm.
📋 Release PreviewChangelog0.4.0 (2026-10-21)🚀 Features
🩹 Bug Fixes
⚡ Performance Improvements
📖 Documentation
🔧 Miscellaneous Chores |
|
🎉 This PR is included in version 0.4.0 🎉 The release is available on: Your semantic-release bot 📦🚀 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Releases everything merged into
incrementsince 0.3.0:thisin script functions #12 Supportthisin script functionsHighlights
thisin script functions. Functions that aren't arrows now get strict-modethis: the object of a method call,undefinedfor a plain call and at the top level, and whatevercall,applyandbindpass. Arrows takethisfrom the function around them. Array callbacks,Array.fromand theforEachof Map and Set take athisArg. Constructors and prototypes are still unsupported.databefore the first statement, which was where almost all of its time went. Now each top-level key is copied the first time the script reads it, at most once per run. The less ofdataa script reads, the bigger the gain: a script that reads one or two flat keys of a large record ran about 48× faster in the Run typical scripts about 48× faster by copying only the data they read #13 benchmark and allocated a fraction of the memory. Copying across the boundary is also cheaper, which speeds up object literals, spread,Object.fromEntriesandJSON.parse.new Maple({ astCache: true })keeps the syntax trees of up to 200 scripts ({ maxEntries }sets a different limit, and the least recently used one is dropped first).maple.clearAstCache()empties it.Behaviour changes for hosts
datamust be a plain object.run(code, '{"a":1}')now throwsTypeError: data must be a plain object, so hosts that hold JSON text have to parse it first.datakey (a class instance, a typed array, nesting deeper than 1000 levels) no longer throws aTypeErrorbefore the run. It ends the run withINTERNAL_ERRORwhen the script reads that key, and a key the script never reads goes unnoticed. A symbol or bigint directly underdatastill throws before the run.datavalue before the script first reads it, the script sees the change.thisnow, as in JavaScript. A replacer also gets its holder asthis.Tooling
measure-memoryis nowmeasure-run. It adds timing, a comparison with js-interpreter,--ast-cache, and a synthetic contact record as its fixture.