ccstatelisted
Install: claude install-skill vm0-ai/vm0
# ccstate Patterns and Best Practices
This document records common patterns and best practices when using ccstate in the vm0 platform.
## DOM Callback Pattern
When handling DOM events (like button clicks) that trigger async commands, follow this pattern:
### Problem
DOM event handlers that call async commands will trigger TypeScript lint error `@typescript-eslint/no-floating-promises`.
### Solution
Use the `detach()` function with `Reason.DomCallback` to explicitly mark the promise as intentionally fire-and-forget.
### Pattern
```typescript
import { useSet, useGet } from "ccstate-react";
import { pageSignal$ } from "../../signals/page-signal.ts";
import { detach, Reason } from "../../signals/utils.ts";
import { someCommand$ } from "../../signals/some-command.ts";
function MyComponent() {
const commandFn = useSet(someCommand$);
const pageSignal = useGet(pageSignal$);
const handleClick = () => {
detach(commandFn(pageSignal), Reason.DomCallback);
};
return <button onClick={handleClick}>Click me</button>;
}
```
### Key Points
0. This pattern only applies to React views — it is forbidden to use in the signals directory
1. **Always use `pageSignal$`**: Get the page signal using `useGet(pageSignal$)` instead of creating a new `AbortController`
2. **Use `detach()` instead of `void`**: The `detach()` function properly handles promise rejection and tracks the promise for testing
3. **Use `Reason.DomCallback`**: This enum value indicates the promise is from a