@clockworkdog/cogs-client 1.5.5 → 2.0.0-beta.1
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/LICENSE +21 -0
- package/README.md +90 -21
- package/dist/AudioPlayer.d.ts +2 -2
- package/dist/AudioPlayer.js +22 -21
- package/dist/CogsConnection.d.ts +62 -55
- package/dist/CogsConnection.js +88 -42
- package/dist/RtspStreamer.js +1 -1
- package/dist/VideoPlayer.d.ts +2 -2
- package/dist/VideoPlayer.js +4 -4
- package/dist/browser/index.js +139 -87
- package/dist/index.d.ts +2 -1
- package/dist/index.js +7 -2
- package/dist/types/AllMediaClipStatesMessage.d.ts +1 -1
- package/dist/types/AudioState.d.ts +1 -1
- package/dist/types/CogsClientMessage.d.ts +4 -4
- package/dist/types/ManifestTypes.d.ts +33 -0
- package/dist/types/ManifestTypes.js +2 -0
- package/dist/types/MediaClipStateMessage.d.ts +1 -1
- package/dist/types/MediaObjectFit.d.ts +1 -1
- package/dist/types/PluginManifestJson.d.ts +27 -14
- package/dist/types/ShowPhase.d.ts +7 -0
- package/dist/types/{valueTypes.js → ShowPhase.js} +2 -2
- package/dist/types/VideoState.js +1 -1
- package/dist/types/utils.d.ts +9 -0
- package/dist/types/utils.js +2 -0
- package/package.json +4 -3
- package/dist/types/valueTypes.d.ts +0 -18
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2023 Clockwork Dog
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -30,10 +30,61 @@ yarn add @clockworkdog/cogs-client
|
|
|
30
30
|
|
|
31
31
|
## Usage
|
|
32
32
|
|
|
33
|
-
### Create a `cogs-plugin-manifest.
|
|
33
|
+
### Create a `cogs-plugin-manifest.js` file
|
|
34
34
|
|
|
35
35
|
See [PluginManifestJson](https://clockwork-dog.github.io/cogs-client-lib/interfaces/PluginManifestJson.html) for details of what to include.
|
|
36
36
|
|
|
37
|
+
If using Typescript set `"allowJs": true` in your `tsconfig.json`.
|
|
38
|
+
|
|
39
|
+
Use the `@type {const}` JSDoc annotation to allow the manifest to be imported as a literal type and `@satisfies {import("@clockworkdog/cogs-client").PluginManifestJson}` to allow your editor to check the validity of the manifest.
|
|
40
|
+
|
|
41
|
+
e.g.
|
|
42
|
+
|
|
43
|
+
```js
|
|
44
|
+
module.exports =
|
|
45
|
+
/**
|
|
46
|
+
* @type {const}
|
|
47
|
+
* @satisfies {import("@clockworkdog/cogs-client").PluginManifestJsonReadonly}
|
|
48
|
+
*/
|
|
49
|
+
({
|
|
50
|
+
name: 'Big Button',
|
|
51
|
+
icon: 'bullseye-pointer',
|
|
52
|
+
description: 'A big, colorful touchscreen button',
|
|
53
|
+
version: '1',
|
|
54
|
+
config: [
|
|
55
|
+
{
|
|
56
|
+
name: 'Color',
|
|
57
|
+
value: { type: 'string', default: 'red' },
|
|
58
|
+
},
|
|
59
|
+
],
|
|
60
|
+
state: [
|
|
61
|
+
{
|
|
62
|
+
name: 'Enabled',
|
|
63
|
+
value: { type: 'boolean', default: false },
|
|
64
|
+
writableFromCogs: true,
|
|
65
|
+
},
|
|
66
|
+
],
|
|
67
|
+
events: {
|
|
68
|
+
toCogs: [
|
|
69
|
+
{
|
|
70
|
+
name: 'Pressed',
|
|
71
|
+
value: { type: 'boolean' },
|
|
72
|
+
},
|
|
73
|
+
],
|
|
74
|
+
fromCogs: [
|
|
75
|
+
{
|
|
76
|
+
name: 'Explosion',
|
|
77
|
+
},
|
|
78
|
+
],
|
|
79
|
+
},
|
|
80
|
+
media: {
|
|
81
|
+
audio: true,
|
|
82
|
+
video: true,
|
|
83
|
+
images: true,
|
|
84
|
+
},
|
|
85
|
+
});
|
|
86
|
+
```
|
|
87
|
+
|
|
37
88
|
### Import the library
|
|
38
89
|
|
|
39
90
|
#### Browser
|
|
@@ -48,7 +99,7 @@ const { CogsConnection, CogsAudioPlayer } = COGS;
|
|
|
48
99
|
const { CogsConnection, CogsAudioPlayer } = require('@clockworkdog/cogs-client');
|
|
49
100
|
```
|
|
50
101
|
|
|
51
|
-
####
|
|
102
|
+
#### Typescript / ES6
|
|
52
103
|
|
|
53
104
|
```ts
|
|
54
105
|
import { CogsConnection, CogsAudioPlayer } from '@clockworkdog/cogs-client';
|
|
@@ -56,35 +107,35 @@ import { CogsConnection, CogsAudioPlayer } from '@clockworkdog/cogs-client';
|
|
|
56
107
|
|
|
57
108
|
### Connect to COGS
|
|
58
109
|
|
|
110
|
+
Initialize a [CogsConnection](https://clockwork-dog.github.io/cogs-client-lib/interfaces/CogsConnection.html) with the manifest you created above.
|
|
111
|
+
|
|
59
112
|
```ts
|
|
60
113
|
let connected = false;
|
|
61
114
|
|
|
62
|
-
|
|
115
|
+
import manifest from './cogs-plugin-manifest.js'; // Requires `"allowJs": true` in `tsconfig.json`
|
|
116
|
+
|
|
117
|
+
const cogsConnection = new CogsConnection(manifest);
|
|
63
118
|
cogsConnection.addEventListener('open', () => {
|
|
64
119
|
connected = true;
|
|
65
120
|
});
|
|
66
121
|
cogsConnection.addEventListener('close', () => {
|
|
67
122
|
connected = false;
|
|
68
123
|
});
|
|
69
|
-
cogsConnection.addEventListener('config', (
|
|
70
|
-
|
|
71
|
-
//
|
|
72
|
-
// `config` is of type `{ [configKey: string]: number | string | boolean }`
|
|
124
|
+
cogsConnection.addEventListener('config', ({ config }) => {
|
|
125
|
+
// Handle new config
|
|
126
|
+
// `config` is of type `{ [name: string]: number | string | boolean }`
|
|
73
127
|
});
|
|
74
|
-
cogsConnection.addEventListener('
|
|
75
|
-
|
|
76
|
-
//
|
|
77
|
-
// `updates` is of type `{ [portName: string]: number | string | boolean }`
|
|
128
|
+
cogsConnection.addEventListener('state', ({ state }) => {
|
|
129
|
+
// Handle state updates
|
|
130
|
+
// `state` is of type `{ [name: string]: number | string | boolean }`
|
|
78
131
|
});
|
|
79
|
-
cogsConnection.addEventListener('event', (
|
|
80
|
-
|
|
81
|
-
//
|
|
82
|
-
// `
|
|
83
|
-
// `value` is the type defined in COGS, one of `number | string | boolean | undefined`
|
|
132
|
+
cogsConnection.addEventListener('event', ({ name, value }) => {
|
|
133
|
+
// Handle events from COGS
|
|
134
|
+
// `name` is the event name.
|
|
135
|
+
// `value` is of the type defined in manifest, one of `number | string | boolean | undefined`.
|
|
84
136
|
});
|
|
85
|
-
cogsConnection.addEventListener('message', (
|
|
86
|
-
|
|
87
|
-
// Handle message. See `types/CogsClientMessage.ts`
|
|
137
|
+
cogsConnection.addEventListener('message', ({ message }) => {
|
|
138
|
+
// Handle low-level COGS messages. See `types/CogsClientMessage.ts`
|
|
88
139
|
});
|
|
89
140
|
|
|
90
141
|
function sendEventToCogs() {
|
|
@@ -92,12 +143,30 @@ function sendEventToCogs() {
|
|
|
92
143
|
}
|
|
93
144
|
|
|
94
145
|
function sendPortUpdateToCogs() {
|
|
95
|
-
cogsConnection.
|
|
146
|
+
cogsConnection.setState({ port1: 100 });
|
|
147
|
+
}
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
### Support audio actions
|
|
151
|
+
|
|
152
|
+
Add `audio` to `cogs-plugin-manifest.js`:
|
|
153
|
+
|
|
154
|
+
```js
|
|
155
|
+
{
|
|
156
|
+
media: {
|
|
157
|
+
audio: true;
|
|
158
|
+
}
|
|
96
159
|
}
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
Add [CogsAudioPlayer](https://clockwork-dog.github.io/cogs-client-lib/classes/CogsAudioPlayer.html) to your page:
|
|
97
163
|
|
|
164
|
+
```ts
|
|
98
165
|
const audioPlayer = new CogsAudioPlayer(cogsConnection);
|
|
166
|
+
|
|
167
|
+
// Optional
|
|
99
168
|
audioPlayer.addEventListener('state', (audioState) => {
|
|
100
|
-
// Handle audio state. See `types/AudioState.ts`
|
|
169
|
+
// Handle audio state changes. See `types/AudioState.ts`
|
|
101
170
|
});
|
|
102
171
|
```
|
|
103
172
|
|
package/dist/AudioPlayer.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import CogsConnection from './CogsConnection';
|
|
2
2
|
import { AudioState } from './types/AudioState';
|
|
3
3
|
import MediaClipStateMessage from './types/MediaClipStateMessage';
|
|
4
|
-
|
|
4
|
+
type EventTypes = {
|
|
5
5
|
state: AudioState;
|
|
6
6
|
audioClipState: MediaClipStateMessage;
|
|
7
7
|
};
|
|
@@ -10,7 +10,7 @@ export default class AudioPlayer {
|
|
|
10
10
|
private globalVolume;
|
|
11
11
|
private audioClipPlayers;
|
|
12
12
|
private sinkId;
|
|
13
|
-
constructor(cogsConnection: CogsConnection);
|
|
13
|
+
constructor(cogsConnection: CogsConnection<any>);
|
|
14
14
|
setGlobalVolume(volume: number): void;
|
|
15
15
|
playAudioClip(path: string, { playId, volume, fade, loop }: {
|
|
16
16
|
playId: string;
|
package/dist/AudioPlayer.js
CHANGED
|
@@ -16,8 +16,7 @@ class AudioPlayer {
|
|
|
16
16
|
cogsConnection.sendMediaClipState(detail);
|
|
17
17
|
});
|
|
18
18
|
// Listen for audio control messages
|
|
19
|
-
cogsConnection.addEventListener('message', (
|
|
20
|
-
const message = event.detail;
|
|
19
|
+
cogsConnection.addEventListener('message', ({ message }) => {
|
|
21
20
|
switch (message.type) {
|
|
22
21
|
case 'media_config_update':
|
|
23
22
|
if (this.globalVolume !== message.globalVolume) {
|
|
@@ -95,7 +94,7 @@ class AudioPlayer {
|
|
|
95
94
|
.filter(([, { state }]) => state.type === 'pausing')
|
|
96
95
|
.map(([id]) => parseInt(id));
|
|
97
96
|
pausedSoundIds.forEach((soundId) => {
|
|
98
|
-
log('Resuming paused clip',
|
|
97
|
+
log('Resuming paused clip', soundId);
|
|
99
98
|
clipPlayer.player.play(soundId);
|
|
100
99
|
});
|
|
101
100
|
// Clips with pause requested no longer need to pause, they can continue playing now
|
|
@@ -106,7 +105,7 @@ class AudioPlayer {
|
|
|
106
105
|
const newSoundIds = pausedSoundIds.length > 0 || pausingSoundIds.length > 0 || pauseRequestedSoundIds.length > 0 ? [] : [clipPlayer.player.play()];
|
|
107
106
|
// Pausing clips are technically currently playing as far as Howler is concerned
|
|
108
107
|
pausingSoundIds.forEach((soundId) => {
|
|
109
|
-
log('Stopping fade and resuming pausing clip',
|
|
108
|
+
log('Stopping fade and resuming pausing clip', soundId);
|
|
110
109
|
// Stop the fade callback
|
|
111
110
|
clipPlayer.player.off('fade', undefined, soundId);
|
|
112
111
|
// Set loop property
|
|
@@ -135,7 +134,6 @@ class AudioPlayer {
|
|
|
135
134
|
// Non-preloaded clips don't yet have an HTML audio node
|
|
136
135
|
// so we need to set the audio output when it's playing
|
|
137
136
|
clipPlayer.player.once('play', () => {
|
|
138
|
-
log('play() callback - setPlayerSinkId', { soundId });
|
|
139
137
|
setPlayerSinkId(clipPlayer.player, this.sinkId);
|
|
140
138
|
});
|
|
141
139
|
clipPlayer.player.once('stop', () => this.handleStoppedClip(path, playId, soundId), soundId);
|
|
@@ -152,12 +150,11 @@ class AudioPlayer {
|
|
|
152
150
|
loop,
|
|
153
151
|
volume,
|
|
154
152
|
};
|
|
155
|
-
log('CLIP -> play_requested');
|
|
153
|
+
log('CLIP -> play_requested', soundId);
|
|
156
154
|
// Once clip starts, check if it should actually be paused or stopped
|
|
157
155
|
// If not, then update state to 'playing'
|
|
158
156
|
clipPlayer.player.once('play', () => {
|
|
159
157
|
var _a;
|
|
160
|
-
log('play() callback - update state', { soundId });
|
|
161
158
|
const clipState = (_a = clipPlayer.activeClips[soundId]) === null || _a === void 0 ? void 0 : _a.state;
|
|
162
159
|
if ((clipState === null || clipState === void 0 ? void 0 : clipState.type) === 'pause_requested') {
|
|
163
160
|
log('Clip started playing but should be paused', { path, soundId });
|
|
@@ -168,7 +165,7 @@ class AudioPlayer {
|
|
|
168
165
|
this.stopAudioClip(path, { fade: clipState.fade }, soundId, true);
|
|
169
166
|
}
|
|
170
167
|
else {
|
|
171
|
-
log('CLIP -> playing');
|
|
168
|
+
log('CLIP -> playing', soundId);
|
|
172
169
|
this.updateActiveAudioClip(path, soundId, (clip) => ({ ...clip, state: { type: 'playing' } }));
|
|
173
170
|
}
|
|
174
171
|
}, soundId);
|
|
@@ -178,7 +175,6 @@ class AudioPlayer {
|
|
|
178
175
|
clipPlayer.player.volume(0, soundId);
|
|
179
176
|
clipPlayer.player.mute(false, soundId);
|
|
180
177
|
clipPlayer.player.once('play', () => {
|
|
181
|
-
log('play() callback - fade volume', { soundId });
|
|
182
178
|
fadeAudioPlayerVolume(clipPlayer.player, volume, fade * 1000, soundId);
|
|
183
179
|
}, soundId);
|
|
184
180
|
}
|
|
@@ -208,25 +204,25 @@ class AudioPlayer {
|
|
|
208
204
|
// Fade then pause
|
|
209
205
|
clipPlayer.player.once('fade', (soundId) => {
|
|
210
206
|
clipPlayer.player.pause(soundId);
|
|
211
|
-
log('CLIP -> paused (after fade)');
|
|
207
|
+
log('CLIP -> paused (after fade)', soundId);
|
|
212
208
|
this.updateActiveAudioClip(path, soundId, (clip) => ({ ...clip, state: { type: 'paused' } }));
|
|
213
209
|
this.notifyClipStateListeners(clip.playId, path, 'paused');
|
|
214
210
|
}, soundId);
|
|
215
211
|
fadeAudioPlayerVolume(clipPlayer.player, 0, fade * 1000, soundId);
|
|
216
|
-
log('CLIP -> pausing');
|
|
212
|
+
log('CLIP -> pausing', soundId);
|
|
217
213
|
clip.state = { type: 'pausing' };
|
|
218
214
|
}
|
|
219
215
|
else {
|
|
220
216
|
// Pause now
|
|
221
217
|
clipPlayer.player.pause(soundId);
|
|
222
|
-
log('CLIP -> paused');
|
|
218
|
+
log('CLIP -> paused', soundId);
|
|
223
219
|
clip.state = { type: 'paused' };
|
|
224
220
|
this.notifyClipStateListeners(clip.playId, path, 'paused');
|
|
225
221
|
}
|
|
226
222
|
}
|
|
227
223
|
// Clip hasn't started playing yet, or has already had pause_requested (but fade may have changed so update here)
|
|
228
224
|
else if (clip.state.type === 'play_requested' || clip.state.type === 'pause_requested') {
|
|
229
|
-
log('CLIP -> pause_requested');
|
|
225
|
+
log('CLIP -> pause_requested', soundId);
|
|
230
226
|
clip.state = { type: 'pause_requested', fade };
|
|
231
227
|
}
|
|
232
228
|
}
|
|
@@ -236,9 +232,10 @@ class AudioPlayer {
|
|
|
236
232
|
});
|
|
237
233
|
}
|
|
238
234
|
stopAudioClip(path, { fade }, onlySoundId, allowIfStopRequested) {
|
|
239
|
-
var _a, _b;
|
|
235
|
+
var _a, _b, _c;
|
|
236
|
+
log('Stop audio clip', { activeClips: (_a = this.audioClipPlayers[path]) === null || _a === void 0 ? void 0 : _a.activeClips });
|
|
240
237
|
// No active clips to stop
|
|
241
|
-
if (Object.keys((
|
|
238
|
+
if (Object.keys((_c = (_b = this.audioClipPlayers[path]) === null || _b === void 0 ? void 0 : _b.activeClips) !== null && _c !== void 0 ? _c : {}).length === 0) {
|
|
242
239
|
return;
|
|
243
240
|
}
|
|
244
241
|
this.updateAudioClipPlayer(path, (clipPlayer) => {
|
|
@@ -257,11 +254,16 @@ class AudioPlayer {
|
|
|
257
254
|
clipPlayer.player.off('fade', soundId);
|
|
258
255
|
fadeAudioPlayerVolume(clipPlayer.player, 0, fade * 1000, soundId);
|
|
259
256
|
// Set callback after starting new fade, otherwise it will fire straight away as the previous fade is cancelled
|
|
260
|
-
clipPlayer.player.once('fade', (soundId) =>
|
|
261
|
-
|
|
257
|
+
clipPlayer.player.once('fade', (soundId) => {
|
|
258
|
+
clipPlayer.player.loop(false, soundId);
|
|
259
|
+
clipPlayer.player.stop(soundId), soundId;
|
|
260
|
+
});
|
|
261
|
+
log('CLIP -> stopping', soundId);
|
|
262
262
|
clip.state = { type: 'stopping' };
|
|
263
263
|
}
|
|
264
264
|
else {
|
|
265
|
+
log('Stop clip', soundId);
|
|
266
|
+
clipPlayer.player.loop(false, soundId);
|
|
265
267
|
clipPlayer.player.stop(soundId);
|
|
266
268
|
}
|
|
267
269
|
}
|
|
@@ -269,7 +271,7 @@ class AudioPlayer {
|
|
|
269
271
|
// or has pause_requested, but stop takes precedence
|
|
270
272
|
else if (clip.state.type === 'play_requested' || clip.state.type === 'pause_requested' || clip.state.type === 'stop_requested') {
|
|
271
273
|
log("Trying to stop clip which hasn't started playing yet", { path, soundId });
|
|
272
|
-
log('CLIP -> stop_requested');
|
|
274
|
+
log('CLIP -> stop_requested', soundId);
|
|
273
275
|
clip.state = { type: 'stop_requested', fade };
|
|
274
276
|
}
|
|
275
277
|
}
|
|
@@ -405,7 +407,7 @@ class AudioPlayer {
|
|
|
405
407
|
}
|
|
406
408
|
createPlayer(path, config) {
|
|
407
409
|
const player = new howler_1.Howl({
|
|
408
|
-
src: urls_1.assetUrl(path),
|
|
410
|
+
src: (0, urls_1.assetUrl)(path),
|
|
409
411
|
autoplay: false,
|
|
410
412
|
loop: false,
|
|
411
413
|
volume: 1,
|
|
@@ -471,9 +473,8 @@ function setAudioPlayerVolume(howl, volume, soundId) {
|
|
|
471
473
|
/**
|
|
472
474
|
* Fade to audio volume
|
|
473
475
|
*
|
|
474
|
-
* This doesn't work on iOS (volume is read-only)
|
|
476
|
+
* Note: This doesn't work on iOS (volume is read-only)
|
|
475
477
|
*/
|
|
476
478
|
function fadeAudioPlayerVolume(howl, volume, fade, soundId) {
|
|
477
|
-
howl.mute(false, soundId);
|
|
478
479
|
howl.fade(howl.volume(soundId), volume, fade, soundId);
|
|
479
480
|
}
|
package/dist/CogsConnection.d.ts
CHANGED
|
@@ -1,57 +1,18 @@
|
|
|
1
|
-
import
|
|
1
|
+
import ShowPhase from './types/ShowPhase';
|
|
2
2
|
import CogsClientMessage from './types/CogsClientMessage';
|
|
3
3
|
import MediaClipStateMessage from './types/MediaClipStateMessage';
|
|
4
4
|
import AllMediaClipStatesMessage from './types/AllMediaClipStatesMessage';
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
[port: string]: PortValue;
|
|
11
|
-
};
|
|
12
|
-
inputEvents?: {
|
|
13
|
-
[key: string]: EventValue | null;
|
|
14
|
-
};
|
|
15
|
-
}> {
|
|
16
|
-
open: undefined;
|
|
17
|
-
close: undefined;
|
|
18
|
-
message: CogsClientMessage;
|
|
19
|
-
config: CustomTypes['config'];
|
|
20
|
-
updates: Partial<CustomTypes['inputPorts']>;
|
|
21
|
-
event: CustomTypes['inputEvents'] extends {
|
|
22
|
-
[key: string]: EventValue | null;
|
|
23
|
-
} ? EventKeyValue<CustomTypes['inputEvents']> : Record<string, never>;
|
|
24
|
-
}
|
|
25
|
-
export declare type TimerState = Omit<Extract<CogsClientMessage, {
|
|
26
|
-
type: 'adjustable_timer_update';
|
|
27
|
-
}>, 'type'> & {
|
|
28
|
-
startedAt: number;
|
|
29
|
-
};
|
|
30
|
-
export default class CogsConnection<CustomTypes extends {
|
|
31
|
-
config?: {
|
|
32
|
-
[configKey: string]: ConfigValue;
|
|
33
|
-
};
|
|
34
|
-
inputPorts?: {
|
|
35
|
-
[port: string]: PortValue;
|
|
36
|
-
};
|
|
37
|
-
outputPorts?: {
|
|
38
|
-
[port: string]: PortValue;
|
|
39
|
-
};
|
|
40
|
-
inputEvents?: {
|
|
41
|
-
[key: string]: EventValue | null;
|
|
42
|
-
};
|
|
43
|
-
outputEvents?: {
|
|
44
|
-
[key: string]: EventValue | null;
|
|
45
|
-
};
|
|
46
|
-
} = Record<never, never>> {
|
|
5
|
+
import { PluginManifestEventJson } from './types/PluginManifestJson';
|
|
6
|
+
import * as ManifestTypes from './types/ManifestTypes';
|
|
7
|
+
import { DeepReadonly } from './types/utils';
|
|
8
|
+
export default class CogsConnection<Manifest extends ManifestTypes.PluginManifest> {
|
|
9
|
+
readonly manifest: Manifest;
|
|
47
10
|
private websocket;
|
|
48
11
|
private eventTarget;
|
|
49
12
|
private currentConfig;
|
|
50
|
-
get config():
|
|
51
|
-
private
|
|
52
|
-
get
|
|
53
|
-
private currentOutputPortValues;
|
|
54
|
-
get outputPortValues(): CustomTypes['outputPorts'];
|
|
13
|
+
get config(): ManifestTypes.ConfigAsObject<Manifest>;
|
|
14
|
+
private currentState;
|
|
15
|
+
get state(): ManifestTypes.StateAsObject<Manifest>;
|
|
55
16
|
private _showPhase;
|
|
56
17
|
get showPhase(): ShowPhase;
|
|
57
18
|
private _timerState;
|
|
@@ -62,14 +23,18 @@ export default class CogsConnection<CustomTypes extends {
|
|
|
62
23
|
private audioOutputs;
|
|
63
24
|
private _selectedAudioOutput;
|
|
64
25
|
get selectedAudioOutput(): string;
|
|
65
|
-
constructor({ hostname, port }?: {
|
|
26
|
+
constructor(manifest: Manifest, { hostname, port }?: {
|
|
66
27
|
hostname?: string;
|
|
67
28
|
port?: number;
|
|
68
|
-
},
|
|
29
|
+
}, initialClientState?: Partial<ManifestTypes.StateAsObject<Manifest, {
|
|
30
|
+
writableFromClient: true;
|
|
31
|
+
}>> | undefined);
|
|
69
32
|
get isConnected(): boolean;
|
|
70
33
|
close(): void;
|
|
71
|
-
sendEvent<EventName extends
|
|
72
|
-
|
|
34
|
+
sendEvent<EventName extends ManifestTypes.EventToCogsKey<Manifest>>(eventName: EventName, ...[eventValue]: ManifestTypes.EventToCogsAsObject<Manifest>[EventName] extends undefined ? [] : [ManifestTypes.EventToCogsAsObject<Manifest>[EventName]]): void;
|
|
35
|
+
setState(values: Partial<ManifestTypes.StateAsObject<Manifest, {
|
|
36
|
+
writableFromClient: true;
|
|
37
|
+
}>>): void;
|
|
73
38
|
getAudioSinkId(audioOutput: string): string | undefined;
|
|
74
39
|
sendInitialMediaClipStates(allMediaClipStates: AllMediaClipStatesMessage): void;
|
|
75
40
|
sendMediaClipState(mediaClipState: MediaClipStateMessage): void;
|
|
@@ -80,8 +45,50 @@ export default class CogsConnection<CustomTypes extends {
|
|
|
80
45
|
* This is only relevant for plugins, not for Media Master content.
|
|
81
46
|
*/
|
|
82
47
|
setPluginWindowVisible(visible: boolean): void;
|
|
83
|
-
addEventListener<
|
|
84
|
-
|
|
48
|
+
addEventListener<EventType extends CogsConnectionEvent<Manifest>['type']>(type: EventType, listener: (event: CogsConnectionEvent<Manifest> & {
|
|
49
|
+
type: EventType;
|
|
50
|
+
}) => void, options?: boolean | AddEventListenerOptions): void;
|
|
51
|
+
removeEventListener<EventType extends CogsConnectionEvent<Manifest>['type']>(type: EventType, listener: (event: Extract<CogsConnectionEvent<Manifest>, {
|
|
52
|
+
type: EventType;
|
|
53
|
+
}>) => void, options?: boolean | EventListenerOptions): void;
|
|
85
54
|
private dispatchEvent;
|
|
86
55
|
}
|
|
87
|
-
export {
|
|
56
|
+
export type TimerState = Omit<Extract<CogsClientMessage, {
|
|
57
|
+
type: 'adjustable_timer_update';
|
|
58
|
+
}>, 'type'> & {
|
|
59
|
+
startedAt: number;
|
|
60
|
+
};
|
|
61
|
+
export declare class CogsConnectionOpenEvent extends Event {
|
|
62
|
+
readonly type = "open";
|
|
63
|
+
constructor();
|
|
64
|
+
}
|
|
65
|
+
export declare class CogsConnectionCloseEvent extends Event {
|
|
66
|
+
readonly type = "close";
|
|
67
|
+
constructor();
|
|
68
|
+
}
|
|
69
|
+
export declare class CogsMessageEvent extends Event {
|
|
70
|
+
readonly message: CogsClientMessage;
|
|
71
|
+
readonly type = "message";
|
|
72
|
+
constructor(message: CogsClientMessage);
|
|
73
|
+
}
|
|
74
|
+
export declare class CogsConfigChangedEvent<CogsConfig> extends Event {
|
|
75
|
+
readonly config: CogsConfig;
|
|
76
|
+
readonly type = "config";
|
|
77
|
+
constructor(config: CogsConfig);
|
|
78
|
+
}
|
|
79
|
+
export declare class CogsStateChangedEvent<CogsState> extends Event {
|
|
80
|
+
readonly state: CogsState;
|
|
81
|
+
readonly type = "state";
|
|
82
|
+
constructor(state: CogsState);
|
|
83
|
+
}
|
|
84
|
+
export declare class CogsIncomingEvent<CogsEvent extends DeepReadonly<PluginManifestEventJson> | PluginManifestEventJson> extends Event {
|
|
85
|
+
readonly name: CogsEvent['name'];
|
|
86
|
+
readonly value: ManifestTypes.TypeFromCogsValueType<CogsEvent['value']>;
|
|
87
|
+
readonly type = "event";
|
|
88
|
+
constructor(name: CogsEvent['name'], value: ManifestTypes.TypeFromCogsValueType<CogsEvent['value']>);
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Allows CogsIncomingEvent of each supported value type
|
|
92
|
+
*/
|
|
93
|
+
export type CogsIncomingEventTypes<CogsEvent extends DeepReadonly<PluginManifestEventJson> | PluginManifestEventJson> = CogsEvent extends unknown ? CogsIncomingEvent<CogsEvent> : never;
|
|
94
|
+
export type CogsConnectionEvent<Manifest extends ManifestTypes.PluginManifest> = CogsConnectionOpenEvent | CogsConnectionCloseEvent | CogsMessageEvent | CogsConfigChangedEvent<ManifestTypes.ConfigAsObject<Manifest>> | CogsStateChangedEvent<Partial<ManifestTypes.StateAsObject<Manifest>>> | CogsIncomingEventTypes<ManifestTypes.EventsFromCogs<Manifest>>;
|