{"$schema":"https:\/\/ui.particle.academy\/schema\/registry-item.json","name":"screen-system","type":"registry:ui","title":"ScreenSystem","description":"Root provider.","package":"fancy-screens","dependencies":[],"registryDependencies":[],"files":[{"path":"components\/fancy\/screen-system\/ScreenSystem.tsx","content":"import { useMemo, useRef, useState, type ReactNode } from \"react\";\r\nimport { ScreenSystemContext, type ScreenSystemValue } from \".\/ScreenSystem.context\";\r\nimport type { RegisteredStore, ScreenMeta } from \".\/Screen.types\";\r\n\r\ninterface ScreenSystemProps {\r\n  children?: ReactNode;\r\n}\r\n\r\n\/**\r\n * Root provider for fancy-screens. Wrap your app once. Owns the screen\r\n * registry and a Map of registered Zustand stores. Without this,\r\n * `<Screen>` and `useScreens()` will throw.\r\n *\/\r\nexport function ScreenSystem({ children }: ScreenSystemProps) {\r\n  const registryRef = useRef<Map<string, ScreenMeta>>(new Map());\r\n  const storesRef = useRef<Map<string, RegisteredStore>>(new Map());\r\n  const [registryVersion, setRegistryVersion] = useState(0);\r\n\r\n  const value = useMemo<ScreenSystemValue>(() => {\r\n    const bump = () => setRegistryVersion((v) => v + 1);\r\n    return {\r\n      registry: registryRef.current,\r\n      registryVersion,\r\n      stores: storesRef.current,\r\n      registerScreen: (meta) => {\r\n        registryRef.current.set(meta.id, meta);\r\n        bump();\r\n      },\r\n      updateScreen: (id, patch) => {\r\n        const existing = registryRef.current.get(id);\r\n        if (!existing) return;\r\n        registryRef.current.set(id, { ...existing, ...patch });\r\n        bump();\r\n      },\r\n      unregisterScreen: (id) => {\r\n        registryRef.current.delete(id);\r\n        \/\/ Drop any stores registered to this screen so the maps don't drift.\r\n        const prefix = `${id}.`;\r\n        for (const key of storesRef.current.keys()) {\r\n          if (key.startsWith(prefix)) storesRef.current.delete(key);\r\n        }\r\n        bump();\r\n      },\r\n      registerStore: (key, store) => {\r\n        storesRef.current.set(key, store);\r\n        \/\/ Patch the storeKeys array on the owning screen so consumers can\r\n        \/\/ enumerate stores without scanning the global map.\r\n        const [screenId, storeName] = key.split(\".\");\r\n        if (screenId && storeName) {\r\n          const existing = registryRef.current.get(screenId);\r\n          if (existing && !existing.storeKeys.includes(storeName)) {\r\n            registryRef.current.set(screenId, {\r\n              ...existing,\r\n              storeKeys: [...existing.storeKeys, storeName],\r\n            });\r\n          }\r\n        }\r\n        bump();\r\n        return () => {\r\n          storesRef.current.delete(key);\r\n          if (screenId && storeName) {\r\n            const existing = registryRef.current.get(screenId);\r\n            if (existing) {\r\n              registryRef.current.set(screenId, {\r\n                ...existing,\r\n                storeKeys: existing.storeKeys.filter((n) => n !== storeName),\r\n              });\r\n            }\r\n          }\r\n          bump();\r\n        };\r\n      },\r\n    };\r\n  }, [registryVersion]);\r\n\r\n  return (\r\n    <ScreenSystemContext.Provider value={value}>{children}<\/ScreenSystemContext.Provider>\r\n  );\r\n}\r\n\r\nScreenSystem.displayName = \"ScreenSystem\";\r\n","type":"registry:ui","target":"components\/fancy\/screen-system\/ScreenSystem.tsx"}]}