effect-web-midi 0.1.0

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 (222) hide show
  1. package/README.md +7 -0
  2. package/dist/index.js +2 -0
  3. package/dist/index.js.map +1 -0
  4. package/dist/src/EMIDIAccess.js +68 -0
  5. package/dist/src/EMIDIAccess.js.map +1 -0
  6. package/dist/src/EMIDIInput.js +226 -0
  7. package/dist/src/EMIDIInput.js.map +1 -0
  8. package/dist/src/EMIDIOutput.js +225 -0
  9. package/dist/src/EMIDIOutput.js.map +1 -0
  10. package/dist/src/EMIDIPort.js +213 -0
  11. package/dist/src/EMIDIPort.js.map +1 -0
  12. package/dist/src/MIDIErrors.js +4 -0
  13. package/dist/src/MIDIErrors.js.map +1 -0
  14. package/dist/src/Parsing.js +2 -0
  15. package/dist/src/Parsing.js.map +1 -0
  16. package/dist/src/StreamMaker.js +1 -0
  17. package/dist/src/StreamMaker.js.map +1 -0
  18. package/dist/src/Util.js +4 -0
  19. package/dist/src/Util.js.map +1 -0
  20. package/dist/src/index.js +9 -0
  21. package/dist/src/index.js.map +1 -0
  22. package/dist/src/internal/EMIDIAccess.js +409 -0
  23. package/dist/src/internal/EMIDIAccess.js.map +1 -0
  24. package/dist/src/internal/EMIDIInput.js +69 -0
  25. package/dist/src/internal/EMIDIInput.js.map +1 -0
  26. package/dist/src/internal/EMIDIOutput.js +120 -0
  27. package/dist/src/internal/EMIDIOutput.js.map +1 -0
  28. package/dist/src/internal/EMIDIPort.js +125 -0
  29. package/dist/src/internal/EMIDIPort.js.map +1 -0
  30. package/dist/src/internal/MIDIPortMethodCalls/acquireReleasePortConnection/acquireReleasePortConnectionByPort.js +27 -0
  31. package/dist/src/internal/MIDIPortMethodCalls/acquireReleasePortConnection/acquireReleasePortConnectionByPort.js.map +1 -0
  32. package/dist/src/internal/MIDIPortMethodCalls/acquireReleasePortConnection/acquireReleasePortConnectionByPortIdAndAccess.js +19 -0
  33. package/dist/src/internal/MIDIPortMethodCalls/acquireReleasePortConnection/acquireReleasePortConnectionByPortIdAndAccess.js.map +1 -0
  34. package/dist/src/internal/MIDIPortMethodCalls/acquireReleasePortConnection/acquireReleasePortConnectionByPortIdInContext.js +16 -0
  35. package/dist/src/internal/MIDIPortMethodCalls/acquireReleasePortConnection/acquireReleasePortConnectionByPortIdInContext.js.map +1 -0
  36. package/dist/src/internal/MIDIPortMethodCalls/actOnPort.js +18 -0
  37. package/dist/src/internal/MIDIPortMethodCalls/actOnPort.js.map +1 -0
  38. package/dist/src/internal/MIDIPortMethodCalls/closePortConnection/closePortConnectionByPort.js +27 -0
  39. package/dist/src/internal/MIDIPortMethodCalls/closePortConnection/closePortConnectionByPort.js.map +1 -0
  40. package/dist/src/internal/MIDIPortMethodCalls/closePortConnection/closePortConnectionByPortIdAndAccess.js +18 -0
  41. package/dist/src/internal/MIDIPortMethodCalls/closePortConnection/closePortConnectionByPortIdAndAccess.js.map +1 -0
  42. package/dist/src/internal/MIDIPortMethodCalls/closePortConnection/closePortConnectionByPortIdInContext.js +16 -0
  43. package/dist/src/internal/MIDIPortMethodCalls/closePortConnection/closePortConnectionByPortIdInContext.js.map +1 -0
  44. package/dist/src/internal/MIDIPortMethodCalls/makeMIDIPortMethodCallerFactory.js +21 -0
  45. package/dist/src/internal/MIDIPortMethodCalls/makeMIDIPortMethodCallerFactory.js.map +1 -0
  46. package/dist/src/internal/MIDIPortMethodCalls/openPortConnection/openPortConnectionByPort.js +30 -0
  47. package/dist/src/internal/MIDIPortMethodCalls/openPortConnection/openPortConnectionByPort.js.map +1 -0
  48. package/dist/src/internal/MIDIPortMethodCalls/openPortConnection/openPortConnectionByPortIdAndAccess.js +18 -0
  49. package/dist/src/internal/MIDIPortMethodCalls/openPortConnection/openPortConnectionByPortIdAndAccess.js.map +1 -0
  50. package/dist/src/internal/MIDIPortMethodCalls/openPortConnection/openPortConnectionByPortIdInContext.js +16 -0
  51. package/dist/src/internal/MIDIPortMethodCalls/openPortConnection/openPortConnectionByPortIdInContext.js.map +1 -0
  52. package/dist/src/internal/StreamMaker.js +101 -0
  53. package/dist/src/internal/StreamMaker.js.map +1 -0
  54. package/dist/src/internal/errors.js +161 -0
  55. package/dist/src/internal/errors.js.map +1 -0
  56. package/dist/src/internal/getPortByPortId/getPortByPortIdAndAccess.js +53 -0
  57. package/dist/src/internal/getPortByPortId/getPortByPortIdAndAccess.js.map +1 -0
  58. package/dist/src/internal/getPortByPortId/getPortByPortIdInContext.js +18 -0
  59. package/dist/src/internal/getPortByPortId/getPortByPortIdInContext.js.map +1 -0
  60. package/dist/src/internal/makePortStateChangesStream/makePortStateChangesStreamByPort.js +52 -0
  61. package/dist/src/internal/makePortStateChangesStream/makePortStateChangesStreamByPort.js.map +1 -0
  62. package/dist/src/internal/makePortStateChangesStream/makePortStateChangesStreamByPortIdAndAccess.js +13 -0
  63. package/dist/src/internal/makePortStateChangesStream/makePortStateChangesStreamByPortIdAndAccess.js.map +1 -0
  64. package/dist/src/internal/makePortStateChangesStream/makePortStateChangesStreamByPortIdInContext.js +18 -0
  65. package/dist/src/internal/makePortStateChangesStream/makePortStateChangesStreamByPortIdInContext.js.map +1 -0
  66. package/dist/src/internal/mutablePropertyTools/doesMutablePortPropertyHaveSpecificValue/doesMutablePortPropertyHaveSpecificValueByPort.js +66 -0
  67. package/dist/src/internal/mutablePropertyTools/doesMutablePortPropertyHaveSpecificValue/doesMutablePortPropertyHaveSpecificValueByPort.js.map +1 -0
  68. package/dist/src/internal/mutablePropertyTools/doesMutablePortPropertyHaveSpecificValue/doesMutablePortPropertyHaveSpecificValueByPortIdAndAccess.js +61 -0
  69. package/dist/src/internal/mutablePropertyTools/doesMutablePortPropertyHaveSpecificValue/doesMutablePortPropertyHaveSpecificValueByPortIdAndAccess.js.map +1 -0
  70. package/dist/src/internal/mutablePropertyTools/doesMutablePortPropertyHaveSpecificValue/doesMutablePortPropertyHaveSpecificValueByPortIdInContext.js +61 -0
  71. package/dist/src/internal/mutablePropertyTools/doesMutablePortPropertyHaveSpecificValue/doesMutablePortPropertyHaveSpecificValueByPortIdInContext.js.map +1 -0
  72. package/dist/src/internal/mutablePropertyTools/getMutablePortProperty/getMutablePortPropertyByPort.js +42 -0
  73. package/dist/src/internal/mutablePropertyTools/getMutablePortProperty/getMutablePortPropertyByPort.js.map +1 -0
  74. package/dist/src/internal/mutablePropertyTools/getMutablePortProperty/getMutablePortPropertyByPortIdAndAccess.js +42 -0
  75. package/dist/src/internal/mutablePropertyTools/getMutablePortProperty/getMutablePortPropertyByPortIdAndAccess.js.map +1 -0
  76. package/dist/src/internal/mutablePropertyTools/getMutablePortProperty/getMutablePortPropertyByPortIdInContext.js +29 -0
  77. package/dist/src/internal/mutablePropertyTools/getMutablePortProperty/getMutablePortPropertyByPortIdInContext.js.map +1 -0
  78. package/dist/src/internal/mutablePropertyTools/getValueInRawPortFieldUnsafe.js +6 -0
  79. package/dist/src/internal/mutablePropertyTools/getValueInRawPortFieldUnsafe.js.map +1 -0
  80. package/dist/src/internal/mutablePropertyTools/matchMutablePortProperty/matchMutablePortPropertyByPort.js +46 -0
  81. package/dist/src/internal/mutablePropertyTools/matchMutablePortProperty/matchMutablePortPropertyByPort.js.map +1 -0
  82. package/dist/src/internal/mutablePropertyTools/matchMutablePortProperty/matchMutablePortPropertyByPortIdAndAccess.js +25 -0
  83. package/dist/src/internal/mutablePropertyTools/matchMutablePortProperty/matchMutablePortPropertyByPortIdAndAccess.js.map +1 -0
  84. package/dist/src/internal/mutablePropertyTools/matchMutablePortProperty/matchMutablePortPropertyByPortIdInContext.js +31 -0
  85. package/dist/src/internal/mutablePropertyTools/matchMutablePortProperty/matchMutablePortPropertyByPortIdInContext.js.map +1 -0
  86. package/dist/src/internal/parsing.js +117 -0
  87. package/dist/src/internal/parsing.js.map +1 -0
  88. package/dist/src/internal/util.js +59 -0
  89. package/dist/src/internal/util.js.map +1 -0
  90. package/dist-types/index.d.ts +2 -0
  91. package/dist-types/index.d.ts.map +1 -0
  92. package/dist-types/src/EMIDIAccess.d.ts +27 -0
  93. package/dist-types/src/EMIDIAccess.d.ts.map +1 -0
  94. package/dist-types/src/EMIDIInput.d.ts +26 -0
  95. package/dist-types/src/EMIDIInput.d.ts.map +1 -0
  96. package/dist-types/src/EMIDIOutput.d.ts +26 -0
  97. package/dist-types/src/EMIDIOutput.d.ts.map +1 -0
  98. package/dist-types/src/EMIDIPort.d.ts +26 -0
  99. package/dist-types/src/EMIDIPort.d.ts.map +1 -0
  100. package/dist-types/src/MIDIErrors.d.ts +2 -0
  101. package/dist-types/src/MIDIErrors.d.ts.map +1 -0
  102. package/dist-types/src/Parsing.d.ts +2 -0
  103. package/dist-types/src/Parsing.d.ts.map +1 -0
  104. package/dist-types/src/StreamMaker.d.ts +2 -0
  105. package/dist-types/src/StreamMaker.d.ts.map +1 -0
  106. package/dist-types/src/Util.d.ts +2 -0
  107. package/dist-types/src/Util.d.ts.map +1 -0
  108. package/dist-types/src/index.d.ts +9 -0
  109. package/dist-types/src/index.d.ts.map +1 -0
  110. package/dist-types/src/internal/EMIDIAccess.d.ts +339 -0
  111. package/dist-types/src/internal/EMIDIAccess.d.ts.map +1 -0
  112. package/dist-types/src/internal/EMIDIInput.d.ts +48 -0
  113. package/dist-types/src/internal/EMIDIInput.d.ts.map +1 -0
  114. package/dist-types/src/internal/EMIDIOutput.d.ts +93 -0
  115. package/dist-types/src/internal/EMIDIOutput.d.ts.map +1 -0
  116. package/dist-types/src/internal/EMIDIPort.d.ts +87 -0
  117. package/dist-types/src/internal/EMIDIPort.d.ts.map +1 -0
  118. package/dist-types/src/internal/MIDIPortMethodCalls/acquireReleasePortConnection/acquireReleasePortConnectionByPort.d.ts +16 -0
  119. package/dist-types/src/internal/MIDIPortMethodCalls/acquireReleasePortConnection/acquireReleasePortConnectionByPort.d.ts.map +1 -0
  120. package/dist-types/src/internal/MIDIPortMethodCalls/acquireReleasePortConnection/acquireReleasePortConnectionByPortIdAndAccess.d.ts +15 -0
  121. package/dist-types/src/internal/MIDIPortMethodCalls/acquireReleasePortConnection/acquireReleasePortConnectionByPortIdAndAccess.d.ts.map +1 -0
  122. package/dist-types/src/internal/MIDIPortMethodCalls/acquireReleasePortConnection/acquireReleasePortConnectionByPortIdInContext.d.ts +13 -0
  123. package/dist-types/src/internal/MIDIPortMethodCalls/acquireReleasePortConnection/acquireReleasePortConnectionByPortIdInContext.d.ts.map +1 -0
  124. package/dist-types/src/internal/MIDIPortMethodCalls/actOnPort.d.ts +11 -0
  125. package/dist-types/src/internal/MIDIPortMethodCalls/actOnPort.d.ts.map +1 -0
  126. package/dist-types/src/internal/MIDIPortMethodCalls/closePortConnection/closePortConnectionByPort.d.ts +23 -0
  127. package/dist-types/src/internal/MIDIPortMethodCalls/closePortConnection/closePortConnectionByPort.d.ts.map +1 -0
  128. package/dist-types/src/internal/MIDIPortMethodCalls/closePortConnection/closePortConnectionByPortIdAndAccess.d.ts +15 -0
  129. package/dist-types/src/internal/MIDIPortMethodCalls/closePortConnection/closePortConnectionByPortIdAndAccess.d.ts.map +1 -0
  130. package/dist-types/src/internal/MIDIPortMethodCalls/closePortConnection/closePortConnectionByPortIdInContext.d.ts +13 -0
  131. package/dist-types/src/internal/MIDIPortMethodCalls/closePortConnection/closePortConnectionByPortIdInContext.d.ts.map +1 -0
  132. package/dist-types/src/internal/MIDIPortMethodCalls/makeMIDIPortMethodCallerFactory.d.ts +15 -0
  133. package/dist-types/src/internal/MIDIPortMethodCalls/makeMIDIPortMethodCallerFactory.d.ts.map +1 -0
  134. package/dist-types/src/internal/MIDIPortMethodCalls/openPortConnection/openPortConnectionByPort.d.ts +21 -0
  135. package/dist-types/src/internal/MIDIPortMethodCalls/openPortConnection/openPortConnectionByPort.d.ts.map +1 -0
  136. package/dist-types/src/internal/MIDIPortMethodCalls/openPortConnection/openPortConnectionByPortIdAndAccess.d.ts +15 -0
  137. package/dist-types/src/internal/MIDIPortMethodCalls/openPortConnection/openPortConnectionByPortIdAndAccess.d.ts.map +1 -0
  138. package/dist-types/src/internal/MIDIPortMethodCalls/openPortConnection/openPortConnectionByPortIdInContext.d.ts +13 -0
  139. package/dist-types/src/internal/MIDIPortMethodCalls/openPortConnection/openPortConnectionByPortIdInContext.d.ts.map +1 -0
  140. package/dist-types/src/internal/StreamMaker.d.ts +202 -0
  141. package/dist-types/src/internal/StreamMaker.d.ts.map +1 -0
  142. package/dist-types/src/internal/errors.d.ts +260 -0
  143. package/dist-types/src/internal/errors.d.ts.map +1 -0
  144. package/dist-types/src/internal/getPortByPortId/getPortByPortIdAndAccess.d.ts +27 -0
  145. package/dist-types/src/internal/getPortByPortId/getPortByPortIdAndAccess.d.ts.map +1 -0
  146. package/dist-types/src/internal/getPortByPortId/getPortByPortIdInContext.d.ts +20 -0
  147. package/dist-types/src/internal/getPortByPortId/getPortByPortIdInContext.d.ts.map +1 -0
  148. package/dist-types/src/internal/makePortStateChangesStream/makePortStateChangesStreamByPort.d.ts +71 -0
  149. package/dist-types/src/internal/makePortStateChangesStream/makePortStateChangesStreamByPort.d.ts.map +1 -0
  150. package/dist-types/src/internal/makePortStateChangesStream/makePortStateChangesStreamByPortIdAndAccess.d.ts +4 -0
  151. package/dist-types/src/internal/makePortStateChangesStream/makePortStateChangesStreamByPortIdAndAccess.d.ts.map +1 -0
  152. package/dist-types/src/internal/makePortStateChangesStream/makePortStateChangesStreamByPortIdInContext.d.ts +20 -0
  153. package/dist-types/src/internal/makePortStateChangesStream/makePortStateChangesStreamByPortIdInContext.d.ts.map +1 -0
  154. package/dist-types/src/internal/mutablePropertyTools/doesMutablePortPropertyHaveSpecificValue/doesMutablePortPropertyHaveSpecificValueByPort.d.ts +62 -0
  155. package/dist-types/src/internal/mutablePropertyTools/doesMutablePortPropertyHaveSpecificValue/doesMutablePortPropertyHaveSpecificValueByPort.d.ts.map +1 -0
  156. package/dist-types/src/internal/mutablePropertyTools/doesMutablePortPropertyHaveSpecificValue/doesMutablePortPropertyHaveSpecificValueByPortIdAndAccess.d.ts +16 -0
  157. package/dist-types/src/internal/mutablePropertyTools/doesMutablePortPropertyHaveSpecificValue/doesMutablePortPropertyHaveSpecificValueByPortIdAndAccess.d.ts.map +1 -0
  158. package/dist-types/src/internal/mutablePropertyTools/doesMutablePortPropertyHaveSpecificValue/doesMutablePortPropertyHaveSpecificValueByPortIdInContext.d.ts +16 -0
  159. package/dist-types/src/internal/mutablePropertyTools/doesMutablePortPropertyHaveSpecificValue/doesMutablePortPropertyHaveSpecificValueByPortIdInContext.d.ts.map +1 -0
  160. package/dist-types/src/internal/mutablePropertyTools/getMutablePortProperty/getMutablePortPropertyByPort.d.ts +36 -0
  161. package/dist-types/src/internal/mutablePropertyTools/getMutablePortProperty/getMutablePortPropertyByPort.d.ts.map +1 -0
  162. package/dist-types/src/internal/mutablePropertyTools/getMutablePortProperty/getMutablePortPropertyByPortIdAndAccess.d.ts +22 -0
  163. package/dist-types/src/internal/mutablePropertyTools/getMutablePortProperty/getMutablePortPropertyByPortIdAndAccess.d.ts.map +1 -0
  164. package/dist-types/src/internal/mutablePropertyTools/getMutablePortProperty/getMutablePortPropertyByPortIdInContext.d.ts +17 -0
  165. package/dist-types/src/internal/mutablePropertyTools/getMutablePortProperty/getMutablePortPropertyByPortIdInContext.d.ts.map +1 -0
  166. package/dist-types/src/internal/mutablePropertyTools/getValueInRawPortFieldUnsafe.d.ts +7 -0
  167. package/dist-types/src/internal/mutablePropertyTools/getValueInRawPortFieldUnsafe.d.ts.map +1 -0
  168. package/dist-types/src/internal/mutablePropertyTools/matchMutablePortProperty/matchMutablePortPropertyByPort.d.ts +71 -0
  169. package/dist-types/src/internal/mutablePropertyTools/matchMutablePortProperty/matchMutablePortPropertyByPort.d.ts.map +1 -0
  170. package/dist-types/src/internal/mutablePropertyTools/matchMutablePortProperty/matchMutablePortPropertyByPortIdAndAccess.d.ts +7 -0
  171. package/dist-types/src/internal/mutablePropertyTools/matchMutablePortProperty/matchMutablePortPropertyByPortIdAndAccess.d.ts.map +1 -0
  172. package/dist-types/src/internal/mutablePropertyTools/matchMutablePortProperty/matchMutablePortPropertyByPortIdInContext.d.ts +28 -0
  173. package/dist-types/src/internal/mutablePropertyTools/matchMutablePortProperty/matchMutablePortPropertyByPortIdInContext.d.ts.map +1 -0
  174. package/dist-types/src/internal/parsing.d.ts +72 -0
  175. package/dist-types/src/internal/parsing.d.ts.map +1 -0
  176. package/dist-types/src/internal/util.d.ts +33 -0
  177. package/dist-types/src/internal/util.d.ts.map +1 -0
  178. package/index.ts +1 -0
  179. package/package.json +83 -0
  180. package/src/EMIDIAccess.ts +271 -0
  181. package/src/EMIDIInput.ts +270 -0
  182. package/src/EMIDIOutput.ts +269 -0
  183. package/src/EMIDIPort.ts +267 -0
  184. package/src/MIDIErrors.ts +13 -0
  185. package/src/Parsing.ts +12 -0
  186. package/src/StreamMaker.ts +12 -0
  187. package/src/Util.ts +19 -0
  188. package/src/index.ts +8 -0
  189. package/src/internal/EMIDIAccess.ts +893 -0
  190. package/src/internal/EMIDIInput.ts +114 -0
  191. package/src/internal/EMIDIOutput.ts +228 -0
  192. package/src/internal/EMIDIPort.ts +233 -0
  193. package/src/internal/MIDIPortMethodCalls/acquireReleasePortConnection/acquireReleasePortConnectionByPort.ts +43 -0
  194. package/src/internal/MIDIPortMethodCalls/acquireReleasePortConnection/acquireReleasePortConnectionByPortIdAndAccess.ts +39 -0
  195. package/src/internal/MIDIPortMethodCalls/acquireReleasePortConnection/acquireReleasePortConnectionByPortIdInContext.ts +27 -0
  196. package/src/internal/MIDIPortMethodCalls/actOnPort.ts +66 -0
  197. package/src/internal/MIDIPortMethodCalls/closePortConnection/closePortConnectionByPort.ts +38 -0
  198. package/src/internal/MIDIPortMethodCalls/closePortConnection/closePortConnectionByPortIdAndAccess.ts +38 -0
  199. package/src/internal/MIDIPortMethodCalls/closePortConnection/closePortConnectionByPortIdInContext.ts +27 -0
  200. package/src/internal/MIDIPortMethodCalls/makeMIDIPortMethodCallerFactory.ts +73 -0
  201. package/src/internal/MIDIPortMethodCalls/openPortConnection/openPortConnectionByPort.ts +44 -0
  202. package/src/internal/MIDIPortMethodCalls/openPortConnection/openPortConnectionByPortIdAndAccess.ts +38 -0
  203. package/src/internal/MIDIPortMethodCalls/openPortConnection/openPortConnectionByPortIdInContext.ts +27 -0
  204. package/src/internal/StreamMaker.ts +414 -0
  205. package/src/internal/errors.ts +220 -0
  206. package/src/internal/getPortByPortId/getPortByPortIdAndAccess.ts +116 -0
  207. package/src/internal/getPortByPortId/getPortByPortIdInContext.ts +26 -0
  208. package/src/internal/makePortStateChangesStream/makePortStateChangesStreamByPort.ts +148 -0
  209. package/src/internal/makePortStateChangesStream/makePortStateChangesStreamByPortIdAndAccess.ts +14 -0
  210. package/src/internal/makePortStateChangesStream/makePortStateChangesStreamByPortIdInContext.ts +51 -0
  211. package/src/internal/mutablePropertyTools/doesMutablePortPropertyHaveSpecificValue/doesMutablePortPropertyHaveSpecificValueByPort.ts +127 -0
  212. package/src/internal/mutablePropertyTools/doesMutablePortPropertyHaveSpecificValue/doesMutablePortPropertyHaveSpecificValueByPortIdAndAccess.ts +74 -0
  213. package/src/internal/mutablePropertyTools/doesMutablePortPropertyHaveSpecificValue/doesMutablePortPropertyHaveSpecificValueByPortIdInContext.ts +74 -0
  214. package/src/internal/mutablePropertyTools/getMutablePortProperty/getMutablePortPropertyByPort.ts +63 -0
  215. package/src/internal/mutablePropertyTools/getMutablePortProperty/getMutablePortPropertyByPortIdAndAccess.ts +110 -0
  216. package/src/internal/mutablePropertyTools/getMutablePortProperty/getMutablePortPropertyByPortIdInContext.ts +37 -0
  217. package/src/internal/mutablePropertyTools/getValueInRawPortFieldUnsafe.ts +12 -0
  218. package/src/internal/mutablePropertyTools/matchMutablePortProperty/matchMutablePortPropertyByPort.ts +183 -0
  219. package/src/internal/mutablePropertyTools/matchMutablePortProperty/matchMutablePortPropertyByPortIdAndAccess.ts +29 -0
  220. package/src/internal/mutablePropertyTools/matchMutablePortProperty/matchMutablePortPropertyByPortIdInContext.ts +86 -0
  221. package/src/internal/parsing.ts +219 -0
  222. package/src/internal/util.ts +152 -0
@@ -0,0 +1,414 @@
1
+ /** biome-ignore-all lint/style/useShorthandFunctionType: It's a nice way to
2
+ * preserve JSDoc comments attached to the function signature */
3
+
4
+ import * as Cause from 'effect/Cause'
5
+ import * as Effect from 'effect/Effect'
6
+ import * as EFunction from 'effect/Function'
7
+ import * as Stream from 'effect/Stream'
8
+ import type * as EMIDIAccess from './EMIDIAccess.ts'
9
+ import type * as EMIDIInput from './EMIDIInput.ts'
10
+ import type * as EMIDIOutput from './EMIDIOutput.ts'
11
+ import * as Util from './util.ts'
12
+
13
+ // TODO: make an experiment to see if listeners are automatically removed on disconnect
14
+
15
+ /**
16
+ * Set of possible ways to react when the MIDI-related event will have relevant
17
+ * field be null. Although there should be no sane scenario where it would be
18
+ * the case, it's still allowed by the spec, and for a better UX this lib lets
19
+ * the developer make a decision on how to handle such cases.
20
+ *
21
+ * - `fail` will add an error into a signature of a stream, allowing the user to
22
+ * handle it
23
+ * - `die` will throw a defect, which won't be reflected as a possible failure
24
+ * in types
25
+ * - `ignore` will just silently remove such events from the stream
26
+ * - `passthrough` - will pass such events with an unmodified content of the
27
+ * relevant field
28
+ *
29
+ * @internal
30
+ */
31
+ const validOnNullStrategies = new Set([
32
+ 'fail',
33
+ 'die',
34
+ 'ignore',
35
+ 'passthrough',
36
+ ] as const)
37
+
38
+ /**
39
+ * Helper utility to turn MIDI event listeners into effect's Streams.
40
+ *
41
+ * The signature is split into 2 calls, so that you are able at first call pass
42
+ * into generic an interface with `addEventListener` types of the raw web MIDI
43
+ * objects as keys and according event structures as values.
44
+ *
45
+ * **Second call arguments**
46
+ *
47
+ * - `isSelf` - Function determining if the maker was called as an overload with
48
+ * all parameters passed all at once, or with them spread by 2 calls. `self`
49
+ * will be later assigned to a `cameFrom` property of the object in the
50
+ * success channel of the stream
51
+ *
52
+ * - `buildConfig` - Function that makes config out of an effectful version
53
+ * (e.g. {@linkcode EMIDIAccess.EMIDIAccessInstance}, {@linkcode EMIDIInput.EMIDIInput},
54
+ * {@linkcode EMIDIOutput.EMIDIOutput}) of a MIDI object.
55
+ *
56
+ * - `remapValueToContainer` - Callback that maps the value of the event's
57
+ * selected field to an extension of the object inside stream's success
58
+ * channel. All fields of the returned object must always be present and
59
+ * should be consistently nullable, when the incoming event's field is null.
60
+ *
61
+ * @template TEventTypeToEventValueMap An interface with event types of raw
62
+ * Web MIDI objects as keys and according event structures as values. e.g.
63
+ * `MIDIAccessEventMap`, `MIDIPortEventMap`, `MIDIInputEventMap`
64
+ *
65
+ * @internal
66
+ */
67
+ export const createStreamMakerFrom =
68
+ <TEventTypeToEventValueMap extends object>() =>
69
+ /**
70
+ * @param isSelf Function determining if the maker was called as an overload
71
+ * with all parameters passed all at once, or with them spread by 2 calls.
72
+ * `self` will be later assigned to a `cameFrom` property of the object in the
73
+ * success channel of the stream
74
+ *
75
+ * @param buildConfig Function that makes config out of an effectful version
76
+ * (e.g. {@linkcode EMIDIAccess.EMIDIAccessInstance}, {@linkcode EMIDIInput.EMIDIInput},
77
+ * {@linkcode EMIDIOutput.EMIDIOutput}) of a MIDI object.
78
+ *
79
+ * @param remapValueToContainer Callback that maps the `fieldValue` of the
80
+ * event's selected field (`nullableFieldName`) to an extension of the object
81
+ * inside stream's success channel. The value is not null, except when
82
+ * `onNullStrategy` is `'passthrough'`. All fields of the returned object must
83
+ * always be present and should be consistently nullable, if the incoming
84
+ * event's field is null.
85
+ */
86
+ <
87
+ TEventTarget extends Stream.EventListener<
88
+ TEventTypeToEventValueMap[TSelectedEventType]
89
+ >,
90
+ const TSelectedEventType extends Extract<
91
+ keyof TEventTypeToEventValueMap,
92
+ string
93
+ >,
94
+ const TNullableFieldName extends Extract<
95
+ keyof TEventTypeToEventValueMap[TSelectedEventType],
96
+ string
97
+ >,
98
+ TCameFrom,
99
+ const TTag extends string,
100
+ TContainerWithNullableFields extends object,
101
+ >(
102
+ isSelf: (self: unknown) => self is TCameFrom,
103
+ buildConfig: (
104
+ self: TCameFrom,
105
+ ) => StreamConfig<
106
+ TTag,
107
+ TEventTarget,
108
+ TSelectedEventType,
109
+ TNullableFieldName
110
+ >,
111
+ remapValueToContainer: (
112
+ fieldValue: TEventTypeToEventValueMap[TSelectedEventType][TNullableFieldName],
113
+ ) => TContainerWithNullableFields,
114
+ ): DualStreamMaker<TCameFrom, TTag, TContainerWithNullableFields> =>
115
+ EFunction.dual<
116
+ MakeStreamTargetLast<TCameFrom, TTag, TContainerWithNullableFields>,
117
+ MakeStreamTargetFirst<TCameFrom, TTag, TContainerWithNullableFields>
118
+ >(
119
+ Util.polymorphicCheckInDual(isSelf),
120
+ (cameFromPolymorphic, options) =>
121
+ Effect.gen(function* () {
122
+ const onNullStrategy = ((
123
+ options as { onExtremelyRareNullableField?: OnNullStrategy }
124
+ )?.onExtremelyRareNullableField ?? 'die') as Exclude<
125
+ OnNullStrategy,
126
+ undefined
127
+ >
128
+
129
+ if (!validOnNullStrategies.has(onNullStrategy))
130
+ throw new Error(
131
+ `Invalid strategy to handle nullish values: ${onNullStrategy}`,
132
+ )
133
+
134
+ const cameFrom = yield* Util.fromPolymorphic(
135
+ cameFromPolymorphic,
136
+ isSelf,
137
+ )
138
+
139
+ const {
140
+ tag,
141
+ eventListener: { target, type },
142
+ spanAttributes,
143
+ nullableFieldName: field,
144
+ } = buildConfig(cameFrom)
145
+
146
+ const missingFieldMessage = `Property ${field} of ${tag} is null`
147
+ const NullCausedErrorEffect = new Cause.NoSuchElementException(
148
+ missingFieldMessage,
149
+ )
150
+
151
+ return Stream.fromEventListener(target, type, options).pipe(
152
+ Stream.filter(
153
+ event => !!event[field] || onNullStrategy !== 'ignore',
154
+ ),
155
+ Stream.mapEffect(event =>
156
+ event[field] || onNullStrategy === 'passthrough'
157
+ ? Effect.succeed({
158
+ _tag: tag,
159
+ ...remapValueToContainer(event[field]),
160
+ cameFrom,
161
+ capturedAt: new Date(),
162
+ })
163
+ : onNullStrategy === 'fail'
164
+ ? NullCausedErrorEffect
165
+ : Effect.dieMessage(missingFieldMessage),
166
+ ),
167
+ Stream.withSpan('MIDI Web API event stream', {
168
+ kind: 'producer',
169
+ attributes: { eventType: type, ...spanAttributes },
170
+ }),
171
+ )
172
+ // biome-ignore lint/suspicious/noExplicitAny: <I don't care>
173
+ }).pipe(Stream.unwrap) as any,
174
+ )
175
+
176
+ interface StreamConfig<
177
+ TTag,
178
+ TEventTarget,
179
+ TSelectedEventType,
180
+ TNullableFieldName,
181
+ > {
182
+ /**
183
+ * Tag that will be assigned to the object inside stream's success channel
184
+ */
185
+ readonly tag: TTag
186
+
187
+ /**
188
+ * Config specifying where to attach the event listener
189
+ */
190
+ readonly eventListener: {
191
+ /**
192
+ * Native MIDI object (e.g. {@linkcode MIDIAccess},
193
+ * {@linkcode MIDIInput}, {@linkcode MIDIOutput}) that can have new
194
+ * listeners attached
195
+ */
196
+ readonly target: TEventTarget
197
+
198
+ /**
199
+ * The type of event supported by the native MIDI object,
200
+ * `addEventListener`'s first argument (e.g.
201
+ * {@linkcode MIDIAccess.addEventListener|MIDIAccess's},
202
+ * {@linkcode MIDIInput.addEventListener|MIDIInput's},
203
+ * {@linkcode MIDIOutput.addEventListener|MIDIOutput's}) which can have
204
+ * new listeners attached. Restricted by the keys of
205
+ * {@linkcode TEventTypeToEventValueMap} passed in the first call
206
+ */
207
+ readonly type: TSelectedEventType
208
+ }
209
+
210
+ /**
211
+ * Additional attributes that will be attached to Open Telemetry span of
212
+ * the stream
213
+ */
214
+ readonly spanAttributes: {
215
+ readonly spanTargetName: string
216
+ readonly [k: string]: unknown
217
+ }
218
+
219
+ /**
220
+ * The name of the field that will be extracted from the event (e.g.
221
+ * {@linkcode MIDIConnectionEvent.port|MIDIConnectionEvent's port},
222
+ * {@linkcode MIDIMessageEvent.data|MIDIMessageEvent's data})
223
+ */
224
+ readonly nullableFieldName: TNullableFieldName
225
+ }
226
+
227
+ export interface StreamMakerOptionsWellknown {
228
+ /**
229
+ * A boolean value indicating that events of this type will be dispatched to
230
+ * the registered `listener` before being dispatched to any `EventTarget`
231
+ * beneath it in the DOM tree.
232
+ * @default false
233
+ */
234
+ readonly capture?: boolean
235
+
236
+ /**
237
+ * A boolean value indicating that the `listener` should be invoked at most
238
+ * once after being added. If `true`, the `listener` would be automatically
239
+ * removed when invoked.
240
+ * @default false
241
+ */
242
+ readonly passive?: boolean
243
+
244
+ /**
245
+ * A boolean value that, if true, indicates that the function specified by
246
+ * listener will never call `preventDefault()`. If a passive listener calls
247
+ * `preventDefault()`, nothing will happen and a console warning may be
248
+ * generated.
249
+ * @default false
250
+ */
251
+ readonly once?: boolean
252
+
253
+ /**
254
+ * How many elements sent by event target to buffer while waiting for the
255
+ * moment they are consumed. Can be limited to a certain number
256
+ * @default "unbounded"
257
+ */
258
+ readonly bufferSize?: number | 'unbounded' | undefined
259
+ }
260
+
261
+ export interface StreamMakerOptionsObject<
262
+ TOnNullStrategy extends OnNullStrategy,
263
+ > extends StreamMakerOptionsWellknown {
264
+ /**
265
+ * A strategy to react when the MIDI-related event will have relevant field be
266
+ * null. Although there should be no sane scenario where it would be the case,
267
+ * it's still allowed by the spec, and for a better DevX this lib lets the dev
268
+ * make a decision on how to handle such cases.
269
+ *
270
+ * - `fail` will add an error into a signature of a stream, allowing the user
271
+ * to handle it
272
+ * - `die` will throw a defect, which won't be reflected as a possible failure
273
+ * in types. Selected by default. `undefined` is treated the same.
274
+ * - `ignore` will just silently remove such events from the stream
275
+ * - `passthrough` - will pass such events with an unmodified content of the
276
+ * relevant field
277
+ *
278
+ * @default 'die'
279
+ */
280
+ readonly onExtremelyRareNullableField?: TOnNullStrategy
281
+ }
282
+
283
+ /**
284
+ * Passing a value of a `boolean` type is equivalent to setting
285
+ * `options.capture` property
286
+ */
287
+ export type StreamMakerOptions<TOnNullStrategy extends OnNullStrategy> =
288
+ | boolean
289
+ | StreamMakerOptionsObject<TOnNullStrategy>
290
+ | undefined
291
+
292
+ export type OnNullStrategy =
293
+ | (typeof validOnNullStrategies extends Set<infer U> ? U : never)
294
+ | undefined
295
+
296
+ export type StreamValue<
297
+ TTag extends string,
298
+ TCameFrom,
299
+ TContainerWithNullableFields extends object,
300
+ TOnNullStrategy extends OnNullStrategy,
301
+ > = {
302
+ readonly _tag: TTag
303
+ /**
304
+ * An effectful MIDI entity that wraps the raw MIDI object, which triggered an
305
+ * event
306
+ */
307
+ readonly cameFrom: TCameFrom
308
+ readonly capturedAt: Date
309
+ } & (
310
+ | {
311
+ readonly [NullableField in keyof TContainerWithNullableFields]: Exclude<
312
+ TContainerWithNullableFields[NullableField],
313
+ null
314
+ >
315
+ }
316
+ | ([TOnNullStrategy] extends ['passthrough']
317
+ ? {
318
+ readonly [NullableField in keyof TContainerWithNullableFields]: null
319
+ }
320
+ : never)
321
+ )
322
+
323
+ export type StreamError<TOnNullStrategy extends OnNullStrategy, E> =
324
+ | E
325
+ | ([TOnNullStrategy] extends ['fail'] ? Cause.NoSuchElementException : never)
326
+
327
+ export interface BuiltStream<
328
+ TTag extends string,
329
+ TCameFrom,
330
+ TContainerWithNullableFields extends object,
331
+ TOnNullStrategy extends OnNullStrategy,
332
+ E = never,
333
+ R = never,
334
+ > extends Stream.Stream<
335
+ StreamValue<TTag, TCameFrom, TContainerWithNullableFields, TOnNullStrategy>,
336
+ StreamError<TOnNullStrategy, E>,
337
+ R
338
+ > {}
339
+
340
+ export interface DualStreamMaker<
341
+ TCameFrom,
342
+ TTag extends string,
343
+ TContainerWithNullableFields extends object,
344
+ > extends MakeStreamTargetFirst<TCameFrom, TTag, TContainerWithNullableFields>,
345
+ MakeStreamTargetLast<TCameFrom, TTag, TContainerWithNullableFields> {}
346
+
347
+ export interface MakeStreamTargetFirst<
348
+ TCameFrom,
349
+ TTag extends string,
350
+ TContainerWithNullableFields extends object,
351
+ > {
352
+ /**
353
+ * @param polymorphicEventTargetWrapper Raw MIDI object, which triggers
354
+ * events, wrapped in this lib's abstraction and potentially inside Effect.
355
+ * Will be assigned to the `cameFrom` property of the stream's success channel
356
+ * object
357
+ *
358
+ * @param options Passing a value of a `boolean` type is equivalent to setting
359
+ * `options.capture` property
360
+ */
361
+ <
362
+ E = never,
363
+ R = never,
364
+ const TOnNullStrategy extends OnNullStrategy = undefined,
365
+ >(
366
+ polymorphicEventTargetWrapper: Util.PolymorphicEffect<TCameFrom, E, R>,
367
+ options?: StreamMakerOptions<TOnNullStrategy>,
368
+ ): BuiltStream<
369
+ TTag,
370
+ TCameFrom,
371
+ TContainerWithNullableFields,
372
+ TOnNullStrategy,
373
+ E,
374
+ R
375
+ >
376
+ }
377
+
378
+ export interface MakeStreamTargetLast<
379
+ TCameFrom,
380
+ TTag extends string,
381
+ TContainerWithNullableFields extends object,
382
+ > {
383
+ /**
384
+ * @param options Passing a value of a `boolean` type is equivalent to setting
385
+ * `options.capture` property
386
+ *
387
+ * **Second call argument**
388
+ *
389
+ * - `polymorphicEventTargetWrapper` Raw MIDI object, which triggers events,
390
+ * wrapped in this lib's abstraction and potentially inside Effect. Will be
391
+ * assigned to the `cameFrom` property of the stream's success channel
392
+ * object
393
+ */
394
+ <const TOnNullStrategy extends OnNullStrategy = undefined>(
395
+ options?: StreamMakerOptions<TOnNullStrategy>,
396
+ ): {
397
+ /**
398
+ * @param polymorphicEventTargetWrapper Raw MIDI object, which triggers
399
+ * events, wrapped in this lib's abstraction and potentially inside Effect.
400
+ * Will be assigned to the `cameFrom` property of the stream's success
401
+ * channel object
402
+ */
403
+ <E = never, R = never>(
404
+ polymorphicEventTargetWrapper: Util.PolymorphicEffect<TCameFrom, E, R>,
405
+ ): BuiltStream<
406
+ TTag,
407
+ TCameFrom,
408
+ TContainerWithNullableFields,
409
+ TOnNullStrategy,
410
+ E,
411
+ R
412
+ >
413
+ }
414
+ }
@@ -0,0 +1,220 @@
1
+ import * as Schema from 'effect/Schema'
2
+ import type * as Types from 'effect/Types'
3
+ import type * as EMIDIAccess from './EMIDIAccess.ts'
4
+ import * as EMIDIPort from './EMIDIPort.ts'
5
+
6
+ // NOTE: stacks are properly extracted from error instances into structs, while
7
+ // decoding
8
+
9
+ const PortId = Schema.fromBrand(EMIDIPort.BothId)(Schema.NonEmptyTrimmedString)
10
+
11
+ const ErrorSchema = <TSchema extends Schema.Schema.Any | undefined = undefined>(
12
+ nameSchema?: TSchema,
13
+ ) =>
14
+ Schema.Struct({
15
+ name: (nameSchema ??
16
+ Schema.NonEmptyTrimmedString) as TSchema extends undefined
17
+ ? typeof Schema.NonEmptyTrimmedString
18
+ : TSchema,
19
+ message: Schema.NonEmptyTrimmedString,
20
+ stack: Schema.NonEmptyTrimmedString.pipe(
21
+ Schema.optionalWith({ exact: true }),
22
+ ),
23
+ cause: Schema.Unknown.pipe(Schema.optionalWith({ exact: true })),
24
+ })
25
+
26
+ const midiAccessFailureFields = {
27
+ whileAskingForPermissions: Schema.Struct({
28
+ sysex: Schema.optional(Schema.Boolean),
29
+ software: Schema.optional(Schema.Boolean),
30
+ }),
31
+ }
32
+
33
+ /**
34
+ * Thrown if the document or page is going to be closed due to user navigation.
35
+ *
36
+ * Wraps `DOMException { name: 'AbortError' }`
37
+ *
38
+ * @see {@link https://webidl.spec.whatwg.org/#aborterror|Web IDL spec}
39
+ */
40
+ export class AbortError extends Schema.TaggedError<AbortError>()('AbortError', {
41
+ cause: ErrorSchema(Schema.Literal('AbortError')),
42
+ }) {}
43
+
44
+ /**
45
+ * Thrown if the underlying system raises any errors when trying to open the
46
+ * port.
47
+ *
48
+ * Wraps `DOMException { name: 'InvalidStateError' }`
49
+ *
50
+ * @see {@link https://webidl.spec.whatwg.org/#invalidstateerror|Web IDL spec}
51
+ */
52
+ export class UnderlyingSystemError extends Schema.TaggedError<UnderlyingSystemError>()(
53
+ 'UnderlyingSystemError',
54
+ {
55
+ cause: ErrorSchema(Schema.Literal('InvalidStateError')),
56
+ ...midiAccessFailureFields,
57
+ },
58
+ ) {}
59
+
60
+ /**
61
+ * Thrown if the MIDI API, or a certain configuration of it is not supported by
62
+ * the system.
63
+ *
64
+ * Wraps `ReferenceError | TypeError | DOMException { name: 'NotSupportedError' }`
65
+ *
66
+ * @see {@link https://webidl.spec.whatwg.org/#notsupportederror|Web IDL spec}
67
+ */
68
+ export class MIDIAccessNotSupportedError extends Schema.TaggedError<MIDIAccessNotSupportedError>()(
69
+ 'MIDIAccessNotSupportedError',
70
+ {
71
+ cause: ErrorSchema(
72
+ Schema.Literal('ReferenceError', 'TypeError', 'NotSupportedError'),
73
+ ),
74
+ ...midiAccessFailureFields,
75
+ },
76
+ ) {}
77
+
78
+ /**
79
+ * Thrown on platforms where `.clear()` method of output ports is not supported
80
+ * (currently supported only in Firefox)
81
+ *
82
+ * Wraps `TypeError | DOMException { name: 'NotSupportedError' }`
83
+ *
84
+ * @see {@link https://webidl.spec.whatwg.org/#notsupportederror|Web IDL spec}
85
+ */
86
+ export class ClearingSendingQueueIsNotSupportedError extends Schema.TaggedError<ClearingSendingQueueIsNotSupportedError>()(
87
+ 'ClearingSendingQueueIsNotSupportedError',
88
+ {
89
+ cause: ErrorSchema(Schema.Literal('TypeError', 'NotSupportedError')),
90
+ portId: PortId,
91
+ },
92
+ ) {}
93
+
94
+ /**
95
+ * Thrown when attempt to open the port failed because it is unavailable (e.g.
96
+ * is already in use by another process and cannot be opened, or is
97
+ * disconnected).
98
+ *
99
+ * Wraps `DOMException { name: 'InvalidAccessError' | 'NotAllowedError' | 'InvalidStateError' }`
100
+ *
101
+ * @see Web IDL specs: {@link https://webidl.spec.whatwg.org/#invalidaccesserror|InvalidAccessError}, {@link https://webidl.spec.whatwg.org/#notallowederror|NotAllowedError}, {@link https://webidl.spec.whatwg.org/#invalidstateerror|InvalidStateError}
102
+ */
103
+ export class UnavailablePortError extends Schema.TaggedError<UnavailablePortError>()(
104
+ 'UnavailablePortError',
105
+ {
106
+ cause: ErrorSchema(
107
+ Schema.Literal(
108
+ 'InvalidAccessError',
109
+ 'NotAllowedError',
110
+ 'InvalidStateError',
111
+ ),
112
+ ),
113
+ portId: PortId,
114
+ },
115
+ ) {}
116
+
117
+ /**
118
+ * Thrown when `.send` operation was called on a disconnected port.
119
+ *
120
+ * Wraps `DOMException { name: 'InvalidStateError' }`
121
+ *
122
+ * @see {@link https://webidl.spec.whatwg.org/#invalidaccesserror|Web IDL spec}
123
+ */
124
+ export class DisconnectedPortError extends Schema.TaggedError<DisconnectedPortError>()(
125
+ 'DisconnectedPortError',
126
+ {
127
+ cause: ErrorSchema(Schema.Literal('InvalidStateError')),
128
+ portId: PortId,
129
+ },
130
+ ) {}
131
+
132
+ /**
133
+ * Thrown when trying to send system exclusive message from the access handle,
134
+ * that doesn't have this permission
135
+ *
136
+ * Wraps `DOMException { name: 'InvalidAccessError' | 'NotAllowedError' }`
137
+ *
138
+ * @see Web IDL specs: {@link https://webidl.spec.whatwg.org/#invalidaccesserror|InvalidAccessError}, {@link https://webidl.spec.whatwg.org/#notallowederror|NotAllowedError}
139
+ */
140
+ export class CantSendSysexMessagesError extends Schema.TaggedError<CantSendSysexMessagesError>()(
141
+ 'CantSendSysexMessagesError',
142
+ {
143
+ cause: ErrorSchema(Schema.Literal('InvalidAccessError', 'NotAllowedError')),
144
+ portId: PortId,
145
+ },
146
+ ) {}
147
+
148
+ /**
149
+ * Thrown if the user, the system or their security settings denied the
150
+ * application from creating an {@linkcode EMIDIAccess.EMIDIAccessInstance} object
151
+ * with the requested {@linkcode EMIDIAccess.RequestMIDIAccessOptions|options}, or if the
152
+ * document is not allowed to use the feature (for example, because of a
153
+ * Permission Policy, or because the user previously denied a permission
154
+ * request).
155
+ *
156
+ * Wraps `DOMException { name: 'NotAllowedError' | 'SecurityError' }`
157
+ *
158
+ * @see Web IDL specs: {@link https://webidl.spec.whatwg.org/#notallowederror|NotAllowedError}, {@link https://webidl.spec.whatwg.org/#securityerror|SecurityError}
159
+ */
160
+ export class MIDIAccessNotAllowedError extends Schema.TaggedError<MIDIAccessNotAllowedError>()(
161
+ 'MIDIAccessNotAllowedError',
162
+ {
163
+ cause: ErrorSchema(Schema.Literal('NotAllowedError', 'SecurityError')),
164
+ ...midiAccessFailureFields,
165
+ },
166
+ ) {}
167
+
168
+ /**
169
+ * Thrown when data to be sent is not a valid sequence or does not contain a
170
+ * valid MIDI message
171
+ *
172
+ * Wraps `TypeError`
173
+ */
174
+ export class MalformedMidiMessageError extends Schema.TaggedError<MalformedMidiMessageError>()(
175
+ 'MalformedMidiMessageError',
176
+ {
177
+ cause: ErrorSchema(Schema.Literal('TypeError')),
178
+ portId: PortId,
179
+ midiMessage: Schema.Array(Schema.Int),
180
+ },
181
+ ) {}
182
+
183
+ /**
184
+ * Keep in mind that if port isn't found, it might not mean it's disconnected.
185
+ * For example, virtual ports created by software won't show up in the list of
186
+ * available inputs/outputs of MIDI Access handle with disabled
187
+ * {@linkcode EMIDIAccess.RequestMIDIAccessOptions.software} flag.
188
+ */
189
+ export class PortNotFoundError extends Schema.TaggedError<PortNotFoundError>()(
190
+ 'PortNotFound',
191
+ { portId: PortId },
192
+ ) {}
193
+
194
+ /**
195
+ *
196
+ * @internal
197
+ */
198
+ export const remapErrorByName =
199
+ // biome-ignore lint/suspicious/noExplicitAny: I don't care
200
+ <TErrorClassUnion extends new (arg: any) => Error>(
201
+ map: { [name: string]: TErrorClassUnion },
202
+ absurdMessage: string,
203
+ rest: Omit<
204
+ Types.UnionToIntersection<
205
+ // biome-ignore lint/suspicious/noExplicitAny: I don't care
206
+ TErrorClassUnion extends new (arg: infer P) => any ? P : never
207
+ >,
208
+ 'cause'
209
+ >,
210
+ ) =>
211
+ (cause: unknown) => {
212
+ if (!(cause instanceof Error && cause.name in map))
213
+ throw new Error(absurdMessage)
214
+ // biome-ignore lint/style/noNonNullAssertion: Because we checked it above with `cause.name in map`
215
+ const Class = map[cause.name]!
216
+ return new Class({
217
+ cause,
218
+ ...rest,
219
+ }) as InstanceType<TErrorClassUnion>
220
+ }