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,110 @@
|
|
|
1
|
+
import type * as Brand from 'effect/Brand'
|
|
2
|
+
import * as Effect from 'effect/Effect'
|
|
3
|
+
import * as EFunction from 'effect/Function'
|
|
4
|
+
import * as Option from 'effect/Option'
|
|
5
|
+
import * as Record from 'effect/Record'
|
|
6
|
+
import * as EMIDIAccess from '../../EMIDIAccess.ts'
|
|
7
|
+
import type * as EMIDIPort from '../../EMIDIPort.ts'
|
|
8
|
+
import * as Errors from '../../errors.ts'
|
|
9
|
+
import type * as Util from '../../util.ts'
|
|
10
|
+
import * as Get from './getMutablePortPropertyByPort.ts'
|
|
11
|
+
|
|
12
|
+
const getPortByIdGeneric2 =
|
|
13
|
+
// biome-ignore lint/suspicious/noExplicitAny: I don't care
|
|
14
|
+
<T extends Record.ReadonlyRecord<string & Brand.Brand<'MIDIPortId'>, any>>(
|
|
15
|
+
getPortMap: <E = never, R = never>(
|
|
16
|
+
polymorphicAccess: EMIDIAccess.PolymorphicAccessInstance<E, R>,
|
|
17
|
+
) => Effect.Effect<T, E, R>,
|
|
18
|
+
) =>
|
|
19
|
+
<A, E2, R2, TE = never, TR = never>(
|
|
20
|
+
polymorphicAccess: Util.PolymorphicEffect<
|
|
21
|
+
EMIDIAccess.EMIDIAccessInstance,
|
|
22
|
+
TE,
|
|
23
|
+
TR
|
|
24
|
+
>,
|
|
25
|
+
transformPortEffect: (
|
|
26
|
+
effect: Effect.Effect<
|
|
27
|
+
T[Extract<keyof T, string & Brand.Brand<'MIDIPortId'>>],
|
|
28
|
+
TE | Errors.PortNotFoundError,
|
|
29
|
+
TR
|
|
30
|
+
>,
|
|
31
|
+
) => Effect.Effect<A, E2, R2>,
|
|
32
|
+
portId: Extract<keyof T, EMIDIPort.BothId>,
|
|
33
|
+
) =>
|
|
34
|
+
EFunction.pipe(
|
|
35
|
+
getPortMap(polymorphicAccess),
|
|
36
|
+
Effect.flatMap(
|
|
37
|
+
EFunction.flow(
|
|
38
|
+
Record.get(portId),
|
|
39
|
+
Option.match({
|
|
40
|
+
onNone: () => new Errors.PortNotFoundError({ portId }),
|
|
41
|
+
onSome: e => Effect.succeed(e),
|
|
42
|
+
}),
|
|
43
|
+
),
|
|
44
|
+
),
|
|
45
|
+
transformPortEffect,
|
|
46
|
+
)
|
|
47
|
+
|
|
48
|
+
// TODO: Check if software synth devices access is present. Having desired
|
|
49
|
+
// port absent in the record doesn't guarantee it's disconnected
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
*
|
|
53
|
+
*
|
|
54
|
+
*/
|
|
55
|
+
export const getPortDeviceStateByPortIdAndAccess = <TE = never, TR = never>(
|
|
56
|
+
polymorphicAccess: Util.PolymorphicEffect<
|
|
57
|
+
EMIDIAccess.EMIDIAccessInstance,
|
|
58
|
+
TE,
|
|
59
|
+
TR
|
|
60
|
+
>,
|
|
61
|
+
id: EMIDIPort.BothId,
|
|
62
|
+
) =>
|
|
63
|
+
getPortByIdGeneric2(EMIDIAccess.getAllPortsRecord)(
|
|
64
|
+
polymorphicAccess,
|
|
65
|
+
EFunction.flow(
|
|
66
|
+
Get.getPortDeviceStateByPort,
|
|
67
|
+
Effect.catchTag('PortNotFound', () =>
|
|
68
|
+
Effect.succeed('disconnected' as const),
|
|
69
|
+
),
|
|
70
|
+
),
|
|
71
|
+
id,
|
|
72
|
+
)
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
*
|
|
76
|
+
*
|
|
77
|
+
*/
|
|
78
|
+
export const getPortConnectionStateByPortIdAndAccess = <TE = never, TR = never>(
|
|
79
|
+
polymorphicAccess: Util.PolymorphicEffect<
|
|
80
|
+
EMIDIAccess.EMIDIAccessInstance,
|
|
81
|
+
TE,
|
|
82
|
+
TR
|
|
83
|
+
>,
|
|
84
|
+
id: EMIDIPort.BothId,
|
|
85
|
+
) =>
|
|
86
|
+
getPortByIdGeneric2(EMIDIAccess.getAllPortsRecord)(
|
|
87
|
+
polymorphicAccess,
|
|
88
|
+
Get.getPortConnectionStateByPort,
|
|
89
|
+
id,
|
|
90
|
+
)
|
|
91
|
+
|
|
92
|
+
// TODO: getInputConnectionStateByPortIdAndAccess
|
|
93
|
+
export const getInputConnectionStateByPortIdAndAccess = () => {
|
|
94
|
+
throw new Error('not implemented')
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
// TODO: getInputDeviceStateByPortIdAndAccess
|
|
98
|
+
export const getInputDeviceStateByPortIdAndAccess = () => {
|
|
99
|
+
throw new Error('not implemented')
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
// TODO: getOutputConnectionStateByPortIdAndAccess
|
|
103
|
+
export const getOutputConnectionStateByPortIdAndAccess = () => {
|
|
104
|
+
throw new Error('not implemented')
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
// TODO: getOutputDeviceStateByPortIdAndAccess
|
|
108
|
+
export const getOutputDeviceStateByPortIdAndAccess = () => {
|
|
109
|
+
throw new Error('not implemented')
|
|
110
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import * as EMIDIAccess from '../../EMIDIAccess.ts'
|
|
2
|
+
import type * as EMIDIPort from '../../EMIDIPort.ts'
|
|
3
|
+
import * as Get from './getMutablePortPropertyByPortIdAndAccess.ts'
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
*
|
|
7
|
+
*
|
|
8
|
+
*/
|
|
9
|
+
export const getPortDeviceStateByPortId = (id: EMIDIPort.BothId) =>
|
|
10
|
+
Get.getPortDeviceStateByPortIdAndAccess(EMIDIAccess.EMIDIAccess, id)
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
*
|
|
14
|
+
*
|
|
15
|
+
*/
|
|
16
|
+
export const getPortConnectionStateByPortId = (id: EMIDIPort.BothId) =>
|
|
17
|
+
Get.getPortConnectionStateByPortIdAndAccess(EMIDIAccess.EMIDIAccess, id)
|
|
18
|
+
|
|
19
|
+
// TODO: getInputConnectionStateByPortId
|
|
20
|
+
export const getInputConnectionStateByPortId = () => {
|
|
21
|
+
throw new Error('not implemented')
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
// TODO: getInputDeviceStateByPortId
|
|
25
|
+
export const getInputDeviceStateByPortId = () => {
|
|
26
|
+
throw new Error('not implemented')
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
// TODO: getOutputConnectionStateByPortId
|
|
30
|
+
export const getOutputConnectionStateByPortId = () => {
|
|
31
|
+
throw new Error('not implemented')
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
// TODO: getOutputDeviceStateByPortId
|
|
35
|
+
export const getOutputDeviceStateByPortId = () => {
|
|
36
|
+
throw new Error('not implemented')
|
|
37
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import * as EMIDIPort from '../EMIDIPort.ts'
|
|
2
|
+
import type { MIDIPortMutableProperty } from './matchMutablePortProperty/matchMutablePortPropertyByPort.ts'
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* @internal
|
|
6
|
+
*/
|
|
7
|
+
export const getValueInRawPortFieldUnsafe =
|
|
8
|
+
<const TMIDIPortMutableProperty extends MIDIPortMutableProperty>(
|
|
9
|
+
property: TMIDIPortMutableProperty,
|
|
10
|
+
) =>
|
|
11
|
+
(port: EMIDIPort.EMIDIPort) =>
|
|
12
|
+
EMIDIPort.assumeImpl(port)._port[property]
|
package/src/internal/mutablePropertyTools/matchMutablePortProperty/matchMutablePortPropertyByPort.ts
ADDED
|
@@ -0,0 +1,183 @@
|
|
|
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 Effect from 'effect/Effect'
|
|
5
|
+
import * as EFunction from 'effect/Function'
|
|
6
|
+
import * as Record from 'effect/Record'
|
|
7
|
+
import * as EMIDIInput from '../../EMIDIInput.ts'
|
|
8
|
+
import * as EMIDIOutput from '../../EMIDIOutput.ts'
|
|
9
|
+
import * as EMIDIPort from '../../EMIDIPort.ts'
|
|
10
|
+
import * as Util from '../../util.ts'
|
|
11
|
+
import * as Get from '../getValueInRawPortFieldUnsafe.ts'
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* @internal
|
|
15
|
+
*/
|
|
16
|
+
const matchMutableMIDIPortProperty = <
|
|
17
|
+
const TMIDIPortProperty extends MIDIPortMutableProperty,
|
|
18
|
+
THighLevelPortType extends MIDIPortType,
|
|
19
|
+
>(
|
|
20
|
+
property: TMIDIPortProperty,
|
|
21
|
+
is: (port: unknown) => port is EMIDIPort.EMIDIPort<THighLevelPortType>,
|
|
22
|
+
): DualMatchPortState<THighLevelPortType, TMIDIPortProperty> =>
|
|
23
|
+
EFunction.dual<
|
|
24
|
+
MatchStatePortLast<THighLevelPortType, TMIDIPortProperty>,
|
|
25
|
+
MatchStatePortFirst<THighLevelPortType, TMIDIPortProperty>
|
|
26
|
+
>(
|
|
27
|
+
Util.polymorphicCheckInDual(is),
|
|
28
|
+
Effect.fn(function* (polymorphicPort, config) {
|
|
29
|
+
const port = yield* Util.fromPolymorphic(
|
|
30
|
+
polymorphicPort,
|
|
31
|
+
is as (
|
|
32
|
+
port: unknown,
|
|
33
|
+
) => port is EMIDIPort.EMIDIPort<THighLevelPortType>,
|
|
34
|
+
)
|
|
35
|
+
|
|
36
|
+
const state = Get.getValueInRawPortFieldUnsafe(property)(port)
|
|
37
|
+
|
|
38
|
+
for (const [stateCase, stateCallback] of Record.toEntries(config))
|
|
39
|
+
if (state === stateCase)
|
|
40
|
+
return (stateCallback as PortStateHandler)(port)
|
|
41
|
+
|
|
42
|
+
return yield* Effect.dieMessage(
|
|
43
|
+
`AssertionFailed: Missing handler for "${state}" state inside "${property}" property`,
|
|
44
|
+
)
|
|
45
|
+
}),
|
|
46
|
+
)
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
*
|
|
50
|
+
*/
|
|
51
|
+
export const matchPortConnectionStateByPort = matchMutableMIDIPortProperty(
|
|
52
|
+
'connection',
|
|
53
|
+
EMIDIPort.is,
|
|
54
|
+
)
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
*
|
|
58
|
+
*/
|
|
59
|
+
export const matchPortDeviceStateByPort = matchMutableMIDIPortProperty(
|
|
60
|
+
'state',
|
|
61
|
+
EMIDIPort.is,
|
|
62
|
+
)
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
*
|
|
66
|
+
*/
|
|
67
|
+
export const matchInputConnectionStateByPort = matchMutableMIDIPortProperty(
|
|
68
|
+
'connection',
|
|
69
|
+
EMIDIInput.is,
|
|
70
|
+
)
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
*
|
|
74
|
+
*/
|
|
75
|
+
export const matchInputDeviceStateByPort = matchMutableMIDIPortProperty(
|
|
76
|
+
'state',
|
|
77
|
+
EMIDIInput.is,
|
|
78
|
+
)
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
*
|
|
82
|
+
*/
|
|
83
|
+
export const matchOutputConnectionStateByPort = matchMutableMIDIPortProperty(
|
|
84
|
+
'connection',
|
|
85
|
+
EMIDIOutput.is,
|
|
86
|
+
)
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
*
|
|
90
|
+
*/
|
|
91
|
+
export const matchOutputDeviceStateByPort = matchMutableMIDIPortProperty(
|
|
92
|
+
'state',
|
|
93
|
+
EMIDIOutput.is,
|
|
94
|
+
)
|
|
95
|
+
|
|
96
|
+
export type MIDIPortMutableProperty = 'state' | 'connection'
|
|
97
|
+
|
|
98
|
+
export interface PortStateHandler {
|
|
99
|
+
// biome-ignore lint/suspicious/noExplicitAny: <There's no better way to type>
|
|
100
|
+
(port: EMIDIPort.EMIDIPort): any
|
|
101
|
+
}
|
|
102
|
+
export interface MatcherConfigPlain extends Record<string, PortStateHandler> {}
|
|
103
|
+
|
|
104
|
+
export interface MatchResult<TActualConf extends MatcherConfigPlain, E, R>
|
|
105
|
+
extends Effect.Effect<ReturnType<TActualConf[keyof TActualConf]>, E, R> {}
|
|
106
|
+
|
|
107
|
+
export interface DualMatchPortState<
|
|
108
|
+
THighLevelPortType extends MIDIPortType,
|
|
109
|
+
TMIDIPortProperty extends MIDIPortMutableProperty,
|
|
110
|
+
> extends MatchStatePortLast<THighLevelPortType, TMIDIPortProperty>,
|
|
111
|
+
MatchStatePortFirst<THighLevelPortType, TMIDIPortProperty> {}
|
|
112
|
+
|
|
113
|
+
export interface MatchStatePortFirst<
|
|
114
|
+
THighLevelPortType extends MIDIPortType,
|
|
115
|
+
TMIDIPortProperty extends MIDIPortMutableProperty,
|
|
116
|
+
> {
|
|
117
|
+
/**
|
|
118
|
+
* Description placeholder
|
|
119
|
+
*
|
|
120
|
+
* @param polymorphicPort
|
|
121
|
+
* @param stateCaseToHandlerMap
|
|
122
|
+
* @returns
|
|
123
|
+
*/
|
|
124
|
+
<
|
|
125
|
+
TStateCaseToHandlerMap extends StateCaseToHandlerMap<
|
|
126
|
+
TMIDIPortProperty,
|
|
127
|
+
THighLevelPortType,
|
|
128
|
+
TStateCaseToHandlerMap
|
|
129
|
+
>,
|
|
130
|
+
E = never,
|
|
131
|
+
R = never,
|
|
132
|
+
>(
|
|
133
|
+
polymorphicPort: EMIDIPort.PolymorphicPort<E, R, THighLevelPortType>,
|
|
134
|
+
stateCaseToHandlerMap: TStateCaseToHandlerMap,
|
|
135
|
+
): MatchResult<TStateCaseToHandlerMap, E, R>
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
export interface MatchStatePortLast<
|
|
139
|
+
THighLevelPortType extends MIDIPortType,
|
|
140
|
+
TMIDIPortProperty extends MIDIPortMutableProperty,
|
|
141
|
+
> {
|
|
142
|
+
/**
|
|
143
|
+
* Description placeholder
|
|
144
|
+
*
|
|
145
|
+
* @param stateCaseToHandlerMap
|
|
146
|
+
* @returns
|
|
147
|
+
*/
|
|
148
|
+
<
|
|
149
|
+
TStateCaseToHandlerMap extends StateCaseToHandlerMap<
|
|
150
|
+
TMIDIPortProperty,
|
|
151
|
+
THighLevelPortType,
|
|
152
|
+
TStateCaseToHandlerMap
|
|
153
|
+
>,
|
|
154
|
+
>(
|
|
155
|
+
stateCaseToHandlerMap: TStateCaseToHandlerMap,
|
|
156
|
+
): {
|
|
157
|
+
/**
|
|
158
|
+
* Description placeholder
|
|
159
|
+
*
|
|
160
|
+
* @param polymorphicPort
|
|
161
|
+
* @returns
|
|
162
|
+
*/
|
|
163
|
+
<E = never, R = never>(
|
|
164
|
+
polymorphicPort: EMIDIPort.PolymorphicPort<E, R, THighLevelPortType>,
|
|
165
|
+
): MatchResult<TStateCaseToHandlerMap, E, R>
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
export type StateCaseToHandlerMap<
|
|
170
|
+
TMIDIPortProperty extends MIDIPortMutableProperty,
|
|
171
|
+
TMIDIPortType extends MIDIPortType,
|
|
172
|
+
TConfigSelf,
|
|
173
|
+
> = {
|
|
174
|
+
readonly [StateCase in MIDIPort[TMIDIPortProperty]]: (
|
|
175
|
+
port: EMIDIPort.EMIDIPort<TMIDIPortType>,
|
|
176
|
+
// biome-ignore lint/suspicious/noExplicitAny: <There's no preciser type>
|
|
177
|
+
) => any
|
|
178
|
+
} & {
|
|
179
|
+
readonly [RedundantValueCaseHandling in Exclude<
|
|
180
|
+
keyof TConfigSelf,
|
|
181
|
+
MIDIPort[TMIDIPortProperty]
|
|
182
|
+
>]: never
|
|
183
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
// TODO: matchInputConnectionStateByPortIdAndAccess
|
|
2
|
+
export const matchInputConnectionStateByPortIdAndAccess = () => {
|
|
3
|
+
throw new Error('not implemented')
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
// TODO: matchInputDeviceStateByPortIdAndAccess
|
|
7
|
+
export const matchInputDeviceStateByPortIdAndAccess = () => {
|
|
8
|
+
throw new Error('not implemented')
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
// TODO: matchOutputConnectionStateByPortIdAndAccess
|
|
12
|
+
export const matchOutputConnectionStateByPortIdAndAccess = () => {
|
|
13
|
+
throw new Error('not implemented')
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
// TODO: matchOutputDeviceStateByPortIdAndAccess
|
|
17
|
+
export const matchOutputDeviceStateByPortIdAndAccess = () => {
|
|
18
|
+
throw new Error('not implemented')
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
// TODO: matchPortConnectionStateByPortIdAndAccess
|
|
22
|
+
export const matchPortConnectionStateByPortIdAndAccess = () => {
|
|
23
|
+
throw new Error('not implemented')
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
// TODO: matchPortDeviceStateByPortIdAndAccess
|
|
27
|
+
export const matchPortDeviceStateByPortIdAndAccess = () => {
|
|
28
|
+
throw new Error('not implemented')
|
|
29
|
+
}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import type * as Effect from 'effect/Effect'
|
|
2
|
+
import type * as EMIDIAccess from '../../EMIDIAccess.ts'
|
|
3
|
+
import type * as EMIDIPort from '../../EMIDIPort.ts'
|
|
4
|
+
import type * as Errors from '../../errors.ts'
|
|
5
|
+
import * as Get from '../../getPortByPortId/getPortByPortIdInContext.ts'
|
|
6
|
+
import * as Match from './matchMutablePortPropertyByPort.ts'
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* @internal
|
|
10
|
+
*/
|
|
11
|
+
const makeMatcherTakingPortIds =
|
|
12
|
+
<
|
|
13
|
+
THighLevelPortType extends MIDIPortType,
|
|
14
|
+
TMIDIPortProperty extends Match.MIDIPortMutableProperty,
|
|
15
|
+
>(
|
|
16
|
+
match: Match.DualMatchPortState<THighLevelPortType, TMIDIPortProperty>,
|
|
17
|
+
getPort: (
|
|
18
|
+
id: EMIDIPort.Id<THighLevelPortType>,
|
|
19
|
+
) => Effect.Effect<
|
|
20
|
+
EMIDIPort.EMIDIPort<NoInfer<THighLevelPortType>>,
|
|
21
|
+
Errors.PortNotFoundError,
|
|
22
|
+
EMIDIAccess.EMIDIAccess
|
|
23
|
+
>,
|
|
24
|
+
) =>
|
|
25
|
+
<
|
|
26
|
+
TStateCaseToHandlerMap extends Match.StateCaseToHandlerMap<
|
|
27
|
+
TMIDIPortProperty,
|
|
28
|
+
THighLevelPortType,
|
|
29
|
+
TStateCaseToHandlerMap
|
|
30
|
+
>,
|
|
31
|
+
>(
|
|
32
|
+
id: EMIDIPort.Id<THighLevelPortType>,
|
|
33
|
+
stateCaseToHandlerMap: TStateCaseToHandlerMap,
|
|
34
|
+
) =>
|
|
35
|
+
match(getPort(id), stateCaseToHandlerMap)
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
*
|
|
39
|
+
*/
|
|
40
|
+
export const matchPortConnectionStateByPortIdInContext =
|
|
41
|
+
makeMatcherTakingPortIds(
|
|
42
|
+
Match.matchPortConnectionStateByPort,
|
|
43
|
+
Get.getPortByPortIdInContext,
|
|
44
|
+
)
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
*
|
|
48
|
+
*/
|
|
49
|
+
export const matchInputConnectionStateByPortIdInContext =
|
|
50
|
+
makeMatcherTakingPortIds(
|
|
51
|
+
Match.matchInputConnectionStateByPort,
|
|
52
|
+
Get.getInputByPortIdInContext,
|
|
53
|
+
)
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
*
|
|
57
|
+
*/
|
|
58
|
+
export const matchOutputConnectionStateByPortIdInContext =
|
|
59
|
+
makeMatcherTakingPortIds(
|
|
60
|
+
Match.matchOutputConnectionStateByPort,
|
|
61
|
+
Get.getOutputByPortIdInContext,
|
|
62
|
+
)
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
*
|
|
66
|
+
*/
|
|
67
|
+
export const matchPortDeviceStateByPortIdInContext = makeMatcherTakingPortIds(
|
|
68
|
+
Match.matchPortDeviceStateByPort,
|
|
69
|
+
Get.getPortByPortIdInContext,
|
|
70
|
+
)
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
*
|
|
74
|
+
*/
|
|
75
|
+
export const matchInputDeviceStateByPortIdInContext = makeMatcherTakingPortIds(
|
|
76
|
+
Match.matchInputDeviceStateByPort,
|
|
77
|
+
Get.getInputByPortIdInContext,
|
|
78
|
+
)
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
*
|
|
82
|
+
*/
|
|
83
|
+
export const matchOutputDeviceStateByPortIdInContext = makeMatcherTakingPortIds(
|
|
84
|
+
Match.matchOutputDeviceStateByPort,
|
|
85
|
+
Get.getOutputByPortIdInContext,
|
|
86
|
+
)
|
|
@@ -0,0 +1,219 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file This module is not for general use, these are just helpers to test the
|
|
3
|
+
* MIDI API with the only MIDI device I have: nanoPAD v1
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import * as Stream from 'effect/Stream'
|
|
7
|
+
|
|
8
|
+
//? NOTE: Look at the issue https://github.com/WebAudio/web-midi-api/issues/179
|
|
9
|
+
// which discusses higher-level MIDI message access
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
*
|
|
13
|
+
* @param self
|
|
14
|
+
* @returns
|
|
15
|
+
*/
|
|
16
|
+
export const withParsedDataField = <
|
|
17
|
+
A extends { readonly midiMessage: Uint8Array<ArrayBuffer> },
|
|
18
|
+
E,
|
|
19
|
+
R,
|
|
20
|
+
>(
|
|
21
|
+
self: Stream.Stream<A, E, R>,
|
|
22
|
+
) =>
|
|
23
|
+
Stream.map(self, ({ midiMessage, ...obj }) => ({
|
|
24
|
+
...obj,
|
|
25
|
+
midiMessage: dataEntryParser(midiMessage),
|
|
26
|
+
})) as Stream.Stream<
|
|
27
|
+
Omit<A, 'midiMessage'> & { readonly midiMessage: ParsedMIDIMessages },
|
|
28
|
+
E,
|
|
29
|
+
R
|
|
30
|
+
>
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
*
|
|
34
|
+
* @param self
|
|
35
|
+
* @returns
|
|
36
|
+
*/
|
|
37
|
+
export const withTouchpadPositionUpdates = <
|
|
38
|
+
A extends {
|
|
39
|
+
midiMessage:
|
|
40
|
+
| ControlChange
|
|
41
|
+
| TouchpadRelease
|
|
42
|
+
| PitchBendChange
|
|
43
|
+
| { _tag: string & {} }
|
|
44
|
+
},
|
|
45
|
+
E,
|
|
46
|
+
R,
|
|
47
|
+
>(
|
|
48
|
+
self: Stream.Stream<A, E, R>,
|
|
49
|
+
): Stream.Stream<
|
|
50
|
+
| A
|
|
51
|
+
| (Omit<A, 'midiMessage'> & { readonly midiMessage: TouchpadPositionUpdate }),
|
|
52
|
+
E,
|
|
53
|
+
R
|
|
54
|
+
> =>
|
|
55
|
+
Stream.mapAccum(
|
|
56
|
+
self,
|
|
57
|
+
{ x: 0, y: 0, seenPressedTouchpadEventsInARow: 0 },
|
|
58
|
+
(ctx, current) => {
|
|
59
|
+
const { midiMessage, ...rest } = current
|
|
60
|
+
const select = <T>(control: T, pitch: T, previous: T) =>
|
|
61
|
+
({
|
|
62
|
+
'Control Change': control,
|
|
63
|
+
'Pitch Bend Change': pitch,
|
|
64
|
+
'Touchpad Release': 0, // resets everything
|
|
65
|
+
})[midiMessage._tag as string] ?? previous
|
|
66
|
+
|
|
67
|
+
const position = {
|
|
68
|
+
x: select(ctx.x, (midiMessage as PitchBendChange).value, ctx.x),
|
|
69
|
+
y: select((midiMessage as ControlChange).value, ctx.y, ctx.y),
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
const seenPressedTouchpadEventsInARow = select(
|
|
73
|
+
ctx.seenPressedTouchpadEventsInARow + 1,
|
|
74
|
+
ctx.seenPressedTouchpadEventsInARow + 1,
|
|
75
|
+
ctx.seenPressedTouchpadEventsInARow,
|
|
76
|
+
)
|
|
77
|
+
|
|
78
|
+
return [
|
|
79
|
+
{ ...position, seenPressedTouchpadEventsInARow },
|
|
80
|
+
seenPressedTouchpadEventsInARow > 1 &&
|
|
81
|
+
(position.x !== ctx.x || position.y !== ctx.y)
|
|
82
|
+
? Stream.make(current, {
|
|
83
|
+
...rest,
|
|
84
|
+
midiMessage: {
|
|
85
|
+
_tag: 'Touchpad Position Update' as const,
|
|
86
|
+
...position,
|
|
87
|
+
} satisfies TouchpadPositionUpdate,
|
|
88
|
+
})
|
|
89
|
+
: Stream.succeed(current),
|
|
90
|
+
]
|
|
91
|
+
},
|
|
92
|
+
).pipe(Stream.flatten())
|
|
93
|
+
|
|
94
|
+
export type ParsedMIDIMessages =
|
|
95
|
+
| NoteRelease
|
|
96
|
+
| NotePress
|
|
97
|
+
| UnknownReply
|
|
98
|
+
| ControlChange
|
|
99
|
+
| TouchpadRelease
|
|
100
|
+
| PitchBendChange
|
|
101
|
+
|
|
102
|
+
function dataEntryParser(
|
|
103
|
+
midiMessage: Uint8Array<ArrayBuffer>,
|
|
104
|
+
): ParsedMIDIMessages {
|
|
105
|
+
const unknown = () => {
|
|
106
|
+
let stack = ''
|
|
107
|
+
if (
|
|
108
|
+
'stackTraceLimit' in Error &&
|
|
109
|
+
'captureStackTrace' in Error &&
|
|
110
|
+
typeof Error.captureStackTrace === 'function'
|
|
111
|
+
) {
|
|
112
|
+
const { stackTraceLimit } = Error
|
|
113
|
+
Error.stackTraceLimit = 4
|
|
114
|
+
const stackHolder = {} as { stack: string }
|
|
115
|
+
Error.captureStackTrace(stackHolder)
|
|
116
|
+
Error.stackTraceLimit = stackTraceLimit
|
|
117
|
+
stack = stackHolder.stack ?? new Error().stack ?? ''
|
|
118
|
+
}
|
|
119
|
+
const result = {
|
|
120
|
+
_tag: 'Unknown Reply' as const,
|
|
121
|
+
unexpectedData: midiMessage.toString(),
|
|
122
|
+
stack,
|
|
123
|
+
}
|
|
124
|
+
return result
|
|
125
|
+
}
|
|
126
|
+
if (midiMessage.length !== 3) return unknown()
|
|
127
|
+
const first = midiMessage.at(0)
|
|
128
|
+
if (first === undefined) return unknown()
|
|
129
|
+
|
|
130
|
+
const second = midiMessage.at(1)
|
|
131
|
+
if (second === undefined) return unknown()
|
|
132
|
+
|
|
133
|
+
const third = midiMessage.at(2)
|
|
134
|
+
if (third === undefined) return unknown()
|
|
135
|
+
|
|
136
|
+
const code = first >> 4
|
|
137
|
+
const channel = first & 0b1111
|
|
138
|
+
|
|
139
|
+
if (code === 0x8) {
|
|
140
|
+
if (third !== 0x40) return unknown()
|
|
141
|
+
return {
|
|
142
|
+
_tag: 'Note Release',
|
|
143
|
+
channel,
|
|
144
|
+
note: second,
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
if (code === 0x9) {
|
|
149
|
+
if (third === 0) return unknown()
|
|
150
|
+
return {
|
|
151
|
+
_tag: 'Note Press',
|
|
152
|
+
channel,
|
|
153
|
+
note: second,
|
|
154
|
+
velocity: third,
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
if (code === 0xb) {
|
|
159
|
+
return {
|
|
160
|
+
_tag: 'Control Change',
|
|
161
|
+
channel,
|
|
162
|
+
control: second,
|
|
163
|
+
value: third,
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
if (code === 0xe) {
|
|
168
|
+
if (second === 0 && third === 0x40)
|
|
169
|
+
return { _tag: 'Touchpad Release', channel }
|
|
170
|
+
|
|
171
|
+
if (second === third)
|
|
172
|
+
return { _tag: 'Pitch Bend Change', channel, value: second }
|
|
173
|
+
return unknown()
|
|
174
|
+
}
|
|
175
|
+
return unknown()
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
export interface NoteRelease
|
|
179
|
+
extends Readonly<{ _tag: 'Note Release'; channel: number; note: number }> {}
|
|
180
|
+
|
|
181
|
+
export interface NotePress
|
|
182
|
+
extends Readonly<{
|
|
183
|
+
_tag: 'Note Press'
|
|
184
|
+
channel: number
|
|
185
|
+
note: number
|
|
186
|
+
velocity: number
|
|
187
|
+
}> {}
|
|
188
|
+
|
|
189
|
+
export interface UnknownReply
|
|
190
|
+
extends Readonly<{
|
|
191
|
+
_tag: 'Unknown Reply'
|
|
192
|
+
unexpectedData: string
|
|
193
|
+
stack: string
|
|
194
|
+
}> {}
|
|
195
|
+
|
|
196
|
+
export interface ControlChange
|
|
197
|
+
extends Readonly<{
|
|
198
|
+
_tag: 'Control Change'
|
|
199
|
+
channel: number
|
|
200
|
+
control: number
|
|
201
|
+
value: number
|
|
202
|
+
}> {}
|
|
203
|
+
|
|
204
|
+
export interface TouchpadRelease
|
|
205
|
+
extends Readonly<{ _tag: 'Touchpad Release'; channel: number }> {}
|
|
206
|
+
|
|
207
|
+
export interface PitchBendChange
|
|
208
|
+
extends Readonly<{
|
|
209
|
+
_tag: 'Pitch Bend Change'
|
|
210
|
+
channel: number
|
|
211
|
+
value: number
|
|
212
|
+
}> {}
|
|
213
|
+
|
|
214
|
+
export interface TouchpadPositionUpdate
|
|
215
|
+
extends Readonly<{
|
|
216
|
+
_tag: 'Touchpad Position Update'
|
|
217
|
+
x: number
|
|
218
|
+
y: number
|
|
219
|
+
}> {}
|