Lifecycle and devtools
Observe persisted model hydration, persistence, migration, sync, reset, and dispose events.
Lifecycle and devtools#
Persisted models can emit typed lifecycle events without exposing full state by default.
Event target#
import { createPersistedEventTarget } from "@kamod-ch/signals";
const events = createPersistedEventTarget<PreferencesSnapshot>();
const unsubscribe = events.subscribe((event) => {
console.log(event.type, event.key, event.metadata);
});
const PreferencesModel = createPersistedModel({
key: "preferences",
storage: "local",
events,
select,
apply,
}, createPreferencesModel);
Listener errors are isolated and do not break persistence. Call unsubscribe() or events.dispose() during cleanup.
Events#
| Event | Meaning |
|---|---|
hydrate:start |
storage/scope hydration started |
hydrate:success |
hydration completed |
hydrate:error |
hydration failed |
persist:start |
snapshot write started |
persist:success |
snapshot write completed |
persist:error |
snapshot write failed |
migrate:start |
migration started |
migrate:success |
migration completed |
migrate:error |
migration or validation failed |
sync:receive |
remote sync message received |
sync:reject |
remote sync message rejected |
reset |
model reset requested |
dispose |
model disposed |
Events include key, optional storage, timestamp, optional metadata, and optional error.
Redaction#
Snapshots are redacted by default:
const events = createPersistedEventTarget();
If you need full snapshots for a controlled development tool, opt in explicitly:
const events = createPersistedEventTarget<PreferencesSnapshot>({
includeSnapshots: true,
});
Do not enable full snapshots for sensitive state.
Development logger#
The optional logger is available through a tree-shakable subpath:
import { createPersistedDevLogger } from "@kamod-ch/signals/devtools";
const events = createPersistedDevLogger();
It logs in development by default and is inactive in production unless explicitly enabled. Snapshots remain redacted unless includeSnapshots: true is passed.
Plugin example#
export function createMetricsPlugin() {
const events = createPersistedEventTarget();
const unsubscribe = events.subscribe((event) => {
if (event.type === "persist:error") {
reportPersistenceError(event.key, event.error);
}
});
return { events, dispose: unsubscribe };
}
A future browser devtools panel can subscribe to the same event API. The core package does not include a browser extension or Redux DevTools dependency.