A hook is a named, prioritized event pipeline that other code can attach handlers to and later call to run them. Handlers are grouped into four ordered stages - peek, provide, mixin, and observe - which run in that order each time the hook is called via Hook:call (or by calling the hook object itself, since it is callable).
Hook call pipeline, stages run in this order:
md
┌─────────┐
│ peek │ --> Always called, return is optional;
└─────────┘ if any handler returns a value,
↓ it overrides the `provide` stage.
┌─────────┐
│ provide │ --> Called only if `peek` produced `nil`.
└─────────┘ First hook that returns a value wins,
↓ its return value becomes the result.
┌─────────┐
│ mixin │ --> Called as long as a result exists.
└─────────┘ Lets handlers mutate the result,
↓ receiving both the old & new value.
┌─────────┐
│ observe │ --> Read-only listeners for the final
└─────────┘ result and args. Any return values
will be ignored.
Attaches a handler function to the given stage of the hook. If the handler is already attached to that stage, only its priority is updated (when a new one is supplied); it will not be attached twice.
If the hook is currently running, the change is deferred and applied once the hook finishes running.
Runs the hook, calling its handlers in order across all four stages: peek (early handlers that may short-circuit the result), provide (produces the base result), mixin (allowed to transform the result), and observe (read-only listeners called with the final result).
Throws (and cancels the hook) if any handler errors, or if the hook is already running.
Parameters
Name
Type
Description
...
any
Arguments forwarded to every handler in every stage.
Returns
Type
Name
Description
T | nil
result
The final value produced by peek/provide and possibly transformed by mixin handlers; nil if no handler produced a value.
Cancels the hook if it is currently running, and removes every handler attached to every stage (peek, provide, observe, mixin), resetting their priority tables as well.
Detaches a previously attached handler from the given stage of the hook. If the hook is currently running, the handler is replaced with a no-op and the actual removal is deferred until the hook finishes running.