fragment-tools 0.2.8 → 0.2.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (89) hide show
  1. package/.changeset/README.md +8 -0
  2. package/.changeset/config.json +11 -0
  3. package/.prettierignore +1 -0
  4. package/CHANGELOG.md +10 -0
  5. package/README.md +14 -10
  6. package/bin/index.js +4 -0
  7. package/package.json +9 -2
  8. package/src/cli/build.js +1 -3
  9. package/src/cli/create.js +55 -6
  10. package/src/cli/createConfig.js +8 -23
  11. package/src/cli/createFragmentFile.js +44 -46
  12. package/src/cli/getEntries.js +13 -5
  13. package/src/cli/plugins/check-dependencies.js +1 -1
  14. package/src/cli/run.js +12 -3
  15. package/src/cli/templates/blank/index.js +4 -4
  16. package/src/cli/templates/blank/index.ts +15 -0
  17. package/src/cli/templates/default/index.js +7 -6
  18. package/src/cli/templates/default/index.ts +20 -0
  19. package/src/cli/templates/fragment-gl/fragment.fs +1 -1
  20. package/src/cli/templates/fragment-gl/index.js +3 -3
  21. package/src/cli/templates/fragment-gl/index.ts +20 -0
  22. package/src/cli/templates/p5/index.js +6 -6
  23. package/src/cli/templates/p5/index.ts +14 -0
  24. package/src/cli/templates/p5-webgl/fragment.fs +2 -4
  25. package/src/cli/templates/p5-webgl/index.js +9 -15
  26. package/src/cli/templates/p5-webgl/index.ts +43 -0
  27. package/src/cli/templates/three-fragment/fragment.fs +1 -1
  28. package/src/cli/templates/three-fragment/index.js +10 -4
  29. package/src/cli/templates/three-fragment/index.ts +68 -0
  30. package/src/cli/templates/three-orthographic/index.js +10 -4
  31. package/src/cli/templates/three-orthographic/index.ts +29 -0
  32. package/src/cli/templates/three-perspective/index.js +10 -4
  33. package/src/cli/templates/three-perspective/index.ts +26 -0
  34. package/src/cli/utils.js +3 -0
  35. package/src/client/app/components/HintRecord.svelte +3 -3
  36. package/src/client/app/hooks.js +5 -5
  37. package/src/client/app/lib/gl/Renderer.js +1 -1
  38. package/src/client/app/lib/gl/Texture.js +1 -1
  39. package/src/client/app/lib/gl/index.js +2 -2
  40. package/src/client/app/modules/AudioAnalyser/Range.svelte +2 -2
  41. package/src/client/app/modules/AudioAnalyser/Spectrum.svelte +3 -3
  42. package/src/client/app/modules/Console/ConsoleLine.svelte +13 -13
  43. package/src/client/app/modules/Console.svelte +6 -4
  44. package/src/client/app/renderers/2DRenderer.js +6 -3
  45. package/src/client/app/renderers/FragmentRenderer.js +39 -2
  46. package/src/client/app/renderers/P5GLRenderer.js +28 -26
  47. package/src/client/app/renderers/P5Renderer.js +49 -9
  48. package/src/client/app/renderers/THREERenderer.js +64 -12
  49. package/src/client/app/state/rendering.svelte.js +2 -2
  50. package/src/client/app/state/utils.svelte.js +9 -2
  51. package/src/client/app/stores/sketches.js +2 -1
  52. package/src/client/app/ui/ErrorOverlay.svelte +5 -5
  53. package/src/client/app/ui/Field.svelte +5 -5
  54. package/src/client/app/ui/FieldGroup.svelte +5 -5
  55. package/src/client/app/ui/FieldSection.svelte +7 -7
  56. package/src/client/app/ui/FieldSpace.svelte +2 -2
  57. package/src/client/app/ui/FieldTrigger.svelte +6 -6
  58. package/src/client/app/ui/FloatingParams.svelte +1 -1
  59. package/src/client/app/ui/LayoutComponent.svelte +7 -7
  60. package/src/client/app/ui/LayoutResizer.svelte +1 -1
  61. package/src/client/app/ui/LayoutToolbar.svelte +6 -6
  62. package/src/client/app/ui/Module.svelte +6 -4
  63. package/src/client/app/ui/ModuleRenderer.svelte +3 -3
  64. package/src/client/app/ui/OutputRenderer.svelte +4 -1
  65. package/src/client/app/ui/SketchRenderer.svelte +4 -1
  66. package/src/client/app/ui/fields/ButtonInput.svelte +11 -11
  67. package/src/client/app/ui/fields/CheckboxInput.svelte +18 -12
  68. package/src/client/app/ui/fields/ColorInput.svelte +9 -7
  69. package/src/client/app/ui/fields/ImageInput.svelte +10 -8
  70. package/src/client/app/ui/fields/Input.svelte +13 -13
  71. package/src/client/app/ui/fields/IntervalInput.svelte +11 -14
  72. package/src/client/app/ui/fields/ListInput.svelte +9 -8
  73. package/src/client/app/ui/fields/ProgressInput.svelte +9 -9
  74. package/src/client/app/ui/fields/Select.svelte +11 -11
  75. package/src/client/app/ui/fields/VectorInput.svelte +1 -1
  76. package/src/client/public/css/global.css +26 -27
  77. package/src/client/public/preview.html +59 -0
  78. package/src/types/client.d.ts +36 -0
  79. package/src/types/gl.d.ts +130 -0
  80. package/src/types/helpers.d.ts +5 -0
  81. package/src/types/hooks.d.ts +14 -0
  82. package/src/types/index.d.ts +8 -0
  83. package/src/types/midi.d.ts +176 -0
  84. package/src/types/props.d.ts +72 -0
  85. package/src/types/renderers.d.ts +100 -0
  86. package/src/types/sketch.d.ts +45 -0
  87. package/src/types/triggers.d.ts +45 -0
  88. package/src/types/utils.ts +11 -0
  89. package/tsconfig.json +38 -0
@@ -42,8 +42,8 @@
42
42
  height: 80px;
43
43
 
44
44
  background-color: #1d1d1e;
45
- border-radius: var(--border-radius-input);
46
- box-shadow: inset 0 0 0 1px var(--color-border-input);
45
+ border-radius: var(--fragment-input-border-radius);
46
+ box-shadow: inset 0 0 0 1px var(--fragment-input-border-color);
47
47
  overflow-y: scroll;
48
48
  }
49
49
 
@@ -60,12 +60,14 @@
60
60
 
61
61
  .container::-webkit-scrollbar-track {
62
62
  background-color: var(
63
- --color-lightblack
63
+ --fragment-color-lightblack
64
64
  ); /* color of the tracking area */
65
65
  }
66
66
 
67
67
  .container::-webkit-scrollbar-thumb {
68
- background-color: var(--color-active); /* color of the scroll thumb */
68
+ background-color: var(
69
+ --fragment-accent-color
70
+ ); /* color of the scroll thumb */
69
71
  border-radius: 20px; /* roundness of the scroll thumb */
70
72
  }
71
73
 
@@ -75,7 +77,7 @@
75
77
 
76
78
  margin: 0;
77
79
  padding: 0 3px;
78
- color: var(--color-text);
80
+ color: var(--fragment-text-color);
79
81
  font-size: 10px;
80
82
 
81
83
  opacity: 0.35;
@@ -90,15 +92,14 @@
90
92
  }
91
93
 
92
94
  .list:not(.disabled) .label:hover {
93
- box-shadow: inset 0 0 0 1px var(--color-active);
95
+ box-shadow: inset 0 0 0 1px var(--fragment-accent-color);
94
96
  }
95
97
 
96
98
  .list:not(.disabled) .label:active {
97
- box-shadow: 0 0 0 2px var(--color-active);
99
+ box-shadow: 0 0 0 2px var(--fragment-accent-color);
98
100
  }
99
101
 
100
102
  .item:hover {
101
- /* background-color: #0E0E0E; */
102
103
  opacity: 1;
103
104
  }
104
105
 
@@ -101,11 +101,11 @@
101
101
  .progress {
102
102
  position: relative;
103
103
 
104
- height: var(--height-input);
105
- border-radius: var(--border-radius-input);
106
- box-shadow: inset 0 0 0 1px var(--color-border-input);
104
+ height: var(--fragment-input-height);
105
+ border-radius: var(--fragment-input-border-radius);
106
+ box-shadow: inset 0 0 0 1px var(--fragment-input-border-color);
107
107
 
108
- background: var(--color-background-input);
108
+ background: var(--fragment-input-background-color);
109
109
 
110
110
  container-type: size;
111
111
  outline: 0;
@@ -116,13 +116,13 @@
116
116
  }
117
117
 
118
118
  :global(body:not(.fragment-dragging)) .progress:not(.disabled):hover {
119
- box-shadow: inset 0 0 0 1px var(--color-active);
119
+ box-shadow: inset 0 0 0 1px var(--fragment-accent-color);
120
120
  }
121
121
 
122
122
  .progress.dragging,
123
123
  :global(body:not(.fragment-dragging))
124
124
  .progress:not(.disabled):focus-visible {
125
- box-shadow: 0 0 0 2px var(--color-active);
125
+ box-shadow: 0 0 0 2px var(--fragment-accent-color);
126
126
  }
127
127
 
128
128
  .fill {
@@ -145,14 +145,14 @@
145
145
 
146
146
  background: grey;
147
147
  transform-origin: 0 50%;
148
- border-radius: calc(var(--border-radius-input) * 0.5);
148
+ border-radius: calc(var(--fragment-input-border-radius) * 0.5);
149
149
 
150
- background-color: var(--color-active);
150
+ background-color: var(--fragment-accent-color);
151
151
 
152
152
  transform: translate3d(var(--tx), 0px, 0px);
153
153
  }
154
154
 
155
155
  .progress.disabled .fill {
156
- background-color: var(--color-active-disabled);
156
+ background-color: var(--fragment-color-disabled);
157
157
  }
158
158
  </style>
@@ -86,33 +86,33 @@
86
86
  .select-input {
87
87
  width: 100%;
88
88
 
89
- color: var(--color-text-input);
89
+ color: var(--fragment-input-text-color);
90
90
  }
91
91
 
92
92
  .select-input.disabled {
93
- color: var(--color-text-input-disabled);
93
+ color: var(--fragment-input-disabled-text-color);
94
94
  }
95
95
 
96
96
  .container {
97
97
  position: relative;
98
98
 
99
99
  display: flex;
100
- height: var(--height-input);
100
+ height: var(--fragment-input-height);
101
101
  margin: 2px 0;
102
102
 
103
- box-shadow: inset 0 0 0 1px var(--color-border-input);
104
- border-radius: var(--border-radius-input);
105
- background-color: var(--color-background-input);
103
+ box-shadow: inset 0 0 0 1px var(--fragment-input-border-color);
104
+ border-radius: var(--fragment-input-border-radius);
105
+ background-color: var(--fragment-input-background-color);
106
106
  }
107
107
 
108
108
  :global(body:not(.fragment-dragging))
109
109
  .select-input:not(.disabled)
110
110
  .container:hover {
111
- box-shadow: inset 0 0 0 1px var(--color-active);
111
+ box-shadow: inset 0 0 0 1px var(--fragment-accent-color);
112
112
  }
113
113
 
114
114
  .container:focus-within {
115
- box-shadow: 0 0 0 2px var(--color-active);
115
+ box-shadow: 0 0 0 2px var(--fragment-accent-color);
116
116
  }
117
117
 
118
118
  .select {
@@ -121,7 +121,7 @@
121
121
  width: 100%;
122
122
 
123
123
  color: inherit;
124
- font-size: var(--font-size-input);
124
+ font-size: var(--fragment-input-font-size);
125
125
 
126
126
  outline: 0;
127
127
  background-color: transparent;
@@ -133,10 +133,10 @@
133
133
  }
134
134
 
135
135
  .select-input .select option {
136
- background-color: var(--color-background);
136
+ background-color: var(--fragment-background-color);
137
137
  }
138
138
 
139
139
  .select-input:not(.disabled) .select:focus {
140
- color: var(--color-text);
140
+ color: var(--fragment-text-color);
141
141
  }
142
142
  </style>
@@ -131,6 +131,6 @@
131
131
  width: var(--column-gap);
132
132
  height: 1px;
133
133
 
134
- background-color: var(--color-border-input);
134
+ background-color: var(--fragment-input-border-color);
135
135
  }
136
136
  </style>
@@ -12,28 +12,27 @@
12
12
  }
13
13
 
14
14
  :root {
15
- --font-mono: 'Jetbrains Mono', monospace;
16
-
17
- --color-lightred: #ffaeae;
18
- --color-red: #ff4444;
19
- --color-green: #9af49f;
20
- --color-lightblack: #0e0e0e;
21
-
22
- --color-background: #242425;
23
- --color-active: #177bd0;
24
- --color-active-disabled: #214366;
25
- --color-text: #f0f0f0;
26
- --color-border: var(--color-lightblack);
27
- --color-border-input: #000000;
28
- --color-text-input: #989899;
29
- --color-text-input-disabled: #535354;
30
- --color-background-input: #1d1d1e;
31
- --color-spacing: #323233;
32
-
33
- --height-input: 20px;
34
- --height-topbar: 24px;
35
- --border-radius-input: 3px;
36
- --font-size-input: 11px;
15
+ --fragment-font-family: 'Jetbrains Mono', monospace;
16
+
17
+ --fragment-color-lightred: #ffaeae;
18
+ --fragment-color-red: #ff4444;
19
+ --fragment-color-green: #9af49f;
20
+ --fragment-color-lightblack: #0e0e0e;
21
+ --fragment-color-white: #f0f0f0;
22
+
23
+ --fragment-background-color: #242425;
24
+ --fragment-accent-color: #177bd0;
25
+ --fragment-color-disabled: #214366;
26
+ --fragment-text-color: var(--fragment-color-white);
27
+ --fragment-spacing-color: #323233;
28
+
29
+ --fragment-input-border-color: #000000;
30
+ --fragment-input-text-color: #989899;
31
+ --fragment-input-disabled-text-color: #535354;
32
+ --fragment-input-height: 20px;
33
+ --fragment-input-border-radius: 3px;
34
+ --fragment-input-font-size: 11px;
35
+ --fragment-input-background-color: #1d1d1e;
37
36
  }
38
37
 
39
38
  html {
@@ -48,9 +47,9 @@ body {
48
47
 
49
48
  margin: 0;
50
49
  padding: 0;
51
- font-family: var(--font-mono);
50
+ font-family: var(--fragment-font-family);
52
51
 
53
- background-color: var(--color-lightblack);
52
+ background-color: var(--fragment-color-lightblack);
54
53
  overscroll-behavior: none;
55
54
  }
56
55
 
@@ -90,7 +89,7 @@ ol {
90
89
  * {
91
90
  box-sizing: border-box;
92
91
  scrollbar-width: thin;
93
- scrollbar-color: var(--color-active) transparent;
92
+ scrollbar-color: var(--fragment-accent-color) transparent;
94
93
  }
95
94
 
96
95
  input,
@@ -100,7 +99,7 @@ button {
100
99
  padding: 0;
101
100
  margin: 0;
102
101
  border: none;
103
- font-family: var(--font-mono);
102
+ font-family: var(--fragment-font-family);
104
103
  }
105
104
 
106
105
  h1,
@@ -123,7 +122,7 @@ h5 {
123
122
  }
124
123
 
125
124
  .loading {
126
- color: #f0f0f0;
125
+ color: var(--fragment-text-color);
127
126
  padding: 18px;
128
127
  }
129
128
 
@@ -0,0 +1,59 @@
1
+ <!doctype html>
2
+ <html>
3
+ <head>
4
+ <title>Preview</title>
5
+ </head>
6
+ <style>
7
+ body {
8
+ background-color: black;
9
+ display: grid;
10
+ place-items: center;
11
+ }
12
+
13
+ * {
14
+ margin: 0;
15
+ padding: 0;
16
+ }
17
+
18
+ canvas {
19
+ max-width: 100vw !important;
20
+ height: auto;
21
+ margin: 0 auto;
22
+ }
23
+ </style>
24
+ <body>
25
+ <canvas id="preview" width="1920" height="1080"></canvas>
26
+ <script>
27
+ const previewCanvas = document.getElementById('preview');
28
+ const ctx = previewCanvas.getContext('2d');
29
+ let offscreen;
30
+
31
+ window.opener.postMessage(
32
+ {
33
+ type: 'ready',
34
+ },
35
+ '*',
36
+ );
37
+
38
+ window.addEventListener('message', async (e) => {
39
+ console.log(e.data.type);
40
+ if (e.data.type === 'resize') {
41
+ previewCanvas.width = e.data.width;
42
+ previewCanvas.height = e.data.height;
43
+ }
44
+
45
+ if (e.data.bitmap) {
46
+ const bitmap = e.data.bitmap;
47
+ ctx.clearRect(
48
+ 0,
49
+ 0,
50
+ previewCanvas.width,
51
+ previewCanvas.height,
52
+ );
53
+ ctx.drawImage(bitmap, 0, 0);
54
+ bitmap.close(); // release bitmap memory
55
+ }
56
+ });
57
+ </script>
58
+ </body>
59
+ </html>
@@ -0,0 +1,36 @@
1
+ declare const __CWD__: string | undefined;
2
+ declare const __FRAGMENT_PORT__: string | number | undefined;
3
+ declare const __START_TIME__: string | number | undefined;
4
+ declare const __SEED__: string | number | undefined;
5
+ declare const __BUILD__: boolean | undefined;
6
+
7
+ declare const __THREE_RENDERER__: string | undefined;
8
+ declare const __FRAGMENT_RENDERER__: string | undefined;
9
+ declare const __P5_RENDERER__: string | undefined;
10
+ declare const __P5_WEBGL_RENDERER__: string | undefined;
11
+ declare const __2D_RENDERER__: string | undefined;
12
+
13
+ declare module '*.glsl' {
14
+ const value: string;
15
+ export default value;
16
+ }
17
+
18
+ declare module '*.vs' {
19
+ const value: string;
20
+ export default value;
21
+ }
22
+
23
+ declare module '*.vert' {
24
+ const value: string;
25
+ export default value;
26
+ }
27
+
28
+ declare module '*.fs' {
29
+ const value: string;
30
+ export default value;
31
+ }
32
+
33
+ declare module '*.frag' {
34
+ const value: string;
35
+ export default value;
36
+ }
@@ -0,0 +1,130 @@
1
+ declare module '@fragment/lib/gl' {
2
+ type Gl = WebGLRenderingContext | WebGL2RenderingContext;
3
+
4
+ type UniformValue = number | number[] | Texture | null;
5
+ type Uniform = { type?: string; value?: UniformValue };
6
+ type Uniforms = Record<string, Uniform>;
7
+
8
+ type Attributes = Record<string, { data: number[] }>;
9
+
10
+ class Geometry {
11
+ constructor(gl: Gl, attributes?: Attributes);
12
+ gl: Gl;
13
+ attributes: Attributes | null;
14
+ buffers: Record<string, WebGLBuffer> | null;
15
+ }
16
+
17
+ class Texture {
18
+ constructor(
19
+ gl: Gl,
20
+ params?: {
21
+ image?: TexImageSource | null;
22
+ name?: string;
23
+ target?: number;
24
+ type?: number;
25
+ wrapS?: number;
26
+ wrapT?: number;
27
+ generateMipmaps?: boolean;
28
+ format?: number;
29
+ internalFormat?: number;
30
+ minFilter?: number;
31
+ magFilter?: number;
32
+ flipY?: boolean;
33
+ },
34
+ );
35
+ id: number;
36
+ gl: Gl;
37
+ image: TexImageSource | null;
38
+ name: string;
39
+ target: number;
40
+ type: number;
41
+ wrapS: number;
42
+ wrapT: number;
43
+ generateMipmaps: boolean;
44
+ format: number;
45
+ internalFormat: number;
46
+ minFilter: number;
47
+ magFilter: number;
48
+ flipY: boolean;
49
+ needsUpdate: boolean;
50
+ glTexture: WebGLTexture | null;
51
+ bind(): void;
52
+ update(textureUnit?: number): void;
53
+ destroy(): void;
54
+ }
55
+
56
+ class Program {
57
+ constructor(
58
+ gl: Gl,
59
+ params?: {
60
+ vertex?: string;
61
+ fragment?: string;
62
+ uniforms?: Uniforms;
63
+ },
64
+ );
65
+ id: number;
66
+ gl: Gl;
67
+ vertexShader: string;
68
+ fragmentShader: string;
69
+ uniforms: Uniforms;
70
+ needsUpdate: boolean;
71
+ attributesLocations: Record<
72
+ string,
73
+ ReturnType<WebGLRenderingContext['getAttribLocation']>
74
+ >;
75
+ uniformsLocations: Record<
76
+ string,
77
+ ReturnType<WebGLRenderingContext['getUniformLocation']>
78
+ >;
79
+ compile(): void;
80
+ }
81
+
82
+ class Renderer {
83
+ constructor(params?: {
84
+ canvas?: HTMLCanvasElement;
85
+ antialias?: boolean;
86
+ alpha?: boolean;
87
+ depth?: boolean;
88
+ stencil?: boolean;
89
+ premultipliedAlpha?: boolean;
90
+ pixelRatio?: number;
91
+ webgl?: 1 | 2;
92
+ });
93
+ gl: Gl;
94
+ canvas: HTMLCanvasElement;
95
+ render(params: {
96
+ geometry: Geometry;
97
+ program: Program;
98
+ primitiveType?: GLenum;
99
+ offset?: number;
100
+ count?: number;
101
+ }): void;
102
+ setPixelRatio(pixelRatio?: number): void;
103
+ setSize(params?: { width?: number; height?: number }): void;
104
+ setViewport(params?: { width?: number; height?: number }): void;
105
+ destroy(): void;
106
+ }
107
+
108
+ interface Frag {
109
+ gl: Gl;
110
+ program: Program;
111
+ texture: (params?: {}) => Texture;
112
+ shader: string;
113
+ fragmentShader: string;
114
+ vertexShader: string;
115
+ uniforms: Uniforms;
116
+ resize: (params?: {
117
+ width?: number;
118
+ height?: number;
119
+ pixelRatio?: number;
120
+ }) => void;
121
+ render: () => void;
122
+ destroy: () => void;
123
+ }
124
+
125
+ function fragment(params?: {
126
+ canvas?: HTMLCanvasElement;
127
+ shader?: string;
128
+ uniforms?: Uniforms;
129
+ }): Frag;
130
+ }
@@ -0,0 +1,5 @@
1
+ import type { Props } from './props';
2
+
3
+ declare module '@fragment/helpers' {
4
+ function reactiveProps(props?: Props): Props;
5
+ }
@@ -0,0 +1,14 @@
1
+ declare module '@fragment/hooks' {
2
+ type Listener = (params: {
3
+ encoding: string;
4
+ quality: number;
5
+ count: number;
6
+ index: number;
7
+ pixelsPerInch: number;
8
+ }) => Function | void;
9
+
10
+ function onBeforeCapture(listener: Listener, context?: string): void;
11
+ function onAfterCapture(listener: Listener, context?: string): void;
12
+ function onBeforeRecord(listener: Listener, context?: string): void;
13
+ function onAfterRecord(listener: Listener, context?: string): void;
14
+ }
@@ -0,0 +1,8 @@
1
+ export type * from './renderers';
2
+ export type * from './sketch';
3
+ export type * from './props';
4
+ export type * from './helpers';
5
+ export type * from './hooks';
6
+ export type * from './triggers';
7
+ export type * from './midi';
8
+ export type * from './gl';
@@ -0,0 +1,176 @@
1
+ export declare global {
2
+ namespace MIDI {
3
+ /**
4
+ * All the posible notes.
5
+ */
6
+ type MIDINote =
7
+ | 'C'
8
+ | 'C#'
9
+ | 'D'
10
+ | 'D#'
11
+ | 'E'
12
+ | 'F'
13
+ | 'F#'
14
+ | 'G'
15
+ | 'G#'
16
+ | 'A'
17
+ | 'A#'
18
+ | 'B';
19
+
20
+ interface MIDIPort extends EventTarget {
21
+ /**
22
+ * A unique ID of the port. This can be used by developers to remember ports the
23
+ * user has chosen for their application.
24
+ */
25
+ id: string;
26
+
27
+ /**
28
+ * The manufacturer of the port.
29
+ */
30
+ manufacturer?: string | undefined;
31
+
32
+ /**
33
+ * The system name of the port.
34
+ */
35
+ name?: string | undefined;
36
+
37
+ /**
38
+ * A descriptor property to distinguish whether the port is an input or an output
39
+ * port.
40
+ */
41
+ type: MIDIPortType;
42
+
43
+ /**
44
+ * The version of the port.
45
+ */
46
+ version?: string | undefined;
47
+
48
+ /**
49
+ * The state of the device.
50
+ */
51
+ state: MIDIPortDeviceState;
52
+
53
+ /**
54
+ * The state of the connection to the device.
55
+ */
56
+ connection: MIDIPortConnectionState;
57
+
58
+ /**
59
+ * The handler called when an existing port changes its state or connection
60
+ * attributes.
61
+ */
62
+ onstatechange(event: MIDIConnectionEvent): void;
63
+
64
+ addEventListener(
65
+ type: 'statechange',
66
+ listener: (this: this, event: MIDIConnectionEvent) => any,
67
+ options?: boolean | AddEventListenerOptions,
68
+ ): void;
69
+ addEventListener(
70
+ type: string,
71
+ listener: EventListenerOrEventListenerObject,
72
+ options?: boolean | AddEventListenerOptions,
73
+ ): void;
74
+
75
+ /**
76
+ * Makes the MIDI device corresponding to the MIDIPort explicitly available. Note
77
+ * that this call is NOT required in order to use the MIDIPort - calling send() on
78
+ * a MIDIOutput or attaching a MIDIMessageEvent handler on a MIDIInputPort will
79
+ * cause an implicit open().
80
+ *
81
+ * When invoked, this method returns a Promise object representing a request for
82
+ * access to the given MIDI port on the user's system.
83
+ */
84
+ open(): Promise<MIDIPort>;
85
+
86
+ /**
87
+ * Makes the MIDI device corresponding to the MIDIPort
88
+ * explicitly unavailable (subsequently changing the state from "open" to
89
+ * "connected"). Note that successful invocation of this method will result in MIDI
90
+ * messages no longer being delivered to MIDIMessageEvent handlers on a
91
+ * MIDIInputPort (although setting a new handler will cause an implicit open()).
92
+ *
93
+ * When invoked, this method returns a Promise object representing a request for
94
+ * access to the given MIDI port on the user's system. When the port has been
95
+ * closed (and therefore, in exclusive access systems, the port is available to
96
+ * other applications), the vended Promise is resolved. If the port is
97
+ * disconnected, the Promise is rejected.
98
+ */
99
+ close(): Promise<MIDIPort>;
100
+ }
101
+
102
+ interface MIDIInput extends MIDIPort {
103
+ type: 'input';
104
+
105
+ onmidimessage(e: MIDIMessageEvent): void;
106
+
107
+ addEventListener(
108
+ type: 'midimessage',
109
+ listener: (this: this, event: MIDIMessageEvent) => any,
110
+ options?: boolean | AddEventListenerOptions,
111
+ ): void;
112
+ addEventListener(
113
+ type: 'statechange',
114
+ listener: (this: this, event: MIDIConnectionEvent) => any,
115
+ options?: boolean | AddEventListenerOptions,
116
+ ): void;
117
+ addEventListener(
118
+ type: string,
119
+ listener: EventListenerOrEventListenerObject,
120
+ options?: boolean | AddEventListenerOptions,
121
+ ): void;
122
+ }
123
+
124
+ type MIDIMessageEvent = {
125
+ /**
126
+ * The type of the message event.
127
+ */
128
+ type: 'noteon' | 'noteoff' | 'controlchange';
129
+
130
+ /**
131
+ * The triggered note.
132
+ */
133
+ note: { number: number; name: MIDINote };
134
+
135
+ /**
136
+ * The channel the message was sent to.
137
+ */
138
+ channel: number;
139
+
140
+ /**
141
+ * The normalized velocity of the note expressed as a float between 0 and 1.
142
+ */
143
+ velocity: number;
144
+
145
+ /**
146
+ * The raw velocity of the note expressed as an integer between 0 and 127.
147
+ */
148
+ rawVelocity: number;
149
+
150
+ /**
151
+ * The normalized value expressed as a float between 0 and 1.
152
+ */
153
+ value: number;
154
+
155
+ /**
156
+ * The raw value expressed as an integer between 0 and 127.
157
+ */
158
+ rawValue: number;
159
+
160
+ /**
161
+ * The object that dispatched the event.
162
+ */
163
+ currentTarget: MIDIInput;
164
+
165
+ /**
166
+ * The object that dispatched the event.
167
+ */
168
+ target: MIDIInput;
169
+
170
+ /**
171
+ * The object that dispatched the event.
172
+ */
173
+ srcElement: MIDIInput;
174
+ };
175
+ }
176
+ }