DevTools
<AmnesiaProvider enableDevTools> registers the provider with
window.__REACT_AMNESIA_DEVTOOLS__. External tooling can resolve the
provider by id and call its inspection api — read scope state, trigger
undo / redo, dump everything — without touching application code.
<AmnesiaProvider enableDevTools={import.meta.env.DEV} devToolsId="my-app">
{children}
</AmnesiaProvider>
Then anywhere with window access:
const registry = window.__REACT_AMNESIA_DEVTOOLS__;
if (registry) {
const probe = registry.resolve("my-app");
if (probe) {
console.table(probe.dump());
await probe.triggerUndo();
probe.clear("draft");
}
}
Opt-in by design
The registry is lazy-installed. When no provider sets
enableDevTools, the global is never created and the registry-side
machinery stays cold. You can ship enableDevTools={import.meta.env.DEV}
(Vite) or enableDevTools={process.env.NODE_ENV !== "production"} to
gate it behind a build-time env flag.
Inspection api
The api a provider exposes:
| Method | Returns |
|---|---|
id | The id under which the provider is registered. |
getActiveScopeId() | The current active scope. |
scopes() | All registered scope ids. |
getSnapshot(scopeId?) | Snapshot for one scope (active by default). |
pastSnapshot(scopeId?) | Just the past entries. |
futureSnapshot(scopeId?) | Just the future entries. |
dump() | Record<scopeId, AmnesiaState> for every scope. |
triggerUndo(scopeId?) | Async — returns the undone entry id, or null. |
triggerRedo(scopeId?) | Async. |
clear(scopeId?) | Clear one scope, or every scope when omitted. |
Pinning ids vs auto-generated
devToolsId="my-app"registers under that exact id. Recommended for production-shaped builds where external tooling expects a known name.- Omit
devToolsIdand the provider gets an auto-generated id likeamnesia-1. Stable across re-renders within the component instance.
WeakRef behavior
Provider entries are held weakly via WeakRef when available. A
long-lived registry never prevents an unmounted provider from being
garbage-collected. resolve(id) returns null for GC'd entries.
__meta.version bumps on every register / unregister so a polling
extension can detect changes without re-resolving.
What it is NOT
The registry is for inspection — diagnostics, telemetry, agent
introspection. It is NOT a substitute for useAmnesia() snapshots inside
React components. UI state should subscribe normally; treat the registry
as an external observer.
Don't ship it on by default
Anything the registry exposes is reachable from arbitrary user code. If
your meta payloads carry sensitive data, gate enableDevTools to dev
builds AND/OR set metaTransform on the provider so even a leaked
registry surface returns redacted state.