(
options: InjectAudioRecorderOptions<
(recording: AudioRecording) => unknown
> = {},
)
| 53 | options?: InjectAudioRecorderOptions<undefined>, |
| 54 | ): InjectAudioRecorderResult<AudioRecording> |
| 55 | export function injectAudioRecorder( |
| 56 | options: InjectAudioRecorderOptions< |
| 57 | (recording: AudioRecording) => unknown |
| 58 | > = {}, |
| 59 | ): InjectAudioRecorderResult<unknown> { |
| 60 | assertInInjectionContext(injectAudioRecorder) |
| 61 | const destroyRef = inject(DestroyRef) |
| 62 | const recorder = new AudioRecorder({ |
| 63 | ...(options.audio !== undefined && { audio: options.audio }), |
| 64 | ...(options.mimeType !== undefined && { mimeType: options.mimeType }), |
| 65 | ...(options.onError !== undefined && { onError: options.onError }), |
| 66 | }) |
| 67 | const isRecording = signal(false) |
| 68 | const recording = signal<unknown>(null) |
| 69 | |
| 70 | const unsubscribe = recorder.subscribe((state) => { |
| 71 | isRecording.set(state === 'recording') |
| 72 | }) |
| 73 | destroyRef.onDestroy(() => { |
| 74 | unsubscribe() |
| 75 | recorder.cancel() |
| 76 | }) |
| 77 | |
| 78 | const stop = async (): Promise<unknown> => { |
| 79 | const rawRecording = await recorder.stop() |
| 80 | const transformed = await options.onComplete?.(rawRecording) |
| 81 | // Only `undefined` (returning nothing) keeps the raw recording; a returned |
| 82 | // null is a real value, matching the inferred output type. |
| 83 | const output = transformed === undefined ? rawRecording : transformed |
| 84 | recording.set(output) |
| 85 | return output |
| 86 | } |
| 87 | |
| 88 | return { |
| 89 | recording: recording.asReadonly(), |
| 90 | isRecording: isRecording.asReadonly(), |
| 91 | isSupported: AudioRecorder.isSupported(), |
| 92 | start: () => recorder.start(), |
| 93 | stop, |
| 94 | cancel: () => recorder.cancel(), |
| 95 | } |
| 96 | } |
no test coverage detected