JavaScript Support: Difference between revisions

From Kolmafia
Jump to navigation Jump to search
Ikzann (talk | contribs)
mNo edit summary
Ikzann (talk | contribs)
Added more docs
Line 1: Line 1:
As of revision 20509, KoLmafia supports scripting in JavaScript! You can run JS code from the CLI using <code>js <nowiki><code></nowiki></code>, and you can call scripts through any of the normal methods. Consult and "lifecycle" scripts (e.g. <code>betweenBattleScript</code>) are supported as well as of revision 20519. '''This support is still experimental - you have been warned.'''
As of revision 20509, KoLmafia supports scripting in JavaScript! You can run JS code from the CLI using <code>js <nowiki><code></nowiki></code>, and you can call scripts through any of the normal methods. Consult and "lifecycle" scripts (e.g. <code>betweenBattleScript</code>) are supported as well as of revision 20519. '''This support is still experimental - you have been warned.'''


== Basics ==
* All the methods in the ASH runtime library are available, with names of methods converted to camelCase. So, for example, <code>print_html</code> in ASH becomes <code>printHtml</code> in JS.
* All the methods in the ASH runtime library are available, with names of methods converted to camelCase. So, for example, <code>print_html</code> in ASH becomes <code>printHtml</code> in JS.
* In scripts called from a file, you can access the runtime library by calling <code>require("kolmafia")</code>, so <code>const { printHtml } = require("kolmafia")</code>. If running from the command line via <code>js</code>, the runtime library functions are all available in the global scope (so you can do <code>js print("Hello world!");</code>).
* In scripts called from a file, you can access the runtime library by calling <code>require("kolmafia")</code>, so <code>const { printHtml } = require("kolmafia")</code>. If running from the command line via <code>js</code>, the runtime library functions are all available in the global scope (so you can do <code>js print("Hello world!");</code>).
Line 8: Line 9:
* Mafia supports <code>require</code> for both ASH and JS scripts. For ASH scripts, it will execute top-level code but only export functions, not variables, in the top scope.
* Mafia supports <code>require</code> for both ASH and JS scripts. For ASH scripts, it will execute top-level code but only export functions, not variables, in the top scope.
* If you want Mafia to run your <code>main</code> function, you '''<u>must</u>''' export it by adding it to module.exports, just as you would for a Node module. For the uninitiated, this just means adding <code>module.exports.main = main</code> to the end of your script. You will want to do the same with any function or value you want to be available to other scripts via require.
* If you want Mafia to run your <code>main</code> function, you '''<u>must</u>''' export it by adding it to module.exports, just as you would for a Node module. For the uninitiated, this just means adding <code>module.exports.main = main</code> to the end of your script. You will want to do the same with any function or value you want to be available to other scripts via require.
== Bundlers ==
Folks with experience doing JS web development are likely used to using a suite of tools such as Babel, Webpack, and potentially Typescript to write more modern code that transpiles down to a dialect of JS that is supported by browsers or an engine. That approach works well with Rhino. As of r20558, you will still need to apply several patches to Babel in order to get babel-preset-env to work. See [https://github.com/phulin/bean-casual/tree/ts] for an example of a working Babel/Webpack/Typescript configuration; you'll need the configuration files and also the patches, which can be applied with patch-package.

Revision as of 03:49, 12 December 2020

As of revision 20509, KoLmafia supports scripting in JavaScript! You can run JS code from the CLI using js <code>, and you can call scripts through any of the normal methods. Consult and "lifecycle" scripts (e.g. betweenBattleScript) are supported as well as of revision 20519. This support is still experimental - you have been warned.

Basics

  • All the methods in the ASH runtime library are available, with names of methods converted to camelCase. So, for example, print_html in ASH becomes printHtml in JS.
  • In scripts called from a file, you can access the runtime library by calling require("kolmafia"), so const { printHtml } = require("kolmafia"). If running from the command line via js, the runtime library functions are all available in the global scope (so you can do js print("Hello world!");).
  • ASH maps are converted to plain JS objects, and ASH arrays are converted to JS arrays.
  • You can look at the type reference for the JS version of the ASH runtime library with jsref, which works just like ashref.
  • Objects like monsters and items can be constructed via the Monster and Item global objects, along with the rest of ASH's enumerated types (stat, phylum, location, etc.). Monster.get takes a number or a string, just like $monster in ASH, or an array of numbers and strings to construct an array of monsters. Monster.all works like $monsters[] in ASH; it takes no arguments and returns an array of all monsters.
  • Mafia supports require for both ASH and JS scripts. For ASH scripts, it will execute top-level code but only export functions, not variables, in the top scope.
  • If you want Mafia to run your main function, you must export it by adding it to module.exports, just as you would for a Node module. For the uninitiated, this just means adding module.exports.main = main to the end of your script. You will want to do the same with any function or value you want to be available to other scripts via require.

Bundlers

Folks with experience doing JS web development are likely used to using a suite of tools such as Babel, Webpack, and potentially Typescript to write more modern code that transpiles down to a dialect of JS that is supported by browsers or an engine. That approach works well with Rhino. As of r20558, you will still need to apply several patches to Babel in order to get babel-preset-env to work. See [1] for an example of a working Babel/Webpack/Typescript configuration; you'll need the configuration files and also the patches, which can be applied with patch-package.