@hai3/framework 0.2.0-alpha.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CLAUDE.md +161 -0
- package/commands/hai3-fix-violation.md +48 -0
- package/commands/hai3-new-action.md +120 -0
- package/commands/hai3-quick-ref.md +63 -0
- package/commands/hai3-rules.md +43 -0
- package/commands/hai3-validate.md +49 -0
- package/dist/index.cjs +1397 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +842 -0
- package/dist/index.d.ts +842 -0
- package/dist/index.js +1264 -0
- package/dist/index.js.map +1 -0
- package/dist/types.cjs +19 -0
- package/dist/types.cjs.map +1 -0
- package/dist/types.d.cts +440 -0
- package/dist/types.d.ts +440 -0
- package/dist/types.js +1 -0
- package/dist/types.js.map +1 -0
- package/llms.txt +52 -0
- package/package.json +57 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/createHAI3.ts","../src/plugins/screensets.ts","../src/slices/index.ts","../src/slices/headerSlice.ts","../src/slices/footerSlice.ts","../src/slices/menuSlice.ts","../src/slices/sidebarSlice.ts","../src/slices/screenSlice.ts","../src/slices/popupSlice.ts","../src/slices/overlaySlice.ts","../src/slices/tenantSlice.ts","../src/plugins/themes.ts","../src/compat.ts","../src/registries/themeRegistry.ts","../src/registries/routeRegistry.ts","../src/plugins/layout.ts","../src/plugins/navigation.ts","../src/plugins/routing.ts","../src/plugins/i18n.ts","../src/plugins/effects.ts","../src/presets/index.ts","../src/createHAI3App.ts","../src/registries/index.ts","../src/index.ts","../src/effects/tenantEffects.ts","../src/migration.ts"],"sourcesContent":["/**\n * createHAI3 - App Builder Factory\n *\n * Creates a HAI3 app builder for custom plugin composition.\n * This is the core of the plugin architecture.\n *\n * Framework Layer: L2 (Depends on SDK packages)\n */\n\nimport { getStore, registerSlice } from '@hai3/state';\nimport type { EffectInitializer } from '@hai3/state';\nimport type {\n HAI3Config,\n HAI3Plugin,\n HAI3AppBuilder,\n HAI3App,\n HAI3Actions,\n HAI3Store,\n PluginFactory,\n RegisterableSlice,\n ScreensetRegistry,\n ThemeRegistry,\n RouteRegistry,\n} from './types';\nimport { apiRegistry } from '@hai3/api';\n\n// ============================================================================\n// Plugin Resolution\n// ============================================================================\n\n/**\n * Check if value is a plugin factory function\n */\nfunction isPluginFactory(\n value: HAI3Plugin | PluginFactory\n): value is PluginFactory {\n return typeof value === 'function';\n}\n\n/**\n * Resolve plugin - if it's a factory, call it; otherwise return as-is\n */\nfunction resolvePlugin(plugin: HAI3Plugin | PluginFactory): HAI3Plugin {\n return isPluginFactory(plugin) ? plugin() : plugin;\n}\n\n// ============================================================================\n// App Builder Implementation\n// ============================================================================\n\n/**\n * HAI3 App Builder Implementation\n */\nclass HAI3AppBuilderImpl implements HAI3AppBuilder {\n private plugins: HAI3Plugin[] = [];\n private config: HAI3Config;\n\n constructor(config: HAI3Config = {}) {\n this.config = {\n name: 'HAI3 App',\n devMode: false,\n strictMode: false,\n ...config,\n };\n }\n\n /**\n * Add a plugin to the application.\n * Also accepts an array of plugins (for preset support).\n */\n use(plugin: HAI3Plugin | PluginFactory | HAI3Plugin[]): HAI3AppBuilder {\n // Handle arrays (presets return arrays)\n if (Array.isArray(plugin)) {\n plugin.forEach((p) => this.use(p));\n return this;\n }\n\n const resolved = resolvePlugin(plugin);\n\n // Check if plugin already registered\n if (this.plugins.some((p) => p.name === resolved.name)) {\n if (this.config.devMode) {\n console.warn(\n `Plugin \"${resolved.name}\" is already registered. Skipping duplicate.`\n );\n }\n return this;\n }\n\n this.plugins.push(resolved);\n return this;\n }\n\n /**\n * Add multiple plugins at once.\n */\n useAll(plugins: Array<HAI3Plugin | PluginFactory>): HAI3AppBuilder {\n plugins.forEach((plugin) => this.use(plugin));\n return this;\n }\n\n /**\n * Build the application.\n */\n build(): HAI3App {\n // 1. Resolve dependencies and order plugins\n const orderedPlugins = this.resolveDependencies();\n\n // 2. Call onRegister for each plugin\n orderedPlugins.forEach((plugin) => {\n if (plugin.onRegister) {\n plugin.onRegister(this, plugin._configType);\n }\n });\n\n // 3. Aggregate all provides\n const aggregated = this.aggregateProvides(orderedPlugins);\n\n // 4. Create store with aggregated slices\n const store = this.createStoreWithSlices(aggregated.slices);\n\n // 5. Initialize effects\n aggregated.effects.forEach((initEffect) => {\n initEffect(store.dispatch);\n });\n\n // 6. Build the app object\n // Cast actions to HAI3Actions - all plugins have contributed their actions\n // via module augmentation, so the runtime object matches the declared type\n const app: HAI3App = {\n config: this.config,\n store: store as HAI3Store,\n screensetRegistry: aggregated.registries.screensetRegistry as ScreensetRegistry,\n themeRegistry: aggregated.registries.themeRegistry as ThemeRegistry,\n routeRegistry: aggregated.registries.routeRegistry as RouteRegistry,\n apiRegistry: apiRegistry,\n i18nRegistry: aggregated.registries.i18nRegistry as HAI3App['i18nRegistry'],\n actions: aggregated.actions as HAI3Actions,\n destroy: () => this.destroyApp(orderedPlugins, app),\n };\n\n // 7. Call onInit for each plugin\n orderedPlugins.forEach((plugin) => {\n if (plugin.onInit) {\n plugin.onInit(app);\n }\n });\n\n return app;\n }\n\n /**\n * Resolve plugin dependencies using topological sort.\n */\n private resolveDependencies(): HAI3Plugin[] {\n const resolved: HAI3Plugin[] = [];\n const visited = new Set<string>();\n const visiting = new Set<string>();\n\n const visit = (plugin: HAI3Plugin) => {\n if (visited.has(plugin.name)) return;\n\n if (visiting.has(plugin.name)) {\n throw new Error(\n `Circular dependency detected: ${plugin.name} depends on itself or creates a cycle.`\n );\n }\n\n visiting.add(plugin.name);\n\n // Process dependencies first\n if (plugin.dependencies) {\n for (const depName of plugin.dependencies) {\n const dep = this.plugins.find((p) => p.name === depName);\n\n if (!dep) {\n if (this.config.strictMode) {\n throw new Error(\n `Plugin \"${plugin.name}\" requires \"${depName}\" but it is not registered.\\n` +\n `Add the missing plugin: .use(${depName}())`\n );\n } else {\n console.warn(\n `Plugin \"${plugin.name}\" requires \"${depName}\" but it is not registered. ` +\n `Some features may not work correctly.`\n );\n continue;\n }\n }\n\n visit(dep);\n }\n }\n\n visiting.delete(plugin.name);\n visited.add(plugin.name);\n resolved.push(plugin);\n };\n\n this.plugins.forEach(visit);\n return resolved;\n }\n\n /**\n * Aggregate all provides from plugins.\n */\n private aggregateProvides(plugins: HAI3Plugin[]) {\n const registries: Record<string, unknown> = {};\n const slices: RegisterableSlice[] = [];\n const effects: EffectInitializer[] = [];\n // Actions are typed via module augmentation - each plugin declares its actions\n // in HAI3Actions interface. At runtime we merge them all together.\n const actions: Partial<HAI3Actions> = {};\n\n plugins.forEach((plugin) => {\n if (!plugin.provides) return;\n\n // Merge registries\n if (plugin.provides.registries) {\n Object.assign(registries, plugin.provides.registries);\n }\n\n // Collect slices\n if (plugin.provides.slices) {\n slices.push(...plugin.provides.slices);\n }\n\n // Collect effects\n if (plugin.provides.effects) {\n effects.push(...plugin.provides.effects);\n }\n\n // Merge actions (type-safe via HAI3Actions module augmentation)\n if (plugin.provides.actions) {\n Object.assign(actions, plugin.provides.actions);\n }\n });\n\n return { registries, slices, effects, actions };\n }\n\n /**\n * Create store with all aggregated slices.\n *\n * IMPORTANT: This method supports the screenset self-registration pattern.\n * Screensets call registerSlice() as module side effects when imported,\n * which may auto-create a store before createHAI3App() is called.\n *\n * This method:\n * 1. Uses the existing store if one was auto-created by screensets\n * 2. Registers framework slices to the existing store\n * 3. Returns the unified store for HAI3App\n */\n private createStoreWithSlices(slices: RegisterableSlice[]): HAI3Store {\n // Get existing store (may have been created by screenset registerSlice calls)\n // getStore() auto-creates if none exists\n const store = getStore();\n\n // Register framework slices using registerSlice (merges with dynamic slices)\n slices.forEach((slice) => {\n registerSlice(slice);\n });\n\n return store;\n }\n\n /**\n * Destroy the app and cleanup resources.\n */\n private destroyApp(plugins: HAI3Plugin[], app: HAI3App): void {\n // Call onDestroy in reverse order\n [...plugins].reverse().forEach((plugin) => {\n if (plugin.onDestroy) {\n plugin.onDestroy(app);\n }\n });\n }\n}\n\n// ============================================================================\n// Factory Function\n// ============================================================================\n\n/**\n * Create a HAI3 app builder for custom plugin composition.\n *\n * @param config - Optional application configuration\n * @returns App builder for plugin composition\n *\n * @example\n * ```typescript\n * const app = createHAI3()\n * .use(screensets())\n * .use(themes())\n * .build();\n * ```\n */\nexport function createHAI3(config?: HAI3Config): HAI3AppBuilder {\n return new HAI3AppBuilderImpl(config);\n}\n","/**\n * Screensets Plugin - Provides screenset registry and screen slice\n *\n * This is the minimal plugin for screenset orchestration.\n * It does NOT include navigation actions - those are in the navigation plugin.\n *\n * Framework Layer: L2\n *\n * NOTE: Translations are NOT handled by this plugin. Screensets register\n * their translations directly with i18nRegistry via framework re-exports.\n * This maintains clean separation: @hai3/screensets has zero knowledge of i18n.\n */\n\nimport type { UnknownAction } from '@reduxjs/toolkit';\nimport { screensetRegistry as sdkScreensetRegistry } from '@hai3/screensets';\nimport { screenSlice as screenSliceImport, screenActions as screenActionsImport } from '../slices';\nimport type { HAI3Plugin, ScreensetsConfig, RegisterableSlice, ScreensetRegistry } from '../types';\n\n// Type assertions for slice imports (needed for plugin system compatibility)\nconst screenSlice = screenSliceImport as unknown as RegisterableSlice;\ntype ActionCreators = Record<string, (payload?: unknown) => UnknownAction>;\nconst screenActions = screenActionsImport as unknown as ActionCreators;\n\n/**\n * Screensets plugin factory.\n *\n * @param config - Plugin configuration\n * @returns Screensets plugin\n *\n * @example\n * ```typescript\n * const app = createHAI3()\n * .use(screensets({ autoDiscover: true }))\n * .build();\n * ```\n */\nexport function screensets(config?: ScreensetsConfig): HAI3Plugin<ScreensetsConfig> {\n // Use the singleton SDK registry - user screensets register to this\n const screensetRegistry = sdkScreensetRegistry as ScreensetRegistry;\n\n return {\n name: 'screensets',\n dependencies: [],\n\n provides: {\n registries: {\n screensetRegistry,\n },\n slices: [screenSlice],\n actions: {\n setActiveScreen: screenActions.navigateTo,\n setScreenLoading: screenActions.setScreenLoading,\n },\n },\n\n onInit() {\n // Auto-discover screensets if configured\n // Note: In Vite apps, this is handled by glob imports in user code\n if (config?.autoDiscover) {\n console.log(\n '[HAI3] Auto-discover is enabled. ' +\n 'Screensets should be registered via screensetRegistry.register() in your app.'\n );\n }\n\n // NOTE: Translation wiring is NOT done here.\n // Screensets register translations directly with i18nRegistry.\n // This keeps @hai3/screensets free of i18n dependencies.\n },\n };\n}\n","/**\n * Layout Slices\n *\n * @hai3/framework owns all layout domain slices.\n * These slices manage header, footer, menu, sidebar, screen, popup, and overlay state.\n *\n * State access: Components use `useAppSelector` hook from @hai3/react.\n */\n\nimport { combineReducers, type Reducer } from '@reduxjs/toolkit';\nimport type {\n HeaderState,\n FooterState,\n MenuState,\n SidebarState,\n ScreenState,\n OverlayState,\n} from '../layoutTypes';\n\n// Import slice reducers\nimport headerReducer, { headerSlice, headerActions, setUser, setLoading as setHeaderLoading, clearUser } from './headerSlice';\nimport footerReducer, { footerSlice, footerActions, setFooterVisible, setFooterConfig } from './footerSlice';\nimport menuReducer, {\n menuSlice,\n menuActions,\n toggleMenu,\n setMenuCollapsed,\n setMenuItems,\n setMenuVisible,\n setMenuConfig,\n} from './menuSlice';\nimport sidebarReducer, {\n sidebarSlice,\n sidebarActions,\n toggleSidebar,\n setSidebarCollapsed,\n setSidebarPosition,\n setSidebarTitle,\n setSidebarContent,\n setSidebarVisible,\n setSidebarWidth,\n setSidebarConfig,\n} from './sidebarSlice';\nimport screenReducer, {\n screenSlice,\n screenActions,\n setActiveScreen,\n setScreenLoading,\n navigateTo,\n clearActiveScreen,\n} from './screenSlice';\nimport popupReducer, {\n popupSlice,\n popupActions,\n openPopup,\n closePopup,\n closeTopPopup,\n closeAllPopups,\n type PopupSliceState,\n} from './popupSlice';\nimport overlayReducer, {\n overlaySlice,\n overlayActions,\n showOverlay,\n hideOverlay,\n setOverlayVisible,\n} from './overlaySlice';\nimport tenantReducer, {\n tenantSlice,\n tenantActions,\n setTenant,\n setTenantLoading,\n clearTenant,\n} from './tenantSlice';\n\n// ============================================================================\n// Constants\n// ============================================================================\n\nexport const LAYOUT_SLICE_NAME = 'layout' as const;\nexport const TENANT_SLICE_NAME = 'app/tenant' as const;\n\n// ============================================================================\n// Combined Layout Reducer\n// ============================================================================\n\n/** Explicit type for layout domain reducers to avoid incorrect dts generation */\nexport interface LayoutDomainReducersType {\n header: Reducer<HeaderState>;\n footer: Reducer<FooterState>;\n menu: Reducer<MenuState>;\n sidebar: Reducer<SidebarState>;\n screen: Reducer<ScreenState>;\n popup: Reducer<PopupSliceState>;\n overlay: Reducer<OverlayState>;\n}\n\nexport const layoutDomainReducers: LayoutDomainReducersType = {\n header: headerReducer,\n footer: footerReducer,\n menu: menuReducer,\n sidebar: sidebarReducer,\n screen: screenReducer,\n popup: popupReducer,\n overlay: overlayReducer,\n};\n\nexport const layoutReducer = combineReducers(layoutDomainReducers);\n\n// ============================================================================\n// Slice Exports\n// ============================================================================\n\nexport {\n // Slices\n headerSlice,\n footerSlice,\n menuSlice,\n sidebarSlice,\n screenSlice,\n popupSlice,\n overlaySlice,\n // Action groups\n headerActions,\n // Individual actions - header\n setUser,\n setHeaderLoading,\n clearUser,\n footerActions,\n menuActions,\n sidebarActions,\n screenActions,\n popupActions,\n overlayActions,\n // Individual actions - footer\n setFooterVisible,\n setFooterConfig,\n // Individual actions - menu\n toggleMenu,\n setMenuCollapsed,\n setMenuItems,\n setMenuVisible,\n setMenuConfig,\n // Individual actions - sidebar\n toggleSidebar,\n setSidebarCollapsed,\n setSidebarPosition,\n setSidebarTitle,\n setSidebarContent,\n setSidebarVisible,\n setSidebarWidth,\n setSidebarConfig,\n // Individual actions - screen\n setActiveScreen,\n setScreenLoading,\n navigateTo,\n clearActiveScreen,\n // Individual actions - popup\n openPopup,\n closePopup,\n closeTopPopup,\n closeAllPopups,\n // Individual actions - overlay\n showOverlay,\n hideOverlay,\n setOverlayVisible,\n // Tenant slice (app-level, not layout)\n tenantSlice,\n tenantActions,\n tenantReducer,\n // Individual actions - tenant\n setTenant,\n setTenantLoading,\n clearTenant,\n};\n\n// Type exports\nexport type { PopupSliceState };\n","import { createSlice, type ReducerPayload } from '@hai3/state';\nimport type { HeaderState, HeaderUser } from '../layoutTypes';\n\n/**\n * Header slice for managing header state including user info\n */\n\nconst SLICE_KEY = 'layout/header' as const;\n\nconst initialState: HeaderState = {\n user: null,\n loading: false,\n};\n\nconst { slice, setUser, setLoading, clearUser } = createSlice({\n name: SLICE_KEY,\n initialState,\n reducers: {\n setUser: (state, action: ReducerPayload<HeaderUser | null>) => {\n state.user = action.payload;\n state.loading = false;\n },\n setLoading: (state, action: ReducerPayload<boolean>) => {\n state.loading = action.payload;\n },\n clearUser: (state) => {\n state.user = null;\n state.loading = false;\n },\n },\n});\n\nexport const headerSlice = slice;\nexport const headerActions = { setUser, setLoading, clearUser };\n\nexport { setUser, setLoading, clearUser };\n\nexport default slice.reducer;\n","import { createSlice, type ReducerPayload } from '@hai3/state';\nimport type { FooterState } from '../layoutTypes';\n\n/**\n * Footer slice for managing footer configuration\n */\n\nconst SLICE_KEY = 'layout/footer' as const;\n\nconst initialState: FooterState = {\n screensetOptions: [],\n visible: true,\n};\n\nconst { slice, setFooterVisible, setFooterConfig, ...restActions } = createSlice({\n name: SLICE_KEY,\n initialState,\n reducers: {\n setFooterVisible: (state, action: ReducerPayload<boolean>) => {\n state.visible = action.payload;\n },\n setFooterConfig: (state, action: ReducerPayload<Partial<FooterState>>) => {\n return { ...state, ...action.payload };\n },\n },\n});\n\nexport const footerSlice = slice;\nexport { setFooterVisible, setFooterConfig };\nexport const footerActions = { setFooterVisible, setFooterConfig, ...restActions };\n\nexport default slice.reducer;\n","import { createSlice, type ReducerPayload } from '@hai3/state';\nimport type { MenuItem, MenuState } from '../layoutTypes';\n\n/**\n * Menu slice for managing menu state and configuration\n * MenuItem type is defined in layoutTypes.ts\n */\n\nconst SLICE_KEY = 'layout/menu' as const;\n\nconst initialState: MenuState = {\n collapsed: false,\n items: [],\n visible: true,\n};\n\nconst { slice, toggleMenu, setMenuCollapsed, setMenuItems, setMenuVisible, setMenuConfig } = createSlice({\n name: SLICE_KEY,\n initialState,\n reducers: {\n toggleMenu: (state) => {\n state.collapsed = !state.collapsed;\n },\n setMenuCollapsed: (state, action: ReducerPayload<boolean>) => {\n state.collapsed = action.payload;\n },\n setMenuItems: (state, action: ReducerPayload<MenuItem[]>) => {\n state.items = action.payload;\n },\n setMenuVisible: (state, action: ReducerPayload<boolean>) => {\n state.visible = action.payload;\n },\n setMenuConfig: (state, action: ReducerPayload<Partial<MenuState>>) => {\n return { ...state, ...action.payload };\n },\n },\n});\n\nexport const menuSlice = slice;\nexport { toggleMenu, setMenuCollapsed, setMenuItems, setMenuVisible, setMenuConfig };\nexport const menuActions = { toggleMenu, setMenuCollapsed, setMenuItems, setMenuVisible, setMenuConfig };\n\nexport default slice.reducer;\n","import { createSlice, type ReducerPayload } from '@hai3/state';\nimport type { SidebarState, SidebarPosition } from '../layoutTypes';\n\n/**\n * Sidebar slice for managing sidebar state and configuration\n */\n\nconst SLICE_KEY = 'layout/sidebar' as const;\n\nconst initialState: SidebarState = {\n collapsed: false,\n position: 'left',\n title: null,\n content: null,\n visible: false,\n width: 256,\n};\n\nconst {\n slice,\n toggleSidebar,\n setSidebarCollapsed,\n setSidebarPosition,\n setSidebarTitle,\n setSidebarContent,\n setSidebarVisible,\n setSidebarWidth,\n setSidebarConfig,\n} = createSlice({\n name: SLICE_KEY,\n initialState,\n reducers: {\n toggleSidebar: (state) => {\n state.collapsed = !state.collapsed;\n },\n setSidebarCollapsed: (state, action: ReducerPayload<boolean>) => {\n state.collapsed = action.payload;\n },\n setSidebarPosition: (state, action: ReducerPayload<SidebarPosition>) => {\n state.position = action.payload;\n },\n setSidebarTitle: (state, action: ReducerPayload<string | null>) => {\n state.title = action.payload;\n },\n setSidebarContent: (state, action: ReducerPayload<unknown>) => {\n state.content = action.payload;\n },\n setSidebarVisible: (state, action: ReducerPayload<boolean>) => {\n state.visible = action.payload;\n },\n setSidebarWidth: (state, action: ReducerPayload<number>) => {\n state.width = action.payload;\n },\n setSidebarConfig: (state, action: ReducerPayload<Partial<SidebarState>>) => {\n return { ...state, ...action.payload };\n },\n },\n});\n\nexport const sidebarSlice = slice;\nexport {\n toggleSidebar,\n setSidebarCollapsed,\n setSidebarPosition,\n setSidebarTitle,\n setSidebarContent,\n setSidebarVisible,\n setSidebarWidth,\n setSidebarConfig,\n};\nexport const sidebarActions = {\n toggleSidebar,\n setSidebarCollapsed,\n setSidebarPosition,\n setSidebarTitle,\n setSidebarContent,\n setSidebarVisible,\n setSidebarWidth,\n setSidebarConfig,\n};\n\nexport default slice.reducer;\n","import { createSlice, type ReducerPayload } from '@hai3/state';\nimport type { ScreenState } from '../layoutTypes';\n\n/**\n * Screen slice for managing screen state\n */\n\nconst SLICE_KEY = 'layout/screen' as const;\n\nconst initialState: ScreenState = {\n activeScreen: null,\n loading: false,\n};\n\nconst { slice, setActiveScreen, setScreenLoading, navigateTo, clearActiveScreen } = createSlice({\n name: SLICE_KEY,\n initialState,\n reducers: {\n setActiveScreen: (state, action: ReducerPayload<string>) => {\n state.activeScreen = action.payload;\n },\n setScreenLoading: (state, action: ReducerPayload<boolean>) => {\n state.loading = action.payload;\n },\n navigateTo: (state, action: ReducerPayload<string>) => {\n state.activeScreen = action.payload;\n },\n clearActiveScreen: (state) => {\n state.activeScreen = null;\n },\n },\n});\n\nexport const screenSlice = slice;\nexport { setActiveScreen, setScreenLoading, navigateTo, clearActiveScreen };\nexport const screenActions = { setActiveScreen, setScreenLoading, navigateTo, clearActiveScreen };\n\nexport default slice.reducer;\n","import { createSlice, type ReducerPayload } from '@hai3/state';\nimport type { PopupState } from '../layoutTypes';\n\n/**\n * Popup slice for managing popup state\n */\n\nconst SLICE_KEY = 'layout/popup' as const;\n\nexport interface PopupSliceState {\n stack: PopupState[];\n}\n\nconst initialState: PopupSliceState = {\n stack: [],\n};\n\nconst { slice, openPopup, closePopup, closeTopPopup, closeAllPopups } = createSlice({\n name: SLICE_KEY,\n initialState,\n reducers: {\n openPopup: (state, action: ReducerPayload<Omit<PopupState, 'zIndex'>>) => {\n const zIndex = 1000 + state.stack.length * 10;\n state.stack.push({ ...action.payload, zIndex });\n },\n closePopup: (state, action: ReducerPayload<string>) => {\n state.stack = state.stack.filter((popup) => popup.id !== action.payload);\n },\n closeTopPopup: (state) => {\n state.stack.pop();\n },\n closeAllPopups: (state) => {\n state.stack = [];\n },\n },\n});\n\nexport const popupSlice = slice;\nexport { openPopup, closePopup, closeTopPopup, closeAllPopups };\nexport const popupActions = { openPopup, closePopup, closeTopPopup, closeAllPopups };\n\nexport default slice.reducer;\n","import { createSlice, type ReducerPayload } from '@hai3/state';\nimport type { OverlayState } from '../layoutTypes';\n\n/**\n * Overlay slice for managing overlay state\n */\n\nconst SLICE_KEY = 'layout/overlay' as const;\n\nconst initialState: OverlayState = {\n visible: false,\n};\n\nconst { slice, showOverlay, hideOverlay, setOverlayVisible } = createSlice({\n name: SLICE_KEY,\n initialState,\n reducers: {\n showOverlay: (state) => {\n state.visible = true;\n },\n hideOverlay: (state) => {\n state.visible = false;\n },\n setOverlayVisible: (state, action: ReducerPayload<boolean>) => {\n state.visible = action.payload;\n },\n },\n});\n\nexport const overlaySlice = slice;\nexport { showOverlay, hideOverlay, setOverlayVisible };\nexport const overlayActions = { showOverlay, hideOverlay, setOverlayVisible };\n\nexport default slice.reducer;\n","import { createSlice, type ReducerPayload } from '@hai3/state';\nimport type { TenantState, Tenant } from '../layoutTypes';\n\n/**\n * Tenant slice for managing tenant state\n *\n * This slice is NOT part of the layout domain. It lives at the app level\n * as a separate top-level slice: state['app/tenant']\n *\n * Event-driven: Listen for 'app/tenant/changed' to update tenant\n */\n\nconst SLICE_KEY = 'app/tenant' as const;\n\nconst initialState: TenantState = {\n tenant: null,\n loading: false,\n};\n\nconst { slice, setTenant, setTenantLoading, clearTenant } = createSlice({\n name: SLICE_KEY,\n initialState,\n reducers: {\n setTenant: (state, action: ReducerPayload<Tenant | null>) => {\n state.tenant = action.payload;\n state.loading = false;\n },\n setTenantLoading: (state, action: ReducerPayload<boolean>) => {\n state.loading = action.payload;\n },\n clearTenant: (state) => {\n state.tenant = null;\n state.loading = false;\n },\n },\n});\n\nexport const tenantSlice = slice;\nexport const tenantActions = { setTenant, setTenantLoading, clearTenant };\n\nexport { setTenant, setTenantLoading, clearTenant };\n\nexport default slice.reducer;\n","/**\n * Themes Plugin - Provides theme registry and changeTheme action\n *\n * Framework Layer: L2\n */\n\nimport { eventBus } from '@hai3/state';\nimport type { HAI3Plugin, ChangeThemePayload, ThemeRegistry } from '../types';\nimport { themeRegistry as singletonThemeRegistry } from '../compat';\n\n// Define theme events for module augmentation\ndeclare module '@hai3/state' {\n interface EventPayloadMap {\n 'theme/changed': ChangeThemePayload;\n }\n}\n\n/**\n * Change theme action.\n * Emits 'theme/changed' event to trigger theme application.\n *\n * @param payload - The theme change payload\n */\nfunction changeTheme(payload: ChangeThemePayload): void {\n eventBus.emit('theme/changed', payload);\n}\n\n/**\n * Themes plugin factory.\n *\n * @returns Themes plugin\n *\n * @example\n * ```typescript\n * const app = createHAI3()\n * .use(screensets())\n * .use(themes())\n * .build();\n *\n * app.actions.changeTheme({ themeId: 'dark' });\n * ```\n */\nexport function themes(): HAI3Plugin {\n // Use the singleton theme registry - user themes register to this\n const themeRegistry = singletonThemeRegistry as ThemeRegistry;\n\n return {\n name: 'themes',\n dependencies: [],\n\n provides: {\n registries: {\n themeRegistry,\n },\n actions: {\n changeTheme,\n },\n },\n\n onInit(_app) {\n // Subscribe to theme changes\n eventBus.on('theme/changed', (payload: ChangeThemePayload) => {\n themeRegistry.apply(payload.themeId);\n });\n\n // Bootstrap: Apply the first registered theme (or default)\n const themes = themeRegistry.getAll();\n if (themes.length > 0) {\n themeRegistry.apply(themes[0].id);\n }\n },\n };\n}\n","/**\n * Backward Compatibility Exports\n *\n * These exports provide backward compatibility with @hai3/uicore API.\n * They are singletons that mirror the old API.\n *\n * NOTE: These are exported for migration convenience but may be deprecated\n * in future major versions. Prefer using the plugin architecture.\n */\n\nimport type { UnknownAction } from '@reduxjs/toolkit';\nimport { getStore, type AppDispatch } from '@hai3/state';\nimport { apiRegistry } from '@hai3/api';\nimport { screensetRegistry as sdkScreensetRegistry } from '@hai3/screensets';\nimport { screenActions as screenActionsImport } from './slices';\nimport { createThemeRegistry } from './registries/themeRegistry';\nimport { createRouteRegistry } from './registries/routeRegistry';\nimport type { ThemeRegistry, RouteRegistry } from './types';\n\n// Type assertion for slice import (needed for backward compatibility functions)\ntype ActionCreators = Record<string, (payload?: UnknownAction['payload']) => UnknownAction>;\nconst screenActions = screenActionsImport as ActionCreators;\n\n// ACCOUNTS_DOMAIN constant for backward compatibility\n// NOTE: AccountsApiService has been moved to CLI templates\n// This constant is kept for legacy code that references it\nexport const ACCOUNTS_DOMAIN = 'accounts' as const;\n\n// ============================================================================\n// Singleton Registries (backward compatibility)\n// ============================================================================\n\n// screensetRegistry is re-exported from @hai3/screensets directly\n// No need for type assertion - SDK type is canonical\nexport { screensetRegistry } from '@hai3/screensets';\n\n/**\n * Global theme registry singleton\n *\n * @deprecated Prefer using app.themeRegistry from createHAI3App()\n */\nexport const themeRegistry: ThemeRegistry = createThemeRegistry();\n\n/**\n * Global route registry singleton\n *\n * @deprecated Prefer using app.routeRegistry from createHAI3App()\n */\nexport const routeRegistry: RouteRegistry = createRouteRegistry(sdkScreensetRegistry);\n\n// ============================================================================\n// Navigation Actions (backward compatibility)\n// ============================================================================\n\n/**\n * Navigate to a screen by ID.\n * Simply updates the active screen in the store.\n *\n * NOTE: This is a simplified backward-compatible function.\n * For full navigation including screenset switching, use:\n * - useNavigation().navigateToScreen(screensetId, screenId) hook\n * - or app.actions.navigateToScreen({ screensetId, screenId })\n *\n * @param screenId Screen ID to navigate to\n * @deprecated Use useNavigation() hook or app.actions.navigateToScreen()\n */\nexport const navigateToScreen = (screenId: string): void => {\n // Update the active screen\n getStore().dispatch(screenActions.setActiveScreen(screenId));\n};\n\n// ============================================================================\n// User Actions (backward compatibility)\n// ============================================================================\n\n/**\n * Fetch current user from API\n * Returns a thunk action that fetches user data.\n *\n * @deprecated Prefer using api services directly in actions\n */\nexport const fetchCurrentUser = () => (_dispatch: AppDispatch): void => {\n // Get accounts service if registered\n // Type assertion needed because accounts service module augmentation is in deprecated @hai3/uicore\n try {\n const accountsService = (apiRegistry as { getService(domain: string): object }).getService(ACCOUNTS_DOMAIN);\n const service = accountsService as { getCurrentUser?: () => void };\n service.getCurrentUser?.();\n } catch {\n console.warn('fetchCurrentUser: accounts service not registered');\n }\n};\n","/**\n * Theme Registry - Manages theme registration and application\n *\n * Framework Layer: L2\n */\n\nimport type { ThemeRegistry, ThemeConfig, ThemeApplyFn, LegacyTheme } from '../types';\n\n/**\n * Create a new theme registry instance.\n */\nexport function createThemeRegistry(): ThemeRegistry {\n const themes = new Map<string, ThemeConfig>();\n // Store legacy themes for use with custom apply function\n const legacyThemes = new Map<string, LegacyTheme>();\n let currentThemeId: string | null = null;\n let customApplyFn: ThemeApplyFn | null = null;\n\n // Subscription support for React\n const subscribers = new Set<() => void>();\n let version = 0;\n\n /**\n * Notify subscribers of theme change\n */\n function notifySubscribers(): void {\n version++;\n subscribers.forEach((callback) => callback());\n }\n\n /**\n * Apply CSS custom properties from theme to :root\n */\n function applyCSSVariables(config: ThemeConfig): void {\n // Skip if not in browser environment\n if (typeof document === 'undefined') return;\n\n const root = document.documentElement;\n\n // Apply each CSS variable\n Object.entries(config.variables).forEach(([key, value]) => {\n root.style.setProperty(key, value);\n });\n }\n\n return {\n /**\n * Register a theme.\n * Supports both new API (config only) and legacy API (id + theme).\n */\n register(configOrId: ThemeConfig | string, legacyTheme?: LegacyTheme): void {\n // Handle legacy API: register(id, theme)\n if (typeof configOrId === 'string') {\n const id = configOrId;\n if (!legacyTheme) {\n console.warn(`register() called with ID \"${id}\" but no theme object. Skipping.`);\n return;\n }\n\n if (themes.has(id)) {\n console.warn(`Theme \"${id}\" is already registered. Skipping.`);\n return;\n }\n\n // Store legacy theme for apply\n legacyThemes.set(id, legacyTheme);\n\n // Create a minimal ThemeConfig for the new API\n // Try to extract name from legacy theme if it's an object\n let themeName = id;\n if (legacyTheme && typeof legacyTheme === 'object' && 'name' in legacyTheme) {\n const nameValue = (legacyTheme as { name?: unknown }).name;\n if (typeof nameValue === 'string') {\n themeName = nameValue;\n }\n }\n const config: ThemeConfig = {\n id,\n name: themeName,\n variables: {}, // Legacy themes use custom apply function\n };\n\n themes.set(id, config);\n return;\n }\n\n // New API: register(config)\n const config = configOrId;\n\n if (themes.has(config.id)) {\n console.warn(`Theme \"${config.id}\" is already registered. Skipping.`);\n return;\n }\n\n themes.set(config.id, config);\n\n // If this is the default theme and no theme is applied yet, apply it\n if (config.default && currentThemeId === null) {\n this.apply(config.id);\n }\n },\n\n /**\n * Set the apply function (legacy API).\n */\n setApplyFunction(applyFn: ThemeApplyFn): void {\n customApplyFn = applyFn;\n },\n\n /**\n * Get theme by ID.\n */\n get(id: string): ThemeConfig | undefined {\n return themes.get(id);\n },\n\n /**\n * Get all themes.\n */\n getAll(): ThemeConfig[] {\n return Array.from(themes.values());\n },\n\n /**\n * Apply a theme.\n */\n apply(id: string): void {\n const config = themes.get(id);\n\n if (!config) {\n console.warn(`Theme \"${id}\" not found. Cannot apply.`);\n return;\n }\n\n // Check if we have a legacy theme and custom apply function\n const legacyTheme = legacyThemes.get(id);\n if (legacyTheme && customApplyFn) {\n customApplyFn(legacyTheme, id);\n } else if (config.variables && Object.keys(config.variables).length > 0) {\n // Use built-in CSS variables approach\n applyCSSVariables(config);\n }\n\n currentThemeId = id;\n\n // Notify React subscribers of theme change\n notifySubscribers();\n },\n\n /**\n * Get current theme.\n */\n getCurrent(): ThemeConfig | undefined {\n return currentThemeId ? themes.get(currentThemeId) : undefined;\n },\n\n /**\n * Subscribe to theme changes.\n * Returns unsubscribe function.\n */\n subscribe(callback: () => void): () => void {\n subscribers.add(callback);\n return () => {\n subscribers.delete(callback);\n };\n },\n\n /**\n * Get current version number.\n * Used by React for re-rendering.\n */\n getVersion(): number {\n return version;\n },\n };\n}\n","/**\n * Route Registry - Manages routes auto-synced from screensets\n *\n * Framework Layer: L2\n */\n\nimport type { MenuScreenItem, ScreenLoader } from '@hai3/screensets';\nimport type { RouteRegistry, ScreensetRegistry } from '../types';\n\n/**\n * Route entry type\n */\ninterface RouteEntry {\n screensetId: string;\n screenId: string;\n loader: ScreenLoader;\n}\n\n/**\n * Create a new route registry instance.\n *\n * @param screensetRegistry - Screenset registry to sync from\n */\nexport function createRouteRegistry(\n screensetRegistry: ScreensetRegistry\n): RouteRegistry {\n // Lazy-initialized routes cache\n let routes: RouteEntry[] | null = null;\n\n /**\n * Build routes from screensets (lazy initialization)\n */\n function buildRoutes(): RouteEntry[] {\n if (routes !== null) {\n return routes;\n }\n\n routes = [];\n const screensets = screensetRegistry.getAll();\n\n screensets.forEach((screenset) => {\n screenset.menu.forEach((menuScreenItem: MenuScreenItem) => {\n // Use screenId if provided, otherwise fallback to id\n const screenId = menuScreenItem.menuItem.screenId ?? menuScreenItem.menuItem.id;\n if (screenId && menuScreenItem.screen) {\n routes!.push({\n screensetId: screenset.id,\n screenId,\n loader: menuScreenItem.screen,\n });\n }\n });\n });\n\n return routes;\n }\n\n return {\n /**\n * Check if a screen exists by screenId only (globally unique).\n */\n hasScreenById(screenId: string): boolean {\n const allRoutes = buildRoutes();\n return allRoutes.some((route) => route.screenId === screenId);\n },\n\n /**\n * Check if a screen exists (legacy, requires both IDs).\n */\n hasScreen(screensetId: string, screenId: string): boolean {\n const allRoutes = buildRoutes();\n return allRoutes.some(\n (route) =>\n route.screensetId === screensetId && route.screenId === screenId\n );\n },\n\n /**\n * Get screenset ID for a given screen ID (reverse lookup).\n * Screen IDs are globally unique across all screensets.\n */\n getScreensetForScreen(screenId: string): string | undefined {\n const allRoutes = buildRoutes();\n const route = allRoutes.find((r) => r.screenId === screenId);\n return route?.screensetId;\n },\n\n /**\n * Get screen loader by screenId only.\n */\n getScreenById(screenId: string): ScreenLoader | undefined {\n const allRoutes = buildRoutes();\n const route = allRoutes.find((r) => r.screenId === screenId);\n return route?.loader;\n },\n\n /**\n * Get screen loader (legacy, requires both IDs).\n */\n getScreen(\n screensetId: string,\n screenId: string\n ): ScreenLoader | undefined {\n const allRoutes = buildRoutes();\n const route = allRoutes.find(\n (r) => r.screensetId === screensetId && r.screenId === screenId\n );\n return route?.loader;\n },\n\n /**\n * Get all routes.\n */\n getAll(): Array<{ screensetId: string; screenId: string }> {\n const allRoutes = buildRoutes();\n return allRoutes.map(({ screensetId, screenId }) => ({\n screensetId,\n screenId,\n }));\n },\n };\n}\n","/**\n * Layout Plugin - Provides all layout domain slices and effects\n *\n * Framework Layer: L2\n *\n * NOTE: Layout slices are owned by @hai3/framework (not @hai3/uicore which is deprecated)\n */\n\nimport type { Dispatch, UnknownAction } from '@reduxjs/toolkit';\nimport { eventBus } from '@hai3/state';\nimport type { HAI3Plugin, ShowPopupPayload, RegisterableSlice } from '../types';\nimport {\n headerSlice as headerSliceImport,\n footerSlice as footerSliceImport,\n menuSlice as menuSliceImport,\n sidebarSlice as sidebarSliceImport,\n popupSlice as popupSliceImport,\n overlaySlice as overlaySliceImport,\n headerActions as headerActionsImport,\n footerActions as footerActionsImport,\n menuActions as menuActionsImport,\n sidebarActions as sidebarActionsImport,\n popupActions as popupActionsImport,\n overlayActions as overlayActionsImport,\n} from '../slices';\n\n// Type assertions for slice imports (needed for plugin system compatibility)\nconst headerSlice = headerSliceImport as unknown as RegisterableSlice;\nconst footerSlice = footerSliceImport as unknown as RegisterableSlice;\nconst menuSlice = menuSliceImport as unknown as RegisterableSlice;\nconst sidebarSlice = sidebarSliceImport as unknown as RegisterableSlice;\nconst popupSlice = popupSliceImport as unknown as RegisterableSlice;\nconst overlaySlice = overlaySliceImport as unknown as RegisterableSlice;\n\ntype ActionCreators = Record<string, (payload?: unknown) => UnknownAction>;\nconst headerActions = headerActionsImport as unknown as ActionCreators;\nconst footerActions = footerActionsImport as unknown as ActionCreators;\nconst menuActions = menuActionsImport as unknown as ActionCreators;\nconst sidebarActions = sidebarActionsImport as unknown as ActionCreators;\nconst popupActions = popupActionsImport as unknown as ActionCreators;\nconst overlayActions = overlayActionsImport as unknown as ActionCreators;\n\n// Define layout events for module augmentation\ndeclare module '@hai3/state' {\n interface EventPayloadMap {\n 'layout/popup/requested': ShowPopupPayload;\n 'layout/popup/hidden': void;\n 'layout/overlay/requested': { id: string };\n 'layout/overlay/hidden': void;\n 'layout/menu/collapsed': { collapsed: boolean };\n 'layout/sidebar/collapsed': { collapsed: boolean };\n }\n}\n\n/**\n * Show popup action.\n */\nfunction showPopup(payload: ShowPopupPayload): void {\n eventBus.emit('layout/popup/requested', payload);\n}\n\n/**\n * Hide popup action.\n */\nfunction hidePopup(): void {\n eventBus.emit('layout/popup/hidden');\n}\n\n/**\n * Show overlay action.\n */\nfunction showOverlay(payload: { id: string }): void {\n eventBus.emit('layout/overlay/requested', payload);\n}\n\n/**\n * Hide overlay action.\n */\nfunction hideOverlay(): void {\n eventBus.emit('layout/overlay/hidden');\n}\n\n/**\n * Toggle menu collapsed action.\n */\nfunction toggleMenuCollapsed(payload: { collapsed: boolean }): void {\n eventBus.emit('layout/menu/collapsed', payload);\n}\n\n/**\n * Toggle sidebar collapsed action.\n */\nfunction toggleSidebarCollapsed(payload: { collapsed: boolean }): void {\n eventBus.emit('layout/sidebar/collapsed', payload);\n}\n\n/**\n * Layout plugin factory.\n *\n * @returns Layout plugin\n *\n * @example\n * ```typescript\n * const app = createHAI3()\n * .use(screensets())\n * .use(layout())\n * .build();\n * ```\n */\nexport function layout(): HAI3Plugin {\n\n return {\n name: 'layout',\n dependencies: ['screensets'],\n\n provides: {\n slices: [\n headerSlice,\n footerSlice,\n menuSlice,\n sidebarSlice,\n popupSlice,\n overlaySlice,\n ],\n actions: {\n showPopup,\n hidePopup,\n showOverlay,\n hideOverlay,\n toggleMenuCollapsed,\n toggleSidebarCollapsed,\n // Direct slice actions for backward compatibility\n setHeaderVisible: headerActions.setVisible,\n setFooterVisible: footerActions.setVisible,\n setMenuCollapsed: menuActions.setCollapsed,\n setSidebarCollapsed: sidebarActions.setCollapsed,\n },\n },\n\n onInit(app) {\n const dispatch = app.store.dispatch as Dispatch<UnknownAction>;\n\n // Popup effects\n eventBus.on('layout/popup/requested', (payload: ShowPopupPayload) => {\n dispatch(popupActions.open({\n id: payload.id,\n title: payload.title,\n content: payload.content,\n size: payload.size,\n }));\n });\n\n eventBus.on('layout/popup/hidden', () => {\n dispatch(popupActions.close());\n });\n\n // Overlay effects\n eventBus.on('layout/overlay/requested', (payload: { id: string }) => {\n dispatch(overlayActions.show({ id: payload.id }));\n });\n\n eventBus.on('layout/overlay/hidden', () => {\n dispatch(overlayActions.hide());\n });\n\n // Menu effects\n eventBus.on('layout/menu/collapsed', (payload: { collapsed: boolean }) => {\n dispatch(menuActions.setCollapsed(payload.collapsed));\n });\n\n // Sidebar effects\n eventBus.on('layout/sidebar/collapsed', (payload: { collapsed: boolean }) => {\n dispatch(sidebarActions.setCollapsed(payload.collapsed));\n });\n },\n };\n}\n","/**\n * Navigation Plugin - Provides navigation actions and URL sync\n *\n * Framework Layer: L2\n *\n * NOTE: Uses layout slices from @hai3/framework (not @hai3/uicore which is deprecated)\n */\n\nimport type { Dispatch, UnknownAction } from '@reduxjs/toolkit';\nimport { eventBus } from '@hai3/state';\nimport { i18nRegistry } from '@hai3/i18n';\nimport { screenActions as screenActionsImport, menuActions as menuActionsImport } from '../slices';\nimport type { HAI3Plugin, NavigateToScreenPayload, NavigateToScreensetPayload } from '../types';\nimport type { MenuItem } from '../layoutTypes';\nimport type { ScreensetDefinition } from '@hai3/screensets';\n\n// Type assertion for slice imports (needed for plugin system compatibility)\ntype ActionCreators = Record<string, (payload?: unknown) => UnknownAction>;\nconst screenActions = screenActionsImport as unknown as ActionCreators;\nconst menuActions = menuActionsImport as unknown as ActionCreators;\n\n/**\n * Convert screenset menu configuration to MenuItem[] for the menu slice.\n */\nfunction buildMenuItems(screenset: ScreensetDefinition): MenuItem[] {\n return screenset.menu.map((item) => ({\n id: item.menuItem.screenId ?? item.menuItem.id,\n label: item.menuItem.label,\n icon: item.menuItem.icon,\n }));\n}\n\n// Define navigation events for module augmentation\ndeclare module '@hai3/state' {\n interface EventPayloadMap {\n 'navigation/screen/navigated': NavigateToScreenPayload;\n 'navigation/screenset/navigated': NavigateToScreensetPayload;\n }\n}\n\n/**\n * Navigate to screen action.\n * Emits 'navigation/screen/navigated' event.\n *\n * @param payload - The navigation payload\n */\nfunction navigateToScreen(payload: NavigateToScreenPayload): void {\n eventBus.emit('navigation/screen/navigated', payload);\n}\n\n/**\n * Navigate to screenset action.\n * Emits 'navigation/screenset/navigated' event.\n *\n * @param payload - The navigation payload\n */\nfunction navigateToScreenset(payload: NavigateToScreensetPayload): void {\n eventBus.emit('navigation/screenset/navigated', payload);\n}\n\n/**\n * Navigation plugin factory.\n *\n * @returns Navigation plugin\n *\n * @example\n * ```typescript\n * const app = createHAI3()\n * .use(screensets())\n * .use(navigation())\n * .build();\n *\n * app.actions.navigateToScreen({ screensetId: 'demo', screenId: 'home' });\n * ```\n */\nexport function navigation(): HAI3Plugin {\n\n return {\n name: 'navigation',\n dependencies: ['screensets'],\n\n provides: {\n actions: {\n navigateToScreen,\n navigateToScreenset,\n },\n },\n\n onInit(app) {\n const dispatch = app.store.dispatch as Dispatch<UnknownAction>;\n let currentScreensetId: string | null = null;\n\n /**\n * Load translations for a screenset (lazy loading).\n * @param screensetId - The screenset ID\n * @param language - Optional language to load (uses current language if not specified)\n */\n async function loadScreensetTranslations(screensetId: string, language?: string): Promise<void> {\n await i18nRegistry.loadScreensetTranslations(screensetId, language as Parameters<typeof i18nRegistry.loadScreensetTranslations>[1]);\n }\n\n /**\n * Update menu items for the active screenset.\n * Also loads screenset translations lazily.\n */\n function updateMenuForScreenset(screensetId: string): void {\n if (screensetId === currentScreensetId) return;\n\n const screenset = app.screensetRegistry.get(screensetId);\n if (!screenset) return;\n\n currentScreensetId = screensetId;\n\n // Load screenset translations lazily (non-blocking)\n loadScreensetTranslations(screensetId).catch((err) => {\n console.warn(`[HAI3] Failed to load translations for screenset ${screensetId}:`, err);\n });\n\n const menuItems = buildMenuItems(screenset);\n dispatch(menuActions.setMenuItems(menuItems));\n }\n\n // Navigation to screen effect\n eventBus.on('navigation/screen/navigated', (payload: NavigateToScreenPayload) => {\n // Validate screen exists (optional in non-strict mode)\n if (app.routeRegistry && !app.routeRegistry.hasScreen(payload.screensetId, payload.screenId)) {\n console.warn(\n `Screen \"${payload.screenId}\" in screenset \"${payload.screensetId}\" not found.`\n );\n return;\n }\n\n // Update menu items for this screenset\n updateMenuForScreenset(payload.screensetId);\n\n // Update screen state\n dispatch(screenActions.navigateTo(payload.screenId));\n\n // Update URL if in browser environment\n // URL format: /{screenId} (screen IDs are globally unique)\n if (typeof window !== 'undefined') {\n const url = `/${payload.screenId}`;\n window.history.pushState(null, '', url);\n }\n });\n\n // Navigation to screenset effect (navigates to default screen)\n eventBus.on('navigation/screenset/navigated', (payload: NavigateToScreensetPayload) => {\n const screenset = app.screensetRegistry.get(payload.screensetId);\n\n if (!screenset) {\n console.warn(`Screenset \"${payload.screensetId}\" not found.`);\n return;\n }\n\n // Navigate to default screen of the screenset\n navigateToScreen({\n screensetId: payload.screensetId,\n screenId: screenset.defaultScreen,\n });\n });\n\n // Track last loaded language to detect language changes\n let lastLoadedLanguage: string | null = null;\n\n // Subscribe to i18nRegistry changes to reload screenset translations after language changes\n // This runs AFTER setLanguage() completes, ensuring currentLanguage is updated\n i18nRegistry.subscribe(() => {\n const currentLanguage = i18nRegistry.getLanguage();\n if (!currentLanguage || currentLanguage === lastLoadedLanguage) return;\n if (!currentScreensetId) return;\n\n const screenset = app.screensetRegistry.get(currentScreensetId);\n if (!screenset) return;\n\n lastLoadedLanguage = currentLanguage;\n\n // Load screenset translations for the new language\n loadScreensetTranslations(currentScreensetId, currentLanguage).then(() => {\n // Re-dispatch menu items to trigger re-render with new translations\n const menuItems = buildMenuItems(screenset);\n dispatch(menuActions.setMenuItems(menuItems));\n }).catch((err) => {\n console.warn(\n `[HAI3] Failed to reload translations for screenset ${currentScreensetId}:`,\n err\n );\n });\n });\n\n // Listen for browser back/forward navigation\n if (typeof window !== 'undefined') {\n window.addEventListener('popstate', () => {\n const path = window.location.pathname;\n const parts = path.split('/').filter(Boolean);\n\n if (parts.length >= 1) {\n // URL format: /{screenId}\n const screenId = parts[0];\n const screensetId = app.routeRegistry?.getScreensetForScreen(screenId);\n if (screensetId) {\n updateMenuForScreenset(screensetId);\n dispatch(screenActions.navigateTo(screenId));\n }\n }\n });\n\n // Initial navigation based on current URL or first screenset\n const path = window.location.pathname;\n const parts = path.split('/').filter(Boolean);\n\n // Check if autoNavigate is enabled (default: true)\n const autoNavigate = app.config.autoNavigate !== false;\n\n if (parts.length >= 1) {\n // URL has screen - find its screenset and navigate\n const screenId = parts[0];\n const screensetId = app.routeRegistry?.getScreensetForScreen(screenId);\n if (screensetId) {\n navigateToScreen({ screensetId, screenId });\n } else if (autoNavigate) {\n // Screen not found - navigate to first available screenset (only if autoNavigate)\n const screensets = app.screensetRegistry.getAll();\n if (screensets.length > 0) {\n navigateToScreenset({ screensetId: screensets[0].id });\n }\n }\n } else if (autoNavigate) {\n // No URL path - navigate to first available screenset (only if autoNavigate)\n const screensets = app.screensetRegistry.getAll();\n if (screensets.length > 0) {\n navigateToScreenset({ screensetId: screensets[0].id });\n }\n }\n }\n },\n };\n}\n","/**\n * Routing Plugin - Provides route registry auto-synced from screensets\n *\n * Framework Layer: L2\n */\n\nimport type { HAI3Plugin, RouteRegistry } from '../types';\nimport { createRouteRegistry } from '../registries/routeRegistry';\n\n/**\n * Routing plugin factory.\n *\n * @returns Routing plugin\n *\n * @example\n * ```typescript\n * const app = createHAI3()\n * .use(screensets())\n * .use(routing())\n * .build();\n *\n * // Check if a screen exists\n * const exists = app.routeRegistry.hasScreen('demo', 'home');\n * ```\n */\nexport function routing(): HAI3Plugin {\n return {\n name: 'routing',\n dependencies: ['screensets'],\n\n onRegister(_app) {\n // Route registry is created lazily during build\n // because it needs access to the screenset registry\n },\n\n onInit(app) {\n // Create route registry from screenset registry\n const routeRegistry = createRouteRegistry(app.screensetRegistry);\n\n // Attach to app (overwriting the placeholder)\n (app as { routeRegistry: RouteRegistry }).routeRegistry = routeRegistry;\n },\n };\n}\n","/**\n * I18n Plugin - Provides i18n registry wiring and setLanguage action\n *\n * Framework Layer: L2\n */\n\nimport { eventBus } from '@hai3/state';\nimport { i18nRegistry as singletonI18nRegistry, Language } from '@hai3/i18n';\nimport type { HAI3Plugin, SetLanguagePayload } from '../types';\n\n// Define i18n events for module augmentation\ndeclare module '@hai3/state' {\n interface EventPayloadMap {\n 'i18n/language/changed': SetLanguagePayload;\n }\n}\n\n/**\n * Set language action.\n * Emits 'i18n/language/changed' event to trigger language change.\n *\n * @param payload - The language change payload\n */\nfunction setLanguage(payload: SetLanguagePayload): void {\n eventBus.emit('i18n/language/changed', payload);\n}\n\n/**\n * I18n plugin factory.\n *\n * @returns I18n plugin\n *\n * @example\n * ```typescript\n * const app = createHAI3()\n * .use(i18n())\n * .build();\n *\n * app.actions.setLanguage({ language: 'de' });\n * ```\n */\nexport function i18n(): HAI3Plugin {\n // Use the singleton i18n registry - user translations register to this\n const i18nRegistry = singletonI18nRegistry;\n\n return {\n name: 'i18n',\n dependencies: [],\n\n provides: {\n registries: {\n i18nRegistry,\n },\n actions: {\n setLanguage,\n },\n },\n\n onInit(_app) {\n // Language change effect\n eventBus.on('i18n/language/changed', async (payload: SetLanguagePayload) => {\n await i18nRegistry.setLanguage(payload.language as Language);\n });\n\n // Bootstrap: Set initial language to trigger translation loading\n // Run async without blocking - translations load in background\n i18nRegistry.setLanguage(Language.English).catch((err) => {\n console.warn('[HAI3] Failed to load initial translations:', err);\n });\n },\n };\n}\n","/**\n * Effects Plugin - Core effect coordination infrastructure\n *\n * Framework Layer: L2\n */\n\nimport type { HAI3Plugin } from '../types';\n\n/**\n * Effects plugin factory.\n *\n * Provides the core effect coordination infrastructure.\n * Other plugins register their effects through this system.\n *\n * @returns Effects plugin\n *\n * @example\n * ```typescript\n * const app = createHAI3()\n * .use(effects())\n * .use(screensets())\n * .build();\n * ```\n */\nexport function effects(): HAI3Plugin {\n return {\n name: 'effects',\n dependencies: [],\n\n onInit(app) {\n // Effects plugin provides the coordination layer\n // Individual plugins register their own effects in their onInit\n // This plugin ensures effect infrastructure is available\n\n if (app.config.devMode) {\n console.log('[HAI3] Effects plugin initialized');\n }\n },\n };\n}\n","/**\n * Presets - Pre-configured plugin combinations\n *\n * Framework Layer: L2\n */\n\nimport type { HAI3Plugin, Presets } from '../types';\nimport { screensets } from '../plugins/screensets';\nimport { themes } from '../plugins/themes';\nimport { layout } from '../plugins/layout';\nimport { navigation } from '../plugins/navigation';\nimport { routing } from '../plugins/routing';\nimport { i18n } from '../plugins/i18n';\nimport { effects } from '../plugins/effects';\n\n/**\n * Full preset - All plugins for the complete HAI3 experience.\n * This is the default for `hai3 create` projects.\n *\n * Includes:\n * - screensets (screenset registry, screen slice)\n * - themes (theme registry, changeTheme action)\n * - layout (all layout domain slices and effects)\n * - navigation (navigateToScreen, navigateToScreenset actions)\n * - routing (route registry auto-synced from screensets)\n * - i18n (i18n registry, setLanguage action)\n * - effects (effect coordination)\n */\nexport function full(): HAI3Plugin[] {\n return [\n effects(),\n screensets({ autoDiscover: true }),\n themes(),\n layout(),\n routing(),\n navigation(),\n i18n(),\n ];\n}\n\n/**\n * Minimal preset - Screensets + themes only.\n * For users who want basic HAI3 patterns without full layout management.\n *\n * Includes:\n * - screensets (screenset registry, screen slice)\n * - themes (theme registry, changeTheme action)\n */\nexport function minimal(): HAI3Plugin[] {\n return [\n screensets({ autoDiscover: true }),\n themes(),\n ];\n}\n\n/**\n * Headless preset - Screensets only.\n * For external platform integration where you only need screenset orchestration.\n * The external platform provides its own menu, header, navigation, etc.\n *\n * Includes:\n * - screensets (screenset registry, screen slice)\n */\nexport function headless(): HAI3Plugin[] {\n return [\n screensets(),\n ];\n}\n\n/**\n * Presets collection\n */\nexport const presets: Presets = {\n full,\n minimal,\n headless,\n};\n","/**\n * createHAI3App - Convenience function for full HAI3 application\n *\n * Creates a fully configured HAI3 application using the full preset.\n *\n * Framework Layer: L2\n */\n\nimport { createHAI3 } from './createHAI3';\nimport { full } from './presets';\nimport type { HAI3Config, HAI3App } from './types';\n\n/**\n * Create a fully configured HAI3 application.\n *\n * This is a convenience function that uses the full preset.\n * For custom plugin composition, use `createHAI3()` instead.\n *\n * @param config - Optional application configuration\n * @returns The built HAI3 application\n *\n * @example\n * ```typescript\n * // Default - uses full() preset\n * const app = createHAI3App();\n *\n * // With configuration\n * const app = createHAI3App({ devMode: true });\n * ```\n */\nexport function createHAI3App(config?: HAI3Config): HAI3App {\n return createHAI3(config)\n .useAll(full())\n .build();\n}\n","/**\n * Registry exports\n */\n\n// Re-export createScreensetRegistry from SDK - do NOT duplicate\nexport { createScreensetRegistry, screensetRegistry } from '@hai3/screensets';\nexport { createThemeRegistry } from './themeRegistry';\nexport { createRouteRegistry } from './routeRegistry';\n","/**\n * @hai3/framework - HAI3 Framework Package\n *\n * This package provides:\n * - Plugin architecture for composable HAI3 applications\n * - Registries for screensets, themes, routes\n * - Presets for common configurations\n * - Re-exports from SDK packages for convenience\n *\n * Framework Layer: L2 (Depends on all SDK packages)\n */\n\n// ============================================================================\n// Core Exports\n// ============================================================================\n\nexport { createHAI3 } from './createHAI3';\nexport { createHAI3App } from './createHAI3App';\n\n// ============================================================================\n// Plugin Exports\n// ============================================================================\n\nexport {\n screensets,\n themes,\n layout,\n navigation,\n routing,\n i18n,\n effects,\n} from './plugins';\n\n// ============================================================================\n// Preset Exports\n// ============================================================================\n\nexport { presets, full, minimal, headless } from './presets';\n\n// ============================================================================\n// Registry Exports\n// ============================================================================\n\nexport {\n createScreensetRegistry,\n createThemeRegistry,\n createRouteRegistry,\n} from './registries';\n\n// ============================================================================\n// Type Exports\n// ============================================================================\n\nexport type {\n HAI3Config,\n HAI3Plugin,\n HAI3AppBuilder,\n HAI3App,\n PluginFactory,\n PluginProvides,\n PluginLifecycle,\n ScreensetRegistry,\n ThemeRegistry,\n ThemeConfig,\n ThemeApplyFn,\n LegacyTheme,\n RouteRegistry,\n Preset,\n Presets,\n ScreensetsConfig,\n NavigateToScreenPayload,\n NavigateToScreensetPayload,\n ShowPopupPayload,\n ChangeThemePayload,\n SetLanguagePayload,\n} from './types';\n\n// ============================================================================\n// Re-exports from SDK packages for convenience\n// ============================================================================\n\n// From @hai3/state (unified Flux dataflow pattern)\nexport { eventBus, createStore, getStore, registerSlice, hasSlice, createSlice } from '@hai3/state';\nexport type {\n ReducerPayload,\n EventPayloadMap,\n EventHandler,\n Subscription,\n RootState,\n AppDispatch,\n SliceObject,\n EffectInitializer,\n} from '@hai3/state';\n\n// Re-export HAI3Store from types (wrapped version)\nexport type { HAI3Store } from './types';\n\n// From @hai3/screensets (contracts only - SDK Layer L1)\nexport {\n LayoutDomain,\n ScreensetCategory,\n // Note: createScreensetRegistry is exported from ./registries (framework version)\n // SDK version is available via: import { createScreensetRegistry } from '@hai3/screensets'\n} from '@hai3/screensets';\n\n// Re-export screensetRegistry from compat (wraps SDK registry with framework interface)\n// Note: screensetRegistry is also exported from ./compat further down\n\nexport type {\n ScreensetId,\n ScreenId,\n MenuItemConfig,\n ScreenLoader,\n ScreenConfig,\n MenuScreenItem,\n ScreensetDefinition,\n ScreensetRegistry as ScreensetRegistryContract,\n} from '@hai3/screensets';\n\n// Layout slices (owned by @hai3/framework)\nexport {\n layoutReducer,\n layoutDomainReducers,\n LAYOUT_SLICE_NAME,\n // Tenant slice (app-level, not layout)\n TENANT_SLICE_NAME,\n tenantSlice,\n tenantActions,\n tenantReducer,\n setTenant,\n setTenantLoading,\n clearTenant,\n // Domain slices\n headerSlice,\n footerSlice,\n menuSlice,\n sidebarSlice,\n screenSlice,\n popupSlice,\n overlaySlice,\n // Domain actions\n headerActions,\n footerActions,\n menuActions,\n sidebarActions,\n screenActions,\n popupActions,\n overlayActions,\n // Individual reducer functions - header\n setUser,\n setHeaderLoading,\n clearUser,\n // Individual reducer functions - footer\n setFooterVisible,\n setFooterConfig,\n toggleMenu,\n setMenuCollapsed,\n setMenuItems,\n setMenuVisible,\n setMenuConfig,\n toggleSidebar,\n setSidebarCollapsed,\n setSidebarPosition,\n setSidebarTitle,\n setSidebarContent,\n setSidebarVisible,\n setSidebarWidth,\n setSidebarConfig,\n setActiveScreen,\n setScreenLoading,\n navigateTo,\n clearActiveScreen,\n openPopup,\n closePopup,\n closeTopPopup,\n closeAllPopups,\n showOverlay,\n hideOverlay,\n setOverlayVisible,\n} from './slices';\n\n// PopupSliceState type\nexport type { PopupSliceState } from './slices';\n\n// Layout state types (defined locally to avoid circular deps with uicore/react)\nexport type {\n // App-level types\n Tenant,\n TenantState,\n // Layout domain types\n HeaderUser,\n HeaderState,\n HeaderConfig,\n FooterState,\n FooterConfig,\n MenuItem,\n MenuState,\n SidebarPosition,\n SidebarState,\n ScreenState,\n PopupState,\n PopupConfig,\n OverlayState,\n OverlayConfig,\n LayoutState,\n LayoutDomainState,\n RootStateWithLayout,\n LayoutDomainReducers,\n} from './layoutTypes';\n\n// Tenant effects and events\nexport {\n initTenantEffects,\n changeTenant,\n clearTenantAction,\n setTenantLoadingState,\n TenantEvents,\n} from './effects';\nexport type { TenantChangedPayload, TenantClearedPayload } from './effects';\n\n// From @hai3/api\nexport { apiRegistry, BaseApiService, RestProtocol, SseProtocol, MockPlugin } from '@hai3/api';\nexport type {\n ApiService,\n ApiServicesMap,\n MockMap,\n ApiServiceConfig,\n JsonValue,\n JsonObject,\n JsonPrimitive,\n JsonCompatible,\n ApiProtocol,\n SseProtocolConfig,\n RestProtocolConfig,\n} from '@hai3/api';\n\n// NOTE: AccountsApiService, ACCOUNTS_DOMAIN, and account types (ApiUser, UserRole, etc.)\n// have been moved to CLI templates. They are now generated by `hai3 scaffold layout`\n// and should be imported from user code (e.g., @/layout/api or @/api).\n\n// From @hai3/i18n\nexport { i18nRegistry, I18nRegistryImpl, createI18nRegistry, Language, SUPPORTED_LANGUAGES, getLanguageMetadata, TextDirection, LanguageDisplayMode } from '@hai3/i18n';\nexport type { I18nConfig, TranslationLoader, TranslationMap, TranslationDictionary, LanguageMetadata, I18nRegistry as I18nRegistryType } from '@hai3/i18n';\n\n// Backward compatibility aliases\n// I18nRegistry type (capital I) - alias for consistency with old @hai3/uicore API\nexport { I18nRegistryImpl as I18nRegistry } from '@hai3/i18n';\n\n// ScreensetConfig type alias - maps to ScreensetDefinition in new architecture\nexport type { ScreensetDefinition as ScreensetConfig } from '@hai3/screensets';\n\n// Singleton registries for backward compatibility\nexport {\n screensetRegistry,\n themeRegistry,\n routeRegistry,\n // Backward compatibility actions\n navigateToScreen,\n fetchCurrentUser,\n // Backward compatibility constants\n ACCOUNTS_DOMAIN,\n} from './compat';\n\n// ============================================================================\n// Migration Helpers (for @hai3/uicore backward compatibility)\n// ============================================================================\n\nexport {\n createLegacySelector,\n setDeprecationWarnings,\n isDeprecationWarningsEnabled,\n getLayoutDomainState,\n hasLegacyUicoreState,\n hasNewLayoutState,\n legacySelectors,\n STATE_PATH_MAPPING,\n} from './migration';\n\nexport type {\n LegacyUicoreState,\n LegacyRootState,\n Selector,\n} from './migration';\n","/**\n * Tenant Effects\n *\n * Listens for tenant events and updates the tenant slice.\n * Event-driven architecture: consuming apps emit events, effects handle state updates.\n */\n\nimport { eventBus, getStore } from '@hai3/state';\nimport { setTenant, setTenantLoading, clearTenant } from '../slices/tenantSlice';\nimport type { Tenant } from '../layoutTypes';\n\n// ============================================================================\n// Event Types\n// ============================================================================\n\n/** Tenant event names */\nexport const TenantEvents = {\n Changed: 'app/tenant/changed',\n Cleared: 'app/tenant/cleared',\n} as const;\n\n/** Payload for tenant changed event */\nexport interface TenantChangedPayload {\n tenant: Tenant;\n}\n\n/** Payload for tenant cleared event */\nexport interface TenantClearedPayload {\n // Empty payload\n}\n\n// ============================================================================\n// Module Augmentation for Type-Safe Events\n// ============================================================================\n\ndeclare module '@hai3/state' {\n interface EventPayloadMap {\n 'app/tenant/changed': TenantChangedPayload;\n 'app/tenant/cleared': TenantClearedPayload;\n }\n}\n\n// ============================================================================\n// Effect Registration\n// ============================================================================\n\n/**\n * Initialize tenant effects\n * Call this once during app bootstrap to start listening for tenant events.\n */\nexport function initTenantEffects(): () => void {\n const store = getStore();\n\n // Listen for tenant changed event\n const subChanged = eventBus.on(TenantEvents.Changed, (payload) => {\n store.dispatch(setTenant(payload.tenant));\n });\n\n // Listen for tenant cleared event\n const subCleared = eventBus.on(TenantEvents.Cleared, () => {\n store.dispatch(clearTenant());\n });\n\n // Return cleanup function\n return () => {\n subChanged.unsubscribe();\n subCleared.unsubscribe();\n };\n}\n\n// ============================================================================\n// Helper Actions (for consuming apps)\n// ============================================================================\n\n/**\n * Set tenant via event bus\n * This is the recommended way for consuming apps to set tenant.\n *\n * @example\n * ```typescript\n * import { changeTenant } from '@hai3/framework';\n * changeTenant({ id: 'tenant-123' });\n * ```\n */\nexport function changeTenant(tenant: Tenant): void {\n eventBus.emit(TenantEvents.Changed, { tenant });\n}\n\n/**\n * Clear tenant via event bus\n */\nexport function clearTenantAction(): void {\n eventBus.emit(TenantEvents.Cleared, {});\n}\n\n/**\n * Set tenant loading state (direct dispatch, for internal use)\n */\nexport function setTenantLoadingState(loading: boolean): void {\n getStore().dispatch(setTenantLoading(loading));\n}\n","/**\n * Migration Helpers - Utilities for migrating from @hai3/uicore\n *\n * These helpers assist users migrating from the deprecated @hai3/uicore package\n * to the new SDK architecture (@hai3/framework, @hai3/screensets, @hai3/react).\n *\n * Framework Layer: L2\n */\n\nimport type { RootStateWithLayout } from './layoutTypes';\n\n// ============================================================================\n// Types\n// ============================================================================\n\n/**\n * Legacy uicore state structure (for reference/backward compat)\n */\nexport interface LegacyUicoreState {\n app: {\n user: unknown | null;\n tenant: unknown | null;\n language: string | null;\n translationsReady: boolean;\n screenTranslationsVersion: number;\n loading: boolean;\n error: string | null;\n useMockApi: boolean;\n };\n layout: {\n theme: string;\n currentScreenset: string;\n selectedScreen: string | null;\n };\n header: Record<string, unknown>;\n footer: {\n screensetOptions: unknown[];\n visible: boolean;\n };\n menu: {\n collapsed: boolean;\n items: unknown[];\n visible: boolean;\n };\n sidebar: {\n collapsed: boolean;\n position: string;\n title: string | null;\n content: unknown;\n visible: boolean;\n };\n screen: {\n activeScreen: string | null;\n loading: boolean;\n };\n popup: {\n stack: unknown[];\n };\n overlay: {\n visible: boolean;\n };\n}\n\n/**\n * Legacy root state with uicore key\n */\nexport interface LegacyRootState {\n uicore: LegacyUicoreState;\n [key: string]: unknown;\n}\n\n/**\n * State accessor function type\n * Note: \"Selector\" terminology avoided (Redux-specific). Use useAppSelector hook for state access.\n */\nexport type Selector<TState, TResult> = (state: TState) => TResult;\n\n// ============================================================================\n// Migration Path Mapping\n// ============================================================================\n\n/**\n * State path mapping from legacy to new structure\n */\nexport const STATE_PATH_MAPPING = {\n // App state (moved to app slice)\n 'uicore.app.user': 'app.user',\n 'uicore.app.tenant': 'app.tenant',\n 'uicore.app.language': 'app.language',\n 'uicore.app.translationsReady': 'app.translationsReady',\n 'uicore.app.loading': 'app.loading',\n 'uicore.app.error': 'app.error',\n 'uicore.app.useMockApi': 'app.useMockApi',\n\n // Layout state (split into domains)\n 'uicore.layout.theme': 'app.theme',\n 'uicore.layout.currentScreenset': 'app.currentScreenset',\n 'uicore.layout.selectedScreen': 'layout.screen.activeScreen',\n\n // Domain states (moved to layout.*)\n 'uicore.header': 'layout.header',\n 'uicore.footer': 'layout.footer',\n 'uicore.menu': 'layout.menu',\n 'uicore.sidebar': 'layout.sidebar',\n 'uicore.screen': 'layout.screen',\n 'uicore.popup': 'layout.popup',\n 'uicore.overlay': 'layout.overlay',\n} as const;\n\n// ============================================================================\n// Legacy Selector Factory\n// ============================================================================\n\nlet deprecationWarningsEnabled = true;\n\n/**\n * Enable or disable deprecation warnings globally\n */\nexport function setDeprecationWarnings(enabled: boolean): void {\n deprecationWarningsEnabled = enabled;\n}\n\n/**\n * Check if deprecation warnings are enabled\n */\nexport function isDeprecationWarningsEnabled(): boolean {\n return deprecationWarningsEnabled;\n}\n\n/**\n * Create a legacy selector that wraps a new selector with deprecation warnings\n *\n * @param legacyPath - The old state path being accessed (for warning message)\n * @param newSelector - The new selector to use\n * @param migrationHint - Hint for how to migrate (optional)\n * @returns A selector that logs a deprecation warning then returns the new value\n *\n * @example\n * ```typescript\n * import { createLegacySelector, selectMenuCollapsed } from '@hai3/framework';\n *\n * // Create a legacy selector\n * const selectMenuCollapsedLegacy = createLegacySelector(\n * 'uicore.menu.collapsed',\n * selectMenuCollapsed,\n * 'Use selectMenuCollapsed from @hai3/framework'\n * );\n *\n * // In component (will show deprecation warning in dev)\n * const collapsed = useSelector(selectMenuCollapsedLegacy);\n * ```\n */\nexport function createLegacySelector<TState, TResult>(\n legacyPath: string,\n newSelector: Selector<TState, TResult>,\n migrationHint?: string\n): Selector<TState, TResult> {\n let hasWarned = false;\n\n return (state: TState): TResult => {\n if (deprecationWarningsEnabled && !hasWarned && process.env.NODE_ENV === 'development') {\n hasWarned = true;\n const newPath = STATE_PATH_MAPPING[legacyPath as keyof typeof STATE_PATH_MAPPING] ?? 'unknown';\n const hint = migrationHint ?? `Use the new state path: ${newPath}`;\n console.warn(\n `[HAI3 Migration] Deprecated selector accessing \"${legacyPath}\". ${hint}`\n );\n }\n return newSelector(state);\n };\n}\n\n// ============================================================================\n// Legacy State Accessors\n// ============================================================================\n\n/**\n * Get layout domain state from the new structure\n * Maps to what was previously `state.uicore.header`, `state.uicore.menu`, etc.\n */\nexport function getLayoutDomainState<K extends keyof RootStateWithLayout['layout']>(\n state: RootStateWithLayout,\n domain: K\n): RootStateWithLayout['layout'][K] {\n return state.layout[domain];\n}\n\n/**\n * Check if a state object has the legacy uicore structure\n */\nexport function hasLegacyUicoreState(state: unknown): state is LegacyRootState {\n return (\n typeof state === 'object' &&\n state !== null &&\n 'uicore' in state &&\n typeof (state as Record<string, unknown>).uicore === 'object'\n );\n}\n\n/**\n * Check if a state object has the new layout structure\n */\nexport function hasNewLayoutState(state: unknown): state is RootStateWithLayout {\n return (\n typeof state === 'object' &&\n state !== null &&\n 'layout' in state &&\n typeof (state as Record<string, unknown>).layout === 'object'\n );\n}\n\n// ============================================================================\n// Legacy State Accessors (DEPRECATED)\n// ============================================================================\n\n/**\n * Legacy selectors placeholder\n *\n * @deprecated Named selectors are removed. Use useAppSelector hook from @hai3/react\n * with inline state access: `useAppSelector((state) => state.layout.menu)`\n *\n * Migration guide:\n * - Before: `const menu = useSelector(selectMenu);`\n * - After: `const menu = useAppSelector((state: RootState) => state.layout.menu);`\n */\nexport const legacySelectors = {} as const;\n"],"mappings":"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","names":["effects","slice","createSlice","SLICE_KEY","initialState","slice","slice","createSlice","SLICE_KEY","initialState","slice","slice","createSlice","SLICE_KEY","initialState","slice","slice","createSlice","SLICE_KEY","initialState","slice","slice","createSlice","SLICE_KEY","initialState","slice","slice","createSlice","SLICE_KEY","initialState","slice","slice","createSlice","SLICE_KEY","initialState","slice","slice","screenSlice","screenActions","screensetRegistry","getStore","apiRegistry","sdkScreensetRegistry","themes","config","screensetRegistry","screensets","screenActions","sdkScreensetRegistry","getStore","apiRegistry","themeRegistry","themes","eventBus","headerSlice","footerSlice","menuSlice","sidebarSlice","popupSlice","overlaySlice","headerActions","footerActions","menuActions","sidebarActions","popupActions","overlayActions","eventBus","showOverlay","hideOverlay","eventBus","screenActions","menuActions","navigateToScreen","eventBus","path","parts","screensets","routeRegistry","eventBus","i18nRegistry","screensetRegistry","eventBus","getStore","registerSlice","createSlice","eventBus","getStore","getStore","eventBus","apiRegistry","i18nRegistry","Language","I18nRegistryImpl"]}
|
package/dist/types.cjs
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __copyProps = (to, from, except, desc) => {
|
|
7
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
8
|
+
for (let key of __getOwnPropNames(from))
|
|
9
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
10
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
11
|
+
}
|
|
12
|
+
return to;
|
|
13
|
+
};
|
|
14
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
15
|
+
|
|
16
|
+
// src/types.ts
|
|
17
|
+
var types_exports = {};
|
|
18
|
+
module.exports = __toCommonJS(types_exports);
|
|
19
|
+
//# sourceMappingURL=types.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/types.ts"],"sourcesContent":["/**\n * @hai3/framework - Type Definitions\n *\n * Core types for HAI3 framework with plugin architecture.\n * Integrates all SDK packages into a cohesive framework.\n */\n\n// ============================================================================\n// Type Imports from SDK Packages\n// ============================================================================\n\n// From @hai3/state\nimport type {\n HAI3Store as StoreType,\n EffectInitializer,\n} from '@hai3/state';\n\nimport type { Reducer } from '@reduxjs/toolkit';\n\n// From @hai3/screensets\nimport type { ScreensetRegistry } from '@hai3/screensets';\n\n// From @hai3/api\nimport type { ApiRegistry } from '@hai3/api';\n\n// From @hai3/i18n\nimport type { I18nRegistry } from '@hai3/i18n';\n\n// Re-export HAI3Store from @hai3/store for framework consumers\nexport type HAI3Store = StoreType;\n\n// ============================================================================\n// HAI3 Configuration\n// ============================================================================\n\n/**\n * HAI3 Application Configuration\n * Configuration options for creating a HAI3 application.\n */\nexport interface HAI3Config {\n /** Application name */\n name?: string;\n /** Enable development mode */\n devMode?: boolean;\n /** Enable strict mode (throws on errors) */\n strictMode?: boolean;\n /**\n * Auto-navigate to first screenset on mount.\n * When false, stays on \"/\" until navigateToScreen/navigateToScreenset is called.\n * @default true\n */\n autoNavigate?: boolean;\n}\n\n// ============================================================================\n// Internal Slice Types\n// ============================================================================\n\n/**\n * Registerable Slice Interface\n * Minimal interface for slices that can be registered with the framework.\n * Used for heterogeneous slice collections where different state types are mixed.\n *\n * This is an internal framework type - plugins provide slices matching this structure.\n * The Reducer type uses RTK's default, avoiding explicit `any` in HAI3 code.\n */\nexport interface RegisterableSlice {\n /** Slice name - becomes the state key */\n readonly name: string;\n /** Slice reducer function */\n readonly reducer: Reducer;\n /** Slice action creators (optional for registration) */\n readonly actions?: Record<string, unknown>;\n}\n\n// ============================================================================\n// Plugin System Types\n// ============================================================================\n\n/**\n * HAI3 Actions Interface\n * Central registry of all actions available in the application.\n *\n * Built-in actions are defined here. Consumers can extend this interface\n * via module augmentation to add custom actions:\n *\n * @example\n * ```typescript\n * declare module '@hai3/framework' {\n * interface HAI3Actions {\n * myCustomAction: (payload: MyPayload) => void;\n * }\n * }\n * ```\n *\n * Design: Interface (not type) enables TypeScript declaration merging.\n */\nexport interface HAI3Actions {\n // ==========================================================================\n // Navigation actions (from navigation plugin)\n // ==========================================================================\n navigateToScreen: (payload: NavigateToScreenPayload) => void;\n navigateToScreenset: (payload: NavigateToScreensetPayload) => void;\n\n // ==========================================================================\n // Theme actions (from themes plugin)\n // ==========================================================================\n changeTheme: (payload: ChangeThemePayload) => void;\n\n // ==========================================================================\n // I18n actions (from i18n plugin)\n // ==========================================================================\n setLanguage: (payload: SetLanguagePayload) => void;\n\n // ==========================================================================\n // Layout actions (from layout plugin)\n // ==========================================================================\n showPopup: (payload: ShowPopupPayload) => void;\n hidePopup: () => void;\n showOverlay: (payload: { id: string }) => void;\n hideOverlay: () => void;\n toggleMenuCollapsed: (payload: { collapsed: boolean }) => void;\n toggleSidebarCollapsed: (payload: { collapsed: boolean }) => void;\n setHeaderVisible: (payload: boolean) => void;\n setFooterVisible: (payload: boolean) => void;\n setMenuCollapsed: (payload: boolean) => void;\n setSidebarCollapsed: (payload: boolean) => void;\n\n // ==========================================================================\n // Screenset actions (from screensets plugin)\n // ==========================================================================\n setActiveScreen: (payload: string) => void;\n setScreenLoading: (payload: boolean) => void;\n}\n\n/**\n * Plugin Provides Interface\n * What a plugin contributes to the application.\n */\nexport interface PluginProvides {\n /** Registry contributions */\n registries?: Record<string, unknown>;\n /** Redux slices to register */\n slices?: RegisterableSlice[];\n /** Effect initializers to register */\n effects?: EffectInitializer[];\n /** Actions provided by the plugin (subset of HAI3Actions) */\n actions?: Partial<HAI3Actions>;\n}\n\n/**\n * Plugin Lifecycle Interface\n * Lifecycle hooks for plugin initialization.\n */\nexport interface PluginLifecycle {\n /**\n * Called when plugin is registered (before app starts).\n *\n * @param app - The app builder instance\n * @param config - Plugin configuration\n */\n onRegister?(app: HAI3AppBuilder, config: unknown): void;\n\n /**\n * Called after all plugins registered, before app starts.\n *\n * @param app - The built app instance\n */\n onInit?(app: HAI3App): void | Promise<void>;\n\n /**\n * Called when app is destroyed.\n *\n * @param app - The app instance\n */\n onDestroy?(app: HAI3App): void;\n}\n\n/**\n * HAI3 Plugin Interface\n * All plugins implement this contract.\n * Follows Liskov Substitution Principle - any plugin can be used interchangeably.\n *\n * @template TConfig - Plugin configuration type\n *\n * @example\n * ```typescript\n * const screensetsPlugin: HAI3Plugin = {\n * name: 'screensets',\n * dependencies: [],\n * provides: {\n * registries: { screensetRegistry: createScreensetRegistry() },\n * slices: [screenSlice],\n * },\n * onInit(app) {\n * discoverScreensets(app.screensetRegistry);\n * },\n * };\n * ```\n */\nexport interface HAI3Plugin<TConfig = unknown> extends PluginLifecycle {\n /** Unique plugin identifier */\n name: string;\n\n /** Other plugins this plugin requires */\n dependencies?: string[];\n\n /** What this plugin provides to the app */\n provides?: PluginProvides;\n\n /** Plugin configuration type marker (used for type inference) */\n _configType?: TConfig;\n}\n\n/**\n * Plugin Factory Function\n * Factory function that creates a plugin with optional configuration.\n *\n * @template TConfig - Plugin configuration type\n */\nexport type PluginFactory<TConfig = unknown> = (config?: TConfig) => HAI3Plugin<TConfig>;\n\n// ============================================================================\n// App Builder Interface\n// ============================================================================\n\n/**\n * HAI3 App Builder Interface\n * Fluent builder for composing HAI3 applications with plugins.\n *\n * @example\n * ```typescript\n * const app = createHAI3()\n * .use(screensets())\n * .use(themes())\n * .use(layout())\n * .build();\n * ```\n */\nexport interface HAI3AppBuilder {\n /**\n * Add a plugin to the application.\n *\n * @param plugin - Plugin instance or factory\n * @returns Builder for chaining\n */\n use(plugin: HAI3Plugin | PluginFactory): HAI3AppBuilder;\n\n /**\n * Add multiple plugins at once.\n *\n * @param plugins - Array of plugins or factories\n * @returns Builder for chaining\n */\n useAll(plugins: Array<HAI3Plugin | PluginFactory>): HAI3AppBuilder;\n\n /**\n * Build the application.\n * Resolves dependencies, initializes plugins, and returns the app.\n *\n * @returns The built HAI3 application\n */\n build(): HAI3App;\n}\n\n// ============================================================================\n// Built App Interface\n// ============================================================================\n\n// Re-export ScreensetRegistry from SDK - do NOT duplicate the interface\nexport type { ScreensetRegistry } from '@hai3/screensets';\n\n/**\n * Theme Configuration\n * Configuration for a theme.\n */\nexport interface ThemeConfig {\n /** Theme ID */\n id: string;\n /** Theme name */\n name: string;\n /** CSS custom properties */\n variables: Record<string, string>;\n /** Whether this is the default theme */\n default?: boolean;\n}\n\n/**\n * Legacy Theme type (from @hai3/uikit)\n * Used for backward compatibility with old register(id, theme) pattern.\n * Using 'unknown' as the base type to accept any theme structure.\n */\nexport type LegacyTheme = unknown;\n\n/**\n * Theme apply function type\n * Generic to accept any theme type from UI kit implementations.\n * @internal - uses generic function signature for compatibility with various theme implementations\n */\nexport interface ThemeApplyFn {\n (theme: unknown, themeName?: string): void;\n}\n\n/**\n * Theme Registry Interface\n * Registry for managing themes.\n */\nexport interface ThemeRegistry {\n /**\n * Register a theme.\n * Supports both new API (config only) and legacy API (id + theme).\n *\n * @param configOrId - ThemeConfig or theme ID (for legacy API)\n * @param legacyTheme - Legacy Theme object (optional, for backward compatibility)\n */\n register(configOrId: ThemeConfig | string, legacyTheme?: LegacyTheme): void;\n\n /**\n * Set the apply function (legacy API).\n * @deprecated Use the built-in apply or provide applyFn at construction.\n */\n setApplyFunction(applyFn: ThemeApplyFn): void;\n\n /** Get theme by ID */\n get(id: string): ThemeConfig | undefined;\n /** Get all themes */\n getAll(): ThemeConfig[];\n /** Apply a theme */\n apply(id: string): void;\n /** Get current theme */\n getCurrent(): ThemeConfig | undefined;\n\n /**\n * Subscribe to theme changes.\n * @param callback - Called when theme changes\n * @returns Unsubscribe function\n */\n subscribe(callback: () => void): () => void;\n\n /**\n * Get current version number.\n * Used by React for re-rendering on theme changes.\n */\n getVersion(): number;\n}\n\n/**\n * Route Registry Interface\n * Registry for managing routes (auto-synced from screensets).\n */\nexport interface RouteRegistry {\n /** Check if a screen exists by screenId only (globally unique) */\n hasScreenById(screenId: string): boolean;\n /** Check if a screen exists (legacy, requires both IDs) */\n hasScreen(screensetId: string, screenId: string): boolean;\n /** Get screenset ID for a given screen ID (reverse lookup) */\n getScreensetForScreen(screenId: string): string | undefined;\n /** Get screen loader by screenId only */\n getScreenById(screenId: string): (() => Promise<{ default: React.ComponentType }>) | undefined;\n /** Get screen loader (legacy, requires both IDs) */\n getScreen(screensetId: string, screenId: string): (() => Promise<{ default: React.ComponentType }>) | undefined;\n /** Get all routes */\n getAll(): Array<{ screensetId: string; screenId: string }>;\n}\n\n/**\n * HAI3 App Interface\n * The built application with all features available.\n *\n * @example\n * ```typescript\n * const app = createHAI3App();\n *\n * // Access registries\n * const screensets = app.screensetRegistry.getAll();\n *\n * // Access store\n * const state = app.store.getState();\n *\n * // Access actions\n * app.actions.navigateToScreen({ screensetId: 'demo', screenId: 'home' });\n * ```\n */\nexport interface HAI3App {\n /** Application configuration */\n config: HAI3Config;\n\n /** Redux store */\n store: HAI3Store;\n\n /** Screenset registry */\n screensetRegistry: ScreensetRegistry;\n\n /** Theme registry */\n themeRegistry: ThemeRegistry;\n\n /** Route registry */\n routeRegistry: RouteRegistry;\n\n /** API registry */\n apiRegistry: ApiRegistry;\n\n /** I18n registry */\n i18nRegistry: I18nRegistry;\n\n /** All registered actions (type-safe via HAI3Actions interface) */\n actions: HAI3Actions;\n\n /** Destroy the application and cleanup resources */\n destroy(): void;\n}\n\n// ============================================================================\n// Create HAI3 App Function Signature\n// ============================================================================\n\n/**\n * Create HAI3 App Function Signature\n * Creates a fully configured HAI3 application using the full preset.\n *\n * @param config - Optional configuration\n * @returns The built HAI3 application\n *\n * @example\n * ```typescript\n * // Default - uses full() preset\n * const app = createHAI3App();\n *\n * // With configuration\n * const app = createHAI3App({ devMode: true });\n * ```\n */\nexport type CreateHAI3App = (config?: HAI3Config) => HAI3App;\n\n/**\n * Create HAI3 Function Signature\n * Creates a HAI3 app builder for custom plugin composition.\n *\n * @returns App builder for plugin composition\n *\n * @example\n * ```typescript\n * const app = createHAI3()\n * .use(screensets())\n * .use(themes())\n * .build();\n * ```\n */\nexport type CreateHAI3 = () => HAI3AppBuilder;\n\n// ============================================================================\n// Preset Types\n// ============================================================================\n\n/**\n * Preset Type\n * A preset is a function that returns an array of plugins.\n *\n * @example\n * ```typescript\n * const minimal: Preset = () => [\n * screensets({ autoDiscover: true }),\n * themes(),\n * ];\n * ```\n */\nexport type Preset = () => HAI3Plugin[];\n\n/**\n * Presets Collection\n * Available presets for different use cases.\n */\nexport interface Presets {\n /** All plugins - default for hai3 create */\n full: Preset;\n /** Screensets + themes only */\n minimal: Preset;\n /** Screensets only - for external platform integration */\n headless: Preset;\n}\n\n// ============================================================================\n// Screensets Plugin Config\n// ============================================================================\n\n/**\n * Screensets Plugin Configuration\n * Configuration options for the screensets plugin.\n */\nexport interface ScreensetsConfig {\n /** Auto-discover screensets via glob */\n autoDiscover?: boolean;\n /** Glob pattern for screenset discovery */\n globPattern?: string;\n}\n\n// ============================================================================\n// Navigation Action Payloads\n// ============================================================================\n\n/**\n * Navigate to Screen Payload\n */\nexport interface NavigateToScreenPayload {\n screensetId: string;\n screenId: string;\n}\n\n/**\n * Navigate to Screenset Payload\n */\nexport interface NavigateToScreensetPayload {\n screensetId: string;\n}\n\n/**\n * Show Popup Payload\n */\nexport interface ShowPopupPayload {\n id: string;\n title?: string;\n content?: () => Promise<{ default: React.ComponentType }>;\n size?: 'sm' | 'md' | 'lg' | 'xl' | 'full';\n}\n\n/**\n * Change Theme Payload\n */\nexport interface ChangeThemePayload {\n themeId: string;\n}\n\n/**\n * Set Language Payload\n */\nexport interface SetLanguagePayload {\n language: string;\n}\n"],"mappings":";;;;;;;;;;;;;;;;AAAA;AAAA;","names":[]}
|