Hot-reload for IAddon instances — the public surface a host consumes.
Reloading a namespace updates VARS. It does not update the addon INSTANCE the
host registered at mount time, nor the sibling instances that were injected
into its dependents' configs. Those objects were captured when they were
constructed and are frozen; a namespace reload leaves the system holding old
objects that call new code, which is the silent-corruption shape. What this
namespace does is reconstruct them from the one thing a reload cannot
invalidate: the MountSpec, which carries :addon/init-ns + :addon/init-fn
as data. Remount is therefore the ordinary mount pipeline re-run over the
affected slice, not a second registry.
Layout: hive-addon.hot.source — where an addon's source lives (:local/root vs jar) hive-addon.hot.cascade — pure: which addons a reload touches, in what order hive-addon.hot.strategy — OCP: how each addon is reloaded hive-addon.hot — this facade: wiring, triggering, reporting
hive-hot is a SOFT dependency, resolved through the var at call time and never
required. Without it every function here still works — reload-addon! falls
back to require :reload — and hot! degrades to a report saying
:hot/available? false instead of throwing. Consumers that want file-watching
add io.github.hive-agi/hive-hot themselves.
THE ONE HARD RULE: never reload hive-addon.protocol. Reloading a
protocol-defining namespace mints a new protocol var, and every live addon
instance — same class NAME, different class OBJECT — stops satisfying it, so
dispatch misses with an error that reads as if the method were never
implemented. no-reload is that rule as data; feed it to hive-hot's
:no-reload and the hazard cannot be tripped.
Hot-reload for IAddon instances — the public surface a host consumes. Reloading a namespace updates VARS. It does not update the addon INSTANCE the host registered at mount time, nor the sibling instances that were injected into its dependents' configs. Those objects were captured when they were constructed and are frozen; a namespace reload leaves the system holding old objects that call new code, which is the silent-corruption shape. What this namespace does is reconstruct them from the one thing a reload cannot invalidate: the MountSpec, which carries `:addon/init-ns` + `:addon/init-fn` as data. Remount is therefore the ordinary mount pipeline re-run over the affected slice, not a second registry. Layout: hive-addon.hot.source — where an addon's source lives (:local/root vs jar) hive-addon.hot.cascade — pure: which addons a reload touches, in what order hive-addon.hot.strategy — OCP: how each addon is reloaded hive-addon.hot — this facade: wiring, triggering, reporting hive-hot is a SOFT dependency, resolved through the var at call time and never required. Without it every function here still works — `reload-addon!` falls back to `require :reload` — and `hot!` degrades to a report saying :hot/available? false instead of throwing. Consumers that want file-watching add io.github.hive-agi/hive-hot themselves. THE ONE HARD RULE: never reload hive-addon.protocol. Reloading a protocol-defining namespace mints a new protocol var, and every live addon instance — same class NAME, different class OBJECT — stops satisfying it, so dispatch misses with an error that reads as if the method were never implemented. `no-reload` is that rule as data; feed it to hive-hot's :no-reload and the hazard cannot be tripped.
(affected-plan specs seed-ids)(affected-plan specs seed-ids opts)hive-addon.hot.cascade/affected-plan — the ordered slice a reload drives.
hive-addon.hot.cascade/affected-plan — the ordered slice a reload drives.
(available?)Is hive-hot on the classpath?
Is hive-hot on the classpath?
(default-strategies)hive-addon.hot.strategy/default-strategies — a FRESH built-in chain, rebuilt against the current protocol var.
hive-addon.hot.strategy/default-strategies — a FRESH built-in chain, rebuilt against the current protocol var.
(dependents specs seed-ids)(dependents specs seed-ids opts)hive-addon.hot.cascade/dependents — transitive dependent closure of seeds.
hive-addon.hot.cascade/dependents — transitive dependent closure of seeds.
(hot! host specs & [opts])Wire specs into hive-hot so that reloading an addon's constructor namespace
remounts that addon and its dependents.
Registers one hive-hot component per reloadable addon, keyed :addon/<id>. Jar-backed and source-absent addons are NOT registered — they are reported under :hot/skipped, because registering a component whose bytes cannot change would only produce reloads that appear to succeed while changing nothing.
Degrades gracefully: with hive-hot absent this performs no effects and returns a report with :hot/available? false.
Returns a HotReport. Its :hot/dirs and :hot/no-reload are what to pass on to hive-hot's own init:
(let [{:keys [hot/dirs hot/no-reload]} (hot! host specs)] (hive-hot.core/init-with-watcher! {:dirs (vec dirs) :no-reload no-reload}))
Wire `specs` into hive-hot so that reloading an addon's constructor namespace
remounts that addon and its dependents.
Registers one hive-hot component per reloadable addon, keyed :addon/<id>.
Jar-backed and source-absent addons are NOT registered — they are reported
under :hot/skipped, because registering a component whose bytes cannot change
would only produce reloads that appear to succeed while changing nothing.
Degrades gracefully: with hive-hot absent this performs no effects and returns
a report with :hot/available? false.
Returns a HotReport. Its :hot/dirs and :hot/no-reload are what to pass on to
hive-hot's own init:
(let [{:keys [hot/dirs hot/no-reload]} (hot! host specs)]
(hive-hot.core/init-with-watcher! {:dirs (vec dirs) :no-reload no-reload}))(install-strategies! strategies)hive-addon.hot.strategy/install-strategies! — replace the strategy chain.
hive-addon.hot.strategy/install-strategies! — replace the strategy chain.
(installed-strategies)hive-addon.hot.strategy/installed-strategies — the live strategy chain.
hive-addon.hot.strategy/installed-strategies — the live strategy chain.
Keys that belong to boundary/mount!, not to a reload's own options.
A caller that passes one of these at the TOP level of reload opts means it for mount!. Silently ignoring it is the worst available outcome: mount! falls back to resolve-config-default, the addon still constructs, still initializes and still reports :success? true — while coming back DEGRADED, missing the config.edn merge and whatever host adapters its real config carried. Measured in hive-mcp: a remount that lost :resolve-config left hive.carto :active with zero runtime ports and silently dropped its whole MCP subdomain.
So they are FOLDED into :mount-opts rather than dropped.
Keys that belong to boundary/mount!, not to a reload's own options. A caller that passes one of these at the TOP level of reload opts means it for mount!. Silently ignoring it is the worst available outcome: mount! falls back to resolve-config-default, the addon still constructs, still initializes and still reports :success? true — while coming back DEGRADED, missing the config.edn merge and whatever host adapters its real config carried. Measured in hive-mcp: a remount that lost :resolve-config left hive.carto :active with zero runtime ports and silently dropped its whole MCP subdomain. So they are FOLDED into :mount-opts rather than dropped.
Namespaces that must NEVER be reloaded while addons are live, for hive-hot's :no-reload option.
hive-addon.protocol defines IAddon. Reloading it replaces the protocol var; instances built against the previous var keep their old class object and stop satisfying the new protocol, producing "No implementation of method ... for class X" for a class whose name matches perfectly. The mount and hot namespaces are pinned for the same reason — they hold the registry state and the strategy chain a reload would otherwise reset mid-flight.
Namespaces that must NEVER be reloaded while addons are live, for hive-hot's :no-reload option. hive-addon.protocol defines IAddon. Reloading it replaces the protocol var; instances built against the previous var keep their old class object and stop satisfying the new protocol, producing "No implementation of method ... for class X" for a class whose name matches perfectly. The mount and hot namespaces are pinned for the same reason — they hold the registry state and the strategy chain a reload would otherwise reset mid-flight.
(ns-reloader)The namespace-level reloader injected into strategies.
Prefers hive-hot's clj-reload-backed reload!, which reloads every CHANGED
namespace and cascades to their dependents properly. Falls back to plain
require :reload over the given namespaces when hive-hot is absent.
The namespace-level reloader injected into strategies. Prefers hive-hot's clj-reload-backed `reload!`, which reloads every CHANGED namespace and cascades to their dependents properly. Falls back to plain `require :reload` over the given namespaces when hive-hot is absent.
(plan host specs & [opts])What hot! WOULD wire, with no effects — the dry-run parity of hot!.
Reports, per spec, the strategy that would be selected, where its source lives and whether it is reloadable at all. Use it to answer "why is this addon not hot-reloading?" without touching the running system.
What `hot!` WOULD wire, with no effects — the dry-run parity of hot!. Reports, per spec, the strategy that would be selected, where its source lives and whether it is reloadable at all. Use it to answer "why is this addon not hot-reloading?" without touching the running system.
(register-strategy! strategy)hive-addon.hot.strategy/register-strategy! — OCP: add a reload strategy.
hive-addon.hot.strategy/register-strategy! — OCP: add a reload strategy.
(reload-addon! host specs addon-id & [opts])Reload ONE addon by id, cascading to its dependents. This is what the
hive hot reload <addon-id> command drives.
opts: {:trigger :manual | :ns-reload | :file-change :ns-reloaded? true when the namespaces were already reloaded :mount-opts forwarded to mount! (e.g. :resolve-config, :license-gate) :solve-opts forwarded to solve (e.g. :rules) :strategies strategy chain override :reload-ns! namespace-reloader override}
Returns a RemountReport.
Reload ONE addon by id, cascading to its dependents. This is what the
`hive hot reload <addon-id>` command drives.
opts: {:trigger :manual | :ns-reload | :file-change
:ns-reloaded? true when the namespaces were already reloaded
:mount-opts forwarded to mount! (e.g. :resolve-config, :license-gate)
:solve-opts forwarded to solve (e.g. :rules)
:strategies strategy chain override
:reload-ns! namespace-reloader override}
Returns a RemountReport.(reload-all! host specs & [opts])Reload every mounted addon, in dependency order.
Reload every mounted addon, in dependency order.
(reload-namespace! host specs ns-str & [opts])Reload every addon whose constructor namespace is ns-str, plus dependents.
This is what a hive-hot component callback drives, so :ns-reloaded? defaults
to true — clj-reload has already done the namespace work by then.
Reload every addon whose constructor namespace is `ns-str`, plus dependents. This is what a hive-hot component callback drives, so :ns-reloaded? defaults to true — clj-reload has already done the namespace work by then.
(reload-seeds! host specs seed-ids & [opts])Reload seed-ids and every addon that depends on them.
Seeds are grouped by the strategy each one selects, so a system mixing strategies reloads each group under its own policy exactly once — rather than letting one seed's strategy decide for addons that asked for something else.
Returns a RemountReport.
Reload `seed-ids` and every addon that depends on them. Seeds are grouped by the strategy each one selects, so a system mixing strategies reloads each group under its own policy exactly once — rather than letting one seed's strategy decide for addons that asked for something else. Returns a RemountReport.
(reset-strategies!)hive-addon.hot.strategy/reset-strategies! — restore the built-in chain.
hive-addon.hot.strategy/reset-strategies! — restore the built-in chain.
(spec-source spec)hive-addon.hot.source/spec-source — where a spec's constructor ns lives.
hive-addon.hot.source/spec-source — where a spec's constructor ns lives.
(status)Current hot-reload status: hive-hot availability, its component registry, and the installed strategy chain.
Current hot-reload status: hive-hot availability, its component registry, and the installed strategy chain.
(unhot! specs)Deregister every addon in specs from hive-hot. No-op without hive-hot.
Deregister every addon in `specs` from hive-hot. No-op without hive-hot.
(watchable-dirs specs)hive-addon.hot.source/watchable-dirs — the :local/root source dirs to watch.
hive-addon.hot.source/watchable-dirs — the :local/root source dirs to watch.
cljdoc builds & hosts documentation for Clojure/Script libraries
| Ctrl+k | Jump to recent docs |
| ← | Move to previous article |
| → | Move to next article |
| Ctrl+/ | Jump to the search field |