@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,68 @@
1
+ import { Ok, type Result } from "@alanscodelog/utils/Result"
2
+
3
+ import { addKey } from "./addKey.js"
4
+
5
+ import { defaultStringifier } from "../defaults/Stringifier.js"
6
+ import { calculateLayoutSize } from "../helpers/calculateLayoutSize.js"
7
+ import type { Key, Keys, MultipleErrors, PickManager, SHORTCUT_ERROR } from "../types/index.js"
8
+
9
+
10
+ export function createKeys<
11
+ TKey extends
12
+ Key = Key,
13
+ TKeys extends
14
+ (TKey)[] = (TKey)[],
15
+ TEntries extends
16
+ Record<TKeys[number]["id"], Key> = Record<TKeys[number]["id"], Key>,
17
+ // causing issues
18
+ // RecordFromArray<TKeys, "id", Key> =
19
+ // RecordFromArray<TKeys, "id", Key>,
20
+ TCheck extends boolean | "only" = true
21
+ >(
22
+ entries: TKeys,
23
+ manager: PickManager<"options", "stringifier"> = {
24
+ options: { stringifier: defaultStringifier }
25
+ },
26
+ rawKeys: Partial<Pick<Keys, "autoManageLayout" | "layout">> = {} as any,
27
+ {
28
+ check = true as TCheck
29
+ }: { check?: TCheck } = {}
30
+ ): Result<
31
+ TCheck extends "only" ? true : Keys<TEntries>,
32
+ MultipleErrors<
33
+ typeof SHORTCUT_ERROR.DUPLICATE_KEY
34
+ >
35
+ > {
36
+ const keysList = entries
37
+ const keys: Keys = {
38
+ type: "keys",
39
+ // prevent multiple calculations when initially adding keys
40
+ autoManageLayout: false,
41
+ ...rawKeys,
42
+ layout: { y: 0, x: 0, ...(rawKeys.layout ?? {}) },
43
+ entries: {},
44
+ nativeToggleKeys: [],
45
+ nativeModifierKeys: [],
46
+ variants: {},
47
+ toggles: {}
48
+ }
49
+ // clone anything addKey might touch, see below
50
+ const managerClone = { ...manager, keys }
51
+ if (check) {
52
+ for (const key of keysList) {
53
+ // this one is a bit weird
54
+ // we don't use check = "only" because we actually want keys.entries to be modified to error on duplicate keys
55
+ // the entire keys object isn't the user's rawKey copy anymore anyways
56
+ const res = addKey(key, managerClone)
57
+ if (res.isError) return res as any
58
+ }
59
+ }
60
+ if (check === "only") return Ok(true) satisfies Result<true, never> as any
61
+
62
+
63
+ if (rawKeys?.autoManageLayout) {
64
+ keys.autoManageLayout = true
65
+ keys.layout = calculateLayoutSize(keys)
66
+ }
67
+ return Ok(keys) satisfies Result<Keys, never> as any
68
+ }
@@ -0,0 +1,209 @@
1
+ import { castType } from "@alanscodelog/utils/castType"
2
+ import { isArray } from "@alanscodelog/utils/isArray"
3
+ import { Ok, type Result } from "@alanscodelog/utils/Result"
4
+ import type { RecordFromArray } from "@alanscodelog/utils/types"
5
+
6
+ import { createCommand } from "./createCommand.js"
7
+ import { createCommands } from "./createCommands.js"
8
+ import { createKey } from "./createKey.js"
9
+ import { createKeys } from "./createKeys.js"
10
+ import { createManagerOptions } from "./createManagerOptions.js"
11
+ import { createShortcut } from "./createShortcut.js"
12
+ import { createShortcuts } from "./createShortcuts.js"
13
+
14
+ import type { CanHookErrors, CanHooks, Command, Commands, CommandsSetEntries, Context, Hooks, Key, Keys, KeysSetEntries, Manager, ManagerListener, MultipleErrors, RawCommand, RawKey, RawShortcut, Shortcut, SHORTCUT_ERROR, Shortcuts, ShortcutsSetEntries } from "../types/index.js"
15
+
16
+ /**
17
+ * Create a manager which can track key states, layouts, and trigger shortcuts. Basically the brains of the operation.
18
+ *
19
+ * First, all the elements of a manager need to be created.
20
+ * Then you can create the listeners for the manager with {@link createManagerEventListeners}.
21
+ *
22
+ * Then these listeners can be attached/removed from elements (or the {@link Emulator})
23
+ *
24
+ * You could make several managers for different areas of your application or use single manager and different contexts to differ between them.
25
+ *
26
+ * It is easiest to build a manager like so, but the manager also takes in full {@link Keys}/{@link Commands}/{@link Shortcuts} instances, though it's a bit harder to build those first then pass to the manager:
27
+ * ```ts
28
+ *
29
+ * const manager = createManager(
30
+ * {
31
+ * keys: [
32
+ * createKey("a", ),
33
+ * // or using a raw key
34
+ * {id: "b"}
35
+ * ],
36
+ * commands: [
37
+ * createCommand("a"),
38
+ * {name: "b", execute() {....}}
39
+ * ],
40
+ * shortcuts: [
41
+ * { chain: [["a"]], command: "a" }
42
+ * ]
43
+ * context: createContext({...}),
44
+ * options: {
45
+ * // required
46
+ * evaluateCondition() {
47
+ * ...
48
+ * }
49
+ * }
50
+ * }, {
51
+ * // if constructing from raw entries like above, createKeys/Shortcuts can take additional options
52
+ * ...,
53
+ * keys: {...},
54
+ * shortcuts:{...}
55
+ * }).unwrap()
56
+ *
57
+ * const listeners = createManagerEventListeners(manager)
58
+ * attach(document, listeners)
59
+ * // to remove:
60
+ * dettach(document, listeners)
61
+ * ```
62
+ *
63
+ * You will then not need to do much else. It will take care of setting the pressed state of keys, the state of the current chord chain (see {@link Manager._chain}), finding a matching shortcut if it exists, and triggering it's command.
64
+ *
65
+ * The way this works is that when a key is pressed it's added to the current chord in the chain. If the chain matches a shortcut's chain that can be triggered (it must be enabled, it must have a command and a function to execute, and it's condition and it's command's condition must evaluate to true), the command's execute function is triggered with `isKeydown = true`, see {@link Command.execute}.
66
+ *
67
+ * If there are no shortcuts to trigger but there are "potential shortcuts" that start with the current chain and could trigger and current chord contains any non-modifier keys (see {@link Manager.pressedNonModifierKeys}), an empty chord will be added to the chain on the next key pressed and the process repeats.
68
+ *
69
+ * If there are no shortcuts and no potential shortcuts, the callback will be called with {@link SHORTCUT_ERROR.NO_MATCHING_SHORTCUT} and you will probably want to clear the chain. When the chain is cleared (see {@link Manager._chain}), the manager will not add/remove keys from the chain until all non-modifier keys are unpressed. Pressed state is still set/tracked though.
70
+ *
71
+ * The moment a key is released after a shortcut is triggered, the command's execute function is fired again with `isKeydown = false`.
72
+ *
73
+ * If {@link Manager.options.updateStateOnAllEvents} is not disabled and a mouseeneter listener was created, the manager is able to keep the most accurate state of the modifier keys. See {@link Manager.options.updateStateOnAllEvents} for more info.
74
+ *
75
+ * For a detailed usage example, see the demo.
76
+ *
77
+ * ### Other
78
+ *
79
+ * - If you need to emulate keypresses for testing see {@link Emulator}.
80
+ */
81
+
82
+
83
+ export function createManager<
84
+ THooks extends Hooks,
85
+ TKeys extends Keys | RawKey[],
86
+ TShortcuts extends Shortcuts | RawShortcut[],
87
+ TCommands extends Commands | RawCommand[],
88
+ TContext extends Context,
89
+ TListener extends ManagerListener
90
+ >(
91
+ rawManager: {
92
+ name?: string
93
+ options: Partial<Omit<Manager["options"], "evaluateCondition">>
94
+ & Pick<Manager<any, any, any, any, TContext>["options"], "evaluateCondition">
95
+ context?: TContext
96
+ keys?: TKeys
97
+ shortcuts?: TShortcuts
98
+ commands?: TCommands
99
+ hooks?: Partial<THooks>
100
+ listener?: TListener
101
+ },
102
+ additionalOpts: Partial<{
103
+ keys?: Partial<Pick<Keys, "autoManageLayout" | "layout">>
104
+ shortcuts?: Partial<Pick<Shortcuts, "ignoreModifierConflicts" | "ignoreChainConflicts">>
105
+ }
106
+ > = {}
107
+ ): Result<
108
+ Manager<
109
+ THooks,
110
+ TKeys extends Keys
111
+ ? Extract<TKeys, Keys>
112
+ : TKeys extends RawKey[]
113
+ ? Keys<RecordFromArray<TKeys, "id", Key>>
114
+ : never,
115
+ Shortcuts,
116
+ TCommands extends Commands
117
+ ? Extract<TCommands, Commands>
118
+ : TCommands extends RawCommand[]
119
+ ? Commands<RecordFromArray<TCommands, "name", Command>>
120
+ : never,
121
+ TContext
122
+ >,
123
+ MultipleErrors<
124
+ | CommandsSetEntries["entries@add"]["error"]
125
+ | KeysSetEntries["entries@add"]["error"]
126
+ | ShortcutsSetEntries["entries@add"]["error"]
127
+ | typeof SHORTCUT_ERROR.INVALID_VARIANT
128
+ > | CanHookErrors<THooks extends never ? never : THooks, keyof CanHooks>
129
+ > {
130
+ const options = createManagerOptions(rawManager.options as any)
131
+ const m = { options }
132
+ const state = {
133
+ chain: [],
134
+ isAwaitingKeyup: false,
135
+ isRecording: false,
136
+ untrigger: false,
137
+ nextIsChord: false
138
+ } satisfies Manager["state"]
139
+
140
+ let keys = rawManager.keys
141
+
142
+ if (!keys || isArray(keys)) {
143
+ castType<RawKey[]>(keys)
144
+ const keysList: Key[] = []
145
+ if (keys) {
146
+ for (const key of keys) {
147
+ const res = createKey(key.id, key)
148
+ if (res.isError) return res
149
+ keysList.push(res.value)
150
+ }
151
+ }
152
+ const res = createKeys(keysList, m, additionalOpts?.keys)
153
+ if (res.isError) return res
154
+ keys = res.value satisfies Keys as any
155
+ }
156
+
157
+ let commands = rawManager.commands
158
+
159
+ if (!commands || isArray(commands)) {
160
+ castType<RawCommand[]>(commands)
161
+ const commandsList: Command[] = []
162
+ if (commands) {
163
+ for (const command of commands) {
164
+ const res = createCommand(command.name, command)
165
+ commandsList.push(res)
166
+ }
167
+ }
168
+
169
+ const res = createCommands(commandsList, { options })
170
+ if (res.isError) return res as any
171
+ commands = res.value satisfies Commands as any
172
+ }
173
+
174
+ let shortcuts = rawManager.shortcuts
175
+ if (!shortcuts || isArray(shortcuts)) {
176
+ castType<RawShortcut[]>(shortcuts)
177
+ const shortcutsList: Shortcut[] = []
178
+ const m2 = { ...m, commands: commands as Commands, keys: keys as Keys }
179
+ if (shortcuts) {
180
+ for (const shortcut of shortcuts) {
181
+ const res = createShortcut(shortcut, m2)
182
+ if (res.isError) return res
183
+ shortcutsList.push(res.value)
184
+ }
185
+ }
186
+
187
+ const res = createShortcuts(shortcutsList, {
188
+ keys: keys! as Keys,
189
+ commands: commands! as Commands,
190
+ options
191
+ }, additionalOpts?.shortcuts)
192
+ if (res.isError) return res as any
193
+ shortcuts = res.value satisfies Shortcuts as any
194
+ }
195
+
196
+ const manager: Manager = {
197
+ ...rawManager,
198
+ name: rawManager.name ?? "manager",
199
+ type: "manager",
200
+ keys: keys! as Keys,
201
+ shortcuts: shortcuts! as Shortcuts,
202
+ commands: commands! as Commands,
203
+ options,
204
+ state,
205
+ context: rawManager.context!,
206
+ hooks: rawManager?.hooks as any as THooks
207
+ }
208
+ return Ok(manager) as any
209
+ }
@@ -0,0 +1,139 @@
1
+ import { getKeyFromEventCode } from "../helpers/getKeyFromEventCode.js"
2
+ import { addToChain } from "../internal/addToChain.js"
3
+ import { removeFromChain } from "../internal/removeFromChain.js"
4
+ import { setKeysState } from "../internal/setKeysState.js"
5
+ import { updateNativeKeysState } from "../internal/updateNativeKeysState.js"
6
+ import type { EventListenerTypes, EventTypes, Manager } from "../types/index.js"
7
+
8
+
9
+ export function createManagerEventListeners<T extends EventTypes, TTypes extends T[]>(
10
+ manager: Manager,
11
+ types: TTypes = ["keydown", "keyup", "keypress", "wheel", "mousedown", "mouseup", "mouseenter"] as TTypes,
12
+ { debug }: { debug?: true | ((type: EventTypes, e: KeyboardEvent | MouseEvent) => void) } = {}
13
+ ): EventListenerTypes<TTypes[number]> {
14
+ // eslint-disable-next-line no-console
15
+ const debugFn = debug === true ? console.log : undefined
16
+ const listeners: Partial<EventListenerTypes<EventTypes>> = {}
17
+ for (const type of types) {
18
+ switch (type) {
19
+ case "keydown": {
20
+ listeners.keydown = (e: KeyboardEvent): void => {
21
+ debugFn?.("keydown", e)
22
+ if (!manager.options.enableListeners) return
23
+ const keyIds = getKeyFromEventCode(e.code, e, manager.keys.entries)
24
+ if (keyIds.isError) {
25
+ manager.options.cb(manager, keyIds.error, e)
26
+ return
27
+ }
28
+
29
+ const ids = keyIds.value
30
+ manager.listener?.({ event: e, isKeydown: true, keys: ids, manager })
31
+ setKeysState(ids, manager, true)
32
+ updateNativeKeysState(manager, e, ids)
33
+ const res = addToChain(manager, ids, e)
34
+ if (res.isError) { manager.options.cb(manager, res.error, e) }
35
+ }
36
+ break
37
+ }
38
+ case "keyup": {
39
+ listeners.keyup = (e: KeyboardEvent): void => {
40
+ debugFn?.("keyup", e)
41
+ if (!manager.options.enableListeners) return
42
+ const keyIds = getKeyFromEventCode(e.code, e, manager.keys.entries)
43
+
44
+ if (keyIds.isError) {
45
+ manager.options.cb(manager, keyIds.error, e)
46
+ return
47
+ }
48
+
49
+ const ids = keyIds.value
50
+ manager.listener?.({ event: e, isKeydown: false, keys: ids, manager })
51
+ setKeysState(ids, manager, false)
52
+ updateNativeKeysState(manager, e, ids)
53
+ const res = removeFromChain(manager, ids, e)
54
+ if (res.isError) { manager.options.cb(manager, res.error, e) }
55
+ }
56
+ break
57
+ }
58
+ case "wheel": {
59
+ listeners.wheel = (e: WheelEvent): void => {
60
+ debugFn?.("wheel", e)
61
+ if (!manager.options.enableListeners) return
62
+ const dir = e.deltaY < 0 ? "Up" : "Down"
63
+ const code = `Wheel${dir}`
64
+ const keyIds = getKeyFromEventCode(code, e, manager.keys.entries, { pressedState: false })
65
+
66
+ if (keyIds.isError) {
67
+ manager.options.cb(manager, keyIds.error, e)
68
+ return
69
+ }
70
+ const ids = keyIds.value
71
+ manager.listener?.({ event: e, isKeydown: true, keys: ids, manager })
72
+ setKeysState(ids, manager, true)
73
+ updateNativeKeysState(manager, e, ids)
74
+ addToChain(manager, ids, e)
75
+ manager.listener?.({ event: e, isKeydown: false, keys: ids, manager })
76
+ setKeysState(ids, manager, false)
77
+ const res = removeFromChain(manager, ids, e)
78
+ if (res.isError) { manager.options.cb(manager, res.error, e) }
79
+ }
80
+ break
81
+ }
82
+ case "mousedown": {
83
+ listeners.mousedown = (e: MouseEvent): void => {
84
+ debugFn?.("mousedown", e)
85
+ if (!manager.options.enableListeners) return
86
+ const button = e.button.toString()
87
+
88
+ const keyIds = getKeyFromEventCode(button, e, manager.keys.entries, { pressedState: false })
89
+ if (keyIds.isError) {
90
+ manager.options.cb(manager, keyIds.error, e)
91
+ return
92
+ }
93
+ const ids = keyIds.value
94
+ manager.listener?.({ event: e, isKeydown: true, keys: ids, manager })
95
+ setKeysState(ids, manager, true)
96
+
97
+ updateNativeKeysState(manager, e, ids)
98
+ const res = addToChain(manager, ids, e)
99
+ if (res.isError) { manager.options.cb(manager, res.error, e) }
100
+ }
101
+
102
+ break
103
+ }
104
+ case "mouseup": {
105
+ listeners.mouseup = (e: MouseEvent): void => {
106
+ debugFn?.("mouseup", e)
107
+ if (!manager.options.enableListeners) return
108
+ const button = e.button.toString()
109
+ const keyIds = getKeyFromEventCode(button, e, manager.keys.entries, { pressedState: true })
110
+
111
+ if (keyIds.isError) {
112
+ manager.options.cb(manager, keyIds.error, e)
113
+ return
114
+ }
115
+ const ids = keyIds.value
116
+ manager.listener?.({ event: e, isKeydown: false, keys: ids, manager })
117
+ setKeysState(ids, manager, false)
118
+ updateNativeKeysState(manager, e, ids)
119
+ const res = removeFromChain(manager, ids, e)
120
+ if (res.isError) { manager.options.cb(manager, res.error, e) }
121
+ }
122
+
123
+ break
124
+ }
125
+ case "mouseenter": {
126
+ listeners.mouseenter = (e: MouseEvent): void => {
127
+ debugFn?.("mouseenter", e)
128
+ if (!manager.options.enableListeners) return
129
+ manager.listener?.({ event: e, isKeydown: true, keys: [], manager })
130
+ updateNativeKeysState(manager, e, [])
131
+ }
132
+
133
+ break
134
+ }
135
+ }
136
+ }
137
+ return listeners as EventListenerTypes<EventTypes>
138
+ }
139
+
@@ -0,0 +1,29 @@
1
+ import type { createManager } from "./createManager.js"
2
+
3
+ import { defaultConditionEquals } from "../defaults/defaultConditionEquals.js"
4
+ import { defaultManagerCallback } from "../defaults/defaultManagerCallback.js"
5
+ import { defaultSorter } from "../defaults/KeysSorter.js"
6
+ import { defaultStringifier } from "../defaults/Stringifier.js"
7
+ import type { Manager } from "../types/index.js"
8
+
9
+
10
+ /**
11
+ * Many methods require some of the manager's options, but not the entire manager. Also it's easier to create a manager from scratch by first creating it's options
12
+ *
13
+ * This can be used to create the base manager options.
14
+ */
15
+ export function createManagerOptions(
16
+ rawOpts: Parameters<typeof createManager>[0]["options"]
17
+ ): Manager["options"] {
18
+ const options: Manager["options"] = {
19
+ sorter: defaultSorter,
20
+ stringifier: defaultStringifier,
21
+ conditionEquals: defaultConditionEquals,
22
+ cb: defaultManagerCallback,
23
+ enableShortcuts: true,
24
+ enableListeners: true,
25
+ updateStateOnAllEvents: true,
26
+ ...rawOpts
27
+ }
28
+ return options
29
+ }
@@ -0,0 +1,49 @@
1
+ import { Ok, type Result } from "@alanscodelog/utils/Result"
2
+
3
+ import { isValidShortcut } from "../helpers/isValidShortcut.js"
4
+ import type { ChainError, Command, Condition, Manager, MultipleErrors, PickManager, RawShortcut, Shortcut, SHORTCUT_ERROR } from "../types/index.js"
5
+
6
+
7
+ /**
8
+ * Creates a {@link Shortcut} object from a {@link RawShortcut}.
9
+ *
10
+ * If the raw shortcut has no condition, a new blank empty condition is created. If you will be following the suggestion of not having any conditions equal eachother (see {@link ConditionComparer}), you can fallback to passing the same instance of an empty condition without issues.
11
+ */
12
+ export function createShortcut<
13
+ TRawCommand extends Command["name"] | Command = Command["name"] | Command,
14
+ TCommand extends TRawCommand extends string ? Command<TRawCommand> : TRawCommand = TRawCommand extends string ? Command<TRawCommand> : TRawCommand,
15
+ TCondition extends Condition = Condition
16
+
17
+ >(
18
+ rawShortcut: RawShortcut<TRawCommand, TCommand, TCondition>,
19
+ manager: Pick<Manager, "keys" | "commands">
20
+ & PickManager<"options", "stringifier" | "sorter">
21
+ ): Result<Shortcut<TCommand["name"], TCondition>, MultipleErrors<
22
+ | ChainError
23
+ | typeof SHORTCUT_ERROR.UNKNOWN_COMMAND
24
+ >> {
25
+ const sorter = manager.options.sorter
26
+
27
+ const finalChain = []
28
+ for (const chord of rawShortcut.chain) {
29
+ const stringChord = chord.map(key => typeof key === "object" ? key.id : key)
30
+ sorter.sort(stringChord, manager.keys)
31
+ finalChain.push(stringChord)
32
+ }
33
+ const command = typeof rawShortcut.command === "string" ? rawShortcut.command : rawShortcut.command?.name
34
+
35
+ const shortcut: Shortcut = {
36
+ ...rawShortcut as any,
37
+ type: "shortcut",
38
+ enabled: rawShortcut.enabled ?? true,
39
+ command,
40
+ chain: finalChain,
41
+ condition: rawShortcut.condition ?? { type: "condition", text: "" },
42
+ forceUnequal: false
43
+ }
44
+ const res = isValidShortcut(shortcut, manager)
45
+ if (res.isError) return res
46
+
47
+
48
+ return Ok(shortcut satisfies Shortcut as any)
49
+ }
@@ -0,0 +1,51 @@
1
+ import { Ok, type Result } from "@alanscodelog/utils/Result"
2
+
3
+ import { addShortcut } from "./addShortcut.js"
4
+
5
+ import type { CanHookErrors, Manager, MultipleErrors, PickManager, Shortcut, Shortcuts, ShortcutsSetEntries } from "../types/index.js"
6
+
7
+ /**
8
+ * # Shortcut
9
+ *
10
+ * Creates a set of shortcuts.
11
+ *
12
+ */
13
+ export function createShortcuts<
14
+ THooks extends Manager["hooks"],
15
+ TRawShortcuts extends Shortcut[],
16
+ TCheck extends boolean | "only" = true
17
+ >(
18
+ shortcutsList: TRawShortcuts,
19
+ manager: Pick<Manager, "keys" | "commands">
20
+ & PickManager<"options", | "evaluateCondition" | "conditionEquals" | "stringifier" | "sorter">
21
+ & { hooks?: THooks },
22
+ opts?: Partial<Pick<Shortcuts, "ignoreModifierConflicts" | "ignoreChainConflicts">>,
23
+ {
24
+ check = true as TCheck
25
+ }: { check?: boolean | "only" } = {}
26
+ ): Result<
27
+ TCheck extends "only" ? true : Shortcuts,
28
+ MultipleErrors<
29
+ ShortcutsSetEntries["entries@add"]["error"]
30
+ > | CanHookErrors<THooks extends never ? never : THooks, "canSetShortcutsProp">
31
+ > {
32
+ const shortcuts: Shortcuts = {
33
+ entries: [],
34
+ ignoreModifierConflicts: opts?.ignoreModifierConflicts ?? false,
35
+ ignoreChainConflicts: opts?.ignoreChainConflicts ?? false
36
+
37
+ }
38
+ const managerClone = { ...manager, shortcuts }
39
+ if (check) {
40
+ for (const shortcut of shortcutsList) {
41
+ // we check all first to avoid erroring mid-way through
42
+ const res = addShortcut(shortcut, managerClone)
43
+ if (res.isError) return res
44
+ }
45
+ }
46
+ if (check === "only") return Ok(true) satisfies Result<true, never> as any
47
+
48
+
49
+ return Ok(shortcuts) satisfies Result<Shortcuts, never> as any
50
+ }
51
+
@@ -0,0 +1,21 @@
1
+ import { keys } from "@alanscodelog/utils/keys"
2
+ import type { AnyFunction } from "@alanscodelog/utils/types"
3
+
4
+ import type { AttachTarget, EventTypes } from "../types/index.js"
5
+
6
+ /**
7
+ * Detach the listeners from an element.
8
+ *
9
+ * Or you can just use the abort controller returned by {@link attach}.
10
+ */
11
+ export function detach(
12
+ el: AttachTarget,
13
+ listeners: Record<EventTypes, AnyFunction>,
14
+ /** Listeners need ot be detached with the same options they were attached with. */
15
+ opts: Partial<Record<EventTypes, AddEventListenerOptions>> = { wheel: { passive: true } }
16
+ ): void {
17
+ for (const name of keys(listeners)) {
18
+ el.removeEventListener(name, listeners[name], opts[name])
19
+ }
20
+ }
21
+
@@ -0,0 +1,35 @@
1
+ export * from "../types/index.js"
2
+ export * as helpers from "../helpers/index.js"
3
+ export * as utils from "../helpers/index.js"
4
+
5
+ /* Autogenerated Index */
6
+
7
+ export { addCommand } from "./addCommand.js"
8
+ export { addKey } from "./addKey.js"
9
+ export { addShortcut } from "./addShortcut.js"
10
+ export { attach } from "./attach.js"
11
+ export { createCommand } from "./createCommand.js"
12
+ export { createCommands } from "./createCommands.js"
13
+ export { createCondition } from "./createCondition.js"
14
+ export { createContext } from "./createContext.js"
15
+ export { createKey } from "./createKey.js"
16
+ export { createKeys } from "./createKeys.js"
17
+ export { createManager } from "./createManager.js"
18
+ export { createManagerEventListeners } from "./createManagerEventListeners.js"
19
+ export { createManagerOptions } from "./createManagerOptions.js"
20
+ export { createShortcut } from "./createShortcut.js"
21
+ export { createShortcuts } from "./createShortcuts.js"
22
+ export { detach } from "./detach.js"
23
+ export { EmulatedEvent } from "./EmulatedEvent.js"
24
+ export { Emulator } from "./Emulator.js"
25
+ export { removeCommand } from "./removeCommand.js"
26
+ export { removeKey } from "./removeKey.js"
27
+ export { removeShortcut } from "./removeShortcut.js"
28
+ export { setCommandProp } from "./setCommandProp.js"
29
+ export { setCommandsProp } from "./setCommandsProp.js"
30
+ export { setKeyProp } from "./setKeyProp.js"
31
+ export { setKeysProp } from "./setKeysProp.js"
32
+ export { setManagerProp } from "./setManagerProp.js"
33
+ export { setShortcutProp } from "./setShortcutProp.js"
34
+ export { setShortcutsProp } from "./setShortcutsProp.js"
35
+ export { ShortcutManagerManager } from "./ShortcutManagerManager.js"
@@ -0,0 +1,25 @@
1
+ import { Ok, type Result } from "@alanscodelog/utils/Result"
2
+
3
+ import { setCommandsProp } from "./setCommandsProp.js"
4
+
5
+ import type { CanHookErrors, Command, CommandsSetEntries, Manager, MultipleErrors } from "../types/index.js"
6
+
7
+
8
+ export function removeCommand<
9
+ THooks extends Manager["hooks"],
10
+ TCheck extends boolean | "only" = true
11
+ >(
12
+ command: Command,
13
+ manager: CommandsSetEntries["entries@remove"]["manager"] & { hooks?: THooks },
14
+ opts: { check?: TCheck } = {}
15
+ ): Result<
16
+ TCheck extends "only" ? true : Command,
17
+ MultipleErrors<
18
+ CommandsSetEntries["entries@remove"]["error"]
19
+ > | CanHookErrors<THooks extends never ? never : THooks, "canSetCommandsProp">
20
+ > {
21
+ const res = setCommandsProp("entries@remove", command, manager, opts)
22
+ if (res.isError) return res
23
+
24
+ return Ok(command) satisfies Result<Command, never> as any
25
+ }
@@ -0,0 +1,25 @@
1
+ import { Ok, type Result } from "@alanscodelog/utils/Result"
2
+
3
+ import { setKeysProp } from "./setKeysProp.js"
4
+
5
+ import type { CanHookErrors, Key, KeysSetEntries, Manager, MultipleErrors } from "../types/index.js"
6
+
7
+
8
+ export function removeKey<
9
+ THooks extends Manager["hooks"],
10
+ TCheck extends boolean | "only" = true
11
+ >(
12
+ key: Key,
13
+ manager: KeysSetEntries["entries@remove"]["manager"] & { hooks?: THooks },
14
+ opts: { check?: TCheck } = {}
15
+ ): Result<
16
+ TCheck extends "only" ? true : Key,
17
+ MultipleErrors<
18
+ KeysSetEntries["entries@remove"]["error"]
19
+ > | CanHookErrors<THooks extends never ? never : THooks, "canSetKeysProp">
20
+ > {
21
+ const res = setKeysProp("entries@remove", key, manager, opts)
22
+ if (res.isError) return res
23
+ return Ok(key) satisfies Result<Key, never> as any
24
+ }
25
+
@@ -0,0 +1,24 @@
1
+ import { Ok, type Result } from "@alanscodelog/utils/Result"
2
+
3
+ import { setShortcutsProp } from "./setShortcutsProp.js"
4
+
5
+ import type { CanHookErrors, Manager, MultipleErrors, Shortcut, ShortcutsSetEntries } from "../types/index.js"
6
+
7
+
8
+ export function removeShortcut<
9
+ THooks extends Manager["hooks"],
10
+ TCheck extends boolean | "only" = true
11
+ >(
12
+ shortcut: Shortcut,
13
+ manager: ShortcutsSetEntries["entries@remove"]["manager"] & { hooks?: THooks },
14
+ opts: { check?: TCheck } = {}
15
+ ): Result<
16
+ TCheck extends "only" ? true : Shortcut,
17
+ MultipleErrors<
18
+ ShortcutsSetEntries["entries@remove"]["error"]
19
+ > | CanHookErrors<THooks extends never ? never : THooks, "canSetShortcutsProp">
20
+ > {
21
+ const res = setShortcutsProp("entries@remove", shortcut, manager, opts)
22
+ if (res.isError) return res
23
+ return Ok(shortcut) satisfies Result<Shortcut, never> as any
24
+ }