Concepts
Lifecycle
When your extension starts, when update runs, and how the view reaches the island.
An extension registers itself by calling AdanotchKit.activity({...}) once, at the top level of its script. Adanotch then goes through these steps:
- The script loads; its top-level code runs.
setup(ctx)runs once.- The first
update(ctx)runs and its view goes to the island. - From then on,
updateruns again everyrefreshinterval, after every action, after every settings change, and on everyctx.refresh().
AdanotchKit.activity<Settings>({
async setup(ctx) {
// Once: subscribe to events, start timers, prepare the first data.
},
async update(ctx) {
// Return the view.
return { compact: { trailing: AdanotchKit.ui.text("42") } };
},
async onAction(action, ctx, value) {
// A button, toggle, slider, text field or list row was used.
},
async onSettingsChange(ctx) {
// The user changed a value in Settings; ctx.settings already has the new values.
},
});Hooks
Prop
Type
When update runs
| Trigger | Note |
|---|---|
The refresh interval | refresh in manifest.json ("5s", "10m", "1h"); 5 s if left out. "manual" never runs it on its own. |
After onAction | Not if the action throws. |
After onSettingsChange | When the user changes a value in Settings. |
ctx.refresh() | To refresh the view from events and timers. |
Overlapping runs merge
Requests that arrive while an update runs don't queue up; update runs once more when the current one ends. Calling ctx.refresh() ten times during a slow fetch means one more run, not ten.
Changing part of the view: ctx.render
When you don't want to wait for update to return (say, from a timer every second), use ctx.render. Keys you pass replace, null removes, anything you leave out stays as it is:
// Change only the compact area; the card stays as it is.
ctx.render({ compact: { trailing: ui.text("Loading…", { tone: "secondary" }) } });
// Remove the card.
ctx.render({ expanded: null });Several render calls in one turn go out as one message. Calling render inside update and returning nothing is fine too.
Where state lives
- Module variables (
const history: number[] = []) last as long as the extension's process. They reset when Adanotch restarts, when the extension is updated, or when the process is restarted after hitting a limit. ctx.storageis written to disk and survives restarts. Storage and settings
Errors
- If
updatethrows, the last view stays; the error shows with its source line in Settings › Extensions and in theadanotch devoutput. - An uncaught error in an event handler or a timer is logged and doesn't stop the extension.
- An error in
setupor while loading stops the extension at once. - Three
updateerrors in a row, or going over a process limit three times in a row, turns the extension off. Details: Limits.