Tome is a library written to support relay scripts for KoLmafia written in TypeScript with React.
It works as a drop-in replacement for the kolmafia
typescript bindings, and allows use of libram
.
Any kolmafia
function call will return a placeholder value on the first call, and then silently
fetch the correct value in the background, triggering a UI refresh in React when that value arrives.
Essentially, tome
goes for eventual UI consistency.
To get started, simply run:
yarn add kolmafia@npm:tome-kolmafia-mock@^$(npm view tome-kolmafia-mock version) tome-kolmafia-react tome-kolmafia-lib
Afterwards you'll be able to import functions as if from kolmafia, and even use libram in the browser!
The tome developers recommend using TypeScript and vite for your build system.
If VS Code is suggesting imports from tome-kolmafia-lib/kolmafia
in addition to from kolmafia
,
you can exclude this with the following snippet in settings.json
:
"typescript.preferences.autoImportSpecifierExcludeRegexes": [
"^tome-kolmafia-lib/kolmafia$"
]
After that, there's a little more work to be done before you can fully benefit. You'll need
to wrap your App on some level (above wherever you want to run libram/kolmafia functions) with a
RefreshContextProvider
. Then the rest of your app should be in a subcomponent of that context
provider. A top-level component in your app needs to then call useContext(RefreshContext)
.
By default, your app will refresh its data any time the main pane is navigated or whenever key
pieces of character state change.
Typically, you will want to have some kind of a loader script that either creates its own relay frame (for scripts like Guide or CHiT that take up a whole pane), or inserts a div into the KoL HTML (for relay override scripts) that then can get filled by React or another UI framework.
One way to set up the development environment is to use vite or another framework's dev proxy
server with most requests proxied to KoLmafia and then to KoL itself. So e.g. you would access
the development environment at http://localhost:3000/game.php
, which would directly serve
resources for your script and proxy all other requests to 127.0.0.1:60080
.
Example vite config from YORICK
for this setup:
{
plugins: [react()],
base: '/yorick/',
server: {
port: 3000,
proxy: {
[`^/(?!yorick/|src/|node_modules/|@react-refresh|@vite|${publicFilesRegex}).*(?<!.js.map)$`]:
{
target: "http://127.0.0.1:60080",
changeOrigin: true,
secure: false,
},
},
},
}
The RefreshContextProvider
that you wrap your app in can have its default refresh conditions
overwritten via characterStateOverride
. This should be provided with a callback that returns a
Promise<Record<string, unknown>>
. Any time the values in the record change, data will be
refreshed. The default behavior if no characterStateOverride
is provided is to refresh when your turn
count, meat, hp, mp, equipment, familiar, or adventure count change.
For testing actual development of tome itself, run
yarn link /path/to/tome/packages/tome-kolmafia-{lib,mock,react}
in the project that depends on tome.