diff --git a/types/webmidi/index.d.ts b/types/webmidi/index.d.ts index c4ad1cfac2..e64105201f 100644 --- a/types/webmidi/index.d.ts +++ b/types/webmidi/index.d.ts @@ -1,196 +1,237 @@ // Type definitions for Web MIDI API 2.0 -// Project: http://www.w3.org/TR/webmidi/, https://github.com/djipco/webmidi -// Definitions by: six a +// Project: http://www.w3.org/TR/webmidi/ +// Definitions by: DefinitelyTyped // Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped interface Navigator { - /** - * When invoked, returns a Promise object representing a request for access to MIDI - * devices on the user's system. - */ - requestMIDIAccess(options?: WebMidi.MIDIOptions): Promise; + /** + * When invoked, returns a Promise object representing a request for access to MIDI + * devices on the user's system. + */ + requestMIDIAccess(options?: WebMidi.MIDIOptions): Promise; } declare namespace WebMidi { - interface MIDIOptions { - /** - * This member informs the system whether the ability to send and receive system - * exclusive messages is requested or allowed on a given MIDIAccess object. - */ - sysex: boolean; - } - - /** - * This is a maplike interface whose value is a MIDIInput instance and key is its - * ID. - */ - type MIDIInputMap = Map; - - /** - * This is a maplike interface whose value is a MIDIOutput instance and key is its - * ID. - */ - type MIDIOutputMap = Map; - - interface MIDIAccess extends EventTarget { - /** - * The MIDI input ports available to the system. - */ - inputs: MIDIInputMap; + interface MIDIOptions { + /** + * This member informs the system whether the ability to send and receive system + * exclusive messages is requested or allowed on a given MIDIAccess object. + */ + sysex: boolean; + } /** - * The MIDI output ports available to the system. + * This is a maplike interface whose value is a MIDIInput instance and key is its + * ID. */ - outputs: MIDIOutputMap; + type MIDIInputMap = Map; /** - * The handler called when a new port is connected or an existing port changes the - * state attribute. + * This is a maplike interface whose value is a MIDIOutput instance and key is its + * ID. */ - onstatechange(e: MIDIConnectionEvent): void; + type MIDIOutputMap = Map; - /** - * This attribute informs the user whether system exclusive support is enabled on - * this MIDIAccess. - */ - sysexEnabled: boolean; - } + interface MIDIAccess extends EventTarget { + /** + * The MIDI input ports available to the system. + */ + inputs: MIDIInputMap; - type MIDIPortType = "input" | "output"; + /** + * The MIDI output ports available to the system. + */ + outputs: MIDIOutputMap; - type MIDIPortDeviceState = "disconnected" | "connected"; + /** + * The handler called when a new port is connected or an existing port changes the + * state attribute. + */ + onstatechange(e: MIDIConnectionEvent): void; - type MIDIPortConnectionState = "open" | "closed" | "pending"; + addEventListener( + type: 'statechange', + listener: (this: this, e: MIDIConnectionEvent) => any, + options?: boolean | AddEventListenerOptions, + ): void; + addEventListener( + type: string, + listener: EventListenerOrEventListenerObject, + options?: boolean | AddEventListenerOptions, + ): void; - interface MIDIPort extends EventTarget { - /** - * A unique ID of the port. This can be used by developers to remember ports the - * user has chosen for their application. - */ - id: string; + /** + * This attribute informs the user whether system exclusive support is enabled on + * this MIDIAccess. + */ + sysexEnabled: boolean; + } - /** - * The manufacturer of the port. - */ - manufacturer?: string; + type MIDIPortType = 'input' | 'output'; - /** - * The system name of the port. - */ - name?: string; + type MIDIPortDeviceState = 'disconnected' | 'connected'; - /** - * A descriptor property to distinguish whether the port is an input or an output - * port. - */ - type: MIDIPortType; + type MIDIPortConnectionState = 'open' | 'closed' | 'pending'; - /** - * The version of the port. - */ - version?: string; + interface MIDIPort extends EventTarget { + /** + * A unique ID of the port. This can be used by developers to remember ports the + * user has chosen for their application. + */ + id: string; - /** - * The state of the device. - */ - state: MIDIPortDeviceState; + /** + * The manufacturer of the port. + */ + manufacturer?: string; - /** - * The state of the connection to the device. - */ - connection: MIDIPortConnectionState; + /** + * The system name of the port. + */ + name?: string; - /** - * The handler called when an existing port changes its state or connection - * attributes. - */ - onstatechange(e: MIDIConnectionEvent): void; + /** + * A descriptor property to distinguish whether the port is an input or an output + * port. + */ + type: MIDIPortType; - /** - * Makes the MIDI device corresponding to the MIDIPort explicitly available. Note - * that this call is NOT required in order to use the MIDIPort - calling send() on - * a MIDIOutput or attaching a MIDIMessageEvent handler on a MIDIInputPort will - * cause an implicit open(). - * - * When invoked, this method returns a Promise object representing a request for - * access to the given MIDI port on the user's system. - */ - open(): Promise; + /** + * The version of the port. + */ + version?: string; - /** - * Makes the MIDI device corresponding to the MIDIPort - * explicitly unavailable (subsequently changing the state from "open" to - * "connected"). Note that successful invocation of this method will result in MIDI - * messages no longer being delivered to MIDIMessageEvent handlers on a - * MIDIInputPort (although setting a new handler will cause an implicit open()). - * - * When invoked, this method returns a Promise object representing a request for - * access to the given MIDI port on the user's system. When the port has been - * closed (and therefore, in exclusive access systems, the port is available to - * other applications), the vended Promise is resolved. If the port is - * disconnected, the Promise is rejected. - */ - close(): Promise; - } + /** + * The state of the device. + */ + state: MIDIPortDeviceState; - interface MIDIInput extends MIDIPort { - onmidimessage(e: MIDIMessageEvent): void; - } + /** + * The state of the connection to the device. + */ + connection: MIDIPortConnectionState; - interface MIDIOutput extends MIDIPort { - /** - * Enqueues the message to be sent to the corresponding MIDI port. - * @param data The data to be enqueued, with each sequence entry representing a single byte of data. - * @param timestamp The time at which to begin sending the data to the port. If timestamp is set - * to zero (or another time in the past), the data is to be sent as soon as - * possible. - */ - send(data: number[] | Uint8Array, timestamp?: number): void; + /** + * The handler called when an existing port changes its state or connection + * attributes. + */ + onstatechange(e: MIDIConnectionEvent): void; - /** - * Clears any pending send data that has not yet been sent from the MIDIOutput 's - * queue. The implementation will need to ensure the MIDI stream is left in a good - * state, so if the output port is in the middle of a sysex message, a sysex - * termination byte (0xf7) should be sent. - */ - clear(): void; - } + addEventListener( + type: 'statechange', + listener: (this: this, e: MIDIConnectionEvent) => any, + options?: boolean | AddEventListenerOptions, + ): void; + addEventListener( + type: string, + listener: EventListenerOrEventListenerObject, + options?: boolean | AddEventListenerOptions, + ): void; - interface MIDIMessageEvent extends Event { - /** - * A timestamp specifying when the event occurred. - */ - receivedTime: number; + /** + * Makes the MIDI device corresponding to the MIDIPort explicitly available. Note + * that this call is NOT required in order to use the MIDIPort - calling send() on + * a MIDIOutput or attaching a MIDIMessageEvent handler on a MIDIInputPort will + * cause an implicit open(). + * + * When invoked, this method returns a Promise object representing a request for + * access to the given MIDI port on the user's system. + */ + open(): Promise; - /** - * A Uint8Array containing the MIDI data bytes of a single MIDI message. - */ - data: Uint8Array; - } + /** + * Makes the MIDI device corresponding to the MIDIPort + * explicitly unavailable (subsequently changing the state from "open" to + * "connected"). Note that successful invocation of this method will result in MIDI + * messages no longer being delivered to MIDIMessageEvent handlers on a + * MIDIInputPort (although setting a new handler will cause an implicit open()). + * + * When invoked, this method returns a Promise object representing a request for + * access to the given MIDI port on the user's system. When the port has been + * closed (and therefore, in exclusive access systems, the port is available to + * other applications), the vended Promise is resolved. If the port is + * disconnected, the Promise is rejected. + */ + close(): Promise; + } - interface MIDIMessageEventInit extends EventInit { - /** - * A timestamp specifying when the event occurred. - */ - receivedTime: number; + interface MIDIInput extends MIDIPort { + type: 'input'; + onmidimessage(e: MIDIMessageEvent): void; - /** - * A Uint8Array containing the MIDI data bytes of a single MIDI message. - */ - data: Uint8Array; - } + addEventListener( + type: 'midimessage', + listener: (this: this, e: MIDIMessageEvent) => any, + options?: boolean | AddEventListenerOptions, + ): void; + addEventListener( + type: 'statechange', + listener: (this: this, e: MIDIConnectionEvent) => any, + options?: boolean | AddEventListenerOptions, + ): void; + addEventListener( + type: string, + listener: EventListenerOrEventListenerObject, + options?: boolean | AddEventListenerOptions, + ): void; + } - interface MIDIConnectionEvent extends Event { - /** - * The port that has been connected or disconnected. - */ - port: MIDIPort; - } + interface MIDIOutput extends MIDIPort { + type: 'output'; - interface MIDIConnectionEventInit extends EventInit { - /** - * The port that has been connected or disconnected. - */ - port: MIDIPort; - } + /** + * Enqueues the message to be sent to the corresponding MIDI port. + * @param data The data to be enqueued, with each sequence entry representing a single byte of data. + * @param timestamp The time at which to begin sending the data to the port. If timestamp is set + * to zero (or another time in the past), the data is to be sent as soon as + * possible. + */ + send(data: number[] | Uint8Array, timestamp?: number): void; + + /** + * Clears any pending send data that has not yet been sent from the MIDIOutput 's + * queue. The implementation will need to ensure the MIDI stream is left in a good + * state, so if the output port is in the middle of a sysex message, a sysex + * termination byte (0xf7) should be sent. + */ + clear(): void; + } + + interface MIDIMessageEvent extends Event { + /** + * A timestamp specifying when the event occurred. + */ + receivedTime: number; + + /** + * A Uint8Array containing the MIDI data bytes of a single MIDI message. + */ + data: Uint8Array; + } + + interface MIDIMessageEventInit extends EventInit { + /** + * A timestamp specifying when the event occurred. + */ + receivedTime: number; + + /** + * A Uint8Array containing the MIDI data bytes of a single MIDI message. + */ + data: Uint8Array; + } + + interface MIDIConnectionEvent extends Event { + /** + * The port that has been connected or disconnected. + */ + port: MIDIPort; + } + + interface MIDIConnectionEventInit extends EventInit { + /** + * The port that has been connected or disconnected. + */ + port: MIDIPort; + } } diff --git a/types/webmidi/webmidi-tests.ts b/types/webmidi/webmidi-tests.ts index 8380f17be6..ee957018db 100644 --- a/types/webmidi/webmidi-tests.ts +++ b/types/webmidi/webmidi-tests.ts @@ -1,36 +1,43 @@ -const onFulfilled = function(item: WebMidi.MIDIAccess) { - this._midiPort = item; +const onFulfilled = (item: WebMidi.MIDIAccess) => { + const midiPort = item; - item.onstatechange = (event: WebMidi.MIDIConnectionEvent) => { - console.log("onstatechange"); + midiPort.onstatechange = event => { + console.log('onstatechange'); console.log(event); }; + midiPort.addEventListener('statechange', event => { + console.log(event.port); + }); - console.log("sysexenabled"); + console.log('sysexenabled'); console.log(item.sysexEnabled); - const inputs = this._midiPort.inputs.values(); - - for (const o of inputs) { - this._inputs.push(o); - console.log(o); - } - const outputs = item.outputs.values(); for (const op of outputs) { - this._outputs.push(op); - op.send([ 0x90, 0x45, 0x7f ]); - op.send(new Uint8Array([ 0x90, 0x45, 0x7f ])); + op.send([0x90, 0x45, 0x7f]); + op.send(new Uint8Array([0x90, 0x45, 0x7f])); } - for (const input of this._inputs) { - input.onmidimessage = (event: WebMidi.MIDIMessageEvent) => { - this.onMidiMessage(event.data); + const inputs = midiPort.inputs.values(); + for (const input of inputs) { + input.onmidimessage = event => { + console.log(event.data); }; + input.addEventListener('midimessage', event => { + console.log(event.data); + }); + } + + const inputOrOutput = [...inputs, ...outputs][0]; + if (inputOrOutput.type === 'output') { + // 'send' only available on outputs + inputOrOutput.send([12345]); } }; -const onRejected = (e: Error) => { console.error(e); }; +const onRejected = (e: Error) => { + console.error(e); +}; if (navigator.requestMIDIAccess !== undefined) { navigator.requestMIDIAccess().then(onFulfilled, onRejected);