( raw: unknown, activeTabFallback: TabType )
| 78 | } |
| 79 | |
| 80 | export function parseRightSidebarLayoutState( |
| 81 | raw: unknown, |
| 82 | activeTabFallback: TabType |
| 83 | ): RightSidebarLayoutState { |
| 84 | // Pre-parse migration: strip removed static tabs from raw data before validation. |
| 85 | // Must run before isRightSidebarLayoutState since isTabType rejects legacy tabs. |
| 86 | if (raw && typeof raw === "object") { |
| 87 | const r = raw as Record<string, unknown>; |
| 88 | if (r.root && typeof r.root === "object") { |
| 89 | stripRemovedStaticTabs(r.root as Record<string, unknown>); |
| 90 | } |
| 91 | } |
| 92 | |
| 93 | if (isRightSidebarLayoutState(raw)) { |
| 94 | // Post-validation migration: auto-add any registry-declared `inDefaultLayout` |
| 95 | // tabs that the persisted layout is missing. This means newly-introduced |
| 96 | // default tabs (e.g., the Instructions tab) appear for existing users |
| 97 | // automatically — no user action, no extra bookkeeping in this module. |
| 98 | return ensureDefaultLayoutTabs(raw); |
| 99 | } |
| 100 | |
| 101 | return getDefaultRightSidebarLayoutState(activeTabFallback); |
| 102 | } |
| 103 | |
| 104 | /** |
| 105 | * Ensure every `inDefaultLayout: true` tab from the registry is present in |
no test coverage detected