refactor(api)!: declare callbacks as classes an app composes

The runtime has always called fields on the table main.lua returns, but
@lua-global declared them as loose functions, so the stubs type-checked
something that does not exist and read as "define a global".

Callbacks are now @lua-app blocks that generate a class: App for the core
contract, TouchHandlers and ButtonHandlers beside the namespaces they belong
to. An app composes what it implements:

  ---@class PaintApp : App, TouchHandlers

Names follow the rest of the surface: onTouchDown rather than on_touch_down,
with the field names the runtime looks up renamed to match. @lua-field carries
the plain fields (home, data) that were prose in a preamble before.
This commit is contained in:
2026-08-05 10:42:01 -04:00
parent 75b3a2c490
commit b9f7c9347c
11 changed files with 153 additions and 87 deletions
+6
View File
@@ -41,6 +41,12 @@ files are committed for editors and checked for drift by `make test`, so a names
by the code that registers it, including the callbacks in `core/runtime.lua` and the feature files,
which are generated from the `Runtime::call*` sites that fire them.
Callbacks are fields on the table an app returns, not globals, so each `@lua-app` block generates a
class rather than loose functions: `App` for the core contract, `TouchHandlers` and `ButtonHandlers`
alongside the namespaces they belong to. An app composes the ones it implements
(`---@class PaintApp : App, TouchHandlers`), which is as close to per-device stubs as static
declarations get -- what a firmware actually provides is still `sys.hasFeature()` at runtime.
Nothing under `lua/api/` ever runs: it is `---@meta` for editors and the drift check. `lua/lib/`
is the opposite -- real modules that ship to the SD card, so composition like `ui.lua` and
`hints.lua` changes without a reflash.