Devtools
These are the v1 docs. They are not maintained.
This page is a verbatim snapshot of the commiq 1.x documentation, kept for people still running 1.x. It is not corrected and not tested against any release. Several pages contain claims that were wrong when written: examples that do not run as printed, sealStore described as read-only when it was not, handledEvent presented as a working subscription pattern when it never matched, and effects described as swallowing only AbortError when they swallowed everything.
Do not treat anything here as a statement about how commiq 2.x behaves.
What changed in 2.0 and how to upgrade · Current documentation
Site search only indexes the current docs. Use the sidebar to browse these pages.
Devtools
Commiq includes built-in instrumentation and a devtools package for debugging, event inspection, and state tracking.
Instrumentation
Every event and command in Commiq carries instrumentation metadata automatically:
timestamp—Date.now()when the event was emittedcorrelationId— unique identifier for each event/commandcausedBy— links to the parent command or event that triggered this one (nullfor user-initiated commands)
This enables full causality tracking: you can trace any event back through the chain of commands and events that caused it.
Installation
pnpm add @naikidev/commiq-devtools-corenpm install @naikidev/commiq-devtools-coreyarn add @naikidev/commiq-devtools-corebun add @naikidev/commiq-devtools-coreBasic Usage
import { createStore, createCommand } from "@naikidev/commiq";
import { createDevtools } from "@naikidev/commiq-devtools-core";
const store = createStore({ count: 0 });
store.addCommandHandler("increment", (ctx) => {
ctx.setState({ count: ctx.state.count + 1 });
});
// Connect devtools
const devtools = createDevtools();
devtools.connect(store, "counter");
// Events are now tracked
store.queue(createCommand("increment", undefined));Query API
Query collected events programmatically at any time:
// Get full event timeline
const timeline = devtools.getTimeline();
// Filter by store
const counterEvents = devtools.getTimeline("counter");
// Get causality chain for an event
const chain = devtools.getChain(someCorrelationId);
// Get state change history
const history = devtools.getStateHistory("counter");Console Logging
Enable structured console output for quick debugging:
const devtools = createDevtools({ logToConsole: true });
devtools.connect(store, "counter");
// Console output:
// [12:34:56.789] counter | commandStarted a3K9mX7p
// [12:34:56.789] counter | stateChanged b7yP2nX1 (caused by a3K9mX7p)
// [12:34:56.790] counter | commandHandled c1zR4qW8 (caused by a3K9mX7p)
// [12:34:57.001] counter | commandInterrupted d2xT5mQ9 (caused by a3K9mX7p)Event Classification
Timeline entries are classified by type for filtering and color-coding:
| Classification | Events | Color |
|---|---|---|
| Command | commandStarted, commandHandled | Indigo |
| Error | commandHandlingError, invalidCommand | Red |
| Interrupted | commandInterrupted | Orange |
| State change | stateChanged | Amber |
| Event | Custom events, stateReset | Green |
Interruptable commands that are cancelled (either while queued or running) appear as commandInterrupted entries with a phase field ("queued" or "running").
Custom Transports
The default transport uses window.postMessage, which serves as an integration point for external tools. You can provide custom transports for other environments:
import { createDevtools, memoryTransport } from "@naikidev/commiq-devtools-core";
// In-memory transport for testing
const transport = memoryTransport();
const devtools = createDevtools({ transport });
devtools.connect(store, "counter");
// Inspect captured messages
console.log(transport.messages);Implementing a Custom Transport
import type { Transport, DevtoolsMessage } from "@naikidev/commiq-devtools-core";
const customTransport: Transport = {
send(message: DevtoolsMessage) {
// Send to your backend, WebSocket, etc.
},
onMessage(handler) {
// Listen for incoming messages
return () => {
/* cleanup */
};
},
destroy() {
// Clean up resources
},
};
const devtools = createDevtools({ transport: customTransport });Options
| Option | Type | Default | Description |
|---|---|---|---|
transport | Transport | windowMessageTransport() | Message transport |
maxEvents | number | 1000 | Ring buffer size |
logToConsole | boolean | false | Log events to console |
Cleanup
// Disconnect a single store
devtools.disconnect("counter");
// Disconnect all stores and clean up
devtools.destroy();