@flighthq/media 0.3.0-next.906.07cea63 → 0.3.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.
@@ -1,4 +1,4 @@
1
- import type { AudioBus, AudioBusOptions, AudioChannel, AudioMixer, AudioMixerOptions } from '@flighthq/types/contract';
1
+ import type { AudioBus, AudioBusMixerGuard, AudioBusOptions, AudioChannel, AudioMixer, AudioMixerOptions } from '@flighthq/types/contract';
2
2
  export declare function addAudioBusToMixer(mixer: Readonly<AudioMixer>, bus: AudioBus): void;
3
3
  export declare function createAudioBus(options?: Readonly<AudioBusOptions>): AudioBus;
4
4
  export declare function createAudioMixer(context: AudioContext, options?: Readonly<AudioMixerOptions>): AudioMixer;
@@ -9,6 +9,7 @@ export declare function pauseAllAudioMixerChannels(mixer: Readonly<AudioMixer>):
9
9
  export declare function resumeAllAudioMixerChannels(mixer: Readonly<AudioMixer>): void;
10
10
  export declare function routeAudioChannelToMixerBus(mixer: Readonly<AudioMixer>, channel: AudioChannel, bus: AudioBus): void;
11
11
  export declare function setAudioBusGain(bus: AudioBus, value: number): number;
12
+ export declare function setAudioBusMixerGuard(guard: AudioBusMixerGuard | null): void;
12
13
  export declare function setAudioBusMuted(bus: AudioBus, muted: boolean): boolean;
13
14
  export declare function setAudioBusPan(bus: AudioBus, value: number): number;
14
15
  export declare function setAudioMixerMasterGain(mixer: AudioMixer, value: number): number;
@@ -1 +1 @@
1
- {"version":3,"file":"audioMixer.d.ts","sourceRoot":"","sources":["../src/audioMixer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,eAAe,EAAE,YAAY,EAAE,UAAU,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAIvH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,QAAQ,CAAC,UAAU,CAAC,EAAE,GAAG,EAAE,QAAQ,GAAG,IAAI,CAmBnF;AAED,wBAAgB,cAAc,CAAC,OAAO,CAAC,EAAE,QAAQ,CAAC,eAAe,CAAC,GAAG,QAAQ,CAO5E;AAED,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,YAAY,EAAE,OAAO,CAAC,EAAE,QAAQ,CAAC,iBAAiB,CAAC,GAAG,UAAU,CAkBzG;AAED,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,QAAQ,CAAC,UAAU,CAAC,GAAG,IAAI,CAenE;AAED,wBAAgB,gBAAgB,CAC9B,KAAK,EAAE,QAAQ,CAAC,UAAU,CAAC,EAC3B,GAAG,EAAE,QAAQ,EACb,UAAU,EAAE,MAAM,EAClB,UAAU,EAAE,MAAM,GACjB,IAAI,CAYN;AAED,wBAAgB,2BAA2B,CAAC,KAAK,EAAE,QAAQ,CAAC,UAAU,CAAC,GAAG,SAAS,YAAY,EAAE,CAIhG;AAED,wBAAgB,0BAA0B,CAAC,KAAK,EAAE,QAAQ,CAAC,UAAU,CAAC,GAAG,IAAI,CAO5E;AAED,wBAAgB,2BAA2B,CAAC,KAAK,EAAE,QAAQ,CAAC,UAAU,CAAC,GAAG,IAAI,CAQ7E;AAED,wBAAgB,2BAA2B,CAAC,KAAK,EAAE,QAAQ,CAAC,UAAU,CAAC,EAAE,OAAO,EAAE,YAAY,EAAE,GAAG,EAAE,QAAQ,GAAG,IAAI,CAYnH;AAED,wBAAgB,eAAe,CAAC,GAAG,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAQpE;AAED,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,QAAQ,EAAE,KAAK,EAAE,OAAO,GAAG,OAAO,CAIvE;AAED,wBAAgB,cAAc,CAAC,GAAG,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAInE;AAED,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAOhF;AAED,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,UAAU,EAAE,KAAK,EAAE,OAAO,GAAG,OAAO,CAOnF;AAED,wBAAgB,yBAAyB,CAAC,KAAK,EAAE,QAAQ,CAAC,UAAU,CAAC,GAAG,IAAI,CAQ3E;AAED,wBAAgB,+BAA+B,CAAC,KAAK,EAAE,QAAQ,CAAC,UAAU,CAAC,EAAE,OAAO,EAAE,YAAY,GAAG,IAAI,CAOxG"}
1
+ {"version":3,"file":"audioMixer.d.ts","sourceRoot":"","sources":["../src/audioMixer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,QAAQ,EACR,kBAAkB,EAElB,eAAe,EACf,YAAY,EACZ,UAAU,EACV,iBAAiB,EAClB,MAAM,0BAA0B,CAAC;AAIlC,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,QAAQ,CAAC,UAAU,CAAC,EAAE,GAAG,EAAE,QAAQ,GAAG,IAAI,CAmBnF;AAED,wBAAgB,cAAc,CAAC,OAAO,CAAC,EAAE,QAAQ,CAAC,eAAe,CAAC,GAAG,QAAQ,CAO5E;AAED,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,YAAY,EAAE,OAAO,CAAC,EAAE,QAAQ,CAAC,iBAAiB,CAAC,GAAG,UAAU,CAmBzG;AAED,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,QAAQ,CAAC,UAAU,CAAC,GAAG,IAAI,CAenE;AAED,wBAAgB,gBAAgB,CAC9B,KAAK,EAAE,QAAQ,CAAC,UAAU,CAAC,EAC3B,GAAG,EAAE,QAAQ,EACb,UAAU,EAAE,MAAM,EAClB,UAAU,EAAE,MAAM,GACjB,IAAI,CAYN;AAED,wBAAgB,2BAA2B,CAAC,KAAK,EAAE,QAAQ,CAAC,UAAU,CAAC,GAAG,SAAS,YAAY,EAAE,CAIhG;AAED,wBAAgB,0BAA0B,CAAC,KAAK,EAAE,QAAQ,CAAC,UAAU,CAAC,GAAG,IAAI,CAU5E;AAED,wBAAgB,2BAA2B,CAAC,KAAK,EAAE,QAAQ,CAAC,UAAU,CAAC,GAAG,IAAI,CAY7E;AAED,wBAAgB,2BAA2B,CAAC,KAAK,EAAE,QAAQ,CAAC,UAAU,CAAC,EAAE,OAAO,EAAE,YAAY,EAAE,GAAG,EAAE,QAAQ,GAAG,IAAI,CAYnH;AASD,wBAAgB,eAAe,CAAC,GAAG,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAKpE;AAMD,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,kBAAkB,GAAG,IAAI,GAAG,IAAI,CAE5E;AAGD,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,QAAQ,EAAE,KAAK,EAAE,OAAO,GAAG,OAAO,CAKvE;AAGD,wBAAgB,cAAc,CAAC,GAAG,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAKnE;AAED,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAOhF;AAED,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,UAAU,EAAE,KAAK,EAAE,OAAO,GAAG,OAAO,CAOnF;AAED,wBAAgB,yBAAyB,CAAC,KAAK,EAAE,QAAQ,CAAC,UAAU,CAAC,GAAG,IAAI,CAY3E;AA4CD,wBAAgB,+BAA+B,CAAC,KAAK,EAAE,QAAQ,CAAC,UAAU,CAAC,EAAE,OAAO,EAAE,YAAY,GAAG,IAAI,CAQxG"}
@@ -41,6 +41,7 @@ export function createAudioMixer(context, options) {
41
41
  };
42
42
  mixerRuntimes.set(mixer, {
43
43
  activeChannels: new Set(),
44
+ channelsPausedByMixer: new Set(),
44
45
  buses: new Map(),
45
46
  busGainNodes: new Map(),
46
47
  busOutputNodes: new Map(),
@@ -94,22 +95,29 @@ export function pauseAllAudioMixerChannels(mixer) {
94
95
  const runtime = mixerRuntimes.get(mixer);
95
96
  if (runtime === undefined)
96
97
  return;
97
- // Actually stop each source node (not just flip the flag) so audio halts on pause.
98
+ // Actually stop each source node (not just flip the flag) so audio halts on pause. Only channels
99
+ // that were playing are recorded: one already paused by the caller is not this mixer's to resume.
98
100
  for (const channel of runtime.activeChannels) {
99
- if (channel.state === 'playing')
100
- pauseAudioChannel(channel);
101
+ if (channel.state !== 'playing')
102
+ continue;
103
+ pauseAudioChannel(channel);
104
+ runtime.channelsPausedByMixer.add(channel);
101
105
  }
102
106
  }
103
107
  export function resumeAllAudioMixerChannels(mixer) {
104
108
  const runtime = mixerRuntimes.get(mixer);
105
109
  if (runtime === undefined)
106
110
  return;
107
- // Restart the source node for channels this mixer paused; bus routing survives the restart
108
- // because the channel's destination node is preserved across stop/start.
109
- for (const channel of runtime.activeChannels) {
111
+ // Restart the source node for channels this mixer paused; bus routing survives the restart because
112
+ // the channel's destination node is preserved across stop/start. Resuming every paused channel
113
+ // instead would resurrect one the caller had deliberately paused on its own — a mixer-wide pause and
114
+ // resume around a menu would silently un-pause it. The state re-check covers a channel resumed or
115
+ // stopped individually while the mixer was paused.
116
+ for (const channel of runtime.channelsPausedByMixer) {
110
117
  if (channel.state === 'paused')
111
118
  resumeAudioChannel(channel);
112
119
  }
120
+ runtime.channelsPausedByMixer.clear();
113
121
  }
114
122
  export function routeAudioChannelToMixerBus(mixer, channel, bus) {
115
123
  const runtime = mixerRuntimes.get(mixer);
@@ -125,22 +133,37 @@ export function routeAudioChannelToMixerBus(mixer, channel, bus) {
125
133
  connectAudioChannelToNode(channel, busGainNode);
126
134
  }
127
135
  }
136
+ // Sets the bus gain and pushes it to the gain node of every mixer holding this bus, found by reverse
137
+ // lookup through busToMixerRuntimes.
138
+ //
139
+ // A bus that belongs to NO mixer has no node to push to, so the new value is stored and returned while
140
+ // nothing becomes audible. That is a silent no-op the return value cannot express — it reports the value
141
+ // that was set, not whether anything is listening — so it routes through the guard seam instead of relying
142
+ // on a comment telling callers to add the bus first.
128
143
  export function setAudioBusGain(bus, value) {
129
144
  bus.gain = value;
130
- // Update the bus gain node for all mixers that contain this bus.
131
- // Since we store gain nodes per-bus inside each mixer runtime, iterate the known runtimes.
132
- // The caller must have already added the bus to a mixer via addAudioBusToMixer or routeAudioChannelToMixerBus.
133
- // We use a reverse lookup via busGainNodes — walk active mixers via the busGainNodes map on each runtime.
145
+ reportUnmixedBus(bus, 'gain');
134
146
  updateBusGainNode(bus);
135
147
  return bus.gain;
136
148
  }
149
+ // The diagnostics seam for a bus-property write that cannot reach any audio node, not the caller-facing
150
+ // entry point — use enableAudioMixerGuards, which installs the @flighthq/log reporter through here. Null
151
+ // uninstalls it, and a null slot is the production default: the reverse-map lookup that detects the case
152
+ // runs only while a guard is installed.
153
+ export function setAudioBusMixerGuard(guard) {
154
+ _unmixedBusGuard = guard;
155
+ }
156
+ // Same unmixed-bus caveat as setAudioBusGain: muting a bus no mixer holds changes nothing audible.
137
157
  export function setAudioBusMuted(bus, muted) {
138
158
  bus.muted = muted;
159
+ reportUnmixedBus(bus, 'mute');
139
160
  updateBusGainNode(bus);
140
161
  return bus.muted;
141
162
  }
163
+ // Same unmixed-bus caveat as setAudioBusGain: panning a bus no mixer holds changes nothing audible.
142
164
  export function setAudioBusPan(bus, value) {
143
165
  bus.pan = clamp(value, -1, 1);
166
+ reportUnmixedBus(bus, 'pan');
144
167
  updateBusPannerNode(bus);
145
168
  return bus.pan;
146
169
  }
@@ -169,15 +192,10 @@ export function stopAllAudioMixerChannels(mixer) {
169
192
  channel.currentTime = 0;
170
193
  }
171
194
  runtime.activeChannels.clear();
172
- }
173
- export function unrouteAudioChannelFromMixerBus(mixer, channel) {
174
- const runtime = mixerRuntimes.get(mixer);
175
- if (runtime === undefined)
176
- return;
177
- runtime.activeChannels.delete(channel);
178
- runtime.channelToBus.delete(channel);
179
- // Reconnect the channel output to the context destination so it keeps playing if still active.
180
- connectAudioChannelToNode(channel, runtime.context.destination);
195
+ // Bookkeeping, not a behavioural guard: resume already re-checks that a channel is still paused, so
196
+ // a stopped channel would be skipped anyway. Clearing keeps the record from retaining channels the
197
+ // mixer no longer owns for the rest of its life.
198
+ runtime.channelsPausedByMixer.clear();
181
199
  }
182
200
  const mixerRuntimes = new WeakMap();
183
201
  // Reverse map from AudioBus to all mixer runtimes that contain it.
@@ -205,6 +223,25 @@ function unregisterBusFromReverseMap(bus, runtime) {
205
223
  if (runtimes.size === 0)
206
224
  busToMixerRuntimes.delete(bus);
207
225
  }
226
+ export function unrouteAudioChannelFromMixerBus(mixer, channel) {
227
+ const runtime = mixerRuntimes.get(mixer);
228
+ if (runtime === undefined)
229
+ return;
230
+ runtime.activeChannels.delete(channel);
231
+ runtime.channelsPausedByMixer.delete(channel);
232
+ runtime.channelToBus.delete(channel);
233
+ // Reconnect the channel output to the context destination so it keeps playing if still active.
234
+ connectAudioChannelToNode(channel, runtime.context.destination);
235
+ }
236
+ // Reports a write to a bus that belongs to no mixer. Cheap by construction — the Map lookup happens only
237
+ // when a guard is installed.
238
+ function reportUnmixedBus(bus, operation) {
239
+ if (_unmixedBusGuard === null)
240
+ return;
241
+ if (busToMixerRuntimes.get(bus) === undefined)
242
+ _unmixedBusGuard(operation, bus);
243
+ }
244
+ let _unmixedBusGuard = null;
208
245
  function updateBusGainNode(bus) {
209
246
  const runtimes = busToMixerRuntimes.get(bus);
210
247
  if (runtimes === undefined)
@@ -1 +1 @@
1
- {"version":3,"file":"audioMixer.js","sourceRoot":"","sources":["../src/audioMixer.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"audioMixer.js","sourceRoot":"","sources":["../src/audioMixer.ts"],"names":[],"mappings":"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"}
@@ -1,4 +1,5 @@
1
1
  export * from './audioChannel';
2
2
  export * from './audioMixer';
3
+ export * from './enableAudioMixerGuards';
3
4
  export * from './videoChannel';
4
5
  //# sourceMappingURL=contract.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"contract.d.ts","sourceRoot":"","sources":["../src/contract.ts"],"names":[],"mappings":"AAAA,cAAc,gBAAgB,CAAC;AAC/B,cAAc,cAAc,CAAC;AAC7B,cAAc,gBAAgB,CAAC"}
1
+ {"version":3,"file":"contract.d.ts","sourceRoot":"","sources":["../src/contract.ts"],"names":[],"mappings":"AAAA,cAAc,gBAAgB,CAAC;AAC/B,cAAc,cAAc,CAAC;AAC7B,cAAc,0BAA0B,CAAC;AACzC,cAAc,gBAAgB,CAAC"}
package/dist/contract.js CHANGED
@@ -1,4 +1,5 @@
1
1
  export * from './audioChannel';
2
2
  export * from './audioMixer';
3
+ export * from './enableAudioMixerGuards';
3
4
  export * from './videoChannel';
4
5
  //# sourceMappingURL=contract.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"contract.js","sourceRoot":"","sources":["../src/contract.ts"],"names":[],"mappings":"AAAA,cAAc,gBAAgB,CAAC;AAC/B,cAAc,cAAc,CAAC;AAC7B,cAAc,gBAAgB,CAAC"}
1
+ {"version":3,"file":"contract.js","sourceRoot":"","sources":["../src/contract.ts"],"names":[],"mappings":"AAAA,cAAc,gBAAgB,CAAC;AAC/B,cAAc,cAAc,CAAC;AAC7B,cAAc,0BAA0B,CAAC;AACzC,cAAc,gBAAgB,CAAC"}
@@ -0,0 +1,3 @@
1
+ export declare function disableAudioMixerGuards(): void;
2
+ export declare function enableAudioMixerGuards(): void;
3
+ //# sourceMappingURL=enableAudioMixerGuards.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"enableAudioMixerGuards.d.ts","sourceRoot":"","sources":["../src/enableAudioMixerGuards.ts"],"names":[],"mappings":"AAOA,wBAAgB,uBAAuB,IAAI,IAAI,CAE9C;AAYD,wBAAgB,sBAAsB,IAAI,IAAI,CAE7C"}
@@ -0,0 +1,27 @@
1
+ import { logOnce } from '@flighthq/log/contract';
2
+ import { LogLevel } from '@flighthq/types/contract';
3
+ import { setAudioBusMixerGuard } from './audioMixer';
4
+ // Uninstalls the guard installed by enableAudioMixerGuards.
5
+ export function disableAudioMixerGuards() {
6
+ setAudioBusMixerGuard(null);
7
+ }
8
+ // Installs the caller-facing audio-mixer guard (opt-in, dev-only). setAudioBusGain, setAudioBusMuted and
9
+ // setAudioBusPan all write the bus field, return it, and push the value to the gain/panner node of every
10
+ // mixer holding that bus — but a bus belonging to NO mixer has no node to push to. The write is stored,
11
+ // the setter returns the value it just set, and nothing becomes audible. Nothing throws and the return
12
+ // value cannot express the difference, because it reports what was set rather than whether anything is
13
+ // listening, so "my gain change did nothing" is otherwise a silent debugging session.
14
+ //
15
+ // The guard warns once per operation through @flighthq/log. Not importing this module costs production
16
+ // nothing: the message text and the @flighthq/log dependency live only here, and the reverse-map lookup
17
+ // that detects the case runs only while the guard is installed. Idempotent.
18
+ export function enableAudioMixerGuards() {
19
+ setAudioBusMixerGuard(warnOnUnmixedBus);
20
+ }
21
+ function warnOnUnmixedBus(operation, bus) {
22
+ const setter = operation === 'gain' ? 'setAudioBusGain' : operation === 'mute' ? 'setAudioBusMuted' : 'setAudioBusPan';
23
+ logOnce(`media:unmixed-bus-${operation}`, LogLevel.Warn, {
24
+ message: `${setter}: bus "${bus.name ?? 'unnamed'}" belongs to no mixer, so the value was stored but reached no audio node and nothing changed audibly. Add the bus with addAudioBusToMixer(mixer, bus) — or route a channel through it with routeAudioChannelToMixerBus — before setting its properties.`,
25
+ }, 'media');
26
+ }
27
+ //# sourceMappingURL=enableAudioMixerGuards.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"enableAudioMixerGuards.js","sourceRoot":"","sources":["../src/enableAudioMixerGuards.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,wBAAwB,CAAC;AAEjD,OAAO,EAAE,QAAQ,EAAE,MAAM,0BAA0B,CAAC;AAEpD,OAAO,EAAE,qBAAqB,EAAE,MAAM,cAAc,CAAC;AAErD,4DAA4D;AAC5D,MAAM,UAAU,uBAAuB;IACrC,qBAAqB,CAAC,IAAI,CAAC,CAAC;AAC9B,CAAC;AAED,yGAAyG;AACzG,yGAAyG;AACzG,wGAAwG;AACxG,uGAAuG;AACvG,uGAAuG;AACvG,sFAAsF;AACtF,EAAE;AACF,uGAAuG;AACvG,wGAAwG;AACxG,4EAA4E;AAC5E,MAAM,UAAU,sBAAsB;IACpC,qBAAqB,CAAC,gBAAgB,CAAC,CAAC;AAC1C,CAAC;AAED,SAAS,gBAAgB,CAAC,SAAiC,EAAE,GAAuB;IAClF,MAAM,MAAM,GACV,SAAS,KAAK,MAAM,CAAC,CAAC,CAAC,iBAAiB,CAAC,CAAC,CAAC,SAAS,KAAK,MAAM,CAAC,CAAC,CAAC,kBAAkB,CAAC,CAAC,CAAC,gBAAgB,CAAC;IAC1G,OAAO,CACL,qBAAqB,SAAS,EAAE,EAChC,QAAQ,CAAC,IAAI,EACb;QACE,OAAO,EAAE,GAAG,MAAM,UAAU,GAAG,CAAC,IAAI,IAAI,SAAS,yPAAyP;KAC3S,EACD,OAAO,CACR,CAAC;AACJ,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,8 @@
1
1
  {
2
2
  "name": "@flighthq/media",
3
- "version": "0.3.0-next.906.07cea63",
3
+ "version": "0.3.0",
4
+ "author": "Joshua Granick and other contributors",
5
+ "license": "MIT",
4
6
  "repository": {
5
7
  "type": "git",
6
8
  "url": "https://github.com/flighthq/flight.git",
@@ -36,10 +38,11 @@
36
38
  "clean:dist": "tsx ../../scripts/clean-package-dist.ts"
37
39
  },
38
40
  "dependencies": {
39
- "@flighthq/audio": "0.3.0-next.906.07cea63",
40
- "@flighthq/video": "0.3.0-next.906.07cea63",
41
- "@flighthq/signals": "0.3.0-next.906.07cea63",
42
- "@flighthq/types": "0.3.0-next.906.07cea63"
41
+ "@flighthq/audio": "0.3.0",
42
+ "@flighthq/log": "0.3.0",
43
+ "@flighthq/signals": "0.3.0",
44
+ "@flighthq/types": "0.3.0",
45
+ "@flighthq/video": "0.3.0"
43
46
  },
44
47
  "devDependencies": {
45
48
  "typescript": "^5.3.0"
@@ -1,6 +1,6 @@
1
1
  import { createAudioResource } from '@flighthq/audio/contract';
2
2
 
3
- import { playAudioResource } from './audioChannel';
3
+ import { pauseAudioChannel, playAudioResource } from './audioChannel';
4
4
  import {
5
5
  addAudioBusToMixer,
6
6
  createAudioBus,
@@ -12,6 +12,7 @@ import {
12
12
  resumeAllAudioMixerChannels,
13
13
  routeAudioChannelToMixerBus,
14
14
  setAudioBusGain,
15
+ setAudioBusMixerGuard,
15
16
  setAudioBusMuted,
16
17
  setAudioBusPan,
17
18
  setAudioMixerMasterGain,
@@ -203,6 +204,84 @@ describe('resumeAllAudioMixerChannels', () => {
203
204
  });
204
205
  });
205
206
 
207
+ describe('resumeAllAudioMixerChannels scope', () => {
208
+ function playRouted(mixer: ReturnType<typeof createAudioMixer>, bus: ReturnType<typeof createAudioBus>) {
209
+ const channel = playAudioResource(ctx, createAudioResource(createMockAudioBuffer()))!;
210
+ routeAudioChannelToMixerBus(mixer, channel, bus);
211
+ return channel;
212
+ }
213
+
214
+ function mixerWithBus() {
215
+ const mixer = createAudioMixer(ctx);
216
+ const bus = createAudioBus({ name: 'sfx' });
217
+ addAudioBusToMixer(mixer, bus);
218
+ return { bus, mixer };
219
+ }
220
+
221
+ // A mixer-wide pause/resume around a menu must not resurrect a channel the caller had paused on its
222
+ // own. Resuming every paused channel — rather than the ones this mixer paused — silently did.
223
+ it('leaves a channel the caller paused independently still paused', () => {
224
+ const { bus, mixer } = mixerWithBus();
225
+ const mixerPaused = playRouted(mixer, bus);
226
+ const callerPaused = playRouted(mixer, bus);
227
+
228
+ pauseAudioChannel(callerPaused);
229
+ pauseAllAudioMixerChannels(mixer);
230
+ resumeAllAudioMixerChannels(mixer);
231
+
232
+ expect(mixerPaused.state).toBe('playing');
233
+ expect(callerPaused.state).toBe('paused');
234
+ });
235
+
236
+ it('resumes the channels it paused', () => {
237
+ const { bus, mixer } = mixerWithBus();
238
+ const channel = playRouted(mixer, bus);
239
+
240
+ pauseAllAudioMixerChannels(mixer);
241
+ expect(channel.state).toBe('paused');
242
+ resumeAllAudioMixerChannels(mixer);
243
+
244
+ expect(channel.state).toBe('playing');
245
+ });
246
+
247
+ // Each transition that takes a channel away from the mixer must also drop it from the paused-by-mixer
248
+ // record, or a later resume restarts something the mixer no longer owns.
249
+ it('does not resume a channel unrouted while the mixer was paused', () => {
250
+ const { bus, mixer } = mixerWithBus();
251
+ const channel = playRouted(mixer, bus);
252
+
253
+ pauseAllAudioMixerChannels(mixer);
254
+ unrouteAudioChannelFromMixerBus(mixer, channel);
255
+ resumeAllAudioMixerChannels(mixer);
256
+
257
+ expect(channel.state).toBe('paused');
258
+ });
259
+
260
+ it('does not resume a channel stopped while the mixer was paused', () => {
261
+ const { bus, mixer } = mixerWithBus();
262
+ const channel = playRouted(mixer, bus);
263
+
264
+ pauseAllAudioMixerChannels(mixer);
265
+ stopAllAudioMixerChannels(mixer);
266
+ resumeAllAudioMixerChannels(mixer);
267
+
268
+ expect(channel.state).toBe('stopped');
269
+ });
270
+
271
+ // The record is consumed by the resume, so a second resume has nothing of its own to restart.
272
+ it('does not re-resume on a second call after the caller paused again', () => {
273
+ const { bus, mixer } = mixerWithBus();
274
+ const channel = playRouted(mixer, bus);
275
+
276
+ pauseAllAudioMixerChannels(mixer);
277
+ resumeAllAudioMixerChannels(mixer);
278
+ pauseAudioChannel(channel);
279
+ resumeAllAudioMixerChannels(mixer);
280
+
281
+ expect(channel.state).toBe('paused');
282
+ });
283
+ });
284
+
206
285
  describe('routeAudioChannelToMixerBus', () => {
207
286
  it('adds the channel to the mixer active channels', () => {
208
287
  const mixer = createAudioMixer(ctx);
@@ -222,6 +301,43 @@ describe('setAudioBusGain', () => {
222
301
  });
223
302
  });
224
303
 
304
+ describe('setAudioBusMixerGuard', () => {
305
+ it('reports a bus-property write that reaches no mixer, for each setter', () => {
306
+ const seen: string[] = [];
307
+ setAudioBusMixerGuard((operation) => seen.push(operation));
308
+ try {
309
+ // A bus that was never added to a mixer: every setter stores its value and returns it, but no
310
+ // audio node exists to receive it.
311
+ const orphan = createAudioBus({ name: 'orphan' });
312
+ expect(setAudioBusGain(orphan, 0.25)).toBe(0.25);
313
+ setAudioBusMuted(orphan, true);
314
+ setAudioBusPan(orphan, -1);
315
+ } finally {
316
+ setAudioBusMixerGuard(null);
317
+ }
318
+ expect(seen).toEqual(['gain', 'mute', 'pan']);
319
+ });
320
+
321
+ it('stays silent for a bus that belongs to a mixer, and once uninstalled', () => {
322
+ const seen: string[] = [];
323
+ setAudioBusMixerGuard((operation) => seen.push(operation));
324
+ try {
325
+ const mixer = createAudioMixer(ctx);
326
+ const bus = createAudioBus({ name: 'music' });
327
+ addAudioBusToMixer(mixer, bus);
328
+ setAudioBusGain(bus, 0.5);
329
+ setAudioBusMuted(bus, true);
330
+ setAudioBusPan(bus, 0.5);
331
+ expect(seen).toEqual([]);
332
+ } finally {
333
+ setAudioBusMixerGuard(null);
334
+ }
335
+ // Uninstalled: the orphan write is still a silent no-op, but nothing is reported.
336
+ setAudioBusGain(createAudioBus({ name: 'orphan2' }), 0.75);
337
+ expect(seen).toEqual([]);
338
+ });
339
+ });
340
+
225
341
  describe('setAudioBusMuted', () => {
226
342
  it('mutes the bus', () => {
227
343
  const bus = createAudioBus();
@@ -0,0 +1,84 @@
1
+ import { addLogSink, createMemoryLogSink, getMemoryLogSinkEntries, removeLogSink } from '@flighthq/log/contract';
2
+ import type { LogEntry } from '@flighthq/types/contract';
3
+
4
+ import { addAudioBusToMixer, createAudioBus, createAudioMixer, setAudioBusGain } from './audioMixer';
5
+ import { disableAudioMixerGuards, enableAudioMixerGuards } from './enableAudioMixerGuards';
6
+
7
+ // The narrowest Web Audio stand-in a mixer + bus needs; the guard under test never touches audio itself.
8
+ class MockGainNode {
9
+ gain = { value: 1 };
10
+ connect(): void {}
11
+ disconnect(): void {}
12
+ }
13
+
14
+ class MockAudioContext {
15
+ currentTime = 0;
16
+ destination = {};
17
+ state = 'running';
18
+ createGain(): GainNode {
19
+ return new MockGainNode() as unknown as GainNode;
20
+ }
21
+ createStereoPanner(): StereoPannerNode {
22
+ return { connect() {}, disconnect() {}, pan: { value: 0 } } as unknown as StereoPannerNode;
23
+ }
24
+ }
25
+
26
+ const ctx = new MockAudioContext() as unknown as AudioContext;
27
+
28
+ function captureLog(run: () => void): readonly LogEntry[] {
29
+ const sink = createMemoryLogSink(8);
30
+ addLogSink(sink.sink);
31
+ try {
32
+ run();
33
+ return getMemoryLogSinkEntries(sink);
34
+ } finally {
35
+ removeLogSink(sink.sink);
36
+ }
37
+ }
38
+
39
+ function messageOf(entry: Readonly<LogEntry>): string {
40
+ const data = entry.data;
41
+ return typeof data === 'string' ? data : String(data.message);
42
+ }
43
+
44
+ describe('disableAudioMixerGuards', () => {
45
+ it('uninstalls the guard, returning the silent no-op to silence', () => {
46
+ const entries = captureLog(() => {
47
+ enableAudioMixerGuards();
48
+ disableAudioMixerGuards();
49
+ setAudioBusGain(createAudioBus({ name: 'orphan' }), 0.25);
50
+ });
51
+ expect(entries.length).toBe(0);
52
+ });
53
+ });
54
+
55
+ describe('enableAudioMixerGuards', () => {
56
+ it('WARNS that a gain change on an unmixed bus reached no audio node', () => {
57
+ const entries = captureLog(() => {
58
+ enableAudioMixerGuards();
59
+ try {
60
+ // Returns the value it set, which is exactly why the failure is invisible without the guard.
61
+ expect(setAudioBusGain(createAudioBus({ name: 'orphan' }), 0.25)).toBe(0.25);
62
+ } finally {
63
+ disableAudioMixerGuards();
64
+ }
65
+ });
66
+ expect(entries.length).toBe(1);
67
+ expect(messageOf(entries[0])).toContain('addAudioBusToMixer');
68
+ });
69
+
70
+ it('stays SILENT for a bus that belongs to a mixer', () => {
71
+ const entries = captureLog(() => {
72
+ enableAudioMixerGuards();
73
+ try {
74
+ const mixer = createAudioMixer(ctx);
75
+ const bus = createAudioBus({ name: 'music' });
76
+ addAudioBusToMixer(mixer, bus);
77
+ setAudioBusGain(bus, 0.5);
78
+ } finally {
79
+ disableAudioMixerGuards();
80
+ }
81
+ });
82
+ expect(entries.length).toBe(0);
83
+ });
84
+ });
@@ -44,7 +44,7 @@ describe('getVideoChannelHeight', () => {
44
44
  it('returns 0 when element is null', () => {
45
45
  const channel = playVideoResource(createVideoResource(createMockVideoElement()));
46
46
  expect(channel).not.toBeNull();
47
- channel!.source = { element: null };
47
+ channel!.source = { element: null, objectUrl: null };
48
48
  expect(getVideoChannelHeight(channel!)).toBe(0);
49
49
  });
50
50
  });
@@ -60,7 +60,7 @@ describe('getVideoChannelWidth', () => {
60
60
  it('returns 0 when element is null', () => {
61
61
  const channel = playVideoResource(createVideoResource(createMockVideoElement()));
62
62
  expect(channel).not.toBeNull();
63
- channel!.source = { element: null };
63
+ channel!.source = { element: null, objectUrl: null };
64
64
  expect(getVideoChannelWidth(channel!)).toBe(0);
65
65
  });
66
66
  });