mirror of
https://github.com/Comfy-Org/ComfyUI_frontend.git
synced 2026-02-11 02:20:08 +00:00
- Create reactive featureFlagsStore for centralized feature flag management - Fix race conditions in feature flag updates with version tracking - Make managerStateStore properly reactive to feature flag changes - Add useManagerHelper composable as single entry point for opening manager - Fix Legacy UI keybinding fallback to new manager when appropriate - Update WebSocket handler to sync feature flags with reactive store - Add comprehensive tests for all manager UI states This ensures the Manager UI state (NEW_UI, LEGACY_UI, DISABLED) updates reactively when feature flags change, fixing the issue where manager state wasn't properly responding to server capability changes. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
140 lines
3.7 KiB
TypeScript
140 lines
3.7 KiB
TypeScript
import { get } from 'es-toolkit/compat'
|
|
import { defineStore } from 'pinia'
|
|
import { computed, nextTick, ref } from 'vue'
|
|
|
|
/**
|
|
* Store for managing server and client feature flags reactively
|
|
*/
|
|
export const useFeatureFlagsStore = defineStore('featureFlags', () => {
|
|
// Server feature flags received from WebSocket
|
|
const serverFlags = ref<Record<string, unknown>>({})
|
|
|
|
// Client feature flags (local)
|
|
const clientFlags = ref<Record<string, unknown>>({})
|
|
|
|
// Flag to indicate if the store has received initial server flags
|
|
const isReady = ref(false)
|
|
|
|
// Track update version to prevent race conditions
|
|
let updateVersion = 0
|
|
|
|
/**
|
|
* Update server feature flags
|
|
* Called when WebSocket receives feature_flags message
|
|
*/
|
|
function updateServerFlags(flags: Record<string, unknown>) {
|
|
// Validate input
|
|
if (!flags || typeof flags !== 'object') {
|
|
console.error('[FeatureFlags] Invalid flags received:', flags)
|
|
return
|
|
}
|
|
|
|
// Increment version for this update
|
|
const currentVersion = ++updateVersion
|
|
|
|
// Use nextTick to batch updates and check version
|
|
void nextTick(() => {
|
|
// Only apply if this is still the latest update
|
|
if (currentVersion === updateVersion) {
|
|
serverFlags.value = { ...flags }
|
|
isReady.value = true
|
|
console.log('[FeatureFlags] Server flags updated:', serverFlags.value)
|
|
} else {
|
|
console.log(
|
|
'[FeatureFlags] Skipping outdated update, version:',
|
|
currentVersion
|
|
)
|
|
}
|
|
})
|
|
}
|
|
|
|
/**
|
|
* Update client feature flags
|
|
*/
|
|
function updateClientFlags(flags: Record<string, unknown>) {
|
|
clientFlags.value = { ...flags }
|
|
console.log('[FeatureFlags] Client flags updated:', clientFlags.value)
|
|
}
|
|
|
|
/**
|
|
* Get a server feature flag value (reactive)
|
|
*/
|
|
function getServerFeature<T = unknown>(
|
|
featurePath: string,
|
|
defaultValue?: T
|
|
): T {
|
|
return get(serverFlags.value, featurePath, defaultValue) as T
|
|
}
|
|
|
|
/**
|
|
* Check if server supports a feature (reactive)
|
|
*/
|
|
function serverSupportsFeature(featurePath: string): boolean {
|
|
return get(serverFlags.value, featurePath) === true
|
|
}
|
|
|
|
/**
|
|
* Get a client feature flag value (reactive)
|
|
*/
|
|
function getClientFeature<T = unknown>(
|
|
featurePath: string,
|
|
defaultValue?: T
|
|
): T {
|
|
return get(clientFlags.value, featurePath, defaultValue) as T
|
|
}
|
|
|
|
/**
|
|
* Computed property for manager v4 support
|
|
*/
|
|
const supportsManagerV4 = computed<boolean>(() => {
|
|
return (
|
|
getServerFeature<boolean>('extension.manager.supports_v4', false) === true
|
|
)
|
|
})
|
|
|
|
/**
|
|
* Computed property for client manager v4 UI support
|
|
*/
|
|
const clientSupportsManagerV4UI = computed<boolean>(() => {
|
|
return getClientFeature<boolean>('supports_manager_v4_ui', false) === true
|
|
})
|
|
|
|
/**
|
|
* Reset store state (useful for reconnection)
|
|
*/
|
|
function resetStore() {
|
|
console.log('[FeatureFlags] Resetting store state')
|
|
serverFlags.value = {}
|
|
isReady.value = false
|
|
// Note: We don't reset clientFlags as they're local
|
|
// Increment version to invalidate any pending updates
|
|
updateVersion++
|
|
}
|
|
|
|
/**
|
|
* Cleanup store (for unmounting or preventing memory leaks)
|
|
*/
|
|
function cleanup() {
|
|
console.log('[FeatureFlags] Cleaning up store')
|
|
resetStore()
|
|
clientFlags.value = {}
|
|
// Cancel any pending nextTick callbacks by incrementing version
|
|
updateVersion = Number.MAX_SAFE_INTEGER
|
|
}
|
|
|
|
return {
|
|
serverFlags,
|
|
clientFlags,
|
|
isReady,
|
|
updateServerFlags,
|
|
updateClientFlags,
|
|
getServerFeature,
|
|
serverSupportsFeature,
|
|
getClientFeature,
|
|
supportsManagerV4,
|
|
clientSupportsManagerV4UI,
|
|
resetStore,
|
|
cleanup
|
|
}
|
|
})
|