Globals
Plugins run in QuickJS, not in a browser or Node. A few web-style globals exist so that common code works. Everything else comes from macotron.*.
const last = localStorage.getItem("lastRun");
console.log("loaded, last run", last);
localStorage.setItem("lastRun", new Date().toISOString());
setTimeout(() => console.log("one second later"), 1000);
console
Each call joins its arguments with spaces and writes one line to the macOS log under subsystem io.statico.macotron and category plugin, with the plugin's file name in front. Objects go through JSON.stringify, so an Error prints as {}; log e.message instead.
console.log(...args: any[]): void
Writes at info level. The same as macotron.log.
console.info(...args: any[]): void
Writes at info level, like log. console.debug does the same.
console.warn(...args: any[]): void
Writes at notice level, which the system log keeps by default.
console.error(...args: any[]): void
Writes at error level.
There is no console.table, console.time, or console.assert. Info lines only show when you ask for them:
// In Terminal:
// log stream --level info --style compact --predicate 'subsystem == "io.statico.macotron" AND category == "plugin"'
Timers
Timers run on the main thread. Macotron cancels every timer when plugins reload. Each callback has 5 seconds to return before Macotron interrupts it.
setTimeout(callback: () => void, ms?: number): number
Runs callback once after ms milliseconds, and returns an id. The delay is rounded down to a whole number and is at least 1 ms. Extra arguments are not passed to the callback; use a closure.
setInterval(callback: () => void, ms: number): number
Runs callback every ms milliseconds, and returns an id. ms is required.
clearTimeout(id: number): void
clearInterval(id: number): void
Cancels a timer. The two are the same function, so either one cancels either kind of timer.
For schedules such as "every 5 minutes on the clock" or "at 07:30 on weekdays", use macotron.every and macotron.at. They also catch up after the Mac sleeps.
localStorage
A string key-value store that survives restarts. It is saved to data/localStorage.json in the Macotron folder after every change. All plugins share one store, so put a prefix on your keys, such as "layouts:work".
getItem(key: string): string | null
The stored string, or null when the key is absent.
setItem(key: string, value: string): void
Stores value as a string. Store objects with JSON.stringify and read them back with JSON.parse.
removeItem(key: string): void
Deletes one key.
clear(): void
Deletes every key, including the keys of other plugins.
Dialogs
alert(message?: any): void
confirm(message?: any): boolean
prompt(message?: any, defaultValue?: string): string | null
Browser-style dialogs, shown as a standard macOS alert. They block every plugin until the user answers. confirm returns true for OK. prompt returns the text for OK and null for Cancel. They are the same functions as macotron.alert, macotron.confirm, and macotron.prompt; see macotron (core).
Built into the JavaScript engine
QuickJS supplies the standard language: Promise and async/await, JSON, Map, Set, WeakRef, typed arrays, Proxy, RegExp, and Date. It also adds queueMicrotask, atob and btoa, and performance.now().
What is missing, and what to use instead
| You might expect | Use instead |
|---|---|
fetch, XMLHttpRequest | macotron.http (get, post, put, delete, each a promise) |
Node fs, path | macotron.fs |
Node child_process | macotron.shell.run |
require, npm packages | Not available. Keep a plugin's code in its own file. |
document, window, the DOM | macotron.panel, which hosts a real web page |
Notification | macotron.notify |
| Clipboard API | macotron.clipboard |
| Secret storage | macotron.keychain, or a "password" option in macotron.plugin() |
There is also no process, Buffer, TextEncoder, TextDecoder, URL, crypto, structuredClone, or Intl.
See also
- macotron (core) for commands, events, and scheduling.