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.
- package/README.md +7 -0
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -0
- package/dist/src/EMIDIAccess.js +68 -0
- package/dist/src/EMIDIAccess.js.map +1 -0
- package/dist/src/EMIDIInput.js +226 -0
- package/dist/src/EMIDIInput.js.map +1 -0
- package/dist/src/EMIDIOutput.js +225 -0
- package/dist/src/EMIDIOutput.js.map +1 -0
- package/dist/src/EMIDIPort.js +213 -0
- package/dist/src/EMIDIPort.js.map +1 -0
- package/dist/src/MIDIErrors.js +4 -0
- package/dist/src/MIDIErrors.js.map +1 -0
- package/dist/src/Parsing.js +2 -0
- package/dist/src/Parsing.js.map +1 -0
- package/dist/src/StreamMaker.js +1 -0
- package/dist/src/StreamMaker.js.map +1 -0
- package/dist/src/Util.js +4 -0
- package/dist/src/Util.js.map +1 -0
- package/dist/src/index.js +9 -0
- package/dist/src/index.js.map +1 -0
- package/dist/src/internal/EMIDIAccess.js +409 -0
- package/dist/src/internal/EMIDIAccess.js.map +1 -0
- package/dist/src/internal/EMIDIInput.js +69 -0
- package/dist/src/internal/EMIDIInput.js.map +1 -0
- package/dist/src/internal/EMIDIOutput.js +120 -0
- package/dist/src/internal/EMIDIOutput.js.map +1 -0
- package/dist/src/internal/EMIDIPort.js +125 -0
- package/dist/src/internal/EMIDIPort.js.map +1 -0
- package/dist/src/internal/MIDIPortMethodCalls/acquireReleasePortConnection/acquireReleasePortConnectionByPort.js +27 -0
- package/dist/src/internal/MIDIPortMethodCalls/acquireReleasePortConnection/acquireReleasePortConnectionByPort.js.map +1 -0
- package/dist/src/internal/MIDIPortMethodCalls/acquireReleasePortConnection/acquireReleasePortConnectionByPortIdAndAccess.js +19 -0
- package/dist/src/internal/MIDIPortMethodCalls/acquireReleasePortConnection/acquireReleasePortConnectionByPortIdAndAccess.js.map +1 -0
- package/dist/src/internal/MIDIPortMethodCalls/acquireReleasePortConnection/acquireReleasePortConnectionByPortIdInContext.js +16 -0
- package/dist/src/internal/MIDIPortMethodCalls/acquireReleasePortConnection/acquireReleasePortConnectionByPortIdInContext.js.map +1 -0
- package/dist/src/internal/MIDIPortMethodCalls/actOnPort.js +18 -0
- package/dist/src/internal/MIDIPortMethodCalls/actOnPort.js.map +1 -0
- package/dist/src/internal/MIDIPortMethodCalls/closePortConnection/closePortConnectionByPort.js +27 -0
- package/dist/src/internal/MIDIPortMethodCalls/closePortConnection/closePortConnectionByPort.js.map +1 -0
- package/dist/src/internal/MIDIPortMethodCalls/closePortConnection/closePortConnectionByPortIdAndAccess.js +18 -0
- package/dist/src/internal/MIDIPortMethodCalls/closePortConnection/closePortConnectionByPortIdAndAccess.js.map +1 -0
- package/dist/src/internal/MIDIPortMethodCalls/closePortConnection/closePortConnectionByPortIdInContext.js +16 -0
- package/dist/src/internal/MIDIPortMethodCalls/closePortConnection/closePortConnectionByPortIdInContext.js.map +1 -0
- package/dist/src/internal/MIDIPortMethodCalls/makeMIDIPortMethodCallerFactory.js +21 -0
- package/dist/src/internal/MIDIPortMethodCalls/makeMIDIPortMethodCallerFactory.js.map +1 -0
- package/dist/src/internal/MIDIPortMethodCalls/openPortConnection/openPortConnectionByPort.js +30 -0
- package/dist/src/internal/MIDIPortMethodCalls/openPortConnection/openPortConnectionByPort.js.map +1 -0
- package/dist/src/internal/MIDIPortMethodCalls/openPortConnection/openPortConnectionByPortIdAndAccess.js +18 -0
- package/dist/src/internal/MIDIPortMethodCalls/openPortConnection/openPortConnectionByPortIdAndAccess.js.map +1 -0
- package/dist/src/internal/MIDIPortMethodCalls/openPortConnection/openPortConnectionByPortIdInContext.js +16 -0
- package/dist/src/internal/MIDIPortMethodCalls/openPortConnection/openPortConnectionByPortIdInContext.js.map +1 -0
- package/dist/src/internal/StreamMaker.js +101 -0
- package/dist/src/internal/StreamMaker.js.map +1 -0
- package/dist/src/internal/errors.js +161 -0
- package/dist/src/internal/errors.js.map +1 -0
- package/dist/src/internal/getPortByPortId/getPortByPortIdAndAccess.js +53 -0
- package/dist/src/internal/getPortByPortId/getPortByPortIdAndAccess.js.map +1 -0
- package/dist/src/internal/getPortByPortId/getPortByPortIdInContext.js +18 -0
- package/dist/src/internal/getPortByPortId/getPortByPortIdInContext.js.map +1 -0
- package/dist/src/internal/makePortStateChangesStream/makePortStateChangesStreamByPort.js +52 -0
- package/dist/src/internal/makePortStateChangesStream/makePortStateChangesStreamByPort.js.map +1 -0
- package/dist/src/internal/makePortStateChangesStream/makePortStateChangesStreamByPortIdAndAccess.js +13 -0
- package/dist/src/internal/makePortStateChangesStream/makePortStateChangesStreamByPortIdAndAccess.js.map +1 -0
- package/dist/src/internal/makePortStateChangesStream/makePortStateChangesStreamByPortIdInContext.js +18 -0
- package/dist/src/internal/makePortStateChangesStream/makePortStateChangesStreamByPortIdInContext.js.map +1 -0
- package/dist/src/internal/mutablePropertyTools/doesMutablePortPropertyHaveSpecificValue/doesMutablePortPropertyHaveSpecificValueByPort.js +66 -0
- package/dist/src/internal/mutablePropertyTools/doesMutablePortPropertyHaveSpecificValue/doesMutablePortPropertyHaveSpecificValueByPort.js.map +1 -0
- package/dist/src/internal/mutablePropertyTools/doesMutablePortPropertyHaveSpecificValue/doesMutablePortPropertyHaveSpecificValueByPortIdAndAccess.js +61 -0
- package/dist/src/internal/mutablePropertyTools/doesMutablePortPropertyHaveSpecificValue/doesMutablePortPropertyHaveSpecificValueByPortIdAndAccess.js.map +1 -0
- package/dist/src/internal/mutablePropertyTools/doesMutablePortPropertyHaveSpecificValue/doesMutablePortPropertyHaveSpecificValueByPortIdInContext.js +61 -0
- package/dist/src/internal/mutablePropertyTools/doesMutablePortPropertyHaveSpecificValue/doesMutablePortPropertyHaveSpecificValueByPortIdInContext.js.map +1 -0
- package/dist/src/internal/mutablePropertyTools/getMutablePortProperty/getMutablePortPropertyByPort.js +42 -0
- package/dist/src/internal/mutablePropertyTools/getMutablePortProperty/getMutablePortPropertyByPort.js.map +1 -0
- package/dist/src/internal/mutablePropertyTools/getMutablePortProperty/getMutablePortPropertyByPortIdAndAccess.js +42 -0
- package/dist/src/internal/mutablePropertyTools/getMutablePortProperty/getMutablePortPropertyByPortIdAndAccess.js.map +1 -0
- package/dist/src/internal/mutablePropertyTools/getMutablePortProperty/getMutablePortPropertyByPortIdInContext.js +29 -0
- package/dist/src/internal/mutablePropertyTools/getMutablePortProperty/getMutablePortPropertyByPortIdInContext.js.map +1 -0
- package/dist/src/internal/mutablePropertyTools/getValueInRawPortFieldUnsafe.js +6 -0
- package/dist/src/internal/mutablePropertyTools/getValueInRawPortFieldUnsafe.js.map +1 -0
- package/dist/src/internal/mutablePropertyTools/matchMutablePortProperty/matchMutablePortPropertyByPort.js +46 -0
- package/dist/src/internal/mutablePropertyTools/matchMutablePortProperty/matchMutablePortPropertyByPort.js.map +1 -0
- package/dist/src/internal/mutablePropertyTools/matchMutablePortProperty/matchMutablePortPropertyByPortIdAndAccess.js +25 -0
- package/dist/src/internal/mutablePropertyTools/matchMutablePortProperty/matchMutablePortPropertyByPortIdAndAccess.js.map +1 -0
- package/dist/src/internal/mutablePropertyTools/matchMutablePortProperty/matchMutablePortPropertyByPortIdInContext.js +31 -0
- package/dist/src/internal/mutablePropertyTools/matchMutablePortProperty/matchMutablePortPropertyByPortIdInContext.js.map +1 -0
- package/dist/src/internal/parsing.js +117 -0
- package/dist/src/internal/parsing.js.map +1 -0
- package/dist/src/internal/util.js +59 -0
- package/dist/src/internal/util.js.map +1 -0
- package/dist-types/index.d.ts +2 -0
- package/dist-types/index.d.ts.map +1 -0
- package/dist-types/src/EMIDIAccess.d.ts +27 -0
- package/dist-types/src/EMIDIAccess.d.ts.map +1 -0
- package/dist-types/src/EMIDIInput.d.ts +26 -0
- package/dist-types/src/EMIDIInput.d.ts.map +1 -0
- package/dist-types/src/EMIDIOutput.d.ts +26 -0
- package/dist-types/src/EMIDIOutput.d.ts.map +1 -0
- package/dist-types/src/EMIDIPort.d.ts +26 -0
- package/dist-types/src/EMIDIPort.d.ts.map +1 -0
- package/dist-types/src/MIDIErrors.d.ts +2 -0
- package/dist-types/src/MIDIErrors.d.ts.map +1 -0
- package/dist-types/src/Parsing.d.ts +2 -0
- package/dist-types/src/Parsing.d.ts.map +1 -0
- package/dist-types/src/StreamMaker.d.ts +2 -0
- package/dist-types/src/StreamMaker.d.ts.map +1 -0
- package/dist-types/src/Util.d.ts +2 -0
- package/dist-types/src/Util.d.ts.map +1 -0
- package/dist-types/src/index.d.ts +9 -0
- package/dist-types/src/index.d.ts.map +1 -0
- package/dist-types/src/internal/EMIDIAccess.d.ts +339 -0
- package/dist-types/src/internal/EMIDIAccess.d.ts.map +1 -0
- package/dist-types/src/internal/EMIDIInput.d.ts +48 -0
- package/dist-types/src/internal/EMIDIInput.d.ts.map +1 -0
- package/dist-types/src/internal/EMIDIOutput.d.ts +93 -0
- package/dist-types/src/internal/EMIDIOutput.d.ts.map +1 -0
- package/dist-types/src/internal/EMIDIPort.d.ts +87 -0
- package/dist-types/src/internal/EMIDIPort.d.ts.map +1 -0
- package/dist-types/src/internal/MIDIPortMethodCalls/acquireReleasePortConnection/acquireReleasePortConnectionByPort.d.ts +16 -0
- package/dist-types/src/internal/MIDIPortMethodCalls/acquireReleasePortConnection/acquireReleasePortConnectionByPort.d.ts.map +1 -0
- package/dist-types/src/internal/MIDIPortMethodCalls/acquireReleasePortConnection/acquireReleasePortConnectionByPortIdAndAccess.d.ts +15 -0
- package/dist-types/src/internal/MIDIPortMethodCalls/acquireReleasePortConnection/acquireReleasePortConnectionByPortIdAndAccess.d.ts.map +1 -0
- package/dist-types/src/internal/MIDIPortMethodCalls/acquireReleasePortConnection/acquireReleasePortConnectionByPortIdInContext.d.ts +13 -0
- package/dist-types/src/internal/MIDIPortMethodCalls/acquireReleasePortConnection/acquireReleasePortConnectionByPortIdInContext.d.ts.map +1 -0
- package/dist-types/src/internal/MIDIPortMethodCalls/actOnPort.d.ts +11 -0
- package/dist-types/src/internal/MIDIPortMethodCalls/actOnPort.d.ts.map +1 -0
- package/dist-types/src/internal/MIDIPortMethodCalls/closePortConnection/closePortConnectionByPort.d.ts +23 -0
- package/dist-types/src/internal/MIDIPortMethodCalls/closePortConnection/closePortConnectionByPort.d.ts.map +1 -0
- package/dist-types/src/internal/MIDIPortMethodCalls/closePortConnection/closePortConnectionByPortIdAndAccess.d.ts +15 -0
- package/dist-types/src/internal/MIDIPortMethodCalls/closePortConnection/closePortConnectionByPortIdAndAccess.d.ts.map +1 -0
- package/dist-types/src/internal/MIDIPortMethodCalls/closePortConnection/closePortConnectionByPortIdInContext.d.ts +13 -0
- package/dist-types/src/internal/MIDIPortMethodCalls/closePortConnection/closePortConnectionByPortIdInContext.d.ts.map +1 -0
- package/dist-types/src/internal/MIDIPortMethodCalls/makeMIDIPortMethodCallerFactory.d.ts +15 -0
- package/dist-types/src/internal/MIDIPortMethodCalls/makeMIDIPortMethodCallerFactory.d.ts.map +1 -0
- package/dist-types/src/internal/MIDIPortMethodCalls/openPortConnection/openPortConnectionByPort.d.ts +21 -0
- package/dist-types/src/internal/MIDIPortMethodCalls/openPortConnection/openPortConnectionByPort.d.ts.map +1 -0
- package/dist-types/src/internal/MIDIPortMethodCalls/openPortConnection/openPortConnectionByPortIdAndAccess.d.ts +15 -0
- package/dist-types/src/internal/MIDIPortMethodCalls/openPortConnection/openPortConnectionByPortIdAndAccess.d.ts.map +1 -0
- package/dist-types/src/internal/MIDIPortMethodCalls/openPortConnection/openPortConnectionByPortIdInContext.d.ts +13 -0
- package/dist-types/src/internal/MIDIPortMethodCalls/openPortConnection/openPortConnectionByPortIdInContext.d.ts.map +1 -0
- package/dist-types/src/internal/StreamMaker.d.ts +202 -0
- package/dist-types/src/internal/StreamMaker.d.ts.map +1 -0
- package/dist-types/src/internal/errors.d.ts +260 -0
- package/dist-types/src/internal/errors.d.ts.map +1 -0
- package/dist-types/src/internal/getPortByPortId/getPortByPortIdAndAccess.d.ts +27 -0
- package/dist-types/src/internal/getPortByPortId/getPortByPortIdAndAccess.d.ts.map +1 -0
- package/dist-types/src/internal/getPortByPortId/getPortByPortIdInContext.d.ts +20 -0
- package/dist-types/src/internal/getPortByPortId/getPortByPortIdInContext.d.ts.map +1 -0
- package/dist-types/src/internal/makePortStateChangesStream/makePortStateChangesStreamByPort.d.ts +71 -0
- package/dist-types/src/internal/makePortStateChangesStream/makePortStateChangesStreamByPort.d.ts.map +1 -0
- package/dist-types/src/internal/makePortStateChangesStream/makePortStateChangesStreamByPortIdAndAccess.d.ts +4 -0
- package/dist-types/src/internal/makePortStateChangesStream/makePortStateChangesStreamByPortIdAndAccess.d.ts.map +1 -0
- package/dist-types/src/internal/makePortStateChangesStream/makePortStateChangesStreamByPortIdInContext.d.ts +20 -0
- package/dist-types/src/internal/makePortStateChangesStream/makePortStateChangesStreamByPortIdInContext.d.ts.map +1 -0
- package/dist-types/src/internal/mutablePropertyTools/doesMutablePortPropertyHaveSpecificValue/doesMutablePortPropertyHaveSpecificValueByPort.d.ts +62 -0
- package/dist-types/src/internal/mutablePropertyTools/doesMutablePortPropertyHaveSpecificValue/doesMutablePortPropertyHaveSpecificValueByPort.d.ts.map +1 -0
- package/dist-types/src/internal/mutablePropertyTools/doesMutablePortPropertyHaveSpecificValue/doesMutablePortPropertyHaveSpecificValueByPortIdAndAccess.d.ts +16 -0
- package/dist-types/src/internal/mutablePropertyTools/doesMutablePortPropertyHaveSpecificValue/doesMutablePortPropertyHaveSpecificValueByPortIdAndAccess.d.ts.map +1 -0
- package/dist-types/src/internal/mutablePropertyTools/doesMutablePortPropertyHaveSpecificValue/doesMutablePortPropertyHaveSpecificValueByPortIdInContext.d.ts +16 -0
- package/dist-types/src/internal/mutablePropertyTools/doesMutablePortPropertyHaveSpecificValue/doesMutablePortPropertyHaveSpecificValueByPortIdInContext.d.ts.map +1 -0
- package/dist-types/src/internal/mutablePropertyTools/getMutablePortProperty/getMutablePortPropertyByPort.d.ts +36 -0
- package/dist-types/src/internal/mutablePropertyTools/getMutablePortProperty/getMutablePortPropertyByPort.d.ts.map +1 -0
- package/dist-types/src/internal/mutablePropertyTools/getMutablePortProperty/getMutablePortPropertyByPortIdAndAccess.d.ts +22 -0
- package/dist-types/src/internal/mutablePropertyTools/getMutablePortProperty/getMutablePortPropertyByPortIdAndAccess.d.ts.map +1 -0
- package/dist-types/src/internal/mutablePropertyTools/getMutablePortProperty/getMutablePortPropertyByPortIdInContext.d.ts +17 -0
- package/dist-types/src/internal/mutablePropertyTools/getMutablePortProperty/getMutablePortPropertyByPortIdInContext.d.ts.map +1 -0
- package/dist-types/src/internal/mutablePropertyTools/getValueInRawPortFieldUnsafe.d.ts +7 -0
- package/dist-types/src/internal/mutablePropertyTools/getValueInRawPortFieldUnsafe.d.ts.map +1 -0
- package/dist-types/src/internal/mutablePropertyTools/matchMutablePortProperty/matchMutablePortPropertyByPort.d.ts +71 -0
- package/dist-types/src/internal/mutablePropertyTools/matchMutablePortProperty/matchMutablePortPropertyByPort.d.ts.map +1 -0
- package/dist-types/src/internal/mutablePropertyTools/matchMutablePortProperty/matchMutablePortPropertyByPortIdAndAccess.d.ts +7 -0
- package/dist-types/src/internal/mutablePropertyTools/matchMutablePortProperty/matchMutablePortPropertyByPortIdAndAccess.d.ts.map +1 -0
- package/dist-types/src/internal/mutablePropertyTools/matchMutablePortProperty/matchMutablePortPropertyByPortIdInContext.d.ts +28 -0
- package/dist-types/src/internal/mutablePropertyTools/matchMutablePortProperty/matchMutablePortPropertyByPortIdInContext.d.ts.map +1 -0
- package/dist-types/src/internal/parsing.d.ts +72 -0
- package/dist-types/src/internal/parsing.d.ts.map +1 -0
- package/dist-types/src/internal/util.d.ts +33 -0
- package/dist-types/src/internal/util.d.ts.map +1 -0
- package/index.ts +1 -0
- package/package.json +83 -0
- package/src/EMIDIAccess.ts +271 -0
- package/src/EMIDIInput.ts +270 -0
- package/src/EMIDIOutput.ts +269 -0
- package/src/EMIDIPort.ts +267 -0
- package/src/MIDIErrors.ts +13 -0
- package/src/Parsing.ts +12 -0
- package/src/StreamMaker.ts +12 -0
- package/src/Util.ts +19 -0
- package/src/index.ts +8 -0
- package/src/internal/EMIDIAccess.ts +893 -0
- package/src/internal/EMIDIInput.ts +114 -0
- package/src/internal/EMIDIOutput.ts +228 -0
- package/src/internal/EMIDIPort.ts +233 -0
- package/src/internal/MIDIPortMethodCalls/acquireReleasePortConnection/acquireReleasePortConnectionByPort.ts +43 -0
- package/src/internal/MIDIPortMethodCalls/acquireReleasePortConnection/acquireReleasePortConnectionByPortIdAndAccess.ts +39 -0
- package/src/internal/MIDIPortMethodCalls/acquireReleasePortConnection/acquireReleasePortConnectionByPortIdInContext.ts +27 -0
- package/src/internal/MIDIPortMethodCalls/actOnPort.ts +66 -0
- package/src/internal/MIDIPortMethodCalls/closePortConnection/closePortConnectionByPort.ts +38 -0
- package/src/internal/MIDIPortMethodCalls/closePortConnection/closePortConnectionByPortIdAndAccess.ts +38 -0
- package/src/internal/MIDIPortMethodCalls/closePortConnection/closePortConnectionByPortIdInContext.ts +27 -0
- package/src/internal/MIDIPortMethodCalls/makeMIDIPortMethodCallerFactory.ts +73 -0
- package/src/internal/MIDIPortMethodCalls/openPortConnection/openPortConnectionByPort.ts +44 -0
- package/src/internal/MIDIPortMethodCalls/openPortConnection/openPortConnectionByPortIdAndAccess.ts +38 -0
- package/src/internal/MIDIPortMethodCalls/openPortConnection/openPortConnectionByPortIdInContext.ts +27 -0
- package/src/internal/StreamMaker.ts +414 -0
- package/src/internal/errors.ts +220 -0
- package/src/internal/getPortByPortId/getPortByPortIdAndAccess.ts +116 -0
- package/src/internal/getPortByPortId/getPortByPortIdInContext.ts +26 -0
- package/src/internal/makePortStateChangesStream/makePortStateChangesStreamByPort.ts +148 -0
- package/src/internal/makePortStateChangesStream/makePortStateChangesStreamByPortIdAndAccess.ts +14 -0
- package/src/internal/makePortStateChangesStream/makePortStateChangesStreamByPortIdInContext.ts +51 -0
- package/src/internal/mutablePropertyTools/doesMutablePortPropertyHaveSpecificValue/doesMutablePortPropertyHaveSpecificValueByPort.ts +127 -0
- package/src/internal/mutablePropertyTools/doesMutablePortPropertyHaveSpecificValue/doesMutablePortPropertyHaveSpecificValueByPortIdAndAccess.ts +74 -0
- package/src/internal/mutablePropertyTools/doesMutablePortPropertyHaveSpecificValue/doesMutablePortPropertyHaveSpecificValueByPortIdInContext.ts +74 -0
- package/src/internal/mutablePropertyTools/getMutablePortProperty/getMutablePortPropertyByPort.ts +63 -0
- package/src/internal/mutablePropertyTools/getMutablePortProperty/getMutablePortPropertyByPortIdAndAccess.ts +110 -0
- package/src/internal/mutablePropertyTools/getMutablePortProperty/getMutablePortPropertyByPortIdInContext.ts +37 -0
- package/src/internal/mutablePropertyTools/getValueInRawPortFieldUnsafe.ts +12 -0
- package/src/internal/mutablePropertyTools/matchMutablePortProperty/matchMutablePortPropertyByPort.ts +183 -0
- package/src/internal/mutablePropertyTools/matchMutablePortProperty/matchMutablePortPropertyByPortIdAndAccess.ts +29 -0
- package/src/internal/mutablePropertyTools/matchMutablePortProperty/matchMutablePortPropertyByPortIdInContext.ts +86 -0
- package/src/internal/parsing.ts +219 -0
- 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
|
+
}
|