@witchcraft/spellcraft 0.0.1

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.
Files changed (367) hide show
  1. package/README.md +579 -0
  2. package/dist/core/EmulatedEvent.d.ts +10 -0
  3. package/dist/core/EmulatedEvent.js +19 -0
  4. package/dist/core/Emulator.d.ts +74 -0
  5. package/dist/core/Emulator.js +153 -0
  6. package/dist/core/ShortcutManagerManager.d.ts +103 -0
  7. package/dist/core/ShortcutManagerManager.js +267 -0
  8. package/dist/core/addCommand.d.ts +7 -0
  9. package/dist/core/addCommand.js +7 -0
  10. package/dist/core/addKey.d.ts +7 -0
  11. package/dist/core/addKey.js +7 -0
  12. package/dist/core/addShortcut.d.ts +7 -0
  13. package/dist/core/addShortcut.js +7 -0
  14. package/dist/core/attach.d.ts +10 -0
  15. package/dist/core/attach.js +13 -0
  16. package/dist/core/createCommand.d.ts +4 -0
  17. package/dist/core/createCommand.js +11 -0
  18. package/dist/core/createCommands.d.ts +11 -0
  19. package/dist/core/createCommands.js +20 -0
  20. package/dist/core/createCondition.d.ts +7 -0
  21. package/dist/core/createCondition.js +11 -0
  22. package/dist/core/createContext.d.ts +2 -0
  23. package/dist/core/createContext.js +8 -0
  24. package/dist/core/createKey.d.ts +10 -0
  25. package/dist/core/createKey.js +35 -0
  26. package/dist/core/createKeys.d.ts +5 -0
  27. package/dist/core/createKeys.js +36 -0
  28. package/dist/core/createManager.d.ts +81 -0
  29. package/dist/core/createManager.js +83 -0
  30. package/dist/core/createManagerEventListeners.d.ts +4 -0
  31. package/dist/core/createManagerEventListeners.js +130 -0
  32. package/dist/core/createManagerOptions.d.ts +8 -0
  33. package/dist/core/createManagerOptions.js +17 -0
  34. package/dist/core/createShortcut.d.ts +8 -0
  35. package/dist/core/createShortcut.js +24 -0
  36. package/dist/core/createShortcuts.d.ts +13 -0
  37. package/dist/core/createShortcuts.js +20 -0
  38. package/dist/core/detach.d.ts +10 -0
  39. package/dist/core/detach.js +6 -0
  40. package/dist/core/index.d.ts +32 -0
  41. package/dist/core/index.js +32 -0
  42. package/dist/core/removeCommand.d.ts +7 -0
  43. package/dist/core/removeCommand.js +7 -0
  44. package/dist/core/removeKey.d.ts +7 -0
  45. package/dist/core/removeKey.js +7 -0
  46. package/dist/core/removeShortcut.d.ts +7 -0
  47. package/dist/core/removeShortcut.js +7 -0
  48. package/dist/core/setCommandProp.d.ts +17 -0
  49. package/dist/core/setCommandProp.js +96 -0
  50. package/dist/core/setCommandsProp.d.ts +15 -0
  51. package/dist/core/setCommandsProp.js +94 -0
  52. package/dist/core/setKeyProp.d.ts +16 -0
  53. package/dist/core/setKeyProp.js +47 -0
  54. package/dist/core/setKeysProp.d.ts +10 -0
  55. package/dist/core/setKeysProp.js +166 -0
  56. package/dist/core/setManagerProp.d.ts +34 -0
  57. package/dist/core/setManagerProp.js +54 -0
  58. package/dist/core/setShortcutProp.d.ts +9 -0
  59. package/dist/core/setShortcutProp.js +50 -0
  60. package/dist/core/setShortcutsProp.d.ts +12 -0
  61. package/dist/core/setShortcutsProp.js +93 -0
  62. package/dist/defaults/KeysSorter.d.ts +35 -0
  63. package/dist/defaults/KeysSorter.js +20 -0
  64. package/dist/defaults/Stringifier.d.ts +66 -0
  65. package/dist/defaults/Stringifier.js +119 -0
  66. package/dist/defaults/defaultConditionEquals.d.ts +19 -0
  67. package/dist/defaults/defaultConditionEquals.js +5 -0
  68. package/dist/defaults/defaultManagerCallback.d.ts +7 -0
  69. package/dist/defaults/defaultManagerCallback.js +5 -0
  70. package/dist/helpers/KnownError.d.ts +8 -0
  71. package/dist/helpers/KnownError.js +3 -0
  72. package/dist/helpers/calculateAndSetPositionAndWidth.d.ts +13 -0
  73. package/dist/helpers/calculateAndSetPositionAndWidth.js +18 -0
  74. package/dist/helpers/calculateLayoutSize.d.ts +9 -0
  75. package/dist/helpers/calculateLayoutSize.js +13 -0
  76. package/dist/helpers/doesShortcutConflict.d.ts +18 -0
  77. package/dist/helpers/doesShortcutConflict.js +42 -0
  78. package/dist/helpers/equalsCommand.d.ts +7 -0
  79. package/dist/helpers/equalsCommand.js +4 -0
  80. package/dist/helpers/equalsContext.d.ts +7 -0
  81. package/dist/helpers/equalsContext.js +19 -0
  82. package/dist/helpers/equalsShortcut.d.ts +9 -0
  83. package/dist/helpers/equalsShortcut.js +7 -0
  84. package/dist/helpers/forceClear.d.ts +12 -0
  85. package/dist/helpers/forceClear.js +16 -0
  86. package/dist/helpers/forceUpdateNativeKeysState.d.ts +5 -0
  87. package/dist/helpers/forceUpdateNativeKeysState.js +4 -0
  88. package/dist/helpers/generateKeyShortcutMap.d.ts +23 -0
  89. package/dist/helpers/generateKeyShortcutMap.js +64 -0
  90. package/dist/helpers/getKeyFromEventCode.d.ts +15 -0
  91. package/dist/helpers/getKeyFromEventCode.js +36 -0
  92. package/dist/helpers/getKeyFromIdOrVariant.d.ts +4 -0
  93. package/dist/helpers/getKeyFromIdOrVariant.js +26 -0
  94. package/dist/helpers/getKeyboardLayoutMap.d.ts +5 -0
  95. package/dist/helpers/getKeyboardLayoutMap.js +7 -0
  96. package/dist/helpers/getLabel.d.ts +9 -0
  97. package/dist/helpers/getLabel.js +6 -0
  98. package/dist/helpers/getTriggerableShortcut.d.ts +6 -0
  99. package/dist/helpers/getTriggerableShortcut.js +25 -0
  100. package/dist/helpers/index.d.ts +28 -0
  101. package/dist/helpers/index.js +28 -0
  102. package/dist/helpers/isValidManager.d.ts +3 -0
  103. package/dist/helpers/isValidManager.js +20 -0
  104. package/dist/helpers/isValidShortcut.d.ts +3 -0
  105. package/dist/helpers/isValidShortcut.js +10 -0
  106. package/dist/helpers/labelWithEvent.d.ts +13 -0
  107. package/dist/helpers/labelWithEvent.js +20 -0
  108. package/dist/helpers/labelWithKeyboardMap.d.ts +15 -0
  109. package/dist/helpers/labelWithKeyboardMap.js +17 -0
  110. package/dist/helpers/managerToStorableClone.d.ts +12 -0
  111. package/dist/helpers/managerToStorableClone.js +13 -0
  112. package/dist/helpers/onKeyboardLayoutChange.d.ts +10 -0
  113. package/dist/helpers/onKeyboardLayoutChange.js +7 -0
  114. package/dist/helpers/safeSetManagerChain.d.ts +20 -0
  115. package/dist/helpers/safeSetManagerChain.js +37 -0
  116. package/dist/helpers/shortcutCanExecuteIn.d.ts +4 -0
  117. package/dist/helpers/shortcutCanExecuteIn.js +9 -0
  118. package/dist/helpers/shortcutIsTriggerableBy.d.ts +2 -0
  119. package/dist/helpers/shortcutIsTriggerableBy.js +5 -0
  120. package/dist/helpers/shortcutSwapChords.d.ts +75 -0
  121. package/dist/helpers/shortcutSwapChords.js +118 -0
  122. package/dist/helpers/virtualPress.d.ts +13 -0
  123. package/dist/helpers/virtualPress.js +15 -0
  124. package/dist/helpers/virtualRelease.d.ts +5 -0
  125. package/dist/helpers/virtualRelease.js +15 -0
  126. package/dist/helpers/virtualToggle.d.ts +7 -0
  127. package/dist/helpers/virtualToggle.js +16 -0
  128. package/dist/internal/addToChain.d.ts +3 -0
  129. package/dist/internal/addToChain.js +27 -0
  130. package/dist/internal/areValidKeys.d.ts +7 -0
  131. package/dist/internal/areValidKeys.js +28 -0
  132. package/dist/internal/areValidVariants.d.ts +4 -0
  133. package/dist/internal/areValidVariants.js +45 -0
  134. package/dist/internal/checkTrigger.d.ts +2 -0
  135. package/dist/internal/checkTrigger.js +47 -0
  136. package/dist/internal/checkUntrigger.d.ts +2 -0
  137. package/dist/internal/checkUntrigger.js +18 -0
  138. package/dist/internal/cloneLastChord.d.ts +4 -0
  139. package/dist/internal/cloneLastChord.js +5 -0
  140. package/dist/internal/containsPossibleToggleChords.d.ts +13 -0
  141. package/dist/internal/containsPossibleToggleChords.js +65 -0
  142. package/dist/internal/errorTextAdd.d.ts +1 -0
  143. package/dist/internal/errorTextAdd.js +11 -0
  144. package/dist/internal/errorTextInUse.d.ts +1 -0
  145. package/dist/internal/errorTextInUse.js +8 -0
  146. package/dist/internal/errorTextRemove.d.ts +1 -0
  147. package/dist/internal/errorTextRemove.js +8 -0
  148. package/dist/internal/getModifierState.d.ts +2 -0
  149. package/dist/internal/getModifierState.js +7 -0
  150. package/dist/internal/getPressedKeys.d.ts +7 -0
  151. package/dist/internal/getPressedKeys.js +18 -0
  152. package/dist/internal/getPressedModifierKeys.d.ts +2 -0
  153. package/dist/internal/getPressedModifierKeys.js +10 -0
  154. package/dist/internal/getPressedNonModifierKeys.d.ts +7 -0
  155. package/dist/internal/getPressedNonModifierKeys.js +11 -0
  156. package/dist/internal/inChain.d.ts +5 -0
  157. package/dist/internal/inChain.js +14 -0
  158. package/dist/internal/isValidChain.d.ts +10 -0
  159. package/dist/internal/isValidChain.js +22 -0
  160. package/dist/internal/isValidChord.d.ts +11 -0
  161. package/dist/internal/isValidChord.js +59 -0
  162. package/dist/internal/isValidCommand.d.ts +12 -0
  163. package/dist/internal/isValidCommand.js +20 -0
  164. package/dist/internal/keyOrder.d.ts +6 -0
  165. package/dist/internal/keyOrder.js +14 -0
  166. package/dist/internal/removeFromChain.d.ts +3 -0
  167. package/dist/internal/removeFromChain.js +32 -0
  168. package/dist/internal/safeSetEmulatedToggleState.d.ts +4 -0
  169. package/dist/internal/safeSetEmulatedToggleState.js +13 -0
  170. package/dist/internal/setKeysState.d.ts +8 -0
  171. package/dist/internal/setKeysState.js +42 -0
  172. package/dist/internal/updateNativeKeysState.d.ts +14 -0
  173. package/dist/internal/updateNativeKeysState.js +58 -0
  174. package/dist/layouts/createLayout.d.ts +25 -0
  175. package/dist/layouts/createLayout.js +221 -0
  176. package/dist/module.d.mts +13 -0
  177. package/dist/module.json +9 -0
  178. package/dist/module.mjs +40 -0
  179. package/dist/runtime/composables/useLabeledByKeyboardLayoutMap.d.ts +9 -0
  180. package/dist/runtime/composables/useLabeledByKeyboardLayoutMap.js +19 -0
  181. package/dist/runtime/composables/usePointerCoords.d.ts +32 -0
  182. package/dist/runtime/composables/usePointerCoords.js +17 -0
  183. package/dist/runtime/composables/useShortcutManagerContextCount.d.ts +14 -0
  184. package/dist/runtime/composables/useShortcutManagerContextCount.js +61 -0
  185. package/dist/runtime/composables/useShortcutManagerKeysLayout.d.ts +18 -0
  186. package/dist/runtime/composables/useShortcutManagerKeysLayout.js +22 -0
  187. package/dist/runtime/composables/useShortcutManagerVirtualPress.d.ts +6 -0
  188. package/dist/runtime/composables/useShortcutManagerVirtualPress.js +24 -0
  189. package/dist/runtime/types.d.ts +10 -0
  190. package/dist/runtime/types.js +1 -0
  191. package/dist/runtime/utils/shortcutToId.d.ts +5 -0
  192. package/dist/runtime/utils/shortcutToId.js +6 -0
  193. package/dist/types/commands.d.ts +113 -0
  194. package/dist/types/commands.js +0 -0
  195. package/dist/types/condition.d.ts +29 -0
  196. package/dist/types/condition.js +0 -0
  197. package/dist/types/context.d.ts +18 -0
  198. package/dist/types/context.js +0 -0
  199. package/dist/types/enums.d.ts +186 -0
  200. package/dist/types/enums.js +70 -0
  201. package/dist/types/general.d.ts +92 -0
  202. package/dist/types/general.js +0 -0
  203. package/dist/types/index.d.ts +8 -0
  204. package/dist/types/index.js +8 -0
  205. package/dist/types/keys.d.ts +332 -0
  206. package/dist/types/keys.js +0 -0
  207. package/dist/types/manager.d.ts +249 -0
  208. package/dist/types/manager.js +0 -0
  209. package/dist/types/plugins.d.ts +1 -0
  210. package/dist/types/plugins.js +0 -0
  211. package/dist/types/shortcuts.d.ts +144 -0
  212. package/dist/types/shortcuts.js +0 -0
  213. package/dist/types/utils.d.ts +1 -0
  214. package/dist/types/utils.js +0 -0
  215. package/dist/types.d.mts +3 -0
  216. package/dist/utils/chainContainsSubset.d.ts +27 -0
  217. package/dist/utils/chainContainsSubset.js +45 -0
  218. package/dist/utils/cloneChain.d.ts +2 -0
  219. package/dist/utils/cloneChain.js +11 -0
  220. package/dist/utils/cloneKey.d.ts +3 -0
  221. package/dist/utils/cloneKey.js +26 -0
  222. package/dist/utils/containsKey.d.ts +7 -0
  223. package/dist/utils/containsKey.js +4 -0
  224. package/dist/utils/dedupeKeys.d.ts +9 -0
  225. package/dist/utils/dedupeKeys.js +9 -0
  226. package/dist/utils/equalsKey.d.ts +12 -0
  227. package/dist/utils/equalsKey.js +13 -0
  228. package/dist/utils/equalsKeys.d.ts +24 -0
  229. package/dist/utils/equalsKeys.js +15 -0
  230. package/dist/utils/index.d.ts +14 -0
  231. package/dist/utils/index.js +14 -0
  232. package/dist/utils/isAnyKey.d.ts +5 -0
  233. package/dist/utils/isAnyKey.js +5 -0
  234. package/dist/utils/isMouseKey.d.ts +5 -0
  235. package/dist/utils/isMouseKey.js +20 -0
  236. package/dist/utils/isNormalKey.d.ts +5 -0
  237. package/dist/utils/isNormalKey.js +5 -0
  238. package/dist/utils/isTriggerKey.d.ts +5 -0
  239. package/dist/utils/isTriggerKey.js +3 -0
  240. package/dist/utils/isWheelKey.d.ts +5 -0
  241. package/dist/utils/isWheelKey.js +11 -0
  242. package/dist/utils/mapKeys.d.ts +8 -0
  243. package/dist/utils/mapKeys.js +5 -0
  244. package/dist/utils/removeKeys.d.ts +7 -0
  245. package/dist/utils/removeKeys.js +4 -0
  246. package/package.json +156 -0
  247. package/src/core/EmulatedEvent.ts +29 -0
  248. package/src/core/Emulator.ts +185 -0
  249. package/src/core/ShortcutManagerManager.ts +380 -0
  250. package/src/core/addCommand.ts +24 -0
  251. package/src/core/addKey.ts +25 -0
  252. package/src/core/addShortcut.ts +24 -0
  253. package/src/core/attach.ts +27 -0
  254. package/src/core/createCommand.ts +24 -0
  255. package/src/core/createCommands.ts +45 -0
  256. package/src/core/createCondition.ts +21 -0
  257. package/src/core/createContext.ts +14 -0
  258. package/src/core/createKey.ts +59 -0
  259. package/src/core/createKeys.ts +68 -0
  260. package/src/core/createManager.ts +209 -0
  261. package/src/core/createManagerEventListeners.ts +139 -0
  262. package/src/core/createManagerOptions.ts +29 -0
  263. package/src/core/createShortcut.ts +49 -0
  264. package/src/core/createShortcuts.ts +51 -0
  265. package/src/core/detach.ts +21 -0
  266. package/src/core/index.ts +35 -0
  267. package/src/core/removeCommand.ts +25 -0
  268. package/src/core/removeKey.ts +25 -0
  269. package/src/core/removeShortcut.ts +24 -0
  270. package/src/core/setCommandProp.ts +140 -0
  271. package/src/core/setCommandsProp.ts +128 -0
  272. package/src/core/setKeyProp.ts +80 -0
  273. package/src/core/setKeysProp.ts +205 -0
  274. package/src/core/setManagerProp.ts +111 -0
  275. package/src/core/setShortcutProp.ts +89 -0
  276. package/src/core/setShortcutsProp.ts +124 -0
  277. package/src/defaults/KeysSorter.ts +55 -0
  278. package/src/defaults/Stringifier.ts +234 -0
  279. package/src/defaults/defaultConditionEquals.ts +29 -0
  280. package/src/defaults/defaultManagerCallback.ts +14 -0
  281. package/src/helpers/KnownError.ts +13 -0
  282. package/src/helpers/calculateAndSetPositionAndWidth.ts +30 -0
  283. package/src/helpers/calculateLayoutSize.ts +22 -0
  284. package/src/helpers/doesShortcutConflict.ts +72 -0
  285. package/src/helpers/equalsCommand.ts +18 -0
  286. package/src/helpers/equalsContext.ts +29 -0
  287. package/src/helpers/equalsShortcut.ts +34 -0
  288. package/src/helpers/forceClear.ts +31 -0
  289. package/src/helpers/forceUpdateNativeKeysState.ts +9 -0
  290. package/src/helpers/generateKeyShortcutMap.ts +113 -0
  291. package/src/helpers/getKeyFromEventCode.ts +67 -0
  292. package/src/helpers/getKeyFromIdOrVariant.ts +33 -0
  293. package/src/helpers/getKeyboardLayoutMap.ts +13 -0
  294. package/src/helpers/getLabel.ts +15 -0
  295. package/src/helpers/getTriggerableShortcut.ts +37 -0
  296. package/src/helpers/index.ts +30 -0
  297. package/src/helpers/isValidManager.ts +29 -0
  298. package/src/helpers/isValidShortcut.ts +20 -0
  299. package/src/helpers/labelWithEvent.ts +41 -0
  300. package/src/helpers/labelWithKeyboardMap.ts +37 -0
  301. package/src/helpers/managerToStorableClone.ts +26 -0
  302. package/src/helpers/onKeyboardLayoutChange.ts +17 -0
  303. package/src/helpers/safeSetManagerChain.ts +66 -0
  304. package/src/helpers/shortcutCanExecuteIn.ts +24 -0
  305. package/src/helpers/shortcutIsTriggerableBy.ts +15 -0
  306. package/src/helpers/shortcutSwapChords.ts +240 -0
  307. package/src/helpers/virtualPress.ts +34 -0
  308. package/src/helpers/virtualRelease.ts +25 -0
  309. package/src/helpers/virtualToggle.ts +28 -0
  310. package/src/internal/addToChain.ts +40 -0
  311. package/src/internal/areValidKeys.ts +40 -0
  312. package/src/internal/areValidVariants.ts +59 -0
  313. package/src/internal/checkTrigger.ts +55 -0
  314. package/src/internal/checkUntrigger.ts +26 -0
  315. package/src/internal/cloneLastChord.ts +10 -0
  316. package/src/internal/containsPossibleToggleChords.ts +91 -0
  317. package/src/internal/errorTextAdd.ts +18 -0
  318. package/src/internal/errorTextInUse.ts +10 -0
  319. package/src/internal/errorTextRemove.ts +10 -0
  320. package/src/internal/getModifierState.ts +15 -0
  321. package/src/internal/getPressedKeys.ts +26 -0
  322. package/src/internal/getPressedModifierKeys.ts +14 -0
  323. package/src/internal/getPressedNonModifierKeys.ts +19 -0
  324. package/src/internal/inChain.ts +25 -0
  325. package/src/internal/isValidChain.ts +42 -0
  326. package/src/internal/isValidChord.ts +87 -0
  327. package/src/internal/isValidCommand.ts +35 -0
  328. package/src/internal/keyOrder.ts +24 -0
  329. package/src/internal/removeFromChain.ts +46 -0
  330. package/src/internal/safeSetEmulatedToggleState.ts +23 -0
  331. package/src/internal/setKeysState.ts +71 -0
  332. package/src/internal/updateNativeKeysState.ts +84 -0
  333. package/src/layouts/createLayout.ts +328 -0
  334. package/src/module.ts +62 -0
  335. package/src/runtime/composables/useLabeledByKeyboardLayoutMap.ts +28 -0
  336. package/src/runtime/composables/usePointerCoords.ts +40 -0
  337. package/src/runtime/composables/useShortcutManagerContextCount.ts +81 -0
  338. package/src/runtime/composables/useShortcutManagerKeysLayout.ts +42 -0
  339. package/src/runtime/composables/useShortcutManagerVirtualPress.ts +30 -0
  340. package/src/runtime/types.ts +10 -0
  341. package/src/runtime/utils/shortcutToId.ts +14 -0
  342. package/src/types/commands.ts +148 -0
  343. package/src/types/condition.ts +35 -0
  344. package/src/types/context.ts +19 -0
  345. package/src/types/enums.ts +236 -0
  346. package/src/types/general.ts +117 -0
  347. package/src/types/index.ts +10 -0
  348. package/src/types/keys.ts +385 -0
  349. package/src/types/manager.ts +374 -0
  350. package/src/types/plugins.ts +32 -0
  351. package/src/types/shortcuts.ts +204 -0
  352. package/src/types/utils.ts +40 -0
  353. package/src/utils/chainContainsSubset.ts +97 -0
  354. package/src/utils/cloneChain.ts +13 -0
  355. package/src/utils/cloneKey.ts +33 -0
  356. package/src/utils/containsKey.ts +17 -0
  357. package/src/utils/dedupeKeys.ts +23 -0
  358. package/src/utils/equalsKey.ts +32 -0
  359. package/src/utils/equalsKeys.ts +50 -0
  360. package/src/utils/index.ts +16 -0
  361. package/src/utils/isAnyKey.ts +12 -0
  362. package/src/utils/isMouseKey.ts +27 -0
  363. package/src/utils/isNormalKey.ts +15 -0
  364. package/src/utils/isTriggerKey.ts +7 -0
  365. package/src/utils/isWheelKey.ts +18 -0
  366. package/src/utils/mapKeys.ts +21 -0
  367. package/src/utils/removeKeys.ts +16 -0
@@ -0,0 +1,17 @@
1
+ import { type Result } from "@alanscodelog/utils/Result";
2
+ import { type CanHookErrors, type Command, type CommandSetEntries, type Manager, type MultipleErrors } from "../types/index.js";
3
+ /**
4
+ * Sets a settable command property.
5
+ *
6
+ * You should not use this to set key state the manager manages (those tagged with @Managed in the docs) unless you've forgone using the manager.
7
+ *
8
+ * Note that while the manager argument is always required, for unmanaged properties you can pass {} and for most others you can pass a partial manager if needed. This is because it's very difficult to keep the heavy per prop types and allow the manager to be optional in these cases.
9
+ *
10
+ */
11
+ export declare function setCommandProp<TEntries extends CommandSetEntries, TProp extends keyof CommandSetEntries, TEntry extends TEntries[TProp], THooks extends Manager["hooks"], TCheck extends boolean | "only" = true>(
12
+ /** Command is mutated if check is not "only". */
13
+ command: Command, prop: TProp, val: TEntry["val"], manager: (TEntry["manager"] extends never ? unknown : TEntry["manager"]) & {
14
+ hooks?: THooks;
15
+ }, { check }?: {
16
+ check?: TCheck;
17
+ }): Result<TCheck extends "only" ? true : Command, MultipleErrors<TEntry["error"]> | CanHookErrors<Manager["hooks"] extends never ? never : THooks, "canSetCommandProp">>;
@@ -0,0 +1,96 @@
1
+ import { castType } from "@alanscodelog/utils/castType";
2
+ import { crop } from "@alanscodelog/utils/crop";
3
+ import { indent } from "@alanscodelog/utils/indent";
4
+ import { Err, Ok } from "@alanscodelog/utils/Result";
5
+ import { setCommandsProp } from "./setCommandsProp.js";
6
+ import { setShortcutProp } from "./setShortcutProp.js";
7
+ import { KnownError } from "../helpers/KnownError.js";
8
+ import { errorTextAdd } from "../internal/errorTextAdd.js";
9
+ import { SHORTCUT_ERROR } from "../types/index.js";
10
+ const canHookable = ["condition", "execute"];
11
+ export function setCommandProp(command, prop, val, manager, {
12
+ check = true
13
+ } = {}) {
14
+ if (check) {
15
+ switch (prop) {
16
+ case "name": {
17
+ castType(manager);
18
+ castType(val);
19
+ const s = manager.options.stringifier;
20
+ const existing = manager.commands.entries[val];
21
+ if (existing) {
22
+ return Err(new KnownError(
23
+ SHORTCUT_ERROR.DUPLICATE_COMMAND,
24
+ errorTextAdd(
25
+ "Command",
26
+ val,
27
+ s.stringify(existing),
28
+ s.stringify(command)
29
+ ),
30
+ { existing, self: manager.commands }
31
+ ));
32
+ }
33
+ const managerClone = {
34
+ ...manager,
35
+ commands: {
36
+ ...manager.commands,
37
+ entries: {
38
+ ...manager.commands.entries,
39
+ [val]: { ...command, name: val }
40
+ }
41
+ }
42
+ };
43
+ const shortcutErrors = [];
44
+ for (const shortcut of manager.shortcuts.entries) {
45
+ if (shortcut.command === command.name) {
46
+ const res = setShortcutProp(shortcut, "command", val, managerClone, { check: "only" });
47
+ if (res.isError) shortcutErrors.push(res.error);
48
+ }
49
+ }
50
+ if (shortcutErrors.length > 0) {
51
+ return Err(new KnownError(
52
+ SHORTCUT_ERROR.MULTIPLE_ERRORS,
53
+ crop`
54
+ Received multiple errors attempting to change command name from ${command.name} to ${val}:
55
+ ${indent(shortcutErrors.map((_) => _.message).join("\n"), 7)}
56
+ `,
57
+ { errors: shortcutErrors }
58
+ ));
59
+ }
60
+ break;
61
+ }
62
+ default:
63
+ break;
64
+ }
65
+ if (manager?.hooks && "canSetCommandProp" in manager.hooks && canHookable.includes(prop)) {
66
+ const canHook = manager.hooks.canSetCommandProp?.(command, prop, val);
67
+ if (canHook instanceof Error) {
68
+ return Err(canHook);
69
+ }
70
+ }
71
+ }
72
+ if (check === "only") {
73
+ return Ok(true);
74
+ }
75
+ if (prop === "name") {
76
+ castType(manager);
77
+ castType(val);
78
+ setCommandsProp("entries@add", { ...command, name: val }, manager).unwrap();
79
+ const old = command.name;
80
+ const oldCommand = manager.commands.entries[old];
81
+ for (const shortcut of manager.shortcuts.entries) {
82
+ if (shortcut.command === old) {
83
+ setShortcutProp(shortcut, "command", val, manager).unwrap();
84
+ }
85
+ }
86
+ if (manager.commands.entries[old]) {
87
+ setCommandsProp("entries@remove", oldCommand, manager).unwrap();
88
+ }
89
+ } else {
90
+ command[prop] = val;
91
+ }
92
+ if (manager?.hooks && "onSetCommandProp" in manager.hooks) {
93
+ manager?.hooks?.onSetCommandProp?.(command, prop, val);
94
+ }
95
+ return Ok(command);
96
+ }
@@ -0,0 +1,15 @@
1
+ import { type Result } from "@alanscodelog/utils/Result";
2
+ import { type CanHookErrors, type Command, type CommandsSetEntries, type Manager, type MultipleErrors } from "../types/index.js";
3
+ /**
4
+ * Sets a settable command property.
5
+ *
6
+ * You should not use this to set command state the manager manages (those tagged with @Managed in the docs) unless you've forgone using the manager.
7
+ *
8
+ */
9
+ export declare function setCommandsProp<TEntries extends CommandsSetEntries, TProp extends keyof CommandsSetEntries, TEntry extends TEntries[TProp], THooks extends Manager["hooks"], TCheck extends boolean | "only" = true>(prop: TProp, val: TEntry["val"],
10
+ /** Commands is mutated if check is not "only". */
11
+ manager: TEntry["manager"] & {
12
+ hooks?: THooks;
13
+ }, { check }?: {
14
+ check?: TCheck;
15
+ }): Result<TCheck extends "only" ? true : Command, MultipleErrors<TEntry["error"]> | CanHookErrors<Manager["hooks"] extends never ? never : THooks, "canSetCommandsProp">>;
@@ -0,0 +1,94 @@
1
+ import { castType } from "@alanscodelog/utils/castType";
2
+ import { Err, Ok } from "@alanscodelog/utils/Result";
3
+ import { KnownError } from "../helpers/KnownError.js";
4
+ import { errorTextAdd } from "../internal/errorTextAdd.js";
5
+ import { errorTextInUse } from "../internal/errorTextInUse.js";
6
+ import { errorTextRemove } from "../internal/errorTextRemove.js";
7
+ import { SHORTCUT_ERROR } from "../types/index.js";
8
+ const canHookable = ["entries@add", "entries@remove"];
9
+ export function setCommandsProp(prop, val, manager, {
10
+ check = true
11
+ } = {}) {
12
+ const commands = manager.commands;
13
+ const s = manager.options.stringifier;
14
+ if (check) {
15
+ switch (prop) {
16
+ case "entries@add": {
17
+ castType(val);
18
+ castType(manager);
19
+ const command = val;
20
+ const existing = commands.entries[command.name];
21
+ if (existing) {
22
+ return Err(new KnownError(
23
+ SHORTCUT_ERROR.DUPLICATE_COMMAND,
24
+ errorTextAdd(
25
+ "Command",
26
+ s.stringifyCommand(existing.name, manager),
27
+ s.stringifyCommand(existing.name, manager),
28
+ s.stringifyCommand(command.name, manager)
29
+ ),
30
+ { existing, self: commands }
31
+ ));
32
+ }
33
+ break;
34
+ }
35
+ case "entries@remove": {
36
+ castType(val);
37
+ castType(manager);
38
+ const command = val;
39
+ if (!commands.entries[command.name]) {
40
+ return Err(new KnownError(
41
+ SHORTCUT_ERROR.MISSING,
42
+ errorTextRemove(
43
+ "Command",
44
+ s.stringify(command),
45
+ s.stringifyList("commands", Object.values(commands.entries))
46
+ ),
47
+ { entry: command.name, self: commands }
48
+ ));
49
+ }
50
+ const inUseShortcuts = manager.shortcuts.entries.filter((shortcut) => shortcut.command === command.name);
51
+ if (inUseShortcuts.length > 0) {
52
+ return Err(new KnownError(
53
+ SHORTCUT_ERROR.COMMAND_IN_USE,
54
+ errorTextInUse(
55
+ "command",
56
+ s.stringify(command),
57
+ s.stringifyList("shortcuts", inUseShortcuts, manager)
58
+ ),
59
+ { inUseShortcuts }
60
+ ));
61
+ }
62
+ break;
63
+ }
64
+ default:
65
+ break;
66
+ }
67
+ if (manager?.hooks && "canSetCommandsProp" in manager.hooks && canHookable.includes(prop)) {
68
+ const canHook = manager.hooks?.canSetCommandsProp?.(commands, prop, val);
69
+ if (canHook instanceof Error) {
70
+ return Err(canHook);
71
+ }
72
+ }
73
+ }
74
+ if (check === "only") {
75
+ return Ok(true);
76
+ }
77
+ switch (prop) {
78
+ case "entries@add": {
79
+ const command = val;
80
+ commands.entries[command.name] = command;
81
+ break;
82
+ }
83
+ case "entries@remove": {
84
+ const command = val;
85
+ delete commands.entries[command.name];
86
+ break;
87
+ }
88
+ default:
89
+ commands[prop] = val;
90
+ break;
91
+ }
92
+ manager.hooks?.onSetCommandsProp?.(commands, prop, val);
93
+ return Ok(commands);
94
+ }
@@ -0,0 +1,16 @@
1
+ import { type Result } from "@alanscodelog/utils/Result";
2
+ import type { CanHookErrors, Key, KeySetEntries, Manager, MultipleErrors } from "../types/index.js";
3
+ /**
4
+ * Sets a settable key property.
5
+ *
6
+ * You should not use this to set key state the manager manages (those tagged with @Managed in the docs) unless you've forgone using the manager.
7
+ *
8
+ * Note that while the manager argument is always required, for unmanaged properties you can pass {} and for most others you can pass a partial manager if needed. This is because it's very difficult to keep the heavy per prop types and allow the manager to be optional in these cases.
9
+ */
10
+ export declare function setKeyProp<TEntries extends KeySetEntries, TProp extends keyof KeySetEntries, TEntry extends TEntries[TProp], THooks extends Manager["hooks"], TCheck extends boolean | "only" = true>(
11
+ /** Key is mutated if check is not "only". */
12
+ key: Key, prop: TProp, val: TEntry["val"], manager: (TEntry["manager"] extends never ? unknown : TEntry["manager"]) & {
13
+ hooks?: THooks;
14
+ }, { check }?: {
15
+ check?: TCheck;
16
+ }): Result<TCheck extends "only" ? true : Key, MultipleErrors<TEntry["error"]> | CanHookErrors<THooks extends never ? never : THooks, "canSetKeyProp">>;
@@ -0,0 +1,47 @@
1
+ import { castType } from "@alanscodelog/utils/castType";
2
+ import { crop } from "@alanscodelog/utils/crop";
3
+ import { Err, Ok } from "@alanscodelog/utils/Result";
4
+ import { set } from "@alanscodelog/utils/set";
5
+ import { KnownError } from "../helpers/KnownError.js";
6
+ import { SHORTCUT_ERROR } from "../types/index.js";
7
+ const canHookable = ["x", "y", "width", "height", "label", "enabled", "render", "classes"];
8
+ export function setKeyProp(key, prop, val, manager, {
9
+ check = true
10
+ } = {}) {
11
+ if (check) {
12
+ switch (prop) {
13
+ case "toggleOnPressed":
14
+ case "toggleOffPressed":
15
+ case "pressed": {
16
+ castType(manager);
17
+ const s = manager.options.stringifier;
18
+ if (!key.enabled && val === true) {
19
+ return Err(
20
+ new KnownError(SHORTCUT_ERROR.CANNOT_SET_WHILE_DISABLED, crop`
21
+ The "${prop}" property cannot be set to true while a key is disabled. (Key: ${s.stringify(key, manager)})
22
+ `, { key })
23
+ );
24
+ }
25
+ break;
26
+ }
27
+ default:
28
+ break;
29
+ }
30
+ if (manager?.hooks && "canSetKeyProp" in manager.hooks && canHookable.includes(prop)) {
31
+ const canHook = manager.hooks.canSetKeyProp?.(key, prop, val);
32
+ if (canHook instanceof Error) {
33
+ return Err(canHook);
34
+ }
35
+ }
36
+ }
37
+ if (check === "only") {
38
+ return Ok(true);
39
+ }
40
+ if (prop.includes(".")) {
41
+ set(key, prop.split("."), val);
42
+ } else {
43
+ key[prop] = val;
44
+ }
45
+ manager?.hooks?.onSetKeyProp?.(key, prop, val);
46
+ return Ok(key);
47
+ }
@@ -0,0 +1,10 @@
1
+ import { type Result } from "@alanscodelog/utils/Result";
2
+ import { type CanHookErrors, type Key, type KeysSetEntries, type Manager, type MultipleErrors } from "../types/index.js";
3
+ /**
4
+ * Sets a settable {@link Keys} property.
5
+ */
6
+ export declare function setKeysProp<TEntries extends KeysSetEntries, TProp extends keyof KeysSetEntries, TEntry extends TEntries[TProp], THooks extends Manager["hooks"], TCheck extends boolean | "only" = true>(prop: TProp, val: TEntry["val"], manager: TEntry["manager"] & {
7
+ hooks?: THooks;
8
+ }, { check }?: {
9
+ check?: TCheck;
10
+ }): Result<TCheck extends "only" ? true : Key, MultipleErrors<TEntry["error"]> | CanHookErrors<Manager["hooks"] extends never ? never : THooks, "canSetKeysProp">>;
@@ -0,0 +1,166 @@
1
+ import { castType } from "@alanscodelog/utils/castType";
2
+ import { Err, Ok } from "@alanscodelog/utils/Result";
3
+ import { calculateLayoutSize } from "../helpers/calculateLayoutSize.js";
4
+ import { KnownError } from "../helpers/KnownError.js";
5
+ import { areValidVariants } from "../internal/areValidVariants.js";
6
+ import { errorTextAdd } from "../internal/errorTextAdd.js";
7
+ import { errorTextInUse } from "../internal/errorTextInUse.js";
8
+ import { errorTextRemove } from "../internal/errorTextRemove.js";
9
+ import { SHORTCUT_ERROR } from "../types/index.js";
10
+ import { containsKey } from "../utils/containsKey.js";
11
+ const canHookable = ["entries@add", "entries@remove"];
12
+ export function setKeysProp(prop, val, manager, {
13
+ check = true
14
+ } = {}) {
15
+ const keys = manager.keys;
16
+ if (check) {
17
+ switch (prop) {
18
+ case "entries@add": {
19
+ castType(val);
20
+ castType(manager);
21
+ const s = manager.options.stringifier;
22
+ const key = val;
23
+ const existing = keys.entries[key.id];
24
+ if (existing) {
25
+ return Err(new KnownError(
26
+ SHORTCUT_ERROR.DUPLICATE_KEY,
27
+ errorTextAdd(
28
+ "Key",
29
+ s.stringify(existing, manager),
30
+ s.stringify(existing, manager),
31
+ s.stringify(key, manager)
32
+ ),
33
+ { existing, self: keys }
34
+ ));
35
+ }
36
+ const areValidVariantsRes = areValidVariants(key, manager);
37
+ if (areValidVariantsRes.isError) return areValidVariantsRes;
38
+ break;
39
+ }
40
+ case "entries@remove": {
41
+ castType(val);
42
+ castType(manager);
43
+ const s = manager.options.stringifier;
44
+ const key = val;
45
+ if (!keys.entries[key.id]) {
46
+ return Err(new KnownError(
47
+ SHORTCUT_ERROR.MISSING,
48
+ errorTextRemove(
49
+ "Key",
50
+ s.stringify(key),
51
+ s.stringifyList("keys", Object.values(keys.entries))
52
+ ),
53
+ { entry: key.id, self: keys }
54
+ ));
55
+ }
56
+ const inUseShortcuts = manager.shortcuts.entries.filter((shortcut) => containsKey(shortcut.chain, key.id, keys));
57
+ if (inUseShortcuts.length > 0) {
58
+ return Err(new KnownError(
59
+ SHORTCUT_ERROR.KEY_IN_USE,
60
+ errorTextInUse(
61
+ "key",
62
+ s.stringify(key),
63
+ s.stringifyList("shortcuts", inUseShortcuts, manager)
64
+ ),
65
+ { inUseShortcuts }
66
+ ));
67
+ }
68
+ break;
69
+ }
70
+ default:
71
+ break;
72
+ }
73
+ if (manager.hooks && "canSetKeysProp" in manager.hooks && canHookable.includes(prop)) {
74
+ const canHook = manager.hooks.canSetKeysProp?.(keys, prop, val);
75
+ if (canHook instanceof Error) {
76
+ return Err(canHook);
77
+ }
78
+ }
79
+ }
80
+ if (check === "only") {
81
+ return Ok(true);
82
+ }
83
+ switch (prop) {
84
+ case "entries@add": {
85
+ castType(val);
86
+ castType(manager);
87
+ const key = val;
88
+ keys.entries[key.id] = key;
89
+ if (key.isToggle === "native") {
90
+ setKeysProp("nativeToggleKeys", [
91
+ ...keys.nativeToggleKeys,
92
+ key.id
93
+ ], manager).unwrap();
94
+ }
95
+ if (key.isModifier === "native") {
96
+ setKeysProp("nativeModifierKeys", [
97
+ ...keys.nativeModifierKeys,
98
+ key.id
99
+ ], manager).unwrap();
100
+ }
101
+ if (key.isToggle) {
102
+ setKeysProp(`toggles@add@${key.toggleOnId}`, key, manager).unwrap();
103
+ setKeysProp(`toggles@add@${key.toggleOffId}`, key, manager).unwrap();
104
+ }
105
+ if (key.variants) {
106
+ for (const variant of key.variants) {
107
+ setKeysProp(`variants@add@${variant}`, key.id, manager).unwrap();
108
+ }
109
+ }
110
+ if (keys.autoManageLayout) {
111
+ setKeysProp("layout", calculateLayoutSize(keys), manager).unwrap();
112
+ }
113
+ break;
114
+ }
115
+ case "entries@remove": {
116
+ const key = val;
117
+ delete keys.entries[key.id];
118
+ if (key.isToggle === "native") {
119
+ setKeysProp("nativeToggleKeys", keys.nativeToggleKeys.filter((k) => k !== key.id), manager).unwrap();
120
+ }
121
+ if (key.isModifier === "native") {
122
+ setKeysProp("nativeModifierKeys", keys.nativeToggleKeys.filter((k) => k !== key.id), manager).unwrap();
123
+ }
124
+ if (key.isToggle) {
125
+ setKeysProp(`toggles@remove@${key.toggleOnId}`, key, manager).unwrap();
126
+ setKeysProp(`toggles@remove@${key.toggleOffId}`, key, manager).unwrap();
127
+ }
128
+ if (key.variants) {
129
+ for (const variant of key.variants) {
130
+ setKeysProp(`variants@remove@${variant}`, key.id, manager).unwrap();
131
+ }
132
+ }
133
+ if (keys.autoManageLayout) {
134
+ setKeysProp("layout", calculateLayoutSize(keys), manager).unwrap();
135
+ }
136
+ break;
137
+ }
138
+ default:
139
+ if (prop.startsWith("toggles@add@")) {
140
+ const name = prop.slice("toggles@add@".length);
141
+ keys.toggles[name] = val;
142
+ } else if (prop.startsWith("toggles@remove@")) {
143
+ const name = prop.slice("toggles@remove@".length);
144
+ delete keys.toggles[name];
145
+ } else if (prop.startsWith("variants@add@")) {
146
+ const variant = prop.slice("variants@add@".length);
147
+ const existing = keys.variants[variant] ? [...keys.variants[variant]] : [];
148
+ existing.push(val);
149
+ keys.variants[variant] = existing;
150
+ } else if (prop.startsWith("variants@remove@")) {
151
+ const variant = prop.slice("variants@remove@".length);
152
+ const existing = keys.variants[variant] ? [...keys.variants[variant]] : [];
153
+ existing.splice(existing.indexOf(val), 1);
154
+ if (existing.length > 0) {
155
+ keys.variants[variant] = existing;
156
+ } else {
157
+ delete keys.variants[variant];
158
+ }
159
+ } else {
160
+ keys[prop] = val;
161
+ }
162
+ break;
163
+ }
164
+ manager.hooks?.onSetKeysProp?.(keys, prop, val);
165
+ return Ok(keys);
166
+ }
@@ -0,0 +1,34 @@
1
+ import { type Result } from "@alanscodelog/utils/Result";
2
+ import { type CanHookErrors, type Manager, type ManagerSetEntries, type MultipleErrors } from "../types/index.js";
3
+ /**
4
+ * Safely sets a settable manager property.
5
+ *
6
+ * You should not use this to set properties the manager manages (those tagged with @Managed in the docs) unless you've forgone using the manager.
7
+ *
8
+ * If you need to set the chain, use {@link safeSetManagerChain}.
9
+ *
10
+ * If enabling/disabling {@link Manager.state.isRecording} it's suggested you use {@link safeSetManagerChain} just before.
11
+ *
12
+ * # How to set multiple manager properties safely (i.e. batch replace shortcuts/commands/keys)
13
+ *
14
+ * This can be an issue because there isn't a way to tell the manager you want to replace *multiple* properties and it might be impossible to, for example, replace commands with a smaller subset but not have it error even if you're planning to replace the shortcuts so they don't contain missing commands.
15
+ *
16
+ * To achieve this, you can shallow clone the manager, change all the properties you want directly, then validate it's state by using isValidManager which is what this function does internally.
17
+ *
18
+ * Once you know it's valid, detach the old manager and attach the new one.
19
+ * ```ts
20
+ * const clone = {...manager, keys: newKeys, shortcuts: newShortcuts}
21
+ *
22
+ * if (isValidManager(manager)) {
23
+ * detach(manager, ...)
24
+ * attach(clone, ...)
25
+ * }
26
+ * ```
27
+ */
28
+ export declare function setManagerProp<TEntries extends ManagerSetEntries, TProp extends keyof ManagerSetEntries, TEntry extends TEntries[TProp], THooks extends Manager["hooks"], TCheck extends boolean | "only" = true>(
29
+ /** Manager is mutate if check is not "only" */
30
+ manager: TEntry["manager"] & {
31
+ hooks?: THooks;
32
+ }, prop: TProp, val: TEntry["val"], { check }?: {
33
+ check?: TCheck;
34
+ }): Result<TCheck extends "only" ? true : Manager, MultipleErrors<TEntry["error"]> | CanHookErrors<Manager["hooks"] extends never ? never : THooks, "canSetManagerProp">>;
@@ -0,0 +1,54 @@
1
+ import { castType } from "@alanscodelog/utils/castType";
2
+ import { Err, Ok } from "@alanscodelog/utils/Result";
3
+ import { set } from "@alanscodelog/utils/set";
4
+ import { unreachable } from "@alanscodelog/utils/unreachable";
5
+ import { isValidManager } from "../helpers/isValidManager.js";
6
+ import { areValidKeys } from "../internal/areValidKeys.js";
7
+ import { SHORTCUT_ERROR } from "../types/index.js";
8
+ import { cloneChain } from "../utils/cloneChain.js";
9
+ const canHookable = ["state.chain", "shortcuts", "commands", "keys"];
10
+ export function setManagerProp(manager, prop, val, { check = true } = {}) {
11
+ if (check) {
12
+ switch (prop) {
13
+ case "state.chain": {
14
+ castType(val);
15
+ castType(manager);
16
+ const resIsValid = areValidKeys(val, manager);
17
+ if (resIsValid.isError) return resIsValid;
18
+ break;
19
+ }
20
+ case "commands":
21
+ case "keys":
22
+ case "shortcuts": {
23
+ castType(val);
24
+ castType(manager);
25
+ const managerClone = { ...manager, [prop]: val };
26
+ const res = isValidManager(managerClone);
27
+ if (res.isError && res.error.code === SHORTCUT_ERROR.INVALID_MANAGER) unreachable();
28
+ if (res.isError) return res;
29
+ break;
30
+ }
31
+ default:
32
+ break;
33
+ }
34
+ if (manager?.hooks && "canSetManagerProp" in manager.hooks && canHookable.includes(prop)) {
35
+ const canHook = manager.hooks?.canSetManagerProp?.(manager, prop, val);
36
+ if (canHook instanceof Error) {
37
+ return Err(canHook);
38
+ }
39
+ }
40
+ }
41
+ if (check === "only") {
42
+ return Ok(true);
43
+ }
44
+ if (prop.includes(".")) {
45
+ if (prop === "state.chain") {
46
+ val = cloneChain(val);
47
+ }
48
+ set(manager, prop.split("."), val);
49
+ } else {
50
+ manager[prop] = val;
51
+ }
52
+ manager.hooks?.onSetManagerProp?.(manager, prop, val);
53
+ return Ok(manager);
54
+ }
@@ -0,0 +1,9 @@
1
+ import { type Result } from "@alanscodelog/utils/Result";
2
+ import { type CanHookErrors, type Manager, type MultipleErrors, type Shortcut, type ShortcutSetEntries } from "../types/index.js";
3
+ export declare function setShortcutProp<TEntries extends ShortcutSetEntries, TProp extends keyof ShortcutSetEntries, TEntry extends TEntries[TProp], THooks extends Manager["hooks"], TCheck extends boolean | "only" = true>(
4
+ /** Shortcut is mutated if check is not "only". */
5
+ shortcut: Shortcut, prop: TProp, val: TEntry["val"], manager: (TEntry["manager"] extends never ? unknown : TEntry["manager"]) & {
6
+ hooks?: THooks;
7
+ }, { check }?: {
8
+ check?: TCheck;
9
+ }): Result<TCheck extends "only" ? true : Shortcut, MultipleErrors<TEntry["error"]> | CanHookErrors<Manager["hooks"] extends never ? never : THooks, "canSetShortcutProp">>;
@@ -0,0 +1,50 @@
1
+ import { castType } from "@alanscodelog/utils/castType";
2
+ import { Err, Ok } from "@alanscodelog/utils/Result";
3
+ import { addShortcut } from "./addShortcut.js";
4
+ import { removeShortcut } from "./removeShortcut.js";
5
+ import { isValidChain } from "../internal/isValidChain.js";
6
+ import { isValidCommand } from "../internal/isValidCommand.js";
7
+ import { SHORTCUT_ERROR } from "../types/index.js";
8
+ const canHookable = ["chain", "command", "condition", "enabled"];
9
+ export function setShortcutProp(shortcut, prop, val, manager, { check = true } = {}) {
10
+ if (check) {
11
+ switch (prop) {
12
+ case "chain": {
13
+ castType(val);
14
+ castType(manager);
15
+ const res = isValidChain(val, manager);
16
+ if (res.isError) return res;
17
+ const shortcutsShallowClone = { ...manager.shortcuts, entries: [...manager.shortcuts.entries] };
18
+ const managerClone = { ...manager, shortcuts: shortcutsShallowClone };
19
+ const resRemove = removeShortcut(shortcut, managerClone);
20
+ if (resRemove.isError && "code" in resRemove.error && resRemove.error.code !== SHORTCUT_ERROR.MISSING) return resRemove;
21
+ const resAdd = addShortcut({ ...shortcut, chain: val }, managerClone);
22
+ if (resAdd.isError) return resAdd;
23
+ break;
24
+ }
25
+ case "command": {
26
+ castType(val);
27
+ castType(manager);
28
+ const res = isValidCommand(val, manager, shortcut);
29
+ if (res.isError) return res;
30
+ break;
31
+ }
32
+ default: {
33
+ break;
34
+ }
35
+ }
36
+ if (manager?.hooks && "canSetShortcutProp" in manager.hooks && canHookable.includes(prop)) {
37
+ const canHook = manager.hooks.canSetShortcutProp?.(shortcut, prop, val);
38
+ if (canHook instanceof Error) {
39
+ return Err(canHook);
40
+ }
41
+ }
42
+ }
43
+ if (check === "only") {
44
+ return Ok(true);
45
+ }
46
+ shortcut[prop] = val;
47
+ manager?.hooks?.onSetShortcutProp?.(shortcut, prop, val);
48
+ manager?.hooks?.onSetShortcutProp?.(shortcut, prop, val);
49
+ return Ok(shortcut);
50
+ }
@@ -0,0 +1,12 @@
1
+ import { type Result } from "@alanscodelog/utils/Result";
2
+ import { type CanHookErrors, type Manager, type MultipleErrors, type Shortcut, type ShortcutsSetEntries } from "../types/index.js";
3
+ /**
4
+ * Sets a settable {@link Shortcuts} property.
5
+ */
6
+ export declare function setShortcutsProp<TEntries extends ShortcutsSetEntries, TProp extends keyof ShortcutsSetEntries, TEntry extends TEntries[TProp], THooks extends Manager["hooks"], TCheck extends boolean | "only" = true>(prop: TProp, val: TEntry["val"],
7
+ /** Shortcuts is mutated if check is not "only". */
8
+ manager: TEntry["manager"] & {
9
+ hooks?: THooks;
10
+ }, { check }?: {
11
+ check?: TCheck;
12
+ }): Result<TCheck extends "only" ? true : Shortcut, MultipleErrors<TEntry["error"]> | CanHookErrors<Manager["hooks"] extends never ? never : THooks, "canSetShortcutsProp">>;