commandsState.ts63 lines · main
1import { proxy } from 'valtio'
2
3import { section$new } from '../CommandSection'
4import { type CommandOptions, type ICommandSection, type ICommandsState } from '../types'
5
6const initCommandsState = () => {
7 const state: ICommandsState = proxy({
8 commandSections: [],
9 registerSection: (sectionName, commands, options) => {
10 let editIndex = state.commandSections.findIndex((section) => section.name === sectionName)
11 if (editIndex === -1) editIndex = state.commandSections.length
12
13 state.commandSections[editIndex] ??= section$new(sectionName)
14 if (options?.sectionMeta) {
15 const oldMeta = state.commandSections[editIndex].meta
16 if (!!oldMeta && typeof oldMeta === 'object' && typeof options.sectionMeta === 'object') {
17 state.commandSections[editIndex].meta = { ...oldMeta, ...options.sectionMeta }
18 } else {
19 state.commandSections[editIndex].meta = options.sectionMeta
20 }
21 }
22
23 if (options?.forceMountSection) state.commandSections[editIndex].forceMount = true
24
25 if (options?.orderCommands) {
26 state.commandSections[editIndex].commands = options.orderCommands(
27 state.commandSections[editIndex].commands,
28 commands
29 )
30 } else {
31 state.commandSections[editIndex].commands.push(...commands)
32 }
33
34 state.commandSections =
35 options?.orderSection?.(state.commandSections, editIndex) ?? state.commandSections
36
37 return () => {
38 const idx = state.commandSections.findIndex((section) => section.name === sectionName)
39 if (idx !== -1) {
40 const filteredCommands = state.commandSections[idx].commands.filter(
41 (command) => !commands.map((cmd) => cmd.id).includes(command.id)
42 )
43 if (!filteredCommands.length) {
44 state.commandSections.splice(idx, 1)
45 } else {
46 state.commandSections[idx].commands = filteredCommands
47 }
48 }
49 }
50 },
51 })
52
53 return state
54}
55
56const orderSectionFirst = (sections: ICommandSection[], idx: number) => [
57 sections[idx],
58 ...sections.slice(0, idx),
59 ...sections.slice(idx + 1),
60]
61
62export { initCommandsState, orderSectionFirst }
63export type { CommandOptions }