()
| 30 | const plugins = createMemo(() => store.plugins) |
| 31 | /** |
| 32 | * Derived, never stored. The layout tree is the only record of what is open, |
| 33 | * so this cannot drift out of step with it. |
| 34 | * |
| 35 | * Compared by contents, not identity: `flattenTabs` builds a fresh array every |
| 36 | * time, and without this every unrelated store write would look like a change |
| 37 | * and re-run each plugin's `render`. |
| 38 | */ |
| 39 | const activePlugins = createMemo(() => flattenTabs(store.state.layout), [], { |
| 40 | equals: (a, b) => a.length === b.length && a.every((id, i) => id === b[i]), |
| 41 | }) |
| 42 | const layout = createMemo(() => store.state.layout) |
| 43 | |
| 44 | const setLayout = (next: LayoutNode | null) => { |
| 45 | setStore((previous) => ({ |
| 46 | ...previous, |
| 47 | state: { ...previous.state, layout: next }, |
| 48 | })) |
| 49 | } |
| 50 | |
| 51 | const toggleActivePlugins = (pluginId: string) => { |
| 52 | const current = store.state.layout |
| 53 | const isActive = flattenTabs(current).includes(pluginId) |
| 54 | |
| 55 | if (isActive) { |
| 56 | // `destroy` is deliberately not called here. It hangs off the pane's own |
| 57 | // teardown in `PluginWorkspace`, so it fires exactly once however the pane |
| 58 | // was closed — this toggle, a tab's close button, or a whole group going |
| 59 | // away — and it fires before the mount node is detached. |
| 60 | setLayout(closeTab(current, pluginId)) |
| 61 | return |
| 62 | } |
| 63 | |
| 64 | if (flattenTabs(current).length >= MAX_ACTIVE_PLUGINS) return |
| 65 | |
| 66 | // Opening from the strip adds a pane alongside the others at an equal share, |
| 67 | // which is the side-by-side behaviour the strip has always had. Dragging |
| 68 | // decides placement for itself. |
| 69 | setLayout(appendPane(current, pluginId)) |
| 70 | } |
| 71 | |
| 72 | return { plugins, toggleActivePlugins, activePlugins, layout, setLayout } |
| 73 | } |
| 74 | |
| 75 | export const createDevtoolsState = () => { |
| 76 | const { store, setStore } = createDevtoolsContext() |
| 77 | const state = createMemo(() => store.state) |
no test coverage detected