@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,249 @@
1
+ import type { AnyFunction } from "@alanscodelog/utils/types";
2
+ import type { CanHookCommandProps, CanHookCommandsProps, CanHookKeyProps, CanHookKeysProps, CanHookShortcutProps, CanHookShortcutsProps, ChainError, Command, Commands, CommandSetEntries, CommandsSetEntries, ConditionComparer, ConditionEvaluator, Context, IKeysSorter, IStringifier, Key, KeyboardLayoutMap, Keys, KeySetEntries, KeysSetEntries, MultipleErrors, OnHookCommandProps, OnHookCommandsProps, OnHookKeyProps, OnHookKeysProps, OnHookShortcutProps, OnHookShortcutsProps, Shortcut, SHORTCUT_ERROR, Shortcuts, ShortcutSetEntries, ShortcutsSetEntries, TriggerableShortcut } from "./index.js";
3
+ import type { EmulatedEvent } from "../core/EmulatedEvent.js";
4
+ import type { KnownError } from "../helpers/index.js";
5
+ export type AnyInputEvent = KeyboardEvent | MouseEvent | WheelEvent | EmulatedEvent;
6
+ export type MinimalInputEvent = ({
7
+ button: number;
8
+ } | {
9
+ code?: string;
10
+ key: string;
11
+ } | {
12
+ deltaY: number;
13
+ }) & Record<string, any>;
14
+ export type ManagerReplaceValue = Partial<Pick<Manager, "shortcuts" | "keys" | "commands">>;
15
+ export type ManagerReplaceErrors = KnownError<typeof SHORTCUT_ERROR.UNKNOWN_KEY | typeof SHORTCUT_ERROR.UNKNOWN_COMMAND>;
16
+ export type ManagerListener = ({ event, keys, isKeydown, manager }: {
17
+ event?: AnyInputEvent;
18
+ keys: string[];
19
+ isKeydown: boolean;
20
+ manager: Manager;
21
+ }) => void;
22
+ export type ExportedManager = {
23
+ shortcuts?: Shortcuts;
24
+ keys?: Keys;
25
+ commands?: Commands;
26
+ };
27
+ export type OnHook<TBase, T extends Record<string, {
28
+ val: any;
29
+ }>, TKey extends keyof T = keyof T, TVal extends T[TKey]["val"] = T[TKey]["val"]> = (obj: TBase, key: TKey, val: TVal) => void;
30
+ export type CanHook<TBase, T extends Record<string, {
31
+ val: any;
32
+ }>, TKey extends keyof T = keyof T, TVal extends T[TKey]["val"] = T[TKey]["val"], TError extends Error = Error> = (obj: TBase, key: TKey, val: TVal) => TError | true;
33
+ type GetManagerHooks<T extends OnHookManagerProps> = T extends CanHookManagerProps ? Partial<Pick<NonNullable<Manager["hooks"]>, "canSetManagerProp" | "onSetManagerProp">> : Partial<Pick<NonNullable<Manager["hooks"]>, "onSetManagerProp">>;
34
+ export type OnHookManagerProps = "state.chain" | "shortcuts" | "keys" | "commands" | `state.${keyof Manager["state"]}`;
35
+ export type CanHookManagerProps = "state.chain" | "shortcuts" | "keys" | "commands" | `state.${keyof Pick<Manager["state"], "isRecording">}`;
36
+ type ManagerStateHook<T extends keyof Manager["state"]> = {
37
+ val: Manager["state"][T];
38
+ manager: Manager;
39
+ hooks: GetManagerHooks<`state.${T}`>;
40
+ error: never;
41
+ };
42
+ export type ManagerSetEntries = {
43
+ "state.chain": {
44
+ val: string[][];
45
+ manager: Manager;
46
+ hooks: GetManagerHooks<"state.chain">;
47
+ error: typeof SHORTCUT_ERROR.UNKNOWN_KEY;
48
+ };
49
+ shortcuts: {
50
+ val: Shortcuts;
51
+ manager: Manager;
52
+ hooks: GetManagerHooks<"shortcuts">;
53
+ error: typeof SHORTCUT_ERROR.UNKNOWN_COMMAND | ChainError;
54
+ };
55
+ commands: {
56
+ val: Commands;
57
+ manager: Manager;
58
+ hooks: GetManagerHooks<"commands">;
59
+ error: typeof SHORTCUT_ERROR.UNKNOWN_COMMAND;
60
+ };
61
+ keys: {
62
+ val: Keys;
63
+ manager: Manager;
64
+ hooks: GetManagerHooks<"keys">;
65
+ error: ChainError;
66
+ };
67
+ "state.isRecording": ManagerStateHook<"isRecording">;
68
+ "state.isAwaitingKeyup": ManagerStateHook<"isAwaitingKeyup">;
69
+ "state.nextIsChord": ManagerStateHook<"nextIsChord">;
70
+ "state.untrigger": ManagerStateHook<"untrigger">;
71
+ };
72
+ export type CanHooks = {
73
+ canSetKeyProp?: CanHook<Key, Pick<KeySetEntries, CanHookKeyProps>>;
74
+ canSetKeysProp?: CanHook<Keys, Pick<KeysSetEntries, CanHookKeysProps>>;
75
+ canSetCommandProp?: CanHook<Command, Pick<CommandSetEntries, CanHookCommandProps>>;
76
+ canSetCommandsProp?: CanHook<Commands, Pick<CommandsSetEntries, CanHookCommandsProps>>;
77
+ canSetShortcutProp?: CanHook<Shortcut, Pick<ShortcutSetEntries, CanHookShortcutProps>>;
78
+ canSetShortcutsProp?: CanHook<Shortcuts, Pick<ShortcutsSetEntries, CanHookShortcutsProps>>;
79
+ canSetManagerProp?: CanHook<Manager, Pick<ManagerSetEntries, CanHookManagerProps>>;
80
+ };
81
+ export type OnHooks = {
82
+ onSetKeyProp?: OnHook<Key, Pick<KeySetEntries, OnHookKeyProps>>;
83
+ onSetKeysProp?: OnHook<Keys, Pick<KeysSetEntries, OnHookKeysProps>>;
84
+ onSetCommandProp?: OnHook<Command, Pick<CommandSetEntries, OnHookCommandProps>>;
85
+ onSetCommandsProp?: OnHook<Commands, Pick<CommandsSetEntries, OnHookCommandsProps>>;
86
+ onSetShortcutProp?: OnHook<Shortcut, Pick<ShortcutSetEntries, OnHookShortcutProps>>;
87
+ onSetShortcutsProp?: OnHook<Shortcuts, Pick<ShortcutsSetEntries, OnHookShortcutsProps>>;
88
+ onSetManagerProp?: OnHook<Manager, Pick<ManagerSetEntries, OnHookManagerProps>>;
89
+ };
90
+ export type Hooks = OnHooks & CanHooks;
91
+ export type CanHookErrors<T extends CanHooks | any, TKey extends keyof T | string> = T extends CanHooks ? TKey extends keyof T ? Extract<ReturnType<Extract<T[TKey], AnyFunction>>, Error> : never : never;
92
+ export type Manager<THooks extends Partial<Hooks> = Partial<Hooks>, TKeys extends Keys = Keys, TShortcuts extends Shortcuts = Shortcuts, TCommands extends Commands = Commands, TContext extends Context = Context, TListener extends ManagerListener = ManagerListener> = {
93
+ /** A name for the manager. */
94
+ name: string;
95
+ type: "manager";
96
+ context: TContext;
97
+ keys: TKeys;
98
+ shortcuts: TShortcuts;
99
+ commands: TCommands;
100
+ /** Most options can be set directly, except any readonly options which must go through {@link setManagerProperties} to ensure state remains consistent. */
101
+ options: {
102
+ sorter: IKeysSorter;
103
+ stringifier: IStringifier;
104
+ /**
105
+ * The error callback for recoverable errors such as multiple shortcuts matching, no shortcut matching once a chord chain has been "started", or an unknown key event because no matching key was found (only for keyboard events).
106
+ *
107
+ * Usually you will want to clear the manager's chain when this happens and display the error to the user. The default callback logs the error and clears the chain.
108
+ *
109
+ * In the case of multiple valid shortcuts, if you trigger any of the shortcuts "manually" note that you will need to simulate both the keydown/keyup calls if you differentiate between them.
110
+ *
111
+ * Also the input event can be undefined if you set the manager chain directly since it will check if it should trigger shortcuts.
112
+ */
113
+ cb: (manager: Manager, error: MultipleErrors<typeof SHORTCUT_ERROR.MULTIPLE_MATCHING_SHORTCUTS | typeof SHORTCUT_ERROR.NO_MATCHING_SHORTCUT | typeof SHORTCUT_ERROR.UNKNOWN_KEY_EVENT | typeof SHORTCUT_ERROR.UNKNOWN_KEY_ID | typeof SHORTCUT_ERROR.UNKNOWN_KEY>, e?: AnyInputEvent) => void;
114
+ /**
115
+ * Determines if two conditions are equal.
116
+ *
117
+ * This is actually not a good idea to implement if you use boolean conditions. See {@link ConditionComparer} for why.
118
+ */
119
+ conditionEquals: ConditionComparer;
120
+ /** Determines how conditions are evaluated. */
121
+ evaluateCondition: ConditionEvaluator<TContext>;
122
+ /** Enable/disable triggering of shortcuts. The manager otherwise works as normal. */
123
+ enableShortcuts: boolean;
124
+ /** Enable/disable listeners. Listeners will remain attached but do nothing. */
125
+ enableListeners: boolean;
126
+ /**
127
+ * Whether to check the state of modifier or toggle keys using `event.getModifierState`.
128
+ *
129
+ * This is set to true by default when using `createManager` because it is usually what you want. It tracks the state with the most accuracy when, for example, the user focuses out, toggles a key, then focuses back.
130
+ *
131
+ * But, if you are allowing the user to change key states in some way (e.g. clicking on keys in the settings to visualize shortcuts), you will want to disable this temporarily so that they can click modifier keys. Otherwise they'd be immediately toggled off again (by the state check during the click) and nothing would happen.
132
+ *
133
+ * Keys also have their own individual {@link Key.updateStateOnAllEvents} in case you need more fine grained control.
134
+ *
135
+ * When this is set to false, the default mouseenter handler will ignore the event.
136
+ *
137
+ * If you will always have this set to false, you can forego the mouseenter event listener.
138
+ */
139
+ updateStateOnAllEvents: boolean;
140
+ };
141
+ /**
142
+ * An event listener for all events the manager handles including {@link virtualPress}/{@link virtualRelease}.
143
+ *
144
+ * The listener is called right after keys are found so you can have access to the keys as the manager understood them, but before everything else (setting the state, labeling, adding/removing from the chain). Note that `isKeydown` is always true for wheel events since their keyup is emulated within the same event handler.
145
+ *
146
+ * This exists because not all events trigger shortcuts (which can access only the event that triggered them) but there are many times when you might still want access to the event to do things like `e.preventdefault()`:
147
+ *
148
+ * - When recording, we usually always need to do `e.preventDefault()` except in some rare cases:
149
+ * - For example say you have a div which records while focused, if the manager is attached to a parent element, you will have to allow clicks to the parent so losing focus stops the recording. You do not generally need to allow keys through as you can set all shortcut conditions to only trigger when not recording, temporily swap out the shortcuts while recording, or use the onSetKeyProp hook (note this would mean hardcoding keys, but might be acceptable for a case such as this).
150
+ * - We also need to `e.preventDefault()` for any chords that are also browser shortcuts (though note not all browser shortcuts can be overriden). If you really need to there is the [Keyboard API](https://developer.mozilla.org/en-US/docs/Web/API/Keyboard_API) which allows requesting some keyboard shortcuts be locked (see [Keyboard Locking](https://developer.mozilla.org/en-US/docs/Web/API/Keyboard_API#keyboard_locking)).
151
+ *
152
+ *
153
+ * The following should give you a good starting point:
154
+ *
155
+ * ```ts
156
+ * manager.listener = (({event, isKeydown, keys}) => {
157
+ * if (
158
+ * (manager.isRecording && !(event instanceof MouseEvent))
159
+ * // || TODO browser shortcuts filter
160
+ * ) {
161
+ * event.preventDefault()
162
+ * }
163
+ * })
164
+ * ```
165
+ */
166
+ listener?: TListener;
167
+ /**
168
+ * Hooks provide a way to set further limits on what can be changed (can hooks), and provide listeners for when something *is* about to change (on* hooks).
169
+ *
170
+ * on* hooks allow hooking into changes for certain properties (such as key size/pos changed) to trigger recalculations (e.g. of layouts).
171
+ *
172
+ * They could also technically be used as an escape hatch for frameworks that don't support working mutable data, but I would advice against it. Instead I would recommend using a proxy based state management solution like valtio that allows for mutations and optimized rendering.
173
+ */
174
+ hooks: THooks;
175
+ /**
176
+ * The manager requires some state to function and be a little bit more efficient. All properties are readonly because they should not be modified unless they are allowed to be by {@link setManagerProp}.
177
+ */
178
+ state: {
179
+ /**
180
+ * The current chain of chords.
181
+ *
182
+ * Note that the manager's chain is not neccesarily valid and should be checked before assigning to a shortcut.
183
+ *
184
+ * @RequiresSet @OnHookable @Managed
185
+ */
186
+ readonly chain: string[][];
187
+ /**
188
+ * Whether the manager is waiting for non-modifier keys to be release.
189
+ *
190
+ *@RequiresSet @OnHookable @Managed
191
+ */
192
+ readonly isAwaitingKeyup: boolean;
193
+ /**
194
+ * Whether the manager is in recording mode.
195
+ *
196
+ * When enabling/disabling this property, you should clear the chain first with {@link safeSetSetManagerChain}.
197
+ *
198
+ * ```
199
+ * safeSetManagerChain(manager, [])
200
+ * setManagerProp(manager, "state.isRecording", true)
201
+ * //...
202
+ * safeSetManagerChain(manager, [])
203
+ * setManagerProp(manager, "state.isRecording", false)
204
+ * ```
205
+ *
206
+ * To allow users to record shortcuts, you can do something like have an input element that on focus starts recording and stops when focused is blurred (this has the advantage of working with keyboard navigation). In such a case, you can use the {@link Manager.listener} to `e.preventDefault()` all events except clicks outside the input. See it for more details.
207
+ *
208
+ * @RequiresSet @OnHookable @CanHookable
209
+ */
210
+ readonly isRecording: boolean;
211
+ /**
212
+ * There are times, such as after a keydown event, that a shortcut command will trigger, but we also need to "untrigger" it later on key up. If there is a triggerable shortcut it is saved here. See {@link Manager.state.chain}.
213
+ *
214
+ * @RequiresSet @OnHookable @Managed
215
+ */
216
+ readonly untrigger: false | TriggerableShortcut;
217
+ /**
218
+ * The manager keeps track of whether the next key press should start a new chord or not.
219
+ *
220
+ * @RequiresSet @OnHookable @Managed
221
+ */
222
+ readonly nextIsChord: boolean;
223
+ };
224
+ };
225
+ export type LabelOptions = {
226
+ /**
227
+ * See {@link labelWithKeyboardMap}. This is required for label strategies that use the navigator. You can get the map using [navigator.keyboard.getLayoutMap()](https://developer.mozilla.org/en-US/docs/Web/API/Keyboard/getLayoutMap).
228
+ */
229
+ map: KeyboardLayoutMap;
230
+ /**
231
+ * Filters the auto labeling.
232
+ *
233
+ * If the filter returns true, the key is not labeled.
234
+ *
235
+ * You can also use this to label the key yourself.
236
+ *
237
+ * Common filter actions:
238
+ * - Capitalize all single character keys to match what they look like on real keyboard.
239
+ * - Prevent keys with multi-line labels (e.g. `Num\nLock`, `Scroll\nLock` from getting changed).
240
+ *
241
+ * Note the event is not always a real event because if it's the navigator labeling the key or you're using the {@link Emulator} class, there isn't a real event.
242
+ */
243
+ labelFilter?: (e: AnyInputEvent | MinimalInputEvent, keyId: string, label: string, keys: Keys) => boolean;
244
+ };
245
+ export type EventTypes = "keydown" | "keyup" | "wheel" | "mousedown" | "mouseup" | "mouseenter";
246
+ export type EventListenerTypes<T extends EventTypes = EventTypes> = {
247
+ [key in T]: ((e: key extends "keydown" | "keyup" ? KeyboardEvent : key extends "wheel" ? WheelEvent : MouseEvent) => boolean) | ((e: key extends "keydown" | "keyup" ? KeyboardEvent : key extends "wheel" ? WheelEvent : MouseEvent) => void);
248
+ };
249
+ export {};
File without changes
@@ -0,0 +1 @@
1
+ export {};
File without changes
@@ -0,0 +1,144 @@
1
+ import type { Command } from "./commands.js";
2
+ import type { Condition } from "./condition.js";
3
+ import type { ChainError, SHORTCUT_ERROR } from "./enums.js";
4
+ import type { PickManager } from "./general.js";
5
+ import type { Key } from "./keys.js";
6
+ import type { Manager } from "./manager.js";
7
+ /**
8
+ * Same as {@link Shortcut} except you're allowed to exclude all properties except the chain.
9
+ */
10
+ export interface RawShortcut<TRawCommand extends Command["name"] | Command = Command["name"] | Command, TCommand extends TRawCommand extends string ? Command<TRawCommand> : TRawCommand = TRawCommand extends string ? Command<TRawCommand> : TRawCommand, TCondition extends Condition = Condition> extends Omit<Partial<Shortcut<TCommand["name"], TCondition>>, "chain" | "command"> {
11
+ chain: (string | Key)[][];
12
+ command?: TRawCommand;
13
+ }
14
+ export interface Shortcut<TCommand extends Command["name"] = Command["name"], TCondition extends Condition = Condition> {
15
+ type: "shortcut";
16
+ /**
17
+ * The {@link Command} to associate with the shortcut.
18
+ *
19
+ * @RequiresSet @OnHookable @CanHookable
20
+ */
21
+ readonly command?: TCommand;
22
+ /**
23
+ * The {@link Condition} a shortcut is allowed to be triggered on. If both the command and the shortcut have a condition, both must be met.
24
+ *
25
+ * @RequiresSet @OnHookable @CanHookable
26
+ */
27
+ readonly condition: TCondition;
28
+ /**
29
+ * Whether the shortcut is enabled. Defaults to true.
30
+ *
31
+ * @RequiresSet @OnHookable @CanHookable
32
+ */
33
+ readonly enabled: boolean;
34
+ /**
35
+ * The chain of key chords that make up the shortcut. Note that this is NOT a unique identifier for shortcuts and cannot be used to compare them if you are making use of the when/context/active options.
36
+ *
37
+ * @RequiresSet @OnHookable @CanHookable
38
+ */
39
+ readonly chain: (Key["id"])[][];
40
+ /**
41
+ * It is sometimes useful for some shortcuts to not equal or conflict with eachother temporarily.
42
+ *
43
+ * Only methods that compare shortcut instances are affected.
44
+ *
45
+ * While the property is managed by the manager, it can be safely set then unset if not modifying anything.
46
+ *
47
+ * @RequiresSet @OnHookable @Managed
48
+ */
49
+ readonly forceUnequal: boolean;
50
+ }
51
+ export type Shortcuts<TEntries extends Shortcut[] = Shortcut[]> = {
52
+ /**
53
+ * The shortcut entries.
54
+ *
55
+ * To add/remove entries you should {@link addShortcut}/{@link removeShortcut} or {@link setShortcutsProp} with the synthetic `entries@add/remove` properties.
56
+ *
57
+ * The synthetic properties can be hooked into with {@link Manager.hooks}.
58
+ *
59
+ * @RequiresSet @OnHookable @Managed
60
+ */
61
+ readonly entries: TEntries;
62
+ /**
63
+ * For {@link doesShortcutConflictWith}.
64
+ *
65
+ * @experimental
66
+ * If this is true, the manager's context will be used to check conditions agains.
67
+ *
68
+ * Given all other conditions are equal, the shortcuts can only be in conflict if they both match the context. Note this means if neither match the context they are not considered to conflict (even though they might in another context). This is meant to be used when they both match the context, but some behavior had to be chosen for when they don't.
69
+ */
70
+ useContextInConflictCheck?: boolean;
71
+ /**
72
+ * For {@link doesShortcutConflictWith}.
73
+ *
74
+ * @experimental
75
+ * If this is true, modifier conflicts (e.g. `Ctrl` conflicts with `Ctrl+A`) will be ignored. You will need to figure out how to handle them manually.
76
+ */
77
+ ignoreModifierConflicts?: boolean;
78
+ /**
79
+ * For {@link doesShortcutConflictWith}.
80
+ *
81
+ * @experimental
82
+ * If this is true, partial chain conflicts (e.g. `Space` conflicts with `Space+A`) will be ignored. You will need to figure out how to handle them manually.
83
+ */
84
+ ignoreChainConflicts?: boolean;
85
+ };
86
+ export type RawShortcuts = Pick<Shortcuts, "entries"> & Partial<Shortcuts>;
87
+ export type TriggerableShortcut = Shortcut & {
88
+ command: NonNullable<Command["name"]>;
89
+ };
90
+ type GetShortcutHooks<T extends keyof ShortcutSetEntries | keyof ShortcutsSetEntries> = T extends CanHookShortcutProps ? Partial<Pick<NonNullable<Manager["hooks"]>, "canSetShortcutProp" | "onSetShortcutProp">> : T extends OnHookShortcutProps ? Partial<Pick<NonNullable<Manager["hooks"]>, "onSetShortcutProp">> : T extends CanHookShortcutsProps ? Partial<Pick<NonNullable<Manager["hooks"]>, "canSetShortcutsProp" | "onSetShortcutsProp">> : Partial<Pick<NonNullable<Manager["hooks"]>, "onSetShortcutsProp">>;
91
+ type BaseShortcutManager = Record<any, any>;
92
+ export type ShortcutSetEntries = {
93
+ chain: {
94
+ val: Shortcut["chain"];
95
+ manager: BaseShortcutManager & PickManager<"options", "stringifier" | "sorter"> & Pick<Manager, "shortcuts" | "commands" | "keys">;
96
+ hooks: GetShortcutHooks<"chain">;
97
+ error: ChainError | typeof SHORTCUT_ERROR.DUPLICATE_KEY | typeof SHORTCUT_ERROR.DUPLICATE_SHORTCUT;
98
+ };
99
+ command: {
100
+ val: Shortcut["command"];
101
+ manager: BaseShortcutManager & PickManager<"options", "stringifier"> & Pick<Manager, "commands"> & Partial<Pick<Manager, "keys">>;
102
+ hooks: GetShortcutHooks<"command">;
103
+ error: typeof SHORTCUT_ERROR.UNKNOWN_COMMAND;
104
+ };
105
+ condition: {
106
+ val: Shortcut["condition"];
107
+ manager: never;
108
+ hooks: GetShortcutHooks<"condition">;
109
+ error: never;
110
+ };
111
+ enabled: {
112
+ val: Shortcut["enabled"];
113
+ manager: never;
114
+ hooks: GetShortcutHooks<"enabled">;
115
+ error: never;
116
+ };
117
+ forceUnequal: {
118
+ val: Shortcut["forceUnequal"];
119
+ manager: never;
120
+ hooks: GetShortcutHooks<"forceUnequal">;
121
+ error: never;
122
+ };
123
+ };
124
+ export type OnHookShortcutProps = "chain" | "command" | "condition" | "enabled" | "forceUnequal";
125
+ export type CanHookShortcutProps = Exclude<OnHookShortcutProps, "forceUnequal">;
126
+ export type SyntheticOnHookShortcutsProps = "entries@add" | "entries@remove";
127
+ export type CanHookShortcutsProps = SyntheticOnHookShortcutsProps;
128
+ export type OnHookShortcutsProps = SyntheticOnHookShortcutsProps;
129
+ type BaseShortcutsManager = Pick<Manager, "keys" | "commands" | "shortcuts"> & PickManager<"options", "evaluateCondition" | "conditionEquals" | "stringifier"> & Record<any, any>;
130
+ export type ShortcutsSetEntries = {
131
+ "entries@add": {
132
+ val: Shortcut;
133
+ hooks: GetShortcutHooks<`entries@add`>;
134
+ manager: BaseShortcutsManager & PickManager<"options", "sorter">;
135
+ error: typeof SHORTCUT_ERROR.DUPLICATE_SHORTCUT | typeof SHORTCUT_ERROR.UNKNOWN_COMMAND | ChainError;
136
+ };
137
+ "entries@remove": {
138
+ val: Shortcut;
139
+ hooks: GetShortcutHooks<`entries@remove`>;
140
+ manager: BaseShortcutsManager;
141
+ error: typeof SHORTCUT_ERROR.MISSING;
142
+ };
143
+ };
144
+ export {};
File without changes
@@ -0,0 +1 @@
1
+ export {};
File without changes
@@ -0,0 +1,3 @@
1
+ export { default } from './module.mjs'
2
+
3
+ export { type ModuleOptions } from './module.mjs'
@@ -0,0 +1,27 @@
1
+ import type { Keys } from "../types/index.js";
2
+ /**
3
+ * Returns whether a chain is a subset of another, taking into account variants (this can be disabled).
4
+ */
5
+ export declare const chainContainsSubset: (chain: readonly string[][], chainSubset: readonly string[][], keys: Keys, { onlySubset, onlyPressable, allowVariants }?: {
6
+ /**
7
+ * If true, will return false if the last chord of the chainSubset is exactly equal.
8
+ *
9
+ * So for example, for the chain: [[a], [ctrl+b]], the following would return as follows:
10
+ *
11
+ * ```
12
+ * // true
13
+ * [[]] or []
14
+ * [[a]]
15
+ * [[a], []]
16
+ * [[a], [ctrl]]
17
+ * [[a], [b]]
18
+ *
19
+ * // false
20
+ * [[a], [ctrl, b]]
21
+ * ```
22
+ */
23
+ onlySubset?: boolean;
24
+ /** If true, will return false if the shortcut is not one key press away. */
25
+ onlyPressable?: boolean;
26
+ allowVariants?: boolean;
27
+ }) => boolean;
@@ -0,0 +1,45 @@
1
+ import { containsKey } from "./containsKey.js";
2
+ import { dedupeKeys } from "./dedupeKeys.js";
3
+ import { equalsKeys } from "./equalsKeys.js";
4
+ export const chainContainsSubset = (chain, chainSubset, keys, {
5
+ onlySubset = false,
6
+ onlyPressable = false,
7
+ allowVariants = true
8
+ } = {}) => {
9
+ const opts = { allowVariants };
10
+ if (chainSubset.length === 0) {
11
+ const isEmpty = chain.length === 0 || chain.length === 1 && chain[0].length === 0;
12
+ if (isEmpty) return onlySubset;
13
+ return !onlyPressable || chain.length === 1 && chain[0].length === 1;
14
+ }
15
+ if (chainSubset.length > chain.length) return false;
16
+ const index = chainSubset.length === 0 ? 0 : chainSubset.length - 1;
17
+ const precedingChords = chainSubset.slice(0, index);
18
+ const precedingChordsEqual = index === 0 || equalsKeys(chain, precedingChords, keys, precedingChords.length, opts);
19
+ if (!precedingChordsEqual) return false;
20
+ if (onlyPressable && index !== chain.length - 1) return false;
21
+ const subsetLastChord = dedupeKeys(chainSubset[index], keys, opts);
22
+ const chainLastSharedChord = dedupeKeys(chain[index], keys, opts);
23
+ if (onlySubset) {
24
+ if (subsetLastChord.length === chainLastSharedChord.length) {
25
+ if (chainSubset.length === chain.length) return false;
26
+ if (chainSubset.length < chain.length) return true;
27
+ }
28
+ }
29
+ for (const key of subsetLastChord) {
30
+ if (!containsKey(chainLastSharedChord, key, keys, opts)) {
31
+ return false;
32
+ }
33
+ }
34
+ const subsetModifiers = subsetLastChord.filter((key) => keys.entries[key].isModifier);
35
+ const modifiers = chainLastSharedChord.filter((key) => keys.entries[key].isModifier);
36
+ const modKeysDiff = modifiers.length - subsetModifiers.length;
37
+ const subsetNonModKeysCount = subsetLastChord.length - subsetModifiers.length;
38
+ const nonModKeysCount = chainLastSharedChord.length - modifiers.length;
39
+ const nonModKeysDiff = nonModKeysCount - subsetNonModKeysCount;
40
+ if (onlySubset && modKeysDiff === 0 && nonModKeysDiff === 0) return false;
41
+ if (onlyPressable && !(modKeysDiff === 0 && nonModKeysDiff === 1 || modKeysDiff === 1 && nonModKeysDiff === 0)) {
42
+ return false;
43
+ }
44
+ return true;
45
+ };
@@ -0,0 +1,2 @@
1
+ /** Deep clones a shortcut chain. */
2
+ export declare function cloneChain(chain: string[][]): string[][];
@@ -0,0 +1,11 @@
1
+ export function cloneChain(chain) {
2
+ const clone = [];
3
+ for (const chord of chain) {
4
+ const chordClone = [];
5
+ for (const key of chord) {
6
+ chordClone.push(key);
7
+ }
8
+ clone.push(chordClone);
9
+ }
10
+ return clone;
11
+ }
@@ -0,0 +1,3 @@
1
+ import type { Key } from "../types/index.js";
2
+ /** Deep clones a key. */
3
+ export declare function cloneKey(key: Key): Key;
@@ -0,0 +1,26 @@
1
+ export function cloneKey(key) {
2
+ const clone = {
3
+ type: key.type,
4
+ id: key.id,
5
+ label: key.label,
6
+ classes: [...key.classes],
7
+ x: key.x,
8
+ y: key.y,
9
+ width: key.width,
10
+ height: key.height,
11
+ enabled: key.enabled,
12
+ pressed: key.pressed,
13
+ isModifier: key.isModifier,
14
+ variants: key.variants ? [...key.variants] : void 0,
15
+ render: key.render,
16
+ updateStateOnAllEvents: key.updateStateOnAllEvents,
17
+ isToggle: key.isToggle,
18
+ ...key.isToggle ? {
19
+ toggleOnPressed: key.toggleOnPressed,
20
+ toggleOnId: key.toggleOnId,
21
+ toggleOffId: key.toggleOffId,
22
+ toggleOffPressed: key.toggleOffPressed
23
+ } : {}
24
+ };
25
+ return clone;
26
+ }
@@ -0,0 +1,7 @@
1
+ import type { Keys } from "../types/index.js";
2
+ /**
3
+ * Returns whether a shortcut's chain or chord contains the given key according to {@link equalsKey}.
4
+ */
5
+ export declare function containsKey(chordOrChain: string[][] | string[], key: string, keys: Keys, opts?: {
6
+ allowVariants?: boolean;
7
+ }): boolean;
@@ -0,0 +1,4 @@
1
+ import { equalsKey } from "./equalsKey.js";
2
+ export function containsKey(chordOrChain, key, keys, opts = {}) {
3
+ return chordOrChain.flat().some((existing) => equalsKey(existing, key, keys, opts));
4
+ }
@@ -0,0 +1,9 @@
1
+ import type { Keys } from "../types/index.js";
2
+ /**
3
+ * Returns a new array deduped according to {@link equalsKey}.
4
+ *
5
+ * This is useful when keys have variants to dedupe them by their variants since a shortcut might contain multiple variants, which can make it hard to check chords satisfy certain conditions (e.g. x amount of modifiers).
6
+ */
7
+ export declare const dedupeKeys: (keyList: string[], keys: Keys, opts?: {
8
+ allowVariants?: boolean;
9
+ }) => string[];
@@ -0,0 +1,9 @@
1
+ import { equalsKey } from "./equalsKey.js";
2
+ export const dedupeKeys = (keyList, keys, opts = {}) => {
3
+ const res = [];
4
+ for (const keyId of keyList) {
5
+ if (res.find((id) => equalsKey(id, keyId, keys, opts))) continue;
6
+ res.push(keyId);
7
+ }
8
+ return res;
9
+ };
@@ -0,0 +1,12 @@
1
+ import type { Keys } from "../types/index.js";
2
+ /**
3
+ * Returns whether the key (b) passed is equal to key (a).
4
+ *
5
+ * To return true, their ids must be equal.
6
+ *
7
+ * There is an `allowVariants` option that is true by default that allows the keyB to be equal if any of their variants match.
8
+ *
9
+ */
10
+ export declare function equalsKey(keyIdA: string, keyIdB: string, keys: Keys, { allowVariants }?: {
11
+ allowVariants?: boolean;
12
+ }): boolean;
@@ -0,0 +1,13 @@
1
+ import { getKeyFromIdOrVariant } from "../helpers/getKeyFromIdOrVariant.js";
2
+ export function equalsKey(keyIdA, keyIdB, keys, { allowVariants = true } = {}) {
3
+ const idsEqual = keyIdA === keyIdB;
4
+ const keyA = getKeyFromIdOrVariant(keyIdA, keys).unwrap()[0];
5
+ const keyB = getKeyFromIdOrVariant(keyIdB, keys).unwrap()[0];
6
+ if (!idsEqual && allowVariants && keyA.variants && keyB.variants) {
7
+ for (const variant of keyA.variants) {
8
+ if (keyB.variants.includes(variant)) return true;
9
+ }
10
+ return false;
11
+ }
12
+ return idsEqual;
13
+ }
@@ -0,0 +1,24 @@
1
+ import type { Keys } from "../types/index.js";
2
+ /**
3
+ * Returns if the given chords are equal.
4
+ *
5
+ * Can be passed a length, to limit the search to only the first x chords.
6
+ *
7
+ * ```ts
8
+ * equalsKeys([[keyA]], [[keyA]]) // true
9
+ * equalsKeys([[keyA], [keyB]], [[keyA]]) // false
10
+ * equalsKeys([[keyA], [keyB]], [[keyA]], 1) // true
11
+ * equalsKeys([[keyA], [keyB]], [[keyA], [keyB]], 2) // true
12
+ * equalsKeys([[keyA], [keyB]], [[keyA], [keyB], [keyC]], 3) // false
13
+ * equalsKeys([[keyA], [keyB]], [[keyB]], 1) // false
14
+ * ```
15
+ * Can also pass options to {@link equalsKey}:
16
+ *
17
+ * ```ts
18
+ * equalsKeys([[keyA], [keyB]], [[keyAVariant], [keyB]], 2, { allowVariants: true }) // true
19
+ * ```
20
+ *
21
+ */
22
+ export declare function equalsKeys(chain: readonly string[][], base: readonly string[][], keys: Keys, length?: number, opts?: {
23
+ allowVariants?: boolean;
24
+ }): boolean;
@@ -0,0 +1,15 @@
1
+ import { containsKey } from "./containsKey.js";
2
+ import { dedupeKeys } from "./dedupeKeys.js";
3
+ export function equalsKeys(chain, base, keys, length, opts = {}) {
4
+ if (length === void 0 && base.length !== chain.length || length !== void 0 && (chain.length < length || base.length < length)) return false;
5
+ return chain.slice(0, length ?? chain.length).find((thisChord, c) => {
6
+ if (!base[c]) return true;
7
+ const otherChord = dedupeKeys(base[c], keys, opts);
8
+ thisChord = dedupeKeys(thisChord, keys, opts);
9
+ if (otherChord.length !== thisChord.length) return true;
10
+ for (const otherKey of otherChord) {
11
+ if (!containsKey(thisChord, otherKey, keys, opts)) return true;
12
+ }
13
+ return false;
14
+ }) === void 0;
15
+ }