Compare commits

...

2 Commits

Author SHA1 Message Date
Arjan Singh
712eead2d9 docs: simplify CLAUDE.md for feature flags and settings 2025-09-01 19:22:24 -07:00
Arjan Singh
4b3a56f744 docs: update stores README.md 2025-09-01 19:20:19 -07:00
2 changed files with 207 additions and 32 deletions

View File

@@ -82,39 +82,9 @@ When referencing Comfy-Org repos:
2. Use GitHub API for branches/PRs/metadata
3. Curl GitHub website if needed
## Settings and Feature Flags Quick Reference
## Settings and Feature Flags
### Settings Usage
```typescript
const settingStore = useSettingStore()
const value = settingStore.get('Comfy.SomeSetting') // Get setting
await settingStore.set('Comfy.SomeSetting', newValue) // Update setting
```
### Dynamic Defaults
```typescript
{
id: 'Comfy.Example.Setting',
defaultValue: () => window.innerWidth < 1024 ? 'small' : 'large' // Runtime context
}
```
### Version-Based Defaults
```typescript
{
id: 'Comfy.Example.Feature',
defaultValue: 'legacy',
defaultsByInstallVersion: { '1.25.0': 'enhanced' } // Gradual rollout
}
```
### Feature Flags
```typescript
if (api.serverSupportsFeature('feature_name')) { // Check capability
// Use enhanced feature
}
const value = api.getServerFeature('config_name', defaultValue) // Get config
```
Extensive capabilities to adding settings and feature flags. Read documentation.
**Documentation:**
- Settings system: `docs/SETTINGS.md`

View File

@@ -386,4 +386,209 @@ describe('useExampleStore', () => {
})
```
## ComfyUI-Specific Patterns
ComfyUI stores follow additional patterns specific to the application's architecture:
### WebSocket Message Handling
Many stores handle real-time updates via WebSocket messages. The execution store is a prime example:
```typescript
import { defineStore } from 'pinia'
import { ref } from 'vue'
import type { ExecutionStartWsMessage, ProgressWsMessage } from '@/schemas/apiSchema'
import { api } from '@/scripts/api'
export const useExecutionStore = defineStore('execution', () => {
const activePromptId = ref<string | null>(null)
const nodeProgressStates = ref<Record<string, NodeProgressState>>({})
// Register WebSocket event listeners
function registerEvents() {
api.addEventListener('execution_start', handleExecutionStart)
api.addEventListener('progress', handleProgress)
api.addEventListener('execution_error', handleExecutionError)
}
function handleExecutionStart(e: CustomEvent<ExecutionStartWsMessage>) {
activePromptId.value = e.detail.prompt_id
// Handle execution start
}
function handleProgress(e: CustomEvent<ProgressWsMessage>) {
// Update node progress states
const { value, max } = e.detail
// ... progress handling logic
}
// Clean up listeners when store is no longer needed
function unregisterEvents() {
api.removeEventListener('execution_start', handleExecutionStart)
api.removeEventListener('progress', handleProgress)
api.removeEventListener('execution_error', handleExecutionError)
}
return {
activePromptId,
nodeProgressStates,
registerEvents,
unregisterEvents
}
})
```
### Store Communication Patterns
ComfyUI stores frequently reference each other to maintain consistency across the application:
```typescript
import { defineStore } from 'pinia'
import { computed } from 'vue'
import { useCanvasStore } from './graphStore'
import { useWorkflowStore } from './workflowStore'
export const useExecutionStore = defineStore('execution', () => {
// Reference related stores
const workflowStore = useWorkflowStore()
const canvasStore = useCanvasStore()
// Computed values that depend on other stores
const activeWorkflow = computed(() => workflowStore.activeWorkflow)
// Actions that coordinate between stores
async function executeWorkflow() {
const workflow = workflowStore.serialize()
const canvas = canvasStore.canvas
// Execute with coordination between stores
}
return {
activeWorkflow,
executeWorkflow
}
})
```
### Extension Integration
Extensions can register with stores to extend functionality:
```typescript
import { defineStore } from 'pinia'
import { ref } from 'vue'
import type { ComfyExtension } from '@/types/comfy'
export const useExtensionStore = defineStore('extension', () => {
const extensionByName = ref<Record<string, ComfyExtension>>({})
function registerExtension(extension: ComfyExtension) {
if (!extension.name) {
throw new Error("Extensions must have a 'name' property.")
}
if (extensionByName.value[extension.name]) {
console.warn(`Extension ${extension.name} already registered. Overwriting.`)
}
extensionByName.value[extension.name] = extension
// Call extension setup if provided
if (extension.setup) {
extension.setup()
}
}
function isExtensionEnabled(extensionName: string): boolean {
const extension = extensionByName.value[extensionName]
return extension && !extension.disabled
}
return {
extensionByName: readonly(extensionByName),
registerExtension,
isExtensionEnabled
}
})
```
### Workspace Store Organization
ComfyUI uses a two-tier store organization:
1. **Main stores** (`src/stores/*.ts`) - Core application logic
2. **Workspace stores** (`src/stores/workspace/*.ts`) - UI layout and workspace-specific state
The `useWorkspaceStore` acts as a coordinator, providing computed access to other stores:
```typescript
import { defineStore } from 'pinia'
import { computed } from 'vue'
import { useWorkflowStore } from './workflowStore'
import { useBottomPanelStore } from './workspace/bottomPanelStore'
import { useSidebarTabStore } from './workspace/sidebarTabStore'
export const useWorkspaceStore = defineStore('workspace', () => {
const focusMode = ref(false)
// Provide unified access to related stores
const workflow = computed(() => useWorkflowStore())
const sidebarTab = computed(() => useSidebarTabStore())
const bottomPanel = computed(() => useBottomPanelStore())
// Workspace-level actions that coordinate multiple stores
function toggleFocusMode() {
focusMode.value = !focusMode.value
// Hide/show panels based on focus mode
if (focusMode.value) {
bottomPanel.value.hide()
sidebarTab.value.closeTabs()
}
}
return {
focusMode,
workflow,
sidebarTab,
bottomPanel,
toggleFocusMode
}
})
```
### Node and Workflow State Management
ComfyUI stores often work with node and workflow concepts:
```typescript
import { defineStore } from 'pinia'
import { ref, computed } from 'vue'
import type { ComfyWorkflow, NodeId } from '@/schemas/comfyWorkflowSchema'
export const useWorkflowStore = defineStore('workflow', () => {
const activeWorkflow = ref<ComfyWorkflow | null>(null)
// Convert node ID to a locator for cross-store communication
function nodeIdToNodeLocatorId(nodeId: NodeId): NodeLocatorId {
return createNodeLocatorId(activeWorkflow.value?.path, nodeId)
}
// Serialize current workflow for execution
function serialize(): ComfyApiWorkflow {
if (!activeWorkflow.value) {
throw new Error('No active workflow to serialize')
}
return convertToApiFormat(activeWorkflow.value)
}
return {
activeWorkflow,
nodeIdToNodeLocatorId,
serialize
}
})
```
These patterns ensure that ComfyUI stores work together effectively to manage the complex state of a node-based workflow editor.
For more information on Pinia, refer to the [Pinia documentation](https://pinia.vuejs.org/introduction.html).