@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,97 @@
1
+ import { containsKey } from "./containsKey.js"
2
+ import { dedupeKeys } from "./dedupeKeys.js"
3
+ import { equalsKeys } from "./equalsKeys.js"
4
+
5
+ import type { Keys } from "../types/index.js"
6
+
7
+
8
+ /**
9
+ * Returns whether a chain is a subset of another, taking into account variants (this can be disabled).
10
+ */
11
+
12
+ export const chainContainsSubset = (
13
+ chain: readonly string[][],
14
+ chainSubset: readonly string[][],
15
+ keys: Keys,
16
+ {
17
+ onlySubset = false,
18
+ onlyPressable = false,
19
+ allowVariants = true
20
+ }: {
21
+ /**
22
+ * If true, will return false if the last chord of the chainSubset is exactly equal.
23
+ *
24
+ * So for example, for the chain: [[a], [ctrl+b]], the following would return as follows:
25
+ *
26
+ * ```
27
+ * // true
28
+ * [[]] or []
29
+ * [[a]]
30
+ * [[a], []]
31
+ * [[a], [ctrl]]
32
+ * [[a], [b]]
33
+ *
34
+ * // false
35
+ * [[a], [ctrl, b]]
36
+ * ```
37
+ */
38
+ onlySubset?: boolean
39
+ /** If true, will return false if the shortcut is not one key press away. */
40
+ onlyPressable?: boolean
41
+ allowVariants?: boolean
42
+ } = { }
43
+ ): boolean => {
44
+ const opts = { allowVariants }
45
+
46
+ if (chainSubset.length === 0) {
47
+ const isEmpty = chain.length === 0 || (chain.length === 1 && chain[0].length === 0)
48
+ if (isEmpty) return onlySubset
49
+ return !onlyPressable || (chain.length === 1 && chain[0].length === 1)
50
+ }
51
+
52
+ if (chainSubset.length > chain.length) return false
53
+
54
+
55
+ const index = chainSubset.length === 0 ? 0 : chainSubset.length - 1
56
+
57
+ const precedingChords = chainSubset.slice(0, index)
58
+ const precedingChordsEqual = index === 0 || equalsKeys(chain, precedingChords, keys, precedingChords.length, opts)
59
+ if (!precedingChordsEqual) return false
60
+ if (onlyPressable && index !== chain.length - 1) return false
61
+
62
+ const subsetLastChord = dedupeKeys(chainSubset[index], keys, opts)
63
+ // note it might NOT be the last chord
64
+ const chainLastSharedChord = dedupeKeys(chain[index], keys, opts)
65
+
66
+ if (onlySubset) {
67
+ if (subsetLastChord.length === chainLastSharedChord.length) {
68
+ // they match exactly, so it's not strictly a subset
69
+ if (chainSubset.length === chain.length) return false
70
+ // the chainSubset is x chords too short, this is always a subset
71
+ if (chainSubset.length < chain.length) return true
72
+ }
73
+ }
74
+
75
+ for (const key of subsetLastChord) {
76
+ if (!containsKey(chainLastSharedChord, key, keys, opts)) {
77
+ return false
78
+ }
79
+ }
80
+
81
+ const subsetModifiers = subsetLastChord.filter(key => keys.entries[key].isModifier)
82
+ const modifiers = chainLastSharedChord.filter(key => keys.entries[key].isModifier)
83
+
84
+ const modKeysDiff = modifiers.length - subsetModifiers.length
85
+
86
+ const subsetNonModKeysCount = subsetLastChord.length - subsetModifiers.length
87
+ const nonModKeysCount = chainLastSharedChord.length - modifiers.length
88
+ const nonModKeysDiff = nonModKeysCount - subsetNonModKeysCount
89
+
90
+ if (onlySubset && modKeysDiff === 0 && nonModKeysDiff === 0) return false
91
+ if (onlyPressable && !(
92
+ (modKeysDiff === 0 && nonModKeysDiff === 1)
93
+ || (modKeysDiff === 1 && nonModKeysDiff === 0)
94
+ )) { return false }
95
+
96
+ return true
97
+ }
@@ -0,0 +1,13 @@
1
+ /** Deep clones a shortcut chain. */
2
+ export function cloneChain(chain: string[][]): string[][] {
3
+ const clone = []
4
+ for (const chord of chain) {
5
+ const chordClone = []
6
+ for (const key of chord) {
7
+ chordClone.push(key)
8
+ }
9
+ clone.push(chordClone)
10
+ }
11
+
12
+ return clone
13
+ }
@@ -0,0 +1,33 @@
1
+ import type { Key } from "../types/index.js"
2
+
3
+ /** Deep clones a key. */
4
+ export function cloneKey(key: Key): Key {
5
+ // cloning like this is just lightining fast.
6
+ const clone: Key = {
7
+ type: key.type,
8
+ id: key.id,
9
+ label: key.label,
10
+ classes: [...key.classes],
11
+ x: key.x,
12
+ y: key.y,
13
+ width: key.width,
14
+ height: key.height,
15
+ enabled: key.enabled,
16
+ pressed: key.pressed,
17
+ isModifier: key.isModifier,
18
+ variants: key.variants ? [...key.variants] : undefined,
19
+ render: key.render,
20
+ updateStateOnAllEvents: key.updateStateOnAllEvents,
21
+ isToggle: key.isToggle,
22
+ ...(key.isToggle
23
+ ? {
24
+ toggleOnPressed: key.toggleOnPressed,
25
+ toggleOnId: key.toggleOnId,
26
+ toggleOffId: key.toggleOffId,
27
+ toggleOffPressed: key.toggleOffPressed
28
+ } satisfies Partial<Key<string>>
29
+ : {}) as any
30
+ }
31
+
32
+ return clone
33
+ }
@@ -0,0 +1,17 @@
1
+ import { equalsKey } from "./equalsKey.js"
2
+
3
+ import type { Keys } from "../types/index.js"
4
+
5
+ /**
6
+ * Returns whether a shortcut's chain or chord contains the given key according to {@link equalsKey}.
7
+ */
8
+ export function containsKey(
9
+ chordOrChain: string[][] | string[],
10
+ key: string,
11
+ keys: Keys,
12
+ opts: { allowVariants?: boolean } = {}
13
+ ): boolean {
14
+ return chordOrChain
15
+ .flat()
16
+ .some(existing => equalsKey(existing, key, keys, opts))
17
+ }
@@ -0,0 +1,23 @@
1
+ import { equalsKey } from "./equalsKey.js"
2
+
3
+ import type { Keys } from "../types/index.js"
4
+
5
+ /**
6
+ * Returns a new array deduped according to {@link equalsKey}.
7
+ *
8
+ * 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).
9
+ */
10
+ export const dedupeKeys = (
11
+ // we take a string to avoid having to deal with toggle keys
12
+ keyList: string[],
13
+ keys: Keys,
14
+ opts: { allowVariants?: boolean } = {}
15
+ ): string[] => {
16
+ const res: string[] = []
17
+ for (const keyId of keyList) {
18
+ if (res.find(id => equalsKey(id, keyId, keys, opts))) continue
19
+ res.push(keyId)
20
+ }
21
+ return res
22
+ }
23
+
@@ -0,0 +1,32 @@
1
+ import { getKeyFromIdOrVariant } from "../helpers/getKeyFromIdOrVariant.js"
2
+ import type { Keys } from "../types/index.js"
3
+
4
+ /**
5
+ * Returns whether the key (b) passed is equal to key (a).
6
+ *
7
+ * To return true, their ids must be equal.
8
+ *
9
+ * There is an `allowVariants` option that is true by default that allows the keyB to be equal if any of their variants match.
10
+ *
11
+ */
12
+
13
+ export function equalsKey(
14
+ keyIdA: string,
15
+ keyIdB: string,
16
+ keys: Keys,
17
+ { allowVariants = true }: { allowVariants?: boolean } = {}
18
+ ): boolean {
19
+ const idsEqual = keyIdA === keyIdB
20
+
21
+ const keyA = getKeyFromIdOrVariant(keyIdA, keys).unwrap()[0]
22
+ const keyB = getKeyFromIdOrVariant(keyIdB, keys).unwrap()[0]
23
+
24
+ if (!idsEqual && allowVariants && keyA.variants && keyB.variants) {
25
+ for (const variant of keyA.variants) {
26
+ if (keyB.variants.includes(variant)) return true
27
+ }
28
+ return false
29
+ }
30
+ return idsEqual
31
+ }
32
+
@@ -0,0 +1,50 @@
1
+ import { containsKey } from "./containsKey.js"
2
+ import { dedupeKeys } from "./dedupeKeys.js"
3
+
4
+ import type { Keys } from "../types/index.js"
5
+
6
+ /**
7
+ * Returns if the given chords are equal.
8
+ *
9
+ * Can be passed a length, to limit the search to only the first x chords.
10
+ *
11
+ * ```ts
12
+ * equalsKeys([[keyA]], [[keyA]]) // true
13
+ * equalsKeys([[keyA], [keyB]], [[keyA]]) // false
14
+ * equalsKeys([[keyA], [keyB]], [[keyA]], 1) // true
15
+ * equalsKeys([[keyA], [keyB]], [[keyA], [keyB]], 2) // true
16
+ * equalsKeys([[keyA], [keyB]], [[keyA], [keyB], [keyC]], 3) // false
17
+ * equalsKeys([[keyA], [keyB]], [[keyB]], 1) // false
18
+ * ```
19
+ * Can also pass options to {@link equalsKey}:
20
+ *
21
+ * ```ts
22
+ * equalsKeys([[keyA], [keyB]], [[keyAVariant], [keyB]], 2, { allowVariants: true }) // true
23
+ * ```
24
+ *
25
+ */
26
+ export function equalsKeys(
27
+ chain: readonly string[][],
28
+ base: readonly string[][],
29
+ keys: Keys,
30
+ length?: number,
31
+ opts: { allowVariants?: boolean } = {}
32
+ ): boolean {
33
+ // Since they're pre-sorted this should be quite fast
34
+ if (
35
+ (length === undefined && base.length !== chain.length)
36
+ || (length !== undefined && (chain.length < length || base.length < length))
37
+ ) return false
38
+
39
+ return chain.slice(0, length ?? chain.length)
40
+ .find((thisChord, c) => {
41
+ if (!base[c]) return true
42
+ const otherChord = dedupeKeys(base[c], keys, opts)
43
+ thisChord = dedupeKeys(thisChord, keys, opts)
44
+ if (otherChord.length !== thisChord.length) return true
45
+ for (const otherKey of otherChord) {
46
+ if (!containsKey(thisChord, otherKey, keys, opts)) return true
47
+ }
48
+ return false
49
+ }) === undefined
50
+ }
@@ -0,0 +1,16 @@
1
+ /* Autogenerated Index [Ignore] */
2
+
3
+ export { chainContainsSubset } from "./chainContainsSubset.js"
4
+ export { cloneChain } from "./cloneChain.js"
5
+ export { cloneKey } from "./cloneKey.js"
6
+ export { containsKey } from "./containsKey.js"
7
+ export { dedupeKeys } from "./dedupeKeys.js"
8
+ export { equalsKey } from "./equalsKey.js"
9
+ export { equalsKeys } from "./equalsKeys.js"
10
+ export { isAnyKey } from "./isAnyKey.js"
11
+ export { isMouseKey } from "./isMouseKey.js"
12
+ export { isNormalKey } from "./isNormalKey.js"
13
+ export { isTriggerKey } from "./isTriggerKey.js"
14
+ export { isWheelKey } from "./isWheelKey.js"
15
+ export { mapKeys } from "./mapKeys.js"
16
+ export { removeKeys } from "./removeKeys.js"
@@ -0,0 +1,12 @@
1
+ import { isMouseKey } from "./isMouseKey.js"
2
+ import { isWheelKey } from "./isWheelKey.js"
3
+
4
+ import type { Key } from "../types/index.js"
5
+
6
+
7
+ /**
8
+ * Returns whether a key is a key (and not a mouse button or mouse wheel).
9
+ */
10
+ export function isAnyKey(key: Key): boolean {
11
+ return !isWheelKey(key) && !isMouseKey(key)
12
+ }
@@ -0,0 +1,27 @@
1
+ import type { Key } from "../types/index.js"
2
+
3
+
4
+ const possibleIds = [
5
+ "0",
6
+ "1",
7
+ "2",
8
+ "3",
9
+ "4",
10
+ "0On",
11
+ "1On",
12
+ "2On",
13
+ "3On",
14
+ "4On",
15
+ "0Off",
16
+ "1Off",
17
+ "2Off",
18
+ "3Off",
19
+ "4Off"
20
+ ]
21
+ /**
22
+ * Returns whether a key is a mouse key (id = 0-4).
23
+ */
24
+ export function isMouseKey(key: Key): boolean {
25
+ return possibleIds.includes(key.id)
26
+ || (key.variants?.some(id => possibleIds.includes(id)) ?? false)
27
+ }
@@ -0,0 +1,15 @@
1
+ import { isMouseKey } from "./isMouseKey.js"
2
+ import { isWheelKey } from "./isWheelKey.js"
3
+
4
+ import type { Key } from "../types/index.js"
5
+
6
+
7
+ /**
8
+ * Returns whether a key is a normal key (it is not a modifier, mouse, wheel, or toggle key).
9
+ */
10
+ export function isNormalKey(key: Key): boolean {
11
+ return !isWheelKey(key)
12
+ && !isMouseKey(key)
13
+ && !key.isModifier
14
+ && !key.isToggle
15
+ }
@@ -0,0 +1,7 @@
1
+ import type { Key } from "../types/index.js"
2
+ /**
3
+ * See {@link Manager} and {@link Manager.pressedNonModifierKeys}.
4
+ */
5
+ export function isTriggerKey(key: Key): boolean {
6
+ return !key.isModifier && !key.isToggle
7
+ }
@@ -0,0 +1,18 @@
1
+ import type { Key } from "../types/index.js"
2
+
3
+
4
+ const possibleIds = [
5
+ "WheelUp",
6
+ "WheelDown",
7
+ "WheelUpOn",
8
+ "WheelDownOn",
9
+ "WheelUpOff",
10
+ "WheelDownOff"
11
+ ]
12
+ /**
13
+ * Returns whether a key is a a wheel up/down "key".
14
+ */
15
+ export function isWheelKey(key: Key): boolean {
16
+ return possibleIds.includes(key.id)
17
+ || (key.variants?.some(id => possibleIds.includes(id)) ?? false)
18
+ }
@@ -0,0 +1,21 @@
1
+ import { isArray } from "@alanscodelog/utils/isArray"
2
+
3
+ /**
4
+ * Map keys of a chain or chord\* by the given function.
5
+ *
6
+ * Useful for inspecting a chain/chord when debugging.
7
+ *
8
+ * \*This is determined by checking if the first element is an array or not.
9
+ */
10
+ export function mapKeys<
11
+ TType extends any[] | any[][],
12
+ TReturn = string
13
+ >(
14
+ chainOrChord: TType,
15
+ func: (key: TType extends any[][] ? TType[number][number] : TType[number]) => TReturn = key => (key as any)?.id
16
+ ): TType extends any[][] ? TReturn[][] : TReturn[] {
17
+ if (chainOrChord.length === 0) return []
18
+ return isArray(chainOrChord[0])
19
+ ? (chainOrChord as TType[][]).map(chord => chord.map(key => func(key as any))) as any
20
+ : (chainOrChord as TType[]).map(key => func(key as any)) as any
21
+ }
@@ -0,0 +1,16 @@
1
+ import { equalsKey } from "./equalsKey.js"
2
+
3
+ import type { Keys } from "../types/index.js"
4
+
5
+ /**
6
+ * Returns a copy of keysList with the keys given to remove, removed, checking equality according to {@link equalsKey}.
7
+ */
8
+ export const removeKeys = (
9
+ keysList: readonly string[],
10
+ toRemove: readonly string[],
11
+ keys: Keys,
12
+ opts: { allowVariants?: boolean } = {}
13
+ ): string[] => keysList
14
+ .filter(key =>
15
+ toRemove.find(_ => equalsKey(key, _, keys, opts)) === undefined
16
+ )