@livekit/agents 1.0.46 → 1.0.47

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 (151) hide show
  1. package/dist/cli.cjs +14 -20
  2. package/dist/cli.cjs.map +1 -1
  3. package/dist/cli.d.ts.map +1 -1
  4. package/dist/cli.js +14 -20
  5. package/dist/cli.js.map +1 -1
  6. package/dist/ipc/job_proc_lazy_main.cjs +14 -5
  7. package/dist/ipc/job_proc_lazy_main.cjs.map +1 -1
  8. package/dist/ipc/job_proc_lazy_main.js +14 -5
  9. package/dist/ipc/job_proc_lazy_main.js.map +1 -1
  10. package/dist/llm/chat_context.cjs +19 -0
  11. package/dist/llm/chat_context.cjs.map +1 -1
  12. package/dist/llm/chat_context.d.cts +4 -0
  13. package/dist/llm/chat_context.d.ts +4 -0
  14. package/dist/llm/chat_context.d.ts.map +1 -1
  15. package/dist/llm/chat_context.js +19 -0
  16. package/dist/llm/chat_context.js.map +1 -1
  17. package/dist/llm/provider_format/index.cjs +2 -0
  18. package/dist/llm/provider_format/index.cjs.map +1 -1
  19. package/dist/llm/provider_format/index.d.cts +1 -1
  20. package/dist/llm/provider_format/index.d.ts +1 -1
  21. package/dist/llm/provider_format/index.d.ts.map +1 -1
  22. package/dist/llm/provider_format/index.js +6 -1
  23. package/dist/llm/provider_format/index.js.map +1 -1
  24. package/dist/llm/provider_format/openai.cjs +82 -2
  25. package/dist/llm/provider_format/openai.cjs.map +1 -1
  26. package/dist/llm/provider_format/openai.d.cts +1 -0
  27. package/dist/llm/provider_format/openai.d.ts +1 -0
  28. package/dist/llm/provider_format/openai.d.ts.map +1 -1
  29. package/dist/llm/provider_format/openai.js +80 -1
  30. package/dist/llm/provider_format/openai.js.map +1 -1
  31. package/dist/llm/provider_format/openai.test.cjs +326 -0
  32. package/dist/llm/provider_format/openai.test.cjs.map +1 -1
  33. package/dist/llm/provider_format/openai.test.js +327 -1
  34. package/dist/llm/provider_format/openai.test.js.map +1 -1
  35. package/dist/llm/provider_format/utils.cjs +4 -3
  36. package/dist/llm/provider_format/utils.cjs.map +1 -1
  37. package/dist/llm/provider_format/utils.d.ts.map +1 -1
  38. package/dist/llm/provider_format/utils.js +4 -3
  39. package/dist/llm/provider_format/utils.js.map +1 -1
  40. package/dist/llm/realtime.cjs.map +1 -1
  41. package/dist/llm/realtime.d.cts +1 -0
  42. package/dist/llm/realtime.d.ts +1 -0
  43. package/dist/llm/realtime.d.ts.map +1 -1
  44. package/dist/llm/realtime.js.map +1 -1
  45. package/dist/log.cjs +5 -2
  46. package/dist/log.cjs.map +1 -1
  47. package/dist/log.d.ts.map +1 -1
  48. package/dist/log.js +5 -2
  49. package/dist/log.js.map +1 -1
  50. package/dist/stream/deferred_stream.cjs +15 -6
  51. package/dist/stream/deferred_stream.cjs.map +1 -1
  52. package/dist/stream/deferred_stream.d.ts.map +1 -1
  53. package/dist/stream/deferred_stream.js +15 -6
  54. package/dist/stream/deferred_stream.js.map +1 -1
  55. package/dist/utils.cjs +31 -2
  56. package/dist/utils.cjs.map +1 -1
  57. package/dist/utils.d.cts +7 -0
  58. package/dist/utils.d.ts +7 -0
  59. package/dist/utils.d.ts.map +1 -1
  60. package/dist/utils.js +31 -2
  61. package/dist/utils.js.map +1 -1
  62. package/dist/utils.test.cjs +71 -0
  63. package/dist/utils.test.cjs.map +1 -1
  64. package/dist/utils.test.js +71 -0
  65. package/dist/utils.test.js.map +1 -1
  66. package/dist/version.cjs +1 -1
  67. package/dist/version.cjs.map +1 -1
  68. package/dist/version.d.cts +1 -1
  69. package/dist/version.d.ts +1 -1
  70. package/dist/version.d.ts.map +1 -1
  71. package/dist/version.js +1 -1
  72. package/dist/version.js.map +1 -1
  73. package/dist/voice/agent.cjs +144 -12
  74. package/dist/voice/agent.cjs.map +1 -1
  75. package/dist/voice/agent.d.cts +29 -4
  76. package/dist/voice/agent.d.ts +29 -4
  77. package/dist/voice/agent.d.ts.map +1 -1
  78. package/dist/voice/agent.js +140 -11
  79. package/dist/voice/agent.js.map +1 -1
  80. package/dist/voice/agent.test.cjs +120 -0
  81. package/dist/voice/agent.test.cjs.map +1 -1
  82. package/dist/voice/agent.test.js +122 -2
  83. package/dist/voice/agent.test.js.map +1 -1
  84. package/dist/voice/agent_activity.cjs +383 -298
  85. package/dist/voice/agent_activity.cjs.map +1 -1
  86. package/dist/voice/agent_activity.d.cts +34 -7
  87. package/dist/voice/agent_activity.d.ts +34 -7
  88. package/dist/voice/agent_activity.d.ts.map +1 -1
  89. package/dist/voice/agent_activity.js +383 -293
  90. package/dist/voice/agent_activity.js.map +1 -1
  91. package/dist/voice/agent_session.cjs +140 -40
  92. package/dist/voice/agent_session.cjs.map +1 -1
  93. package/dist/voice/agent_session.d.cts +19 -7
  94. package/dist/voice/agent_session.d.ts +19 -7
  95. package/dist/voice/agent_session.d.ts.map +1 -1
  96. package/dist/voice/agent_session.js +137 -37
  97. package/dist/voice/agent_session.js.map +1 -1
  98. package/dist/voice/audio_recognition.cjs +4 -0
  99. package/dist/voice/audio_recognition.cjs.map +1 -1
  100. package/dist/voice/audio_recognition.d.ts.map +1 -1
  101. package/dist/voice/audio_recognition.js +4 -0
  102. package/dist/voice/audio_recognition.js.map +1 -1
  103. package/dist/voice/generation.cjs +39 -19
  104. package/dist/voice/generation.cjs.map +1 -1
  105. package/dist/voice/generation.d.ts.map +1 -1
  106. package/dist/voice/generation.js +44 -20
  107. package/dist/voice/generation.js.map +1 -1
  108. package/dist/voice/index.cjs +2 -0
  109. package/dist/voice/index.cjs.map +1 -1
  110. package/dist/voice/index.d.cts +1 -1
  111. package/dist/voice/index.d.ts +1 -1
  112. package/dist/voice/index.d.ts.map +1 -1
  113. package/dist/voice/index.js +2 -1
  114. package/dist/voice/index.js.map +1 -1
  115. package/dist/voice/speech_handle.cjs +7 -1
  116. package/dist/voice/speech_handle.cjs.map +1 -1
  117. package/dist/voice/speech_handle.d.cts +2 -0
  118. package/dist/voice/speech_handle.d.ts +2 -0
  119. package/dist/voice/speech_handle.d.ts.map +1 -1
  120. package/dist/voice/speech_handle.js +8 -2
  121. package/dist/voice/speech_handle.js.map +1 -1
  122. package/dist/voice/testing/run_result.cjs +66 -15
  123. package/dist/voice/testing/run_result.cjs.map +1 -1
  124. package/dist/voice/testing/run_result.d.cts +14 -3
  125. package/dist/voice/testing/run_result.d.ts +14 -3
  126. package/dist/voice/testing/run_result.d.ts.map +1 -1
  127. package/dist/voice/testing/run_result.js +66 -15
  128. package/dist/voice/testing/run_result.js.map +1 -1
  129. package/package.json +1 -1
  130. package/src/cli.ts +20 -33
  131. package/src/ipc/job_proc_lazy_main.ts +16 -5
  132. package/src/llm/chat_context.ts +35 -0
  133. package/src/llm/provider_format/index.ts +7 -2
  134. package/src/llm/provider_format/openai.test.ts +385 -1
  135. package/src/llm/provider_format/openai.ts +103 -0
  136. package/src/llm/provider_format/utils.ts +6 -4
  137. package/src/llm/realtime.ts +1 -0
  138. package/src/log.ts +5 -2
  139. package/src/stream/deferred_stream.ts +17 -6
  140. package/src/utils.test.ts +87 -0
  141. package/src/utils.ts +36 -2
  142. package/src/version.ts +1 -1
  143. package/src/voice/agent.test.ts +140 -2
  144. package/src/voice/agent.ts +189 -10
  145. package/src/voice/agent_activity.ts +427 -289
  146. package/src/voice/agent_session.ts +178 -40
  147. package/src/voice/audio_recognition.ts +4 -0
  148. package/src/voice/generation.ts +52 -23
  149. package/src/voice/index.ts +1 -1
  150. package/src/voice/speech_handle.ts +9 -2
  151. package/src/voice/testing/run_result.ts +81 -23
package/dist/utils.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/utils.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2024 LiveKit, Inc.\n//\n// SPDX-License-Identifier: Apache-2.0\nimport type {\n ParticipantKind,\n RemoteParticipant,\n RemoteTrackPublication,\n Room,\n TrackKind,\n} from '@livekit/rtc-node';\nimport { AudioFrame, AudioResampler, RoomEvent } from '@livekit/rtc-node';\nimport { EventEmitter, once } from 'node:events';\nimport type { ReadableStream } from 'node:stream/web';\nimport { TransformStream, type TransformStreamDefaultController } from 'node:stream/web';\nimport { v4 as uuidv4 } from 'uuid';\nimport { log } from './log.js';\n\n/**\n * Recursively expands all nested properties of a type,\n * resolving aliases so as to inspect the real shape in IDE.\n */\n// eslint-disable-next-line @typescript-eslint/ban-types\nexport type Expand<T> = T extends Function\n ? T\n : T extends object\n ? T extends Array<infer U>\n ? Array<Expand<U>>\n : T extends Map<infer K, infer V>\n ? Map<Expand<K>, Expand<V>>\n : T extends Set<infer M>\n ? Set<Expand<M>>\n : { [K in keyof T]: Expand<T[K]> }\n : T;\n\n/** Union of a single and a list of {@link AudioFrame}s */\nexport type AudioBuffer = AudioFrame[] | AudioFrame;\n\nexport const noop = () => {};\n\nexport const isPending = async (promise: Promise<unknown>): Promise<boolean> => {\n const sentinel = Symbol('sentinel');\n const result = await Promise.race([promise, Promise.resolve(sentinel)]);\n return result === sentinel;\n};\n\n/**\n * Merge one or more {@link AudioFrame}s into a single one.\n *\n * @param buffer - Either an {@link AudioFrame} or a list thereof\n * @throws\n * {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypeError\n * | TypeError} if sample rate or channel count are mismatched\n */\nexport const mergeFrames = (buffer: AudioBuffer): AudioFrame => {\n if (Array.isArray(buffer)) {\n buffer = buffer as AudioFrame[];\n if (buffer.length == 0) {\n throw new TypeError('buffer is empty');\n }\n\n const sampleRate = buffer[0]!.sampleRate;\n const channels = buffer[0]!.channels;\n let samplesPerChannel = 0;\n let data = new Int16Array();\n\n for (const frame of buffer) {\n if (frame.sampleRate !== sampleRate) {\n throw new TypeError('sample rate mismatch');\n }\n\n if (frame.channels !== channels) {\n throw new TypeError('channel count mismatch');\n }\n\n data = new Int16Array([...data, ...frame.data]);\n samplesPerChannel += frame.samplesPerChannel;\n }\n\n return new AudioFrame(data, sampleRate, channels, samplesPerChannel);\n }\n\n return buffer;\n};\n\n/** @internal */\nexport class Queue<T> {\n /** @internal */\n items: T[] = [];\n #limit?: number;\n #events = new EventEmitter();\n\n constructor(limit?: number) {\n this.#limit = limit;\n }\n\n async get(): Promise<T> {\n const _get = async (): Promise<T> => {\n if (this.items.length === 0) {\n await once(this.#events, 'put');\n }\n let item = this.items.shift();\n if (!item) {\n item = await _get();\n }\n return item;\n };\n\n const item = _get();\n this.#events.emit('get');\n return item;\n }\n\n async put(item: T) {\n if (this.#limit && this.items.length >= this.#limit) {\n await once(this.#events, 'get');\n }\n this.items.push(item);\n this.#events.emit('put');\n }\n}\n\n/** @internal */\nexport class Future<T = void> {\n #await: Promise<T>;\n #resolvePromise!: (value: T) => void;\n #rejectPromise!: (error: Error) => void;\n #done: boolean = false;\n #rejected: boolean = false;\n #result: T | undefined = undefined;\n #error: Error | undefined = undefined;\n\n constructor() {\n this.#await = new Promise<T>((resolve, reject) => {\n this.#resolvePromise = resolve;\n this.#rejectPromise = reject;\n });\n }\n\n get await() {\n return this.#await;\n }\n\n get done() {\n return this.#done;\n }\n\n get result(): T {\n if (!this.#done) {\n throw new Error('Future is not done');\n }\n\n if (this.#rejected) {\n throw this.#error;\n }\n\n return this.#result!;\n }\n\n /** Whether the future was rejected (cancelled) */\n get rejected() {\n return this.#rejected;\n }\n\n resolve(value: T) {\n this.#done = true;\n this.#result = value;\n this.#resolvePromise(value);\n }\n\n reject(error: Error) {\n this.#done = true;\n this.#rejected = true;\n this.#error = error;\n this.#rejectPromise(error);\n }\n}\n\n/** @internal */\nexport class Event {\n #isSet = false;\n #waiters: Array<() => void> = [];\n\n async wait() {\n if (this.#isSet) return true;\n\n let resolve: () => void = noop;\n const waiter = new Promise<void>((r) => {\n resolve = r;\n this.#waiters.push(resolve);\n });\n\n try {\n await waiter;\n return true;\n } finally {\n const index = this.#waiters.indexOf(resolve);\n if (index !== -1) {\n this.#waiters.splice(index, 1);\n }\n }\n }\n\n get isSet(): boolean {\n return this.#isSet;\n }\n\n set(): void {\n if (this.#isSet) return;\n\n this.#isSet = true;\n this.#waiters.forEach((resolve) => resolve());\n this.#waiters = [];\n }\n\n clear(): void {\n this.#isSet = false;\n }\n}\n\n/** @internal */\nexport class CancellablePromise<T> {\n #promise: Promise<T>;\n #cancelFn: () => void;\n #isCancelled: boolean = false;\n #error: Error | null = null;\n\n constructor(\n executor: (\n resolve: (value: T | PromiseLike<T>) => void,\n reject: (reason?: unknown) => void,\n onCancel: (cancelFn: () => void) => void,\n ) => void,\n ) {\n let cancel: () => void;\n\n this.#promise = new Promise<T>((resolve, reject) => {\n executor(\n resolve,\n (reason) => {\n this.#error = reason instanceof Error ? reason : new Error(String(reason));\n reject(reason);\n },\n (cancelFn) => {\n cancel = () => {\n this.#isCancelled = true;\n cancelFn();\n };\n },\n );\n });\n\n this.#cancelFn = cancel!;\n }\n\n get isCancelled(): boolean {\n return this.#isCancelled;\n }\n\n get error(): Error | null {\n return this.#error;\n }\n\n then<TResult1 = T, TResult2 = never>(\n onfulfilled?: ((value: T) => TResult1 | Promise<TResult1>) | null,\n onrejected?: ((reason: unknown) => TResult2 | Promise<TResult2>) | null,\n ): Promise<TResult1 | TResult2> {\n return this.#promise.then(onfulfilled, onrejected);\n }\n\n catch<TResult = never>(\n onrejected?: ((reason: unknown) => TResult | Promise<TResult>) | null,\n ): Promise<T | TResult> {\n return this.#promise.catch(onrejected);\n }\n\n finally(onfinally?: (() => void) | null): Promise<T> {\n return this.#promise.finally(onfinally);\n }\n\n cancel(): void {\n this.#cancelFn();\n }\n\n static from<T>(promise: Promise<T>): CancellablePromise<T> {\n return new CancellablePromise<T>((resolve, reject) => {\n promise.then(resolve).catch(reject);\n });\n }\n}\n\n/** @internal */\nexport async function gracefullyCancel<T>(promise: CancellablePromise<T>): Promise<void> {\n if (!promise.isCancelled) {\n promise.cancel();\n }\n try {\n await promise;\n } catch (error) {\n // Ignore the error, as it's expected due to cancellation\n }\n}\n\n/** @internal */\nexport class AsyncIterableQueue<T> implements AsyncIterableIterator<T> {\n private static readonly CLOSE_SENTINEL = Symbol('CLOSE_SENTINEL');\n #queue = new Queue<T | typeof AsyncIterableQueue.CLOSE_SENTINEL>();\n #closed = false;\n\n get closed(): boolean {\n return this.#closed;\n }\n\n put(item: T): void {\n if (this.#closed) {\n throw new Error('Queue is closed');\n }\n this.#queue.put(item);\n }\n\n close(): void {\n this.#closed = true;\n this.#queue.put(AsyncIterableQueue.CLOSE_SENTINEL);\n }\n\n async next(): Promise<IteratorResult<T>> {\n if (this.#closed && this.#queue.items.length === 0) {\n return { value: undefined, done: true };\n }\n const item = await this.#queue.get();\n if (item === AsyncIterableQueue.CLOSE_SENTINEL && this.#closed) {\n return { value: undefined, done: true };\n }\n return { value: item as T, done: false };\n }\n\n [Symbol.asyncIterator](): AsyncIterableQueue<T> {\n return this;\n }\n}\n\n/** @internal */\nexport class ExpFilter {\n #alpha: number;\n #max?: number;\n #filtered?: number = undefined;\n\n constructor(alpha: number, max?: number) {\n this.#alpha = alpha;\n this.#max = max;\n }\n\n reset(alpha?: number) {\n if (alpha) {\n this.#alpha = alpha;\n }\n this.#filtered = undefined;\n }\n\n apply(exp: number, sample: number): number {\n if (this.#filtered) {\n const a = this.#alpha ** exp;\n this.#filtered = a * this.#filtered + (1 - a) * sample;\n } else {\n this.#filtered = sample;\n }\n\n if (this.#max && this.#filtered > this.#max) {\n this.#filtered = this.#max;\n }\n\n return this.#filtered;\n }\n\n get filtered(): number | undefined {\n return this.#filtered;\n }\n\n set alpha(alpha: number) {\n this.#alpha = alpha;\n }\n}\n\n/** @internal */\nexport class AudioEnergyFilter {\n #cooldownSeconds: number;\n #cooldown: number;\n\n constructor(cooldownSeconds = 1) {\n this.#cooldownSeconds = cooldownSeconds;\n this.#cooldown = cooldownSeconds;\n }\n\n pushFrame(frame: AudioFrame): boolean {\n const arr = Float32Array.from(frame.data, (x) => x / 32768);\n const rms = (arr.map((x) => x ** 2).reduce((acc, x) => acc + x) / arr.length) ** 0.5;\n if (rms > 0.004) {\n this.#cooldown = this.#cooldownSeconds;\n return true;\n }\n\n const durationSeconds = frame.samplesPerChannel / frame.sampleRate;\n this.#cooldown -= durationSeconds;\n if (this.#cooldown > 0) {\n return true;\n }\n\n return false;\n }\n}\n\nexport enum TaskResult {\n Timeout = 'timeout',\n Completed = 'completed',\n Aborted = 'aborted',\n}\n\n/** @internal */\n/**\n * A task that can be cancelled.\n *\n * We recommend using the `Task.from` method to create a task. When creating subtasks, pass the same controller to all subtasks.\n *\n * @example\n * ```ts\n * const parent = Task.from((controller) => {\n * const child1 = Task.from(() => { ... }, controller);\n * const child2 = Task.from(() => { ... }, controller);\n * });\n * parent.cancel();\n * ```\n *\n * This will cancel all subtasks when the parent is cancelled.\n *\n * @param T - The type of the task result\n */\nexport class Task<T> {\n private resultFuture: Future<T>;\n\n #logger = log();\n\n constructor(\n private readonly fn: (controller: AbortController) => Promise<T>,\n private readonly controller: AbortController,\n readonly name?: string,\n ) {\n this.resultFuture = new Future();\n this.runTask();\n }\n\n /**\n * Creates a new task from a function.\n *\n * @param fn - The function to run\n * @param controller - The abort controller to use\n * @returns A new task\n */\n static from<T>(\n fn: (controller: AbortController) => Promise<T>,\n controller?: AbortController,\n name?: string,\n ) {\n const abortController = controller ?? new AbortController();\n return new Task(fn, abortController, name);\n }\n\n private async runTask() {\n const run = async () => {\n if (this.name) {\n this.#logger.debug(`Task.runTask: task ${this.name} started`);\n }\n return await this.fn(this.controller);\n };\n\n return run()\n .then((value) => {\n this.resultFuture.resolve(value);\n return value;\n })\n .catch((error) => {\n this.resultFuture.reject(error);\n })\n .finally(() => {\n if (this.name) {\n this.#logger.debug(`Task.runTask: task ${this.name} done`);\n }\n });\n }\n\n /**\n * Cancels the task.\n */\n cancel() {\n this.controller.abort();\n }\n\n /**\n * Cancels the task and waits for it to complete.\n *\n * @param timeout - The timeout in milliseconds\n * @returns The result status of the task (timeout, completed, aborted)\n */\n async cancelAndWait(timeout?: number) {\n this.cancel();\n\n // Race between task completion and timeout\n const promises = [\n this.result\n .then(() => TaskResult.Completed)\n .catch((error) => {\n if (error.name === 'AbortError') {\n return TaskResult.Aborted;\n }\n throw error;\n }),\n ];\n\n if (timeout) {\n promises.push(delay(timeout).then(() => TaskResult.Timeout));\n }\n\n const result = await Promise.race(promises);\n\n // Check what happened\n if (result === TaskResult.Timeout) {\n throw new Error('Task cancellation timed out');\n }\n\n return result;\n }\n\n /**\n * The result of the task.\n */\n get result(): Promise<T> {\n return this.resultFuture.await;\n }\n\n /**\n * Whether the task has completed.\n */\n get done(): boolean {\n return this.resultFuture.done;\n }\n\n addDoneCallback(callback: () => void) {\n this.resultFuture.await.finally(callback);\n }\n}\n\nexport async function waitFor(tasks: Task<void>[]): Promise<void> {\n await Promise.allSettled(tasks.map((task) => task.result));\n}\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport async function cancelAndWait(tasks: Task<any>[], timeout?: number): Promise<void> {\n await Promise.allSettled(tasks.map((task) => task.cancelAndWait(timeout)));\n}\n\nexport function withResolvers<T = unknown>() {\n let resolve!: (value: T | PromiseLike<T>) => void;\n let reject!: (reason?: unknown) => void;\n\n const promise = new Promise<T>((res, rej) => {\n resolve = res;\n reject = rej;\n });\n\n return { promise, resolve, reject };\n}\n\n/**\n * Generates a short UUID with a prefix. Mirrors the python agents implementation.\n *\n * @param prefix - The prefix to add to the UUID.\n * @returns A short UUID with the prefix.\n */\nexport function shortuuid(prefix: string = ''): string {\n return `${prefix}${uuidv4().slice(0, 12)}`;\n}\n\nconst READONLY_SYMBOL = Symbol('Readonly');\n\nconst MUTATION_METHODS = [\n 'push',\n 'pop',\n 'shift',\n 'unshift',\n 'splice',\n 'sort',\n 'reverse',\n 'fill',\n 'copyWithin',\n] as const;\n\n// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy\n/**\n * Creates a read-only proxy for an array.\n * @param array - The array to make read-only.\n * @param additionalErrorMessage - An additional error message to include in the error thrown when a mutation method is called.\n * @returns A read-only proxy for the array.\n */\nexport function createImmutableArray<T>(array: T[], additionalErrorMessage: string = ''): T[] {\n return new Proxy(array, {\n get(target, key) {\n if (key === READONLY_SYMBOL) {\n return true;\n }\n\n // Intercept mutation methods\n if (\n typeof key === 'string' &&\n MUTATION_METHODS.includes(key as (typeof MUTATION_METHODS)[number])\n ) {\n return function () {\n throw new TypeError(\n `Cannot call ${key}() on a read-only array. ${additionalErrorMessage}`.trim(),\n );\n };\n }\n\n return Reflect.get(target, key);\n },\n set(_, prop) {\n throw new TypeError(\n `Cannot assign to read-only array index \"${String(prop)}\". ${additionalErrorMessage}`.trim(),\n );\n },\n deleteProperty(_, prop) {\n throw new TypeError(\n `Cannot delete read-only array index \"${String(prop)}\". ${additionalErrorMessage}`.trim(),\n );\n },\n defineProperty(_, prop) {\n throw new TypeError(\n `Cannot define property \"${String(prop)}\" on a read-only array. ${additionalErrorMessage}`.trim(),\n );\n },\n setPrototypeOf() {\n throw new TypeError(\n `Cannot change prototype of a read-only array. ${additionalErrorMessage}`.trim(),\n );\n },\n });\n}\n\nexport function isImmutableArray(array: unknown): boolean {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n return typeof array === 'object' && !!(array as any)[READONLY_SYMBOL];\n}\n\n/**\n * Resamples an audio stream to a target sample rate.\n *\n * WARINING: The input stream will be locked until the resampled stream is closed.\n *\n * @param stream - The input stream to resample.\n * @param outputRate - The target sample rate.\n * @returns A new stream with the resampled audio.\n */\nexport function resampleStream({\n stream,\n outputRate,\n}: {\n stream: ReadableStream<AudioFrame>;\n outputRate: number;\n}): ReadableStream<AudioFrame> {\n let resampler: AudioResampler | null = null;\n const transformStream = new TransformStream<AudioFrame, AudioFrame>({\n transform(chunk: AudioFrame, controller: TransformStreamDefaultController<AudioFrame>) {\n if (chunk.samplesPerChannel === 0) {\n controller.enqueue(chunk);\n return;\n }\n if (!resampler) {\n resampler = new AudioResampler(chunk.sampleRate, outputRate);\n }\n for (const frame of resampler.push(chunk)) {\n controller.enqueue(frame);\n }\n },\n flush(controller) {\n if (resampler) {\n for (const frame of resampler.flush()) {\n controller.enqueue(frame);\n }\n }\n },\n });\n return stream.pipeThrough(transformStream);\n}\n\nexport class InvalidErrorType extends Error {\n readonly error: unknown;\n\n constructor(error: unknown) {\n super(`Expected error, got ${error} (${typeof error})`);\n this.error = error;\n Error.captureStackTrace(this, InvalidErrorType);\n }\n}\n\n/**\n * Check if an error is a stream closed error that can be safely ignored during cleanup.\n * This happens during handover/cleanup when close() is called while operations are still running.\n *\n * @param error - The error to check.\n * @returns True if the error is a stream closed error.\n */\nexport function isStreamClosedError(error: unknown): boolean {\n return (\n error instanceof Error &&\n (error.message === 'Stream is closed' || error.message === 'Input is closed')\n );\n}\n\n/**\n * In JS an error can be any arbitrary value.\n * This function converts an unknown error to an Error and stores the original value in the error object.\n *\n * @param error - The error to convert.\n * @returns An Error.\n */\nexport function toError(error: unknown): Error {\n if (error instanceof Error) {\n return error;\n }\n throw new InvalidErrorType(error);\n}\n\n/**\n * This is a hack to immitate asyncio.create_task so that\n * func will be run after the current event loop iteration.\n *\n * @param func - The function to run.\n */\nexport function startSoon(func: () => void) {\n setTimeout(func, 0);\n}\n\nexport type DelayOptions = {\n signal?: AbortSignal;\n};\n\n/**\n * Delay for a given number of milliseconds.\n *\n * @param ms - The number of milliseconds to delay.\n * @param options - The options for the delay.\n * @returns A promise that resolves after the delay.\n */\nexport function delay(ms: number, options: DelayOptions = {}): Promise<void> {\n const { signal } = options;\n if (signal?.aborted) return Promise.reject(signal.reason);\n return new Promise((resolve, reject) => {\n const abort = () => {\n clearTimeout(i);\n reject(signal?.reason);\n };\n const done = () => {\n signal?.removeEventListener('abort', abort);\n resolve();\n };\n const i = setTimeout(done, ms);\n signal?.addEventListener('abort', abort, { once: true });\n });\n}\n\n/**\n * Returns a participant that matches the given identity. If identity is None, the first\n * participant that joins the room will be returned.\n * If the participant has already joined, the function will return immediately.\n * @param room - The room to wait for a participant in.\n * @param identity - The identity of the participant to wait for.\n * @param kind - The kind of the participant to wait for.\n * @returns A promise that resolves to the participant.\n */\nexport async function waitForParticipant({\n room,\n identity,\n kind,\n}: {\n room: Room;\n identity?: string;\n kind?: ParticipantKind | ParticipantKind[];\n}): Promise<RemoteParticipant> {\n if (!room.isConnected) {\n throw new Error('Room is not connected');\n }\n\n const fut = new Future<RemoteParticipant>();\n\n const kindMatch = (participant: RemoteParticipant) => {\n if (kind === undefined) return true;\n\n if (Array.isArray(kind)) {\n return kind.includes(participant.kind);\n }\n\n return participant.kind === kind;\n };\n\n const onParticipantConnected = (p: RemoteParticipant) => {\n if ((identity === undefined || p.identity === identity) && kindMatch(p)) {\n if (!fut.done) {\n fut.resolve(p);\n }\n }\n };\n\n room.on(RoomEvent.ParticipantConnected, onParticipantConnected);\n\n try {\n for (const p of room.remoteParticipants.values()) {\n onParticipantConnected(p);\n if (fut.done) {\n break;\n }\n }\n\n return await fut.await;\n } finally {\n room.off(RoomEvent.ParticipantConnected, onParticipantConnected);\n }\n}\n\nexport async function waitForTrackPublication({\n room,\n identity,\n kind,\n}: {\n room: Room;\n identity: string;\n kind: TrackKind;\n}): Promise<RemoteTrackPublication> {\n if (!room.isConnected) {\n throw new Error('Room is not connected');\n }\n\n const fut = new Future<RemoteTrackPublication>();\n\n const kindMatch = (k: TrackKind | undefined) => {\n if (kind === undefined || kind === null) {\n return true;\n }\n return k === kind;\n };\n\n const onTrackPublished = (\n publication: RemoteTrackPublication,\n participant: RemoteParticipant,\n ) => {\n if (fut.done) return;\n if (\n (identity === undefined || participant.identity === identity) &&\n kindMatch(publication.kind)\n ) {\n fut.resolve(publication);\n }\n };\n\n room.on(RoomEvent.TrackPublished, onTrackPublished);\n\n try {\n for (const p of room.remoteParticipants.values()) {\n for (const publication of p.trackPublications.values()) {\n onTrackPublished(publication, p);\n if (fut.done) break;\n }\n }\n\n return await fut.await;\n } finally {\n room.off(RoomEvent.TrackPublished, onTrackPublished);\n }\n}\n\nexport async function waitForAbort(signal: AbortSignal) {\n const abortFuture = new Future<void>();\n const handler = () => {\n abortFuture.resolve();\n signal.removeEventListener('abort', handler);\n };\n\n signal.addEventListener('abort', handler, { once: true });\n return await abortFuture.await;\n}\n\n/**\n * Combines two abort signals into a single abort signal.\n * @param a - The first abort signal.\n * @param b - The second abort signal.\n * @returns A new abort signal that is aborted when either of the input signals is aborted.\n */\nexport const combineSignals = (a: AbortSignal, b: AbortSignal): AbortSignal => {\n const c = new AbortController();\n const abortFrom = (s: AbortSignal) => {\n if (c.signal.aborted) return;\n c.abort((s as any).reason);\n };\n if (a.aborted) {\n abortFrom(a);\n } else {\n a.addEventListener('abort', () => abortFrom(a), { once: true });\n }\n if (b.aborted) {\n abortFrom(b);\n } else {\n b.addEventListener('abort', () => abortFrom(b), { once: true });\n }\n return c.signal;\n};\n\nexport const isCloud = (url: URL) => {\n const hostname = url.hostname;\n return hostname.endsWith('.livekit.cloud') || hostname.endsWith('.livekit.run');\n};\n"],"mappings":"AAUA,SAAS,YAAY,gBAAgB,iBAAiB;AACtD,SAAS,cAAc,YAAY;AAEnC,SAAS,uBAA8D;AACvE,SAAS,MAAM,cAAc;AAC7B,SAAS,WAAW;AAsBb,MAAM,OAAO,MAAM;AAAC;AAEpB,MAAM,YAAY,OAAO,YAAgD;AAC9E,QAAM,WAAW,OAAO,UAAU;AAClC,QAAM,SAAS,MAAM,QAAQ,KAAK,CAAC,SAAS,QAAQ,QAAQ,QAAQ,CAAC,CAAC;AACtE,SAAO,WAAW;AACpB;AAUO,MAAM,cAAc,CAAC,WAAoC;AAC9D,MAAI,MAAM,QAAQ,MAAM,GAAG;AACzB,aAAS;AACT,QAAI,OAAO,UAAU,GAAG;AACtB,YAAM,IAAI,UAAU,iBAAiB;AAAA,IACvC;AAEA,UAAM,aAAa,OAAO,CAAC,EAAG;AAC9B,UAAM,WAAW,OAAO,CAAC,EAAG;AAC5B,QAAI,oBAAoB;AACxB,QAAI,OAAO,IAAI,WAAW;AAE1B,eAAW,SAAS,QAAQ;AAC1B,UAAI,MAAM,eAAe,YAAY;AACnC,cAAM,IAAI,UAAU,sBAAsB;AAAA,MAC5C;AAEA,UAAI,MAAM,aAAa,UAAU;AAC/B,cAAM,IAAI,UAAU,wBAAwB;AAAA,MAC9C;AAEA,aAAO,IAAI,WAAW,CAAC,GAAG,MAAM,GAAG,MAAM,IAAI,CAAC;AAC9C,2BAAqB,MAAM;AAAA,IAC7B;AAEA,WAAO,IAAI,WAAW,MAAM,YAAY,UAAU,iBAAiB;AAAA,EACrE;AAEA,SAAO;AACT;AAGO,MAAM,MAAS;AAAA;AAAA,EAEpB,QAAa,CAAC;AAAA,EACd;AAAA,EACA,UAAU,IAAI,aAAa;AAAA,EAE3B,YAAY,OAAgB;AAC1B,SAAK,SAAS;AAAA,EAChB;AAAA,EAEA,MAAM,MAAkB;AACtB,UAAM,OAAO,YAAwB;AACnC,UAAI,KAAK,MAAM,WAAW,GAAG;AAC3B,cAAM,KAAK,KAAK,SAAS,KAAK;AAAA,MAChC;AACA,UAAIA,QAAO,KAAK,MAAM,MAAM;AAC5B,UAAI,CAACA,OAAM;AACT,QAAAA,QAAO,MAAM,KAAK;AAAA,MACpB;AACA,aAAOA;AAAA,IACT;AAEA,UAAM,OAAO,KAAK;AAClB,SAAK,QAAQ,KAAK,KAAK;AACvB,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,IAAI,MAAS;AACjB,QAAI,KAAK,UAAU,KAAK,MAAM,UAAU,KAAK,QAAQ;AACnD,YAAM,KAAK,KAAK,SAAS,KAAK;AAAA,IAChC;AACA,SAAK,MAAM,KAAK,IAAI;AACpB,SAAK,QAAQ,KAAK,KAAK;AAAA,EACzB;AACF;AAGO,MAAM,OAAiB;AAAA,EAC5B;AAAA,EACA;AAAA,EACA;AAAA,EACA,QAAiB;AAAA,EACjB,YAAqB;AAAA,EACrB,UAAyB;AAAA,EACzB,SAA4B;AAAA,EAE5B,cAAc;AACZ,SAAK,SAAS,IAAI,QAAW,CAAC,SAAS,WAAW;AAChD,WAAK,kBAAkB;AACvB,WAAK,iBAAiB;AAAA,IACxB,CAAC;AAAA,EACH;AAAA,EAEA,IAAI,QAAQ;AACV,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,IAAI,OAAO;AACT,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,IAAI,SAAY;AACd,QAAI,CAAC,KAAK,OAAO;AACf,YAAM,IAAI,MAAM,oBAAoB;AAAA,IACtC;AAEA,QAAI,KAAK,WAAW;AAClB,YAAM,KAAK;AAAA,IACb;AAEA,WAAO,KAAK;AAAA,EACd;AAAA;AAAA,EAGA,IAAI,WAAW;AACb,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,QAAQ,OAAU;AAChB,SAAK,QAAQ;AACb,SAAK,UAAU;AACf,SAAK,gBAAgB,KAAK;AAAA,EAC5B;AAAA,EAEA,OAAO,OAAc;AACnB,SAAK,QAAQ;AACb,SAAK,YAAY;AACjB,SAAK,SAAS;AACd,SAAK,eAAe,KAAK;AAAA,EAC3B;AACF;AAGO,MAAM,MAAM;AAAA,EACjB,SAAS;AAAA,EACT,WAA8B,CAAC;AAAA,EAE/B,MAAM,OAAO;AACX,QAAI,KAAK,OAAQ,QAAO;AAExB,QAAI,UAAsB;AAC1B,UAAM,SAAS,IAAI,QAAc,CAAC,MAAM;AACtC,gBAAU;AACV,WAAK,SAAS,KAAK,OAAO;AAAA,IAC5B,CAAC;AAED,QAAI;AACF,YAAM;AACN,aAAO;AAAA,IACT,UAAE;AACA,YAAM,QAAQ,KAAK,SAAS,QAAQ,OAAO;AAC3C,UAAI,UAAU,IAAI;AAChB,aAAK,SAAS,OAAO,OAAO,CAAC;AAAA,MAC/B;AAAA,IACF;AAAA,EACF;AAAA,EAEA,IAAI,QAAiB;AACnB,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,MAAY;AACV,QAAI,KAAK,OAAQ;AAEjB,SAAK,SAAS;AACd,SAAK,SAAS,QAAQ,CAAC,YAAY,QAAQ,CAAC;AAC5C,SAAK,WAAW,CAAC;AAAA,EACnB;AAAA,EAEA,QAAc;AACZ,SAAK,SAAS;AAAA,EAChB;AACF;AAGO,MAAM,mBAAsB;AAAA,EACjC;AAAA,EACA;AAAA,EACA,eAAwB;AAAA,EACxB,SAAuB;AAAA,EAEvB,YACE,UAKA;AACA,QAAI;AAEJ,SAAK,WAAW,IAAI,QAAW,CAAC,SAAS,WAAW;AAClD;AAAA,QACE;AAAA,QACA,CAAC,WAAW;AACV,eAAK,SAAS,kBAAkB,QAAQ,SAAS,IAAI,MAAM,OAAO,MAAM,CAAC;AACzE,iBAAO,MAAM;AAAA,QACf;AAAA,QACA,CAAC,aAAa;AACZ,mBAAS,MAAM;AACb,iBAAK,eAAe;AACpB,qBAAS;AAAA,UACX;AAAA,QACF;AAAA,MACF;AAAA,IACF,CAAC;AAED,SAAK,YAAY;AAAA,EACnB;AAAA,EAEA,IAAI,cAAuB;AACzB,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,IAAI,QAAsB;AACxB,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,KACE,aACA,YAC8B;AAC9B,WAAO,KAAK,SAAS,KAAK,aAAa,UAAU;AAAA,EACnD;AAAA,EAEA,MACE,YACsB;AACtB,WAAO,KAAK,SAAS,MAAM,UAAU;AAAA,EACvC;AAAA,EAEA,QAAQ,WAA6C;AACnD,WAAO,KAAK,SAAS,QAAQ,SAAS;AAAA,EACxC;AAAA,EAEA,SAAe;AACb,SAAK,UAAU;AAAA,EACjB;AAAA,EAEA,OAAO,KAAQ,SAA4C;AACzD,WAAO,IAAI,mBAAsB,CAAC,SAAS,WAAW;AACpD,cAAQ,KAAK,OAAO,EAAE,MAAM,MAAM;AAAA,IACpC,CAAC;AAAA,EACH;AACF;AAGA,eAAsB,iBAAoB,SAA+C;AACvF,MAAI,CAAC,QAAQ,aAAa;AACxB,YAAQ,OAAO;AAAA,EACjB;AACA,MAAI;AACF,UAAM;AAAA,EACR,SAAS,OAAO;AAAA,EAEhB;AACF;AAGO,MAAM,mBAA0D;AAAA,EACrE,OAAwB,iBAAiB,OAAO,gBAAgB;AAAA,EAChE,SAAS,IAAI,MAAoD;AAAA,EACjE,UAAU;AAAA,EAEV,IAAI,SAAkB;AACpB,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,IAAI,MAAe;AACjB,QAAI,KAAK,SAAS;AAChB,YAAM,IAAI,MAAM,iBAAiB;AAAA,IACnC;AACA,SAAK,OAAO,IAAI,IAAI;AAAA,EACtB;AAAA,EAEA,QAAc;AACZ,SAAK,UAAU;AACf,SAAK,OAAO,IAAI,mBAAmB,cAAc;AAAA,EACnD;AAAA,EAEA,MAAM,OAAmC;AACvC,QAAI,KAAK,WAAW,KAAK,OAAO,MAAM,WAAW,GAAG;AAClD,aAAO,EAAE,OAAO,QAAW,MAAM,KAAK;AAAA,IACxC;AACA,UAAM,OAAO,MAAM,KAAK,OAAO,IAAI;AACnC,QAAI,SAAS,mBAAmB,kBAAkB,KAAK,SAAS;AAC9D,aAAO,EAAE,OAAO,QAAW,MAAM,KAAK;AAAA,IACxC;AACA,WAAO,EAAE,OAAO,MAAW,MAAM,MAAM;AAAA,EACzC;AAAA,EAEA,CAAC,OAAO,aAAa,IAA2B;AAC9C,WAAO;AAAA,EACT;AACF;AAGO,MAAM,UAAU;AAAA,EACrB;AAAA,EACA;AAAA,EACA,YAAqB;AAAA,EAErB,YAAY,OAAe,KAAc;AACvC,SAAK,SAAS;AACd,SAAK,OAAO;AAAA,EACd;AAAA,EAEA,MAAM,OAAgB;AACpB,QAAI,OAAO;AACT,WAAK,SAAS;AAAA,IAChB;AACA,SAAK,YAAY;AAAA,EACnB;AAAA,EAEA,MAAM,KAAa,QAAwB;AACzC,QAAI,KAAK,WAAW;AAClB,YAAM,IAAI,KAAK,UAAU;AACzB,WAAK,YAAY,IAAI,KAAK,aAAa,IAAI,KAAK;AAAA,IAClD,OAAO;AACL,WAAK,YAAY;AAAA,IACnB;AAEA,QAAI,KAAK,QAAQ,KAAK,YAAY,KAAK,MAAM;AAC3C,WAAK,YAAY,KAAK;AAAA,IACxB;AAEA,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,IAAI,WAA+B;AACjC,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,IAAI,MAAM,OAAe;AACvB,SAAK,SAAS;AAAA,EAChB;AACF;AAGO,MAAM,kBAAkB;AAAA,EAC7B;AAAA,EACA;AAAA,EAEA,YAAY,kBAAkB,GAAG;AAC/B,SAAK,mBAAmB;AACxB,SAAK,YAAY;AAAA,EACnB;AAAA,EAEA,UAAU,OAA4B;AACpC,UAAM,MAAM,aAAa,KAAK,MAAM,MAAM,CAAC,MAAM,IAAI,KAAK;AAC1D,UAAM,OAAO,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,OAAO,CAAC,KAAK,MAAM,MAAM,CAAC,IAAI,IAAI,WAAW;AACjF,QAAI,MAAM,MAAO;AACf,WAAK,YAAY,KAAK;AACtB,aAAO;AAAA,IACT;AAEA,UAAM,kBAAkB,MAAM,oBAAoB,MAAM;AACxD,SAAK,aAAa;AAClB,QAAI,KAAK,YAAY,GAAG;AACtB,aAAO;AAAA,IACT;AAEA,WAAO;AAAA,EACT;AACF;AAEO,IAAK,aAAL,kBAAKC,gBAAL;AACL,EAAAA,YAAA,aAAU;AACV,EAAAA,YAAA,eAAY;AACZ,EAAAA,YAAA,aAAU;AAHA,SAAAA;AAAA,GAAA;AAyBL,MAAM,KAAQ;AAAA,EAKnB,YACmB,IACA,YACR,MACT;AAHiB;AACA;AACR;AAET,SAAK,eAAe,IAAI,OAAO;AAC/B,SAAK,QAAQ;AAAA,EACf;AAAA,EAXQ;AAAA,EAER,UAAU,IAAI;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAkBd,OAAO,KACL,IACA,YACA,MACA;AACA,UAAM,kBAAkB,cAAc,IAAI,gBAAgB;AAC1D,WAAO,IAAI,KAAK,IAAI,iBAAiB,IAAI;AAAA,EAC3C;AAAA,EAEA,MAAc,UAAU;AACtB,UAAM,MAAM,YAAY;AACtB,UAAI,KAAK,MAAM;AACb,aAAK,QAAQ,MAAM,sBAAsB,KAAK,IAAI,UAAU;AAAA,MAC9D;AACA,aAAO,MAAM,KAAK,GAAG,KAAK,UAAU;AAAA,IACtC;AAEA,WAAO,IAAI,EACR,KAAK,CAAC,UAAU;AACf,WAAK,aAAa,QAAQ,KAAK;AAC/B,aAAO;AAAA,IACT,CAAC,EACA,MAAM,CAAC,UAAU;AAChB,WAAK,aAAa,OAAO,KAAK;AAAA,IAChC,CAAC,EACA,QAAQ,MAAM;AACb,UAAI,KAAK,MAAM;AACb,aAAK,QAAQ,MAAM,sBAAsB,KAAK,IAAI,OAAO;AAAA,MAC3D;AAAA,IACF,CAAC;AAAA,EACL;AAAA;AAAA;AAAA;AAAA,EAKA,SAAS;AACP,SAAK,WAAW,MAAM;AAAA,EACxB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAM,cAAc,SAAkB;AACpC,SAAK,OAAO;AAGZ,UAAM,WAAW;AAAA,MACf,KAAK,OACF,KAAK,MAAM,2BAAoB,EAC/B,MAAM,CAAC,UAAU;AAChB,YAAI,MAAM,SAAS,cAAc;AAC/B,iBAAO;AAAA,QACT;AACA,cAAM;AAAA,MACR,CAAC;AAAA,IACL;AAEA,QAAI,SAAS;AACX,eAAS,KAAK,MAAM,OAAO,EAAE,KAAK,MAAM,uBAAkB,CAAC;AAAA,IAC7D;AAEA,UAAM,SAAS,MAAM,QAAQ,KAAK,QAAQ;AAG1C,QAAI,WAAW,yBAAoB;AACjC,YAAM,IAAI,MAAM,6BAA6B;AAAA,IAC/C;AAEA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKA,IAAI,SAAqB;AACvB,WAAO,KAAK,aAAa;AAAA,EAC3B;AAAA;AAAA;AAAA;AAAA,EAKA,IAAI,OAAgB;AAClB,WAAO,KAAK,aAAa;AAAA,EAC3B;AAAA,EAEA,gBAAgB,UAAsB;AACpC,SAAK,aAAa,MAAM,QAAQ,QAAQ;AAAA,EAC1C;AACF;AAEA,eAAsB,QAAQ,OAAoC;AAChE,QAAM,QAAQ,WAAW,MAAM,IAAI,CAAC,SAAS,KAAK,MAAM,CAAC;AAC3D;AAGA,eAAsB,cAAc,OAAoB,SAAiC;AACvF,QAAM,QAAQ,WAAW,MAAM,IAAI,CAAC,SAAS,KAAK,cAAc,OAAO,CAAC,CAAC;AAC3E;AAEO,SAAS,gBAA6B;AAC3C,MAAI;AACJ,MAAI;AAEJ,QAAM,UAAU,IAAI,QAAW,CAAC,KAAK,QAAQ;AAC3C,cAAU;AACV,aAAS;AAAA,EACX,CAAC;AAED,SAAO,EAAE,SAAS,SAAS,OAAO;AACpC;AAQO,SAAS,UAAU,SAAiB,IAAY;AACrD,SAAO,GAAG,MAAM,GAAG,OAAO,EAAE,MAAM,GAAG,EAAE,CAAC;AAC1C;AAEA,MAAM,kBAAkB,OAAO,UAAU;AAEzC,MAAM,mBAAmB;AAAA,EACvB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AASO,SAAS,qBAAwB,OAAY,yBAAiC,IAAS;AAC5F,SAAO,IAAI,MAAM,OAAO;AAAA,IACtB,IAAI,QAAQ,KAAK;AACf,UAAI,QAAQ,iBAAiB;AAC3B,eAAO;AAAA,MACT;AAGA,UACE,OAAO,QAAQ,YACf,iBAAiB,SAAS,GAAwC,GAClE;AACA,eAAO,WAAY;AACjB,gBAAM,IAAI;AAAA,YACR,eAAe,GAAG,4BAA4B,sBAAsB,GAAG,KAAK;AAAA,UAC9E;AAAA,QACF;AAAA,MACF;AAEA,aAAO,QAAQ,IAAI,QAAQ,GAAG;AAAA,IAChC;AAAA,IACA,IAAI,GAAG,MAAM;AACX,YAAM,IAAI;AAAA,QACR,2CAA2C,OAAO,IAAI,CAAC,MAAM,sBAAsB,GAAG,KAAK;AAAA,MAC7F;AAAA,IACF;AAAA,IACA,eAAe,GAAG,MAAM;AACtB,YAAM,IAAI;AAAA,QACR,wCAAwC,OAAO,IAAI,CAAC,MAAM,sBAAsB,GAAG,KAAK;AAAA,MAC1F;AAAA,IACF;AAAA,IACA,eAAe,GAAG,MAAM;AACtB,YAAM,IAAI;AAAA,QACR,2BAA2B,OAAO,IAAI,CAAC,2BAA2B,sBAAsB,GAAG,KAAK;AAAA,MAClG;AAAA,IACF;AAAA,IACA,iBAAiB;AACf,YAAM,IAAI;AAAA,QACR,iDAAiD,sBAAsB,GAAG,KAAK;AAAA,MACjF;AAAA,IACF;AAAA,EACF,CAAC;AACH;AAEO,SAAS,iBAAiB,OAAyB;AAExD,SAAO,OAAO,UAAU,YAAY,CAAC,CAAE,MAAc,eAAe;AACtE;AAWO,SAAS,eAAe;AAAA,EAC7B;AAAA,EACA;AACF,GAG+B;AAC7B,MAAI,YAAmC;AACvC,QAAM,kBAAkB,IAAI,gBAAwC;AAAA,IAClE,UAAU,OAAmB,YAA0D;AACrF,UAAI,MAAM,sBAAsB,GAAG;AACjC,mBAAW,QAAQ,KAAK;AACxB;AAAA,MACF;AACA,UAAI,CAAC,WAAW;AACd,oBAAY,IAAI,eAAe,MAAM,YAAY,UAAU;AAAA,MAC7D;AACA,iBAAW,SAAS,UAAU,KAAK,KAAK,GAAG;AACzC,mBAAW,QAAQ,KAAK;AAAA,MAC1B;AAAA,IACF;AAAA,IACA,MAAM,YAAY;AAChB,UAAI,WAAW;AACb,mBAAW,SAAS,UAAU,MAAM,GAAG;AACrC,qBAAW,QAAQ,KAAK;AAAA,QAC1B;AAAA,MACF;AAAA,IACF;AAAA,EACF,CAAC;AACD,SAAO,OAAO,YAAY,eAAe;AAC3C;AAEO,MAAM,yBAAyB,MAAM;AAAA,EACjC;AAAA,EAET,YAAY,OAAgB;AAC1B,UAAM,uBAAuB,KAAK,KAAK,OAAO,KAAK,GAAG;AACtD,SAAK,QAAQ;AACb,UAAM,kBAAkB,MAAM,gBAAgB;AAAA,EAChD;AACF;AASO,SAAS,oBAAoB,OAAyB;AAC3D,SACE,iBAAiB,UAChB,MAAM,YAAY,sBAAsB,MAAM,YAAY;AAE/D;AASO,SAAS,QAAQ,OAAuB;AAC7C,MAAI,iBAAiB,OAAO;AAC1B,WAAO;AAAA,EACT;AACA,QAAM,IAAI,iBAAiB,KAAK;AAClC;AAQO,SAAS,UAAU,MAAkB;AAC1C,aAAW,MAAM,CAAC;AACpB;AAaO,SAAS,MAAM,IAAY,UAAwB,CAAC,GAAkB;AAC3E,QAAM,EAAE,OAAO,IAAI;AACnB,MAAI,iCAAQ,QAAS,QAAO,QAAQ,OAAO,OAAO,MAAM;AACxD,SAAO,IAAI,QAAQ,CAAC,SAAS,WAAW;AACtC,UAAM,QAAQ,MAAM;AAClB,mBAAa,CAAC;AACd,aAAO,iCAAQ,MAAM;AAAA,IACvB;AACA,UAAM,OAAO,MAAM;AACjB,uCAAQ,oBAAoB,SAAS;AACrC,cAAQ;AAAA,IACV;AACA,UAAM,IAAI,WAAW,MAAM,EAAE;AAC7B,qCAAQ,iBAAiB,SAAS,OAAO,EAAE,MAAM,KAAK;AAAA,EACxD,CAAC;AACH;AAWA,eAAsB,mBAAmB;AAAA,EACvC;AAAA,EACA;AAAA,EACA;AACF,GAI+B;AAC7B,MAAI,CAAC,KAAK,aAAa;AACrB,UAAM,IAAI,MAAM,uBAAuB;AAAA,EACzC;AAEA,QAAM,MAAM,IAAI,OAA0B;AAE1C,QAAM,YAAY,CAAC,gBAAmC;AACpD,QAAI,SAAS,OAAW,QAAO;AAE/B,QAAI,MAAM,QAAQ,IAAI,GAAG;AACvB,aAAO,KAAK,SAAS,YAAY,IAAI;AAAA,IACvC;AAEA,WAAO,YAAY,SAAS;AAAA,EAC9B;AAEA,QAAM,yBAAyB,CAAC,MAAyB;AACvD,SAAK,aAAa,UAAa,EAAE,aAAa,aAAa,UAAU,CAAC,GAAG;AACvE,UAAI,CAAC,IAAI,MAAM;AACb,YAAI,QAAQ,CAAC;AAAA,MACf;AAAA,IACF;AAAA,EACF;AAEA,OAAK,GAAG,UAAU,sBAAsB,sBAAsB;AAE9D,MAAI;AACF,eAAW,KAAK,KAAK,mBAAmB,OAAO,GAAG;AAChD,6BAAuB,CAAC;AACxB,UAAI,IAAI,MAAM;AACZ;AAAA,MACF;AAAA,IACF;AAEA,WAAO,MAAM,IAAI;AAAA,EACnB,UAAE;AACA,SAAK,IAAI,UAAU,sBAAsB,sBAAsB;AAAA,EACjE;AACF;AAEA,eAAsB,wBAAwB;AAAA,EAC5C;AAAA,EACA;AAAA,EACA;AACF,GAIoC;AAClC,MAAI,CAAC,KAAK,aAAa;AACrB,UAAM,IAAI,MAAM,uBAAuB;AAAA,EACzC;AAEA,QAAM,MAAM,IAAI,OAA+B;AAE/C,QAAM,YAAY,CAAC,MAA6B;AAC9C,QAAI,SAAS,UAAa,SAAS,MAAM;AACvC,aAAO;AAAA,IACT;AACA,WAAO,MAAM;AAAA,EACf;AAEA,QAAM,mBAAmB,CACvB,aACA,gBACG;AACH,QAAI,IAAI,KAAM;AACd,SACG,aAAa,UAAa,YAAY,aAAa,aACpD,UAAU,YAAY,IAAI,GAC1B;AACA,UAAI,QAAQ,WAAW;AAAA,IACzB;AAAA,EACF;AAEA,OAAK,GAAG,UAAU,gBAAgB,gBAAgB;AAElD,MAAI;AACF,eAAW,KAAK,KAAK,mBAAmB,OAAO,GAAG;AAChD,iBAAW,eAAe,EAAE,kBAAkB,OAAO,GAAG;AACtD,yBAAiB,aAAa,CAAC;AAC/B,YAAI,IAAI,KAAM;AAAA,MAChB;AAAA,IACF;AAEA,WAAO,MAAM,IAAI;AAAA,EACnB,UAAE;AACA,SAAK,IAAI,UAAU,gBAAgB,gBAAgB;AAAA,EACrD;AACF;AAEA,eAAsB,aAAa,QAAqB;AACtD,QAAM,cAAc,IAAI,OAAa;AACrC,QAAM,UAAU,MAAM;AACpB,gBAAY,QAAQ;AACpB,WAAO,oBAAoB,SAAS,OAAO;AAAA,EAC7C;AAEA,SAAO,iBAAiB,SAAS,SAAS,EAAE,MAAM,KAAK,CAAC;AACxD,SAAO,MAAM,YAAY;AAC3B;AAQO,MAAM,iBAAiB,CAAC,GAAgB,MAAgC;AAC7E,QAAM,IAAI,IAAI,gBAAgB;AAC9B,QAAM,YAAY,CAAC,MAAmB;AACpC,QAAI,EAAE,OAAO,QAAS;AACtB,MAAE,MAAO,EAAU,MAAM;AAAA,EAC3B;AACA,MAAI,EAAE,SAAS;AACb,cAAU,CAAC;AAAA,EACb,OAAO;AACL,MAAE,iBAAiB,SAAS,MAAM,UAAU,CAAC,GAAG,EAAE,MAAM,KAAK,CAAC;AAAA,EAChE;AACA,MAAI,EAAE,SAAS;AACb,cAAU,CAAC;AAAA,EACb,OAAO;AACL,MAAE,iBAAiB,SAAS,MAAM,UAAU,CAAC,GAAG,EAAE,MAAM,KAAK,CAAC;AAAA,EAChE;AACA,SAAO,EAAE;AACX;AAEO,MAAM,UAAU,CAAC,QAAa;AACnC,QAAM,WAAW,IAAI;AACrB,SAAO,SAAS,SAAS,gBAAgB,KAAK,SAAS,SAAS,cAAc;AAChF;","names":["item","TaskResult"]}
1
+ {"version":3,"sources":["../src/utils.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2024 LiveKit, Inc.\n//\n// SPDX-License-Identifier: Apache-2.0\nimport type {\n ParticipantKind,\n RemoteParticipant,\n RemoteTrackPublication,\n Room,\n TrackKind,\n} from '@livekit/rtc-node';\nimport { AudioFrame, AudioResampler, RoomEvent } from '@livekit/rtc-node';\nimport { AsyncLocalStorage } from 'node:async_hooks';\nimport { EventEmitter, once } from 'node:events';\nimport type { ReadableStream } from 'node:stream/web';\nimport { TransformStream, type TransformStreamDefaultController } from 'node:stream/web';\nimport { v4 as uuidv4 } from 'uuid';\nimport { log } from './log.js';\n\n/**\n * Recursively expands all nested properties of a type,\n * resolving aliases so as to inspect the real shape in IDE.\n */\n// eslint-disable-next-line @typescript-eslint/ban-types\nexport type Expand<T> = T extends Function\n ? T\n : T extends object\n ? T extends Array<infer U>\n ? Array<Expand<U>>\n : T extends Map<infer K, infer V>\n ? Map<Expand<K>, Expand<V>>\n : T extends Set<infer M>\n ? Set<Expand<M>>\n : { [K in keyof T]: Expand<T[K]> }\n : T;\n\n/** Union of a single and a list of {@link AudioFrame}s */\nexport type AudioBuffer = AudioFrame[] | AudioFrame;\n\nexport const noop = () => {};\n\nexport const isPending = async (promise: Promise<unknown>): Promise<boolean> => {\n const sentinel = Symbol('sentinel');\n const result = await Promise.race([promise, Promise.resolve(sentinel)]);\n return result === sentinel;\n};\n\n/**\n * Merge one or more {@link AudioFrame}s into a single one.\n *\n * @param buffer - Either an {@link AudioFrame} or a list thereof\n * @throws\n * {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypeError\n * | TypeError} if sample rate or channel count are mismatched\n */\nexport const mergeFrames = (buffer: AudioBuffer): AudioFrame => {\n if (Array.isArray(buffer)) {\n buffer = buffer as AudioFrame[];\n if (buffer.length == 0) {\n throw new TypeError('buffer is empty');\n }\n\n const sampleRate = buffer[0]!.sampleRate;\n const channels = buffer[0]!.channels;\n let samplesPerChannel = 0;\n let data = new Int16Array();\n\n for (const frame of buffer) {\n if (frame.sampleRate !== sampleRate) {\n throw new TypeError('sample rate mismatch');\n }\n\n if (frame.channels !== channels) {\n throw new TypeError('channel count mismatch');\n }\n\n data = new Int16Array([...data, ...frame.data]);\n samplesPerChannel += frame.samplesPerChannel;\n }\n\n return new AudioFrame(data, sampleRate, channels, samplesPerChannel);\n }\n\n return buffer;\n};\n\n/** @internal */\nexport class Queue<T> {\n /** @internal */\n items: T[] = [];\n #limit?: number;\n #events = new EventEmitter();\n\n constructor(limit?: number) {\n this.#limit = limit;\n }\n\n async get(): Promise<T> {\n const _get = async (): Promise<T> => {\n if (this.items.length === 0) {\n await once(this.#events, 'put');\n }\n let item = this.items.shift();\n if (!item) {\n item = await _get();\n }\n return item;\n };\n\n const item = _get();\n this.#events.emit('get');\n return item;\n }\n\n async put(item: T) {\n if (this.#limit && this.items.length >= this.#limit) {\n await once(this.#events, 'get');\n }\n this.items.push(item);\n this.#events.emit('put');\n }\n}\n\n/** @internal */\nexport class Future<T = void> {\n #await: Promise<T>;\n #resolvePromise!: (value: T) => void;\n #rejectPromise!: (error: Error) => void;\n #done: boolean = false;\n #rejected: boolean = false;\n #result: T | undefined = undefined;\n #error: Error | undefined = undefined;\n\n constructor() {\n this.#await = new Promise<T>((resolve, reject) => {\n this.#resolvePromise = resolve;\n this.#rejectPromise = reject;\n });\n }\n\n get await() {\n return this.#await;\n }\n\n get done() {\n return this.#done;\n }\n\n get result(): T {\n if (!this.#done) {\n throw new Error('Future is not done');\n }\n\n if (this.#rejected) {\n throw this.#error;\n }\n\n return this.#result!;\n }\n\n /** Whether the future was rejected (cancelled) */\n get rejected() {\n return this.#rejected;\n }\n\n resolve(value: T) {\n this.#done = true;\n this.#result = value;\n this.#resolvePromise(value);\n }\n\n reject(error: Error) {\n this.#done = true;\n this.#rejected = true;\n this.#error = error;\n this.#rejectPromise(error);\n }\n}\n\n/** @internal */\nexport class Event {\n #isSet = false;\n #waiters: Array<() => void> = [];\n\n async wait() {\n if (this.#isSet) return true;\n\n let resolve: () => void = noop;\n const waiter = new Promise<void>((r) => {\n resolve = r;\n this.#waiters.push(resolve);\n });\n\n try {\n await waiter;\n return true;\n } finally {\n const index = this.#waiters.indexOf(resolve);\n if (index !== -1) {\n this.#waiters.splice(index, 1);\n }\n }\n }\n\n get isSet(): boolean {\n return this.#isSet;\n }\n\n set(): void {\n if (this.#isSet) return;\n\n this.#isSet = true;\n this.#waiters.forEach((resolve) => resolve());\n this.#waiters = [];\n }\n\n clear(): void {\n this.#isSet = false;\n }\n}\n\n/** @internal */\nexport class CancellablePromise<T> {\n #promise: Promise<T>;\n #cancelFn: () => void;\n #isCancelled: boolean = false;\n #error: Error | null = null;\n\n constructor(\n executor: (\n resolve: (value: T | PromiseLike<T>) => void,\n reject: (reason?: unknown) => void,\n onCancel: (cancelFn: () => void) => void,\n ) => void,\n ) {\n let cancel: () => void;\n\n this.#promise = new Promise<T>((resolve, reject) => {\n executor(\n resolve,\n (reason) => {\n this.#error = reason instanceof Error ? reason : new Error(String(reason));\n reject(reason);\n },\n (cancelFn) => {\n cancel = () => {\n this.#isCancelled = true;\n cancelFn();\n };\n },\n );\n });\n\n this.#cancelFn = cancel!;\n }\n\n get isCancelled(): boolean {\n return this.#isCancelled;\n }\n\n get error(): Error | null {\n return this.#error;\n }\n\n then<TResult1 = T, TResult2 = never>(\n onfulfilled?: ((value: T) => TResult1 | Promise<TResult1>) | null,\n onrejected?: ((reason: unknown) => TResult2 | Promise<TResult2>) | null,\n ): Promise<TResult1 | TResult2> {\n return this.#promise.then(onfulfilled, onrejected);\n }\n\n catch<TResult = never>(\n onrejected?: ((reason: unknown) => TResult | Promise<TResult>) | null,\n ): Promise<T | TResult> {\n return this.#promise.catch(onrejected);\n }\n\n finally(onfinally?: (() => void) | null): Promise<T> {\n return this.#promise.finally(onfinally);\n }\n\n cancel(): void {\n this.#cancelFn();\n }\n\n static from<T>(promise: Promise<T>): CancellablePromise<T> {\n return new CancellablePromise<T>((resolve, reject) => {\n promise.then(resolve).catch(reject);\n });\n }\n}\n\n/** @internal */\nexport async function gracefullyCancel<T>(promise: CancellablePromise<T>): Promise<void> {\n if (!promise.isCancelled) {\n promise.cancel();\n }\n try {\n await promise;\n } catch (error) {\n // Ignore the error, as it's expected due to cancellation\n }\n}\n\n/** @internal */\nexport class AsyncIterableQueue<T> implements AsyncIterableIterator<T> {\n private static readonly CLOSE_SENTINEL = Symbol('CLOSE_SENTINEL');\n #queue = new Queue<T | typeof AsyncIterableQueue.CLOSE_SENTINEL>();\n #closed = false;\n\n get closed(): boolean {\n return this.#closed;\n }\n\n put(item: T): void {\n if (this.#closed) {\n throw new Error('Queue is closed');\n }\n this.#queue.put(item);\n }\n\n close(): void {\n this.#closed = true;\n this.#queue.put(AsyncIterableQueue.CLOSE_SENTINEL);\n }\n\n async next(): Promise<IteratorResult<T>> {\n if (this.#closed && this.#queue.items.length === 0) {\n return { value: undefined, done: true };\n }\n const item = await this.#queue.get();\n if (item === AsyncIterableQueue.CLOSE_SENTINEL && this.#closed) {\n return { value: undefined, done: true };\n }\n return { value: item as T, done: false };\n }\n\n [Symbol.asyncIterator](): AsyncIterableQueue<T> {\n return this;\n }\n}\n\n/** @internal */\nexport class ExpFilter {\n #alpha: number;\n #max?: number;\n #filtered?: number = undefined;\n\n constructor(alpha: number, max?: number) {\n this.#alpha = alpha;\n this.#max = max;\n }\n\n reset(alpha?: number) {\n if (alpha) {\n this.#alpha = alpha;\n }\n this.#filtered = undefined;\n }\n\n apply(exp: number, sample: number): number {\n if (this.#filtered) {\n const a = this.#alpha ** exp;\n this.#filtered = a * this.#filtered + (1 - a) * sample;\n } else {\n this.#filtered = sample;\n }\n\n if (this.#max && this.#filtered > this.#max) {\n this.#filtered = this.#max;\n }\n\n return this.#filtered;\n }\n\n get filtered(): number | undefined {\n return this.#filtered;\n }\n\n set alpha(alpha: number) {\n this.#alpha = alpha;\n }\n}\n\n/** @internal */\nexport class AudioEnergyFilter {\n #cooldownSeconds: number;\n #cooldown: number;\n\n constructor(cooldownSeconds = 1) {\n this.#cooldownSeconds = cooldownSeconds;\n this.#cooldown = cooldownSeconds;\n }\n\n pushFrame(frame: AudioFrame): boolean {\n const arr = Float32Array.from(frame.data, (x) => x / 32768);\n const rms = (arr.map((x) => x ** 2).reduce((acc, x) => acc + x) / arr.length) ** 0.5;\n if (rms > 0.004) {\n this.#cooldown = this.#cooldownSeconds;\n return true;\n }\n\n const durationSeconds = frame.samplesPerChannel / frame.sampleRate;\n this.#cooldown -= durationSeconds;\n if (this.#cooldown > 0) {\n return true;\n }\n\n return false;\n }\n}\n\nexport enum TaskResult {\n Timeout = 'timeout',\n Completed = 'completed',\n Aborted = 'aborted',\n}\n\n/** @internal */\n/**\n * A task that can be cancelled.\n *\n * We recommend using the `Task.from` method to create a task. When creating subtasks, pass the same controller to all subtasks.\n *\n * @example\n * ```ts\n * const parent = Task.from((controller) => {\n * const child1 = Task.from(() => { ... }, controller);\n * const child2 = Task.from(() => { ... }, controller);\n * });\n * parent.cancel();\n * ```\n *\n * This will cancel all subtasks when the parent is cancelled.\n *\n * @param T - The type of the task result\n */\nexport class Task<T> {\n private static readonly currentTaskStorage = new AsyncLocalStorage<Task<unknown>>();\n private resultFuture: Future<T>;\n private doneCallbacks: Set<() => void> = new Set();\n\n #logger = log();\n\n constructor(\n private readonly fn: (controller: AbortController) => Promise<T>,\n private readonly controller: AbortController,\n readonly name?: string,\n ) {\n this.resultFuture = new Future();\n void this.resultFuture.await\n .then(\n () => undefined,\n () => undefined,\n )\n .finally(() => {\n for (const callback of this.doneCallbacks) {\n try {\n callback();\n } catch (error) {\n this.#logger.error({ error }, 'Task done callback failed');\n }\n }\n this.doneCallbacks.clear();\n });\n this.runTask();\n }\n\n /**\n * Creates a new task from a function.\n *\n * @param fn - The function to run\n * @param controller - The abort controller to use\n * @returns A new task\n */\n static from<T>(\n fn: (controller: AbortController) => Promise<T>,\n controller?: AbortController,\n name?: string,\n ) {\n const abortController = controller ?? new AbortController();\n return new Task(fn, abortController, name);\n }\n\n /**\n * Returns the currently running task in this async context, if available.\n */\n static current(): Task<unknown> | undefined {\n return Task.currentTaskStorage.getStore();\n }\n\n private async runTask() {\n const run = async () => {\n if (this.name) {\n this.#logger.debug(`Task.runTask: task ${this.name} started`);\n }\n return await this.fn(this.controller);\n };\n\n return Task.currentTaskStorage\n .run(this as Task<unknown>, run)\n .then((value) => {\n this.resultFuture.resolve(value);\n return value;\n })\n .catch((error) => {\n this.resultFuture.reject(error);\n })\n .finally(() => {\n if (this.name) {\n this.#logger.debug(`Task.runTask: task ${this.name} done`);\n }\n });\n }\n\n /**\n * Cancels the task.\n */\n cancel() {\n this.controller.abort();\n }\n\n /**\n * Cancels the task and waits for it to complete.\n *\n * @param timeout - The timeout in milliseconds\n * @returns The result status of the task (timeout, completed, aborted)\n */\n async cancelAndWait(timeout?: number) {\n this.cancel();\n\n // Race between task completion and timeout\n const promises = [\n this.result\n .then(() => TaskResult.Completed)\n .catch((error) => {\n if (error.name === 'AbortError') {\n return TaskResult.Aborted;\n }\n throw error;\n }),\n ];\n\n if (timeout) {\n promises.push(delay(timeout).then(() => TaskResult.Timeout));\n }\n\n const result = await Promise.race(promises);\n\n // Check what happened\n if (result === TaskResult.Timeout) {\n throw new Error('Task cancellation timed out');\n }\n\n return result;\n }\n\n /**\n * The result of the task.\n */\n get result(): Promise<T> {\n return this.resultFuture.await;\n }\n\n /**\n * Whether the task has completed.\n */\n get done(): boolean {\n return this.resultFuture.done;\n }\n\n addDoneCallback(callback: () => void) {\n if (this.done) {\n queueMicrotask(callback);\n return;\n }\n this.doneCallbacks.add(callback);\n }\n\n removeDoneCallback(callback: () => void) {\n this.doneCallbacks.delete(callback);\n }\n}\n\nexport async function waitFor(tasks: Task<void>[]): Promise<void> {\n await Promise.allSettled(tasks.map((task) => task.result));\n}\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport async function cancelAndWait(tasks: Task<any>[], timeout?: number): Promise<void> {\n await Promise.allSettled(tasks.map((task) => task.cancelAndWait(timeout)));\n}\n\nexport function withResolvers<T = unknown>() {\n let resolve!: (value: T | PromiseLike<T>) => void;\n let reject!: (reason?: unknown) => void;\n\n const promise = new Promise<T>((res, rej) => {\n resolve = res;\n reject = rej;\n });\n\n return { promise, resolve, reject };\n}\n\n/**\n * Generates a short UUID with a prefix. Mirrors the python agents implementation.\n *\n * @param prefix - The prefix to add to the UUID.\n * @returns A short UUID with the prefix.\n */\nexport function shortuuid(prefix: string = ''): string {\n return `${prefix}${uuidv4().slice(0, 12)}`;\n}\n\nconst READONLY_SYMBOL = Symbol('Readonly');\n\nconst MUTATION_METHODS = [\n 'push',\n 'pop',\n 'shift',\n 'unshift',\n 'splice',\n 'sort',\n 'reverse',\n 'fill',\n 'copyWithin',\n] as const;\n\n// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy\n/**\n * Creates a read-only proxy for an array.\n * @param array - The array to make read-only.\n * @param additionalErrorMessage - An additional error message to include in the error thrown when a mutation method is called.\n * @returns A read-only proxy for the array.\n */\nexport function createImmutableArray<T>(array: T[], additionalErrorMessage: string = ''): T[] {\n return new Proxy(array, {\n get(target, key) {\n if (key === READONLY_SYMBOL) {\n return true;\n }\n\n // Intercept mutation methods\n if (\n typeof key === 'string' &&\n MUTATION_METHODS.includes(key as (typeof MUTATION_METHODS)[number])\n ) {\n return function () {\n throw new TypeError(\n `Cannot call ${key}() on a read-only array. ${additionalErrorMessage}`.trim(),\n );\n };\n }\n\n return Reflect.get(target, key);\n },\n set(_, prop) {\n throw new TypeError(\n `Cannot assign to read-only array index \"${String(prop)}\". ${additionalErrorMessage}`.trim(),\n );\n },\n deleteProperty(_, prop) {\n throw new TypeError(\n `Cannot delete read-only array index \"${String(prop)}\". ${additionalErrorMessage}`.trim(),\n );\n },\n defineProperty(_, prop) {\n throw new TypeError(\n `Cannot define property \"${String(prop)}\" on a read-only array. ${additionalErrorMessage}`.trim(),\n );\n },\n setPrototypeOf() {\n throw new TypeError(\n `Cannot change prototype of a read-only array. ${additionalErrorMessage}`.trim(),\n );\n },\n });\n}\n\nexport function isImmutableArray(array: unknown): boolean {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n return typeof array === 'object' && !!(array as any)[READONLY_SYMBOL];\n}\n\n/**\n * Resamples an audio stream to a target sample rate.\n *\n * WARINING: The input stream will be locked until the resampled stream is closed.\n *\n * @param stream - The input stream to resample.\n * @param outputRate - The target sample rate.\n * @returns A new stream with the resampled audio.\n */\nexport function resampleStream({\n stream,\n outputRate,\n}: {\n stream: ReadableStream<AudioFrame>;\n outputRate: number;\n}): ReadableStream<AudioFrame> {\n let resampler: AudioResampler | null = null;\n const transformStream = new TransformStream<AudioFrame, AudioFrame>({\n transform(chunk: AudioFrame, controller: TransformStreamDefaultController<AudioFrame>) {\n if (chunk.samplesPerChannel === 0) {\n controller.enqueue(chunk);\n return;\n }\n if (!resampler) {\n resampler = new AudioResampler(chunk.sampleRate, outputRate);\n }\n for (const frame of resampler.push(chunk)) {\n controller.enqueue(frame);\n }\n },\n flush(controller) {\n if (resampler) {\n for (const frame of resampler.flush()) {\n controller.enqueue(frame);\n }\n }\n },\n });\n return stream.pipeThrough(transformStream);\n}\n\nexport class InvalidErrorType extends Error {\n readonly error: unknown;\n\n constructor(error: unknown) {\n super(`Expected error, got ${error} (${typeof error})`);\n this.error = error;\n Error.captureStackTrace(this, InvalidErrorType);\n }\n}\n\n/**\n * Check if an error is a stream closed error that can be safely ignored during cleanup.\n * This happens during handover/cleanup when close() is called while operations are still running.\n *\n * @param error - The error to check.\n * @returns True if the error is a stream closed error.\n */\nexport function isStreamClosedError(error: unknown): boolean {\n return (\n error instanceof Error &&\n (error.message === 'Stream is closed' || error.message === 'Input is closed')\n );\n}\n\n/**\n * In JS an error can be any arbitrary value.\n * This function converts an unknown error to an Error and stores the original value in the error object.\n *\n * @param error - The error to convert.\n * @returns An Error.\n */\nexport function toError(error: unknown): Error {\n if (error instanceof Error) {\n return error;\n }\n throw new InvalidErrorType(error);\n}\n\n/**\n * This is a hack to immitate asyncio.create_task so that\n * func will be run after the current event loop iteration.\n *\n * @param func - The function to run.\n */\nexport function startSoon(func: () => void) {\n setTimeout(func, 0);\n}\n\nexport type DelayOptions = {\n signal?: AbortSignal;\n};\n\n/**\n * Delay for a given number of milliseconds.\n *\n * @param ms - The number of milliseconds to delay.\n * @param options - The options for the delay.\n * @returns A promise that resolves after the delay.\n */\nexport function delay(ms: number, options: DelayOptions = {}): Promise<void> {\n const { signal } = options;\n if (signal?.aborted) return Promise.reject(signal.reason);\n return new Promise((resolve, reject) => {\n const abort = () => {\n clearTimeout(i);\n reject(signal?.reason);\n };\n const done = () => {\n signal?.removeEventListener('abort', abort);\n resolve();\n };\n const i = setTimeout(done, ms);\n signal?.addEventListener('abort', abort, { once: true });\n });\n}\n\n/**\n * Returns a participant that matches the given identity. If identity is None, the first\n * participant that joins the room will be returned.\n * If the participant has already joined, the function will return immediately.\n * @param room - The room to wait for a participant in.\n * @param identity - The identity of the participant to wait for.\n * @param kind - The kind of the participant to wait for.\n * @returns A promise that resolves to the participant.\n */\nexport async function waitForParticipant({\n room,\n identity,\n kind,\n}: {\n room: Room;\n identity?: string;\n kind?: ParticipantKind | ParticipantKind[];\n}): Promise<RemoteParticipant> {\n if (!room.isConnected) {\n throw new Error('Room is not connected');\n }\n\n const fut = new Future<RemoteParticipant>();\n\n const kindMatch = (participant: RemoteParticipant) => {\n if (kind === undefined) return true;\n\n if (Array.isArray(kind)) {\n return kind.includes(participant.kind);\n }\n\n return participant.kind === kind;\n };\n\n const onParticipantConnected = (p: RemoteParticipant) => {\n if ((identity === undefined || p.identity === identity) && kindMatch(p)) {\n if (!fut.done) {\n fut.resolve(p);\n }\n }\n };\n\n room.on(RoomEvent.ParticipantConnected, onParticipantConnected);\n\n try {\n for (const p of room.remoteParticipants.values()) {\n onParticipantConnected(p);\n if (fut.done) {\n break;\n }\n }\n\n return await fut.await;\n } finally {\n room.off(RoomEvent.ParticipantConnected, onParticipantConnected);\n }\n}\n\nexport async function waitForTrackPublication({\n room,\n identity,\n kind,\n}: {\n room: Room;\n identity: string;\n kind: TrackKind;\n}): Promise<RemoteTrackPublication> {\n if (!room.isConnected) {\n throw new Error('Room is not connected');\n }\n\n const fut = new Future<RemoteTrackPublication>();\n\n const kindMatch = (k: TrackKind | undefined) => {\n if (kind === undefined || kind === null) {\n return true;\n }\n return k === kind;\n };\n\n const onTrackPublished = (\n publication: RemoteTrackPublication,\n participant: RemoteParticipant,\n ) => {\n if (fut.done) return;\n if (\n (identity === undefined || participant.identity === identity) &&\n kindMatch(publication.kind)\n ) {\n fut.resolve(publication);\n }\n };\n\n room.on(RoomEvent.TrackPublished, onTrackPublished);\n\n try {\n for (const p of room.remoteParticipants.values()) {\n for (const publication of p.trackPublications.values()) {\n onTrackPublished(publication, p);\n if (fut.done) break;\n }\n }\n\n return await fut.await;\n } finally {\n room.off(RoomEvent.TrackPublished, onTrackPublished);\n }\n}\n\nexport async function waitForAbort(signal: AbortSignal) {\n const abortFuture = new Future<void>();\n const handler = () => {\n abortFuture.resolve();\n signal.removeEventListener('abort', handler);\n };\n\n signal.addEventListener('abort', handler, { once: true });\n return await abortFuture.await;\n}\n\n/**\n * Combines two abort signals into a single abort signal.\n * @param a - The first abort signal.\n * @param b - The second abort signal.\n * @returns A new abort signal that is aborted when either of the input signals is aborted.\n */\nexport const combineSignals = (a: AbortSignal, b: AbortSignal): AbortSignal => {\n const c = new AbortController();\n const abortFrom = (s: AbortSignal) => {\n if (c.signal.aborted) return;\n c.abort((s as any).reason);\n };\n if (a.aborted) {\n abortFrom(a);\n } else {\n a.addEventListener('abort', () => abortFrom(a), { once: true });\n }\n if (b.aborted) {\n abortFrom(b);\n } else {\n b.addEventListener('abort', () => abortFrom(b), { once: true });\n }\n return c.signal;\n};\n\nexport const isCloud = (url: URL) => {\n const hostname = url.hostname;\n return hostname.endsWith('.livekit.cloud') || hostname.endsWith('.livekit.run');\n};\n"],"mappings":"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","names":["item","TaskResult"]}
@@ -347,6 +347,77 @@ var import_utils = require("../src/utils.cjs");
347
347
  (0, import_vitest.expect)(error.name).toBe("TypeError");
348
348
  }
349
349
  });
350
+ (0, import_vitest.it)("should return undefined for Task.current outside task context", () => {
351
+ (0, import_vitest.expect)(import_utils.Task.current()).toBeUndefined();
352
+ });
353
+ (0, import_vitest.it)("should preserve Task.current inside a task across awaits", async () => {
354
+ const task = import_utils.Task.from(
355
+ async () => {
356
+ const currentAtStart = import_utils.Task.current();
357
+ await (0, import_utils.delay)(5);
358
+ const currentAfterAwait = import_utils.Task.current();
359
+ (0, import_vitest.expect)(currentAtStart).toBeDefined();
360
+ (0, import_vitest.expect)(currentAfterAwait).toBe(currentAtStart);
361
+ return currentAtStart;
362
+ },
363
+ void 0,
364
+ "current-context-test"
365
+ );
366
+ const currentFromResult = await task.result;
367
+ (0, import_vitest.expect)(currentFromResult).toBe(task);
368
+ });
369
+ (0, import_vitest.it)("should isolate nested Task.current context and restore parent context", async () => {
370
+ const parentTask = import_utils.Task.from(
371
+ async (controller) => {
372
+ const parentCurrent2 = import_utils.Task.current();
373
+ (0, import_vitest.expect)(parentCurrent2).toBeDefined();
374
+ const childTask = import_utils.Task.from(
375
+ async () => {
376
+ const childCurrentStart = import_utils.Task.current();
377
+ await (0, import_utils.delay)(5);
378
+ const childCurrentAfterAwait = import_utils.Task.current();
379
+ (0, import_vitest.expect)(childCurrentStart).toBeDefined();
380
+ (0, import_vitest.expect)(childCurrentAfterAwait).toBe(childCurrentStart);
381
+ (0, import_vitest.expect)(childCurrentStart).not.toBe(parentCurrent2);
382
+ return childCurrentStart;
383
+ },
384
+ controller,
385
+ "child-current-context-test"
386
+ );
387
+ const childCurrent2 = await childTask.result;
388
+ const parentCurrentAfterChild = import_utils.Task.current();
389
+ (0, import_vitest.expect)(parentCurrentAfterChild).toBe(parentCurrent2);
390
+ return { parentCurrent: parentCurrent2, childCurrent: childCurrent2 };
391
+ },
392
+ void 0,
393
+ "parent-current-context-test"
394
+ );
395
+ const { parentCurrent, childCurrent } = await parentTask.result;
396
+ (0, import_vitest.expect)(parentCurrent).toBe(parentTask);
397
+ (0, import_vitest.expect)(childCurrent).not.toBe(parentCurrent);
398
+ (0, import_vitest.expect)(import_utils.Task.current()).toBeUndefined();
399
+ });
400
+ (0, import_vitest.it)("should always expose Task.current for concurrent task callbacks", async () => {
401
+ const tasks = Array.from(
402
+ { length: 25 },
403
+ (_, idx) => import_utils.Task.from(
404
+ async () => {
405
+ const currentAtStart = import_utils.Task.current();
406
+ await (0, import_utils.delay)(1);
407
+ const currentAfterAwait = import_utils.Task.current();
408
+ (0, import_vitest.expect)(currentAtStart).toBeDefined();
409
+ (0, import_vitest.expect)(currentAfterAwait).toBe(currentAtStart);
410
+ return currentAtStart;
411
+ },
412
+ void 0,
413
+ `current-context-stress-${idx}`
414
+ )
415
+ );
416
+ const currentTasks = await Promise.all(tasks.map((task) => task.result));
417
+ currentTasks.forEach((currentTask, idx) => {
418
+ (0, import_vitest.expect)(currentTask).toBe(tasks[idx]);
419
+ });
420
+ });
350
421
  });
351
422
  (0, import_vitest.describe)("Event", () => {
352
423
  (0, import_vitest.it)("wait resolves immediately when the event is already set", async () => {
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/utils.test.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2024 LiveKit, Inc.\n//\n// SPDX-License-Identifier: Apache-2.0\nimport { AudioFrame } from '@livekit/rtc-node';\nimport { ReadableStream } from 'node:stream/web';\nimport { describe, expect, it } from 'vitest';\nimport { initializeLogger } from '../src/log.js';\nimport { Event, Task, TaskResult, delay, isPending, resampleStream } from '../src/utils.js';\n\ndescribe('utils', () => {\n // initialize logger\n initializeLogger({ pretty: true, level: 'debug' });\n\n describe('Task', () => {\n it('should execute task successfully and return result', async () => {\n const expectedResult = 'task completed';\n const task = Task.from(async () => {\n await delay(10);\n return expectedResult;\n });\n\n expect(task.done).toBe(false);\n const result = await task.result;\n expect(result).toBe(expectedResult);\n expect(task.done).toBe(true);\n });\n\n it('should handle task errors properly', async () => {\n const expectedError = new Error('Task failed');\n const task = Task.from(async () => {\n await delay(10);\n throw expectedError;\n });\n\n expect(task.done).toBe(false);\n await expect(task.result).rejects.toThrow(expectedError);\n expect(task.done).toBe(true);\n });\n\n it('should cancel task when cancel is called', async () => {\n let taskStarted = false;\n let taskCompleted = false;\n\n const task = Task.from(async (controller) => {\n taskStarted = true;\n await delay(100, { signal: controller.signal });\n taskCompleted = true;\n return 'should not complete';\n });\n\n // Wait a bit to ensure task starts\n await delay(10);\n expect(taskStarted).toBe(true);\n expect(task.done).toBe(false);\n\n // Cancel the task\n task.cancel();\n\n // The task should reject with AbortError\n try {\n await task.result;\n } catch (error: unknown) {\n expect((error as Error).name).toBe('AbortError');\n }\n\n expect(taskCompleted).toBe(false);\n expect(task.done).toBe(true);\n });\n\n it('should use provided AbortController', async () => {\n const controller = new AbortController();\n const task = Task.from(async (ctrl) => {\n expect(ctrl).toBe(controller);\n await delay(100, { signal: ctrl.signal });\n return 'completed';\n }, controller);\n\n await delay(10);\n controller.abort();\n\n try {\n await task.result;\n } catch (error: unknown) {\n expect((error as Error).name).toBe('AbortError');\n }\n\n expect(task.done).toBe(true);\n });\n\n it('should handle immediate resolution', async () => {\n const task = Task.from(async () => {\n return 'immediate';\n });\n\n const result = await task.result;\n expect(result).toBe('immediate');\n expect(task.done).toBe(true);\n });\n\n it('should handle immediate rejection', async () => {\n const expectedError = new Error('Immediate error');\n const task = Task.from(async () => {\n throw expectedError;\n });\n\n try {\n await task.result;\n } catch (error: unknown) {\n expect(error).toBe(expectedError);\n }\n\n expect(task.done).toBe(true);\n });\n\n it('should handle multiple calls to cancel', async () => {\n const task = Task.from(async (controller) => {\n await delay(100, { signal: controller.signal });\n return 'should not complete';\n });\n\n await delay(10);\n\n // Multiple cancellations should not cause issues\n task.cancel();\n task.cancel();\n task.cancel();\n\n try {\n await task.result;\n } catch (error: unknown) {\n expect((error as Error).name).toBe('AbortError');\n }\n\n expect(task.done).toBe(true);\n });\n\n it('should handle task that checks abort signal manually', async () => {\n const arr: number[] = [];\n const task = Task.from(async (controller) => {\n for (let i = 0; i < 10; i++) {\n if (controller.signal.aborted) {\n throw new Error('Task was aborted');\n }\n await delay(10);\n arr.push(i);\n }\n return 'completed';\n });\n\n await delay(39);\n task.cancel();\n\n expect(arr).toEqual([0, 1, 2]);\n try {\n await task.result;\n } catch (error: unknown) {\n expect((error as Error).message).toBe('Task was aborted');\n }\n\n expect(task.done).toBe(true);\n });\n\n it('should handle cleanup in finally block', async () => {\n let cleanupExecuted = false;\n\n const task = Task.from(async (controller) => {\n try {\n await delay(100, { signal: controller.signal });\n return 'completed';\n } finally {\n cleanupExecuted = true;\n }\n });\n\n await delay(10);\n task.cancel();\n\n try {\n await task.result;\n } catch {\n // Ignore the abort error\n }\n\n // Cleanup should still execute even when cancelled\n expect(cleanupExecuted).toBe(true);\n });\n\n it('should handle accessing result multiple times', async () => {\n const task = Task.from(async () => {\n await delay(10);\n return 'result';\n });\n\n const result1 = await task.result;\n const result2 = await task.result;\n const result3 = await task.result;\n\n expect(result1).toBe('result');\n expect(result2).toBe('result');\n expect(result3).toBe('result');\n expect(task.done).toBe(true);\n });\n\n it('should handle accessing result promise before completion', async () => {\n const task = Task.from(async () => {\n await delay(50);\n return 'delayed result';\n });\n\n // Get references to result promise before completion\n const resultPromise1 = task.result;\n const resultPromise2 = task.result;\n\n expect(task.done).toBe(false);\n\n // Both promises should resolve to the same value\n const [result1, result2] = await Promise.all([resultPromise1, resultPromise2]);\n\n expect(result1).toBe('delayed result');\n expect(result2).toBe('delayed result');\n expect(task.done).toBe(true);\n });\n\n it('should cancel child tasks when parent task is canceled', async () => {\n let parentStarted = false;\n let child1Started = false;\n let child2Started = false;\n let parentCompleted = false;\n let child1Completed = false;\n let child2Completed = false;\n\n let child1Task: Task<string> | undefined = undefined;\n let child2Task: Task<string> | undefined = undefined;\n\n const parentTask = Task.from(async (controller) => {\n parentStarted = true;\n\n // Create two child tasks using the parent's controller\n child1Task = Task.from(async (childController) => {\n child1Started = true;\n await delay(100, { signal: childController.signal });\n child1Completed = true;\n return 'child1';\n }, controller);\n\n child2Task = Task.from(async (childController) => {\n child2Started = true;\n await delay(100, { signal: childController.signal });\n child2Completed = true;\n return 'child2';\n }, controller);\n\n // Wait for both child tasks\n const results = await Promise.all([child1Task.result, child2Task.result]);\n parentCompleted = true;\n return results;\n });\n\n // Let tasks start\n await delay(20);\n\n // Verify tasks have started\n expect(parentStarted).toBe(true);\n expect(child1Started).toBe(true);\n expect(child2Started).toBe(true);\n\n // Cancel parent task\n parentTask.cancel();\n\n // Use Promise.allSettled to handle all promise settlements\n const [parentResult, child1Result, child2Result] = await Promise.allSettled([\n parentTask.result,\n child1Task!.result,\n child2Task!.result,\n ]);\n\n // Verify all tasks were rejected with AbortError\n expect(parentResult.status).toBe('rejected');\n expect((parentResult as PromiseRejectedResult).reason.name).toBe('AbortError');\n\n expect(child1Result.status).toBe('rejected');\n expect((child1Result as PromiseRejectedResult).reason.name).toBe('AbortError');\n\n expect(child2Result.status).toBe('rejected');\n expect((child2Result as PromiseRejectedResult).reason.name).toBe('AbortError');\n\n // Verify none of the tasks completed\n expect(parentCompleted).toBe(false);\n expect(child1Completed).toBe(false);\n expect(child2Completed).toBe(false);\n expect(parentTask.done).toBe(true);\n expect(child1Task!.done).toBe(true);\n expect(child2Task!.done).toBe(true);\n });\n\n it('should handle nested tasks that complete successfully', async () => {\n const results: string[] = [];\n\n const parentTask = Task.from(async (controller) => {\n results.push('parent-start');\n\n // Create first child task\n const child1Task = Task.from(async () => {\n results.push('child1-start');\n await delay(25);\n results.push('child1-end');\n return 'child1-result';\n }, controller);\n\n // Create second child task that depends on first\n const child2Task = Task.from(async (childController) => {\n results.push('child2-start');\n\n // Create a grandchild task\n const grandchildTask = Task.from(async () => {\n results.push('grandchild-start');\n await delay(10);\n results.push('grandchild-end');\n return 'grandchild-result';\n }, childController);\n\n const grandchildResult = await grandchildTask.result;\n await delay(10);\n results.push('child2-end');\n return `child2-result-with-${grandchildResult}`;\n }, controller);\n\n // Wait for all tasks\n const [child1Result, child2Result] = await Promise.all([\n child1Task.result,\n child2Task.result,\n ]);\n\n results.push('parent-end');\n return {\n parent: 'parent-result',\n child1: child1Result,\n child2: child2Result,\n };\n });\n\n // Wait for everything to complete\n const finalResult = await parentTask.result;\n\n // Verify results\n expect(finalResult).toEqual({\n parent: 'parent-result',\n child1: 'child1-result',\n child2: 'child2-result-with-grandchild-result',\n });\n\n // Verify execution order\n // Check important ordering constraints without being strict about parallel task ordering\n expect(results).toEqual([\n 'parent-start',\n 'child1-start',\n 'child2-start',\n 'grandchild-start',\n 'grandchild-end',\n 'child2-end',\n 'child1-end',\n 'parent-end',\n ]);\n\n // All tasks should be done\n expect(parentTask.done).toBe(true);\n });\n\n it('should propagate errors from nested tasks', async () => {\n let parentError: Error | null = null;\n let child1Completed = false;\n let child2Started = false;\n\n const parentTask = Task.from(async (controller) => {\n const child1Task = Task.from(async () => {\n await delay(20);\n throw new Error('child1 error');\n }, controller);\n\n const child2Task = Task.from(async () => {\n child2Started = true;\n await delay(30);\n child1Completed = true;\n return 'child2-result';\n }, controller);\n\n // This will throw when child1 fails\n const results = await Promise.all([child1Task.result, child2Task.result]);\n return results;\n });\n\n // Wait for the parent task to fail\n try {\n await parentTask.result;\n expect.fail('Parent task should have thrown');\n } catch (error: unknown) {\n parentError = error as Error;\n }\n\n // Verify the error propagated correctly\n expect(parentError?.message).toBe('child1 error');\n expect(child1Completed).toBe(false);\n expect(child2Started).toBe(true);\n expect(parentTask.done).toBe(true);\n });\n\n it('should cancel and wait for task completion', async () => {\n let taskCompleted = false;\n\n const task = Task.from(async (controller) => {\n await delay(5000, { signal: controller.signal });\n taskCompleted = true;\n return 'should not complete';\n });\n\n // Cancel and wait should complete quickly when task is aborted\n const start = Date.now();\n const result = await task.cancelAndWait(1000);\n const duration = Date.now() - start;\n\n expect(result).toBe(TaskResult.Aborted);\n expect(duration).toBeLessThan(100); // Should not wait for full timeout\n expect(taskCompleted).toBe(false);\n expect(task.done).toBe(true);\n });\n\n it('should timeout if task does not respond to cancellation', async () => {\n const task = Task.from(async () => {\n await delay(1000);\n });\n\n // This should timeout because the task ignores cancellation\n try {\n await task.cancelAndWait(200);\n expect.fail('Task should have timed out');\n } catch (error: unknown) {\n expect(error).instanceof(Error);\n expect((error as Error).message).toBe('Task cancellation timed out');\n }\n });\n\n it('should handle task that completes before timeout', async () => {\n const task = Task.from(async () => {\n await delay(50);\n });\n\n // Start the task\n await delay(10);\n\n // Cancel and wait - but task will complete normally before being canceled\n const result = await task.cancelAndWait(1000);\n\n // Task should have completed normally\n expect(result).toBe(TaskResult.Completed);\n expect(task.done).toBe(true);\n });\n\n it('should propagate non-abort errors from cancelAndWait', async () => {\n const task = Task.from(async () => {\n await delay(10);\n throw new TypeError('Custom error');\n });\n\n try {\n await task.cancelAndWait(1000);\n expect.fail('Task should have thrown');\n } catch (error: unknown) {\n expect((error as Error).message).toBe('Custom error');\n expect((error as Error).name).toBe('TypeError');\n }\n });\n });\n\n describe('Event', () => {\n it('wait resolves immediately when the event is already set', async () => {\n const event = new Event();\n event.set();\n\n const result = await event.wait();\n expect(result).toBe(true);\n });\n\n it('wait resolves after set is called', async () => {\n // check promise is pending\n const event = new Event();\n const waiterPromise = event.wait();\n\n await delay(10);\n expect(await isPending(waiterPromise)).toBe(true);\n\n // check promise is resolved after set is called\n event.set();\n const result = await waiterPromise;\n expect(result).toBe(true);\n });\n\n it('all waiters resolve once set is called', async () => {\n const event = new Event();\n const waiters = [event.wait(), event.wait(), event.wait()];\n\n await delay(10);\n const pendings = await Promise.all(waiters.map((w) => isPending(w)));\n expect(pendings).toEqual([true, true, true]);\n\n event.set();\n const results = await Promise.all(waiters);\n expect(results).toEqual([true, true, true]);\n });\n\n it('wait after 2 seconds is still pending before set', async () => {\n const event = new Event();\n const waiter = event.wait();\n\n await delay(2000);\n expect(await isPending(waiter)).toBe(true);\n\n event.set();\n const result = await waiter;\n expect(result).toBe(true);\n });\n\n it('wait after set and clear should be pending', async () => {\n const event = new Event();\n const waiterBeforeSet = event.wait();\n event.set();\n event.clear();\n\n const waiterAfterSet = event.wait();\n\n const result = await Promise.race([\n waiterBeforeSet.then(() => 'before'),\n waiterAfterSet.then(() => 'after'),\n ]);\n\n expect(result).toBe('before');\n expect(await isPending(waiterBeforeSet)).toBe(false);\n expect(await isPending(waiterAfterSet)).toBe(true);\n\n event.set();\n expect(await waiterAfterSet).toBe(true);\n });\n });\n\n describe('resampleStream', () => {\n const createAudioFrame = (sampleRate: number, samples: number, channels = 1): AudioFrame => {\n const data = new Int16Array(samples * channels);\n for (let i = 0; i < data.length; i++) {\n data[i] = Math.sin((i / samples) * Math.PI * 2) * 16000;\n }\n return new AudioFrame(data, sampleRate, channels, samples);\n };\n\n const streamToArray = async (stream: ReadableStream<AudioFrame>): Promise<AudioFrame[]> => {\n const reader = stream.getReader();\n const chunks: AudioFrame[] = [];\n try {\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n chunks.push(value);\n }\n } finally {\n reader.releaseLock();\n }\n return chunks;\n };\n\n it('should resample audio frames to target sample rate', async () => {\n const inputRate = 48000;\n const outputRate = 16000;\n const inputFrame = createAudioFrame(inputRate, 960); // 20ms at 48kHz\n\n const inputStream = new ReadableStream<AudioFrame>({\n start(controller) {\n controller.enqueue(inputFrame);\n controller.close();\n },\n });\n\n const outputStream = resampleStream({ stream: inputStream, outputRate });\n const outputFrames = await streamToArray(outputStream);\n\n expect(outputFrames.length).toBeGreaterThan(0);\n\n for (const frame of outputFrames) {\n expect(frame.sampleRate).toBe(outputRate);\n expect(frame.channels).toBe(inputFrame.channels);\n }\n });\n\n it('should handle same input and output rate', async () => {\n const sampleRate = 44100;\n const inputFrame = createAudioFrame(sampleRate, 1024);\n\n const inputStream = new ReadableStream<AudioFrame>({\n start(controller) {\n controller.enqueue(inputFrame);\n controller.close();\n },\n });\n\n const outputStream = resampleStream({ stream: inputStream, outputRate: sampleRate });\n const outputFrames = await streamToArray(outputStream);\n\n expect(outputFrames.length).toBeGreaterThan(0);\n\n for (const frame of outputFrames) {\n expect(frame.sampleRate).toBe(sampleRate);\n expect(frame.channels).toBe(inputFrame.channels);\n }\n });\n\n it('should handle multiple input frames', async () => {\n const inputRate = 32000;\n const outputRate = 48000;\n const frame1 = createAudioFrame(inputRate, 640);\n const frame2 = createAudioFrame(inputRate, 640);\n\n const inputStream = new ReadableStream<AudioFrame>({\n start(controller) {\n controller.enqueue(frame1);\n controller.enqueue(frame2);\n controller.close();\n },\n });\n\n const outputStream = resampleStream({ stream: inputStream, outputRate });\n const outputFrames = await streamToArray(outputStream);\n\n expect(outputFrames.length).toBeGreaterThan(0);\n\n for (const frame of outputFrames) {\n expect(frame.sampleRate).toBe(outputRate);\n expect(frame.channels).toBe(frame1.channels);\n }\n });\n\n it('should handle empty stream', async () => {\n const inputStream = new ReadableStream<AudioFrame>({\n start(controller) {\n controller.close();\n },\n });\n\n const outputStream = resampleStream({ stream: inputStream, outputRate: 44100 });\n const outputFrames = await streamToArray(outputStream);\n\n expect(outputFrames).toEqual([]);\n });\n });\n});\n"],"mappings":";AAGA,sBAA2B;AAC3B,iBAA+B;AAC/B,oBAAqC;AACrC,iBAAiC;AACjC,mBAA0E;AAAA,IAE1E,wBAAS,SAAS,MAAM;AAEtB,mCAAiB,EAAE,QAAQ,MAAM,OAAO,QAAQ,CAAC;AAEjD,8BAAS,QAAQ,MAAM;AACrB,0BAAG,sDAAsD,YAAY;AACnE,YAAM,iBAAiB;AACvB,YAAM,OAAO,kBAAK,KAAK,YAAY;AACjC,kBAAM,oBAAM,EAAE;AACd,eAAO;AAAA,MACT,CAAC;AAED,gCAAO,KAAK,IAAI,EAAE,KAAK,KAAK;AAC5B,YAAM,SAAS,MAAM,KAAK;AAC1B,gCAAO,MAAM,EAAE,KAAK,cAAc;AAClC,gCAAO,KAAK,IAAI,EAAE,KAAK,IAAI;AAAA,IAC7B,CAAC;AAED,0BAAG,sCAAsC,YAAY;AACnD,YAAM,gBAAgB,IAAI,MAAM,aAAa;AAC7C,YAAM,OAAO,kBAAK,KAAK,YAAY;AACjC,kBAAM,oBAAM,EAAE;AACd,cAAM;AAAA,MACR,CAAC;AAED,gCAAO,KAAK,IAAI,EAAE,KAAK,KAAK;AAC5B,gBAAM,sBAAO,KAAK,MAAM,EAAE,QAAQ,QAAQ,aAAa;AACvD,gCAAO,KAAK,IAAI,EAAE,KAAK,IAAI;AAAA,IAC7B,CAAC;AAED,0BAAG,4CAA4C,YAAY;AACzD,UAAI,cAAc;AAClB,UAAI,gBAAgB;AAEpB,YAAM,OAAO,kBAAK,KAAK,OAAO,eAAe;AAC3C,sBAAc;AACd,kBAAM,oBAAM,KAAK,EAAE,QAAQ,WAAW,OAAO,CAAC;AAC9C,wBAAgB;AAChB,eAAO;AAAA,MACT,CAAC;AAGD,gBAAM,oBAAM,EAAE;AACd,gCAAO,WAAW,EAAE,KAAK,IAAI;AAC7B,gCAAO,KAAK,IAAI,EAAE,KAAK,KAAK;AAG5B,WAAK,OAAO;AAGZ,UAAI;AACF,cAAM,KAAK;AAAA,MACb,SAAS,OAAgB;AACvB,kCAAQ,MAAgB,IAAI,EAAE,KAAK,YAAY;AAAA,MACjD;AAEA,gCAAO,aAAa,EAAE,KAAK,KAAK;AAChC,gCAAO,KAAK,IAAI,EAAE,KAAK,IAAI;AAAA,IAC7B,CAAC;AAED,0BAAG,uCAAuC,YAAY;AACpD,YAAM,aAAa,IAAI,gBAAgB;AACvC,YAAM,OAAO,kBAAK,KAAK,OAAO,SAAS;AACrC,kCAAO,IAAI,EAAE,KAAK,UAAU;AAC5B,kBAAM,oBAAM,KAAK,EAAE,QAAQ,KAAK,OAAO,CAAC;AACxC,eAAO;AAAA,MACT,GAAG,UAAU;AAEb,gBAAM,oBAAM,EAAE;AACd,iBAAW,MAAM;AAEjB,UAAI;AACF,cAAM,KAAK;AAAA,MACb,SAAS,OAAgB;AACvB,kCAAQ,MAAgB,IAAI,EAAE,KAAK,YAAY;AAAA,MACjD;AAEA,gCAAO,KAAK,IAAI,EAAE,KAAK,IAAI;AAAA,IAC7B,CAAC;AAED,0BAAG,sCAAsC,YAAY;AACnD,YAAM,OAAO,kBAAK,KAAK,YAAY;AACjC,eAAO;AAAA,MACT,CAAC;AAED,YAAM,SAAS,MAAM,KAAK;AAC1B,gCAAO,MAAM,EAAE,KAAK,WAAW;AAC/B,gCAAO,KAAK,IAAI,EAAE,KAAK,IAAI;AAAA,IAC7B,CAAC;AAED,0BAAG,qCAAqC,YAAY;AAClD,YAAM,gBAAgB,IAAI,MAAM,iBAAiB;AACjD,YAAM,OAAO,kBAAK,KAAK,YAAY;AACjC,cAAM;AAAA,MACR,CAAC;AAED,UAAI;AACF,cAAM,KAAK;AAAA,MACb,SAAS,OAAgB;AACvB,kCAAO,KAAK,EAAE,KAAK,aAAa;AAAA,MAClC;AAEA,gCAAO,KAAK,IAAI,EAAE,KAAK,IAAI;AAAA,IAC7B,CAAC;AAED,0BAAG,0CAA0C,YAAY;AACvD,YAAM,OAAO,kBAAK,KAAK,OAAO,eAAe;AAC3C,kBAAM,oBAAM,KAAK,EAAE,QAAQ,WAAW,OAAO,CAAC;AAC9C,eAAO;AAAA,MACT,CAAC;AAED,gBAAM,oBAAM,EAAE;AAGd,WAAK,OAAO;AACZ,WAAK,OAAO;AACZ,WAAK,OAAO;AAEZ,UAAI;AACF,cAAM,KAAK;AAAA,MACb,SAAS,OAAgB;AACvB,kCAAQ,MAAgB,IAAI,EAAE,KAAK,YAAY;AAAA,MACjD;AAEA,gCAAO,KAAK,IAAI,EAAE,KAAK,IAAI;AAAA,IAC7B,CAAC;AAED,0BAAG,wDAAwD,YAAY;AACrE,YAAM,MAAgB,CAAC;AACvB,YAAM,OAAO,kBAAK,KAAK,OAAO,eAAe;AAC3C,iBAAS,IAAI,GAAG,IAAI,IAAI,KAAK;AAC3B,cAAI,WAAW,OAAO,SAAS;AAC7B,kBAAM,IAAI,MAAM,kBAAkB;AAAA,UACpC;AACA,oBAAM,oBAAM,EAAE;AACd,cAAI,KAAK,CAAC;AAAA,QACZ;AACA,eAAO;AAAA,MACT,CAAC;AAED,gBAAM,oBAAM,EAAE;AACd,WAAK,OAAO;AAEZ,gCAAO,GAAG,EAAE,QAAQ,CAAC,GAAG,GAAG,CAAC,CAAC;AAC7B,UAAI;AACF,cAAM,KAAK;AAAA,MACb,SAAS,OAAgB;AACvB,kCAAQ,MAAgB,OAAO,EAAE,KAAK,kBAAkB;AAAA,MAC1D;AAEA,gCAAO,KAAK,IAAI,EAAE,KAAK,IAAI;AAAA,IAC7B,CAAC;AAED,0BAAG,0CAA0C,YAAY;AACvD,UAAI,kBAAkB;AAEtB,YAAM,OAAO,kBAAK,KAAK,OAAO,eAAe;AAC3C,YAAI;AACF,oBAAM,oBAAM,KAAK,EAAE,QAAQ,WAAW,OAAO,CAAC;AAC9C,iBAAO;AAAA,QACT,UAAE;AACA,4BAAkB;AAAA,QACpB;AAAA,MACF,CAAC;AAED,gBAAM,oBAAM,EAAE;AACd,WAAK,OAAO;AAEZ,UAAI;AACF,cAAM,KAAK;AAAA,MACb,QAAQ;AAAA,MAER;AAGA,gCAAO,eAAe,EAAE,KAAK,IAAI;AAAA,IACnC,CAAC;AAED,0BAAG,iDAAiD,YAAY;AAC9D,YAAM,OAAO,kBAAK,KAAK,YAAY;AACjC,kBAAM,oBAAM,EAAE;AACd,eAAO;AAAA,MACT,CAAC;AAED,YAAM,UAAU,MAAM,KAAK;AAC3B,YAAM,UAAU,MAAM,KAAK;AAC3B,YAAM,UAAU,MAAM,KAAK;AAE3B,gCAAO,OAAO,EAAE,KAAK,QAAQ;AAC7B,gCAAO,OAAO,EAAE,KAAK,QAAQ;AAC7B,gCAAO,OAAO,EAAE,KAAK,QAAQ;AAC7B,gCAAO,KAAK,IAAI,EAAE,KAAK,IAAI;AAAA,IAC7B,CAAC;AAED,0BAAG,4DAA4D,YAAY;AACzE,YAAM,OAAO,kBAAK,KAAK,YAAY;AACjC,kBAAM,oBAAM,EAAE;AACd,eAAO;AAAA,MACT,CAAC;AAGD,YAAM,iBAAiB,KAAK;AAC5B,YAAM,iBAAiB,KAAK;AAE5B,gCAAO,KAAK,IAAI,EAAE,KAAK,KAAK;AAG5B,YAAM,CAAC,SAAS,OAAO,IAAI,MAAM,QAAQ,IAAI,CAAC,gBAAgB,cAAc,CAAC;AAE7E,gCAAO,OAAO,EAAE,KAAK,gBAAgB;AACrC,gCAAO,OAAO,EAAE,KAAK,gBAAgB;AACrC,gCAAO,KAAK,IAAI,EAAE,KAAK,IAAI;AAAA,IAC7B,CAAC;AAED,0BAAG,0DAA0D,YAAY;AACvE,UAAI,gBAAgB;AACpB,UAAI,gBAAgB;AACpB,UAAI,gBAAgB;AACpB,UAAI,kBAAkB;AACtB,UAAI,kBAAkB;AACtB,UAAI,kBAAkB;AAEtB,UAAI,aAAuC;AAC3C,UAAI,aAAuC;AAE3C,YAAM,aAAa,kBAAK,KAAK,OAAO,eAAe;AACjD,wBAAgB;AAGhB,qBAAa,kBAAK,KAAK,OAAO,oBAAoB;AAChD,0BAAgB;AAChB,oBAAM,oBAAM,KAAK,EAAE,QAAQ,gBAAgB,OAAO,CAAC;AACnD,4BAAkB;AAClB,iBAAO;AAAA,QACT,GAAG,UAAU;AAEb,qBAAa,kBAAK,KAAK,OAAO,oBAAoB;AAChD,0BAAgB;AAChB,oBAAM,oBAAM,KAAK,EAAE,QAAQ,gBAAgB,OAAO,CAAC;AACnD,4BAAkB;AAClB,iBAAO;AAAA,QACT,GAAG,UAAU;AAGb,cAAM,UAAU,MAAM,QAAQ,IAAI,CAAC,WAAW,QAAQ,WAAW,MAAM,CAAC;AACxE,0BAAkB;AAClB,eAAO;AAAA,MACT,CAAC;AAGD,gBAAM,oBAAM,EAAE;AAGd,gCAAO,aAAa,EAAE,KAAK,IAAI;AAC/B,gCAAO,aAAa,EAAE,KAAK,IAAI;AAC/B,gCAAO,aAAa,EAAE,KAAK,IAAI;AAG/B,iBAAW,OAAO;AAGlB,YAAM,CAAC,cAAc,cAAc,YAAY,IAAI,MAAM,QAAQ,WAAW;AAAA,QAC1E,WAAW;AAAA,QACX,WAAY;AAAA,QACZ,WAAY;AAAA,MACd,CAAC;AAGD,gCAAO,aAAa,MAAM,EAAE,KAAK,UAAU;AAC3C,gCAAQ,aAAuC,OAAO,IAAI,EAAE,KAAK,YAAY;AAE7E,gCAAO,aAAa,MAAM,EAAE,KAAK,UAAU;AAC3C,gCAAQ,aAAuC,OAAO,IAAI,EAAE,KAAK,YAAY;AAE7E,gCAAO,aAAa,MAAM,EAAE,KAAK,UAAU;AAC3C,gCAAQ,aAAuC,OAAO,IAAI,EAAE,KAAK,YAAY;AAG7E,gCAAO,eAAe,EAAE,KAAK,KAAK;AAClC,gCAAO,eAAe,EAAE,KAAK,KAAK;AAClC,gCAAO,eAAe,EAAE,KAAK,KAAK;AAClC,gCAAO,WAAW,IAAI,EAAE,KAAK,IAAI;AACjC,gCAAO,WAAY,IAAI,EAAE,KAAK,IAAI;AAClC,gCAAO,WAAY,IAAI,EAAE,KAAK,IAAI;AAAA,IACpC,CAAC;AAED,0BAAG,yDAAyD,YAAY;AACtE,YAAM,UAAoB,CAAC;AAE3B,YAAM,aAAa,kBAAK,KAAK,OAAO,eAAe;AACjD,gBAAQ,KAAK,cAAc;AAG3B,cAAM,aAAa,kBAAK,KAAK,YAAY;AACvC,kBAAQ,KAAK,cAAc;AAC3B,oBAAM,oBAAM,EAAE;AACd,kBAAQ,KAAK,YAAY;AACzB,iBAAO;AAAA,QACT,GAAG,UAAU;AAGb,cAAM,aAAa,kBAAK,KAAK,OAAO,oBAAoB;AACtD,kBAAQ,KAAK,cAAc;AAG3B,gBAAM,iBAAiB,kBAAK,KAAK,YAAY;AAC3C,oBAAQ,KAAK,kBAAkB;AAC/B,sBAAM,oBAAM,EAAE;AACd,oBAAQ,KAAK,gBAAgB;AAC7B,mBAAO;AAAA,UACT,GAAG,eAAe;AAElB,gBAAM,mBAAmB,MAAM,eAAe;AAC9C,oBAAM,oBAAM,EAAE;AACd,kBAAQ,KAAK,YAAY;AACzB,iBAAO,sBAAsB,gBAAgB;AAAA,QAC/C,GAAG,UAAU;AAGb,cAAM,CAAC,cAAc,YAAY,IAAI,MAAM,QAAQ,IAAI;AAAA,UACrD,WAAW;AAAA,UACX,WAAW;AAAA,QACb,CAAC;AAED,gBAAQ,KAAK,YAAY;AACzB,eAAO;AAAA,UACL,QAAQ;AAAA,UACR,QAAQ;AAAA,UACR,QAAQ;AAAA,QACV;AAAA,MACF,CAAC;AAGD,YAAM,cAAc,MAAM,WAAW;AAGrC,gCAAO,WAAW,EAAE,QAAQ;AAAA,QAC1B,QAAQ;AAAA,QACR,QAAQ;AAAA,QACR,QAAQ;AAAA,MACV,CAAC;AAID,gCAAO,OAAO,EAAE,QAAQ;AAAA,QACtB;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF,CAAC;AAGD,gCAAO,WAAW,IAAI,EAAE,KAAK,IAAI;AAAA,IACnC,CAAC;AAED,0BAAG,6CAA6C,YAAY;AAC1D,UAAI,cAA4B;AAChC,UAAI,kBAAkB;AACtB,UAAI,gBAAgB;AAEpB,YAAM,aAAa,kBAAK,KAAK,OAAO,eAAe;AACjD,cAAM,aAAa,kBAAK,KAAK,YAAY;AACvC,oBAAM,oBAAM,EAAE;AACd,gBAAM,IAAI,MAAM,cAAc;AAAA,QAChC,GAAG,UAAU;AAEb,cAAM,aAAa,kBAAK,KAAK,YAAY;AACvC,0BAAgB;AAChB,oBAAM,oBAAM,EAAE;AACd,4BAAkB;AAClB,iBAAO;AAAA,QACT,GAAG,UAAU;AAGb,cAAM,UAAU,MAAM,QAAQ,IAAI,CAAC,WAAW,QAAQ,WAAW,MAAM,CAAC;AACxE,eAAO;AAAA,MACT,CAAC;AAGD,UAAI;AACF,cAAM,WAAW;AACjB,6BAAO,KAAK,gCAAgC;AAAA,MAC9C,SAAS,OAAgB;AACvB,sBAAc;AAAA,MAChB;AAGA,gCAAO,2CAAa,OAAO,EAAE,KAAK,cAAc;AAChD,gCAAO,eAAe,EAAE,KAAK,KAAK;AAClC,gCAAO,aAAa,EAAE,KAAK,IAAI;AAC/B,gCAAO,WAAW,IAAI,EAAE,KAAK,IAAI;AAAA,IACnC,CAAC;AAED,0BAAG,8CAA8C,YAAY;AAC3D,UAAI,gBAAgB;AAEpB,YAAM,OAAO,kBAAK,KAAK,OAAO,eAAe;AAC3C,kBAAM,oBAAM,KAAM,EAAE,QAAQ,WAAW,OAAO,CAAC;AAC/C,wBAAgB;AAChB,eAAO;AAAA,MACT,CAAC;AAGD,YAAM,QAAQ,KAAK,IAAI;AACvB,YAAM,SAAS,MAAM,KAAK,cAAc,GAAI;AAC5C,YAAM,WAAW,KAAK,IAAI,IAAI;AAE9B,gCAAO,MAAM,EAAE,KAAK,wBAAW,OAAO;AACtC,gCAAO,QAAQ,EAAE,aAAa,GAAG;AACjC,gCAAO,aAAa,EAAE,KAAK,KAAK;AAChC,gCAAO,KAAK,IAAI,EAAE,KAAK,IAAI;AAAA,IAC7B,CAAC;AAED,0BAAG,2DAA2D,YAAY;AACxE,YAAM,OAAO,kBAAK,KAAK,YAAY;AACjC,kBAAM,oBAAM,GAAI;AAAA,MAClB,CAAC;AAGD,UAAI;AACF,cAAM,KAAK,cAAc,GAAG;AAC5B,6BAAO,KAAK,4BAA4B;AAAA,MAC1C,SAAS,OAAgB;AACvB,kCAAO,KAAK,EAAE,WAAW,KAAK;AAC9B,kCAAQ,MAAgB,OAAO,EAAE,KAAK,6BAA6B;AAAA,MACrE;AAAA,IACF,CAAC;AAED,0BAAG,oDAAoD,YAAY;AACjE,YAAM,OAAO,kBAAK,KAAK,YAAY;AACjC,kBAAM,oBAAM,EAAE;AAAA,MAChB,CAAC;AAGD,gBAAM,oBAAM,EAAE;AAGd,YAAM,SAAS,MAAM,KAAK,cAAc,GAAI;AAG5C,gCAAO,MAAM,EAAE,KAAK,wBAAW,SAAS;AACxC,gCAAO,KAAK,IAAI,EAAE,KAAK,IAAI;AAAA,IAC7B,CAAC;AAED,0BAAG,wDAAwD,YAAY;AACrE,YAAM,OAAO,kBAAK,KAAK,YAAY;AACjC,kBAAM,oBAAM,EAAE;AACd,cAAM,IAAI,UAAU,cAAc;AAAA,MACpC,CAAC;AAED,UAAI;AACF,cAAM,KAAK,cAAc,GAAI;AAC7B,6BAAO,KAAK,yBAAyB;AAAA,MACvC,SAAS,OAAgB;AACvB,kCAAQ,MAAgB,OAAO,EAAE,KAAK,cAAc;AACpD,kCAAQ,MAAgB,IAAI,EAAE,KAAK,WAAW;AAAA,MAChD;AAAA,IACF,CAAC;AAAA,EACH,CAAC;AAED,8BAAS,SAAS,MAAM;AACtB,0BAAG,2DAA2D,YAAY;AACxE,YAAM,QAAQ,IAAI,mBAAM;AACxB,YAAM,IAAI;AAEV,YAAM,SAAS,MAAM,MAAM,KAAK;AAChC,gCAAO,MAAM,EAAE,KAAK,IAAI;AAAA,IAC1B,CAAC;AAED,0BAAG,qCAAqC,YAAY;AAElD,YAAM,QAAQ,IAAI,mBAAM;AACxB,YAAM,gBAAgB,MAAM,KAAK;AAEjC,gBAAM,oBAAM,EAAE;AACd,gCAAO,UAAM,wBAAU,aAAa,CAAC,EAAE,KAAK,IAAI;AAGhD,YAAM,IAAI;AACV,YAAM,SAAS,MAAM;AACrB,gCAAO,MAAM,EAAE,KAAK,IAAI;AAAA,IAC1B,CAAC;AAED,0BAAG,0CAA0C,YAAY;AACvD,YAAM,QAAQ,IAAI,mBAAM;AACxB,YAAM,UAAU,CAAC,MAAM,KAAK,GAAG,MAAM,KAAK,GAAG,MAAM,KAAK,CAAC;AAEzD,gBAAM,oBAAM,EAAE;AACd,YAAM,WAAW,MAAM,QAAQ,IAAI,QAAQ,IAAI,CAAC,UAAM,wBAAU,CAAC,CAAC,CAAC;AACnE,gCAAO,QAAQ,EAAE,QAAQ,CAAC,MAAM,MAAM,IAAI,CAAC;AAE3C,YAAM,IAAI;AACV,YAAM,UAAU,MAAM,QAAQ,IAAI,OAAO;AACzC,gCAAO,OAAO,EAAE,QAAQ,CAAC,MAAM,MAAM,IAAI,CAAC;AAAA,IAC5C,CAAC;AAED,0BAAG,oDAAoD,YAAY;AACjE,YAAM,QAAQ,IAAI,mBAAM;AACxB,YAAM,SAAS,MAAM,KAAK;AAE1B,gBAAM,oBAAM,GAAI;AAChB,gCAAO,UAAM,wBAAU,MAAM,CAAC,EAAE,KAAK,IAAI;AAEzC,YAAM,IAAI;AACV,YAAM,SAAS,MAAM;AACrB,gCAAO,MAAM,EAAE,KAAK,IAAI;AAAA,IAC1B,CAAC;AAED,0BAAG,8CAA8C,YAAY;AAC3D,YAAM,QAAQ,IAAI,mBAAM;AACxB,YAAM,kBAAkB,MAAM,KAAK;AACnC,YAAM,IAAI;AACV,YAAM,MAAM;AAEZ,YAAM,iBAAiB,MAAM,KAAK;AAElC,YAAM,SAAS,MAAM,QAAQ,KAAK;AAAA,QAChC,gBAAgB,KAAK,MAAM,QAAQ;AAAA,QACnC,eAAe,KAAK,MAAM,OAAO;AAAA,MACnC,CAAC;AAED,gCAAO,MAAM,EAAE,KAAK,QAAQ;AAC5B,gCAAO,UAAM,wBAAU,eAAe,CAAC,EAAE,KAAK,KAAK;AACnD,gCAAO,UAAM,wBAAU,cAAc,CAAC,EAAE,KAAK,IAAI;AAEjD,YAAM,IAAI;AACV,gCAAO,MAAM,cAAc,EAAE,KAAK,IAAI;AAAA,IACxC,CAAC;AAAA,EACH,CAAC;AAED,8BAAS,kBAAkB,MAAM;AAC/B,UAAM,mBAAmB,CAAC,YAAoB,SAAiB,WAAW,MAAkB;AAC1F,YAAM,OAAO,IAAI,WAAW,UAAU,QAAQ;AAC9C,eAAS,IAAI,GAAG,IAAI,KAAK,QAAQ,KAAK;AACpC,aAAK,CAAC,IAAI,KAAK,IAAK,IAAI,UAAW,KAAK,KAAK,CAAC,IAAI;AAAA,MACpD;AACA,aAAO,IAAI,2BAAW,MAAM,YAAY,UAAU,OAAO;AAAA,IAC3D;AAEA,UAAM,gBAAgB,OAAO,WAA8D;AACzF,YAAM,SAAS,OAAO,UAAU;AAChC,YAAM,SAAuB,CAAC;AAC9B,UAAI;AACF,eAAO,MAAM;AACX,gBAAM,EAAE,MAAM,MAAM,IAAI,MAAM,OAAO,KAAK;AAC1C,cAAI,KAAM;AACV,iBAAO,KAAK,KAAK;AAAA,QACnB;AAAA,MACF,UAAE;AACA,eAAO,YAAY;AAAA,MACrB;AACA,aAAO;AAAA,IACT;AAEA,0BAAG,sDAAsD,YAAY;AACnE,YAAM,YAAY;AAClB,YAAM,aAAa;AACnB,YAAM,aAAa,iBAAiB,WAAW,GAAG;AAElD,YAAM,cAAc,IAAI,0BAA2B;AAAA,QACjD,MAAM,YAAY;AAChB,qBAAW,QAAQ,UAAU;AAC7B,qBAAW,MAAM;AAAA,QACnB;AAAA,MACF,CAAC;AAED,YAAM,mBAAe,6BAAe,EAAE,QAAQ,aAAa,WAAW,CAAC;AACvE,YAAM,eAAe,MAAM,cAAc,YAAY;AAErD,gCAAO,aAAa,MAAM,EAAE,gBAAgB,CAAC;AAE7C,iBAAW,SAAS,cAAc;AAChC,kCAAO,MAAM,UAAU,EAAE,KAAK,UAAU;AACxC,kCAAO,MAAM,QAAQ,EAAE,KAAK,WAAW,QAAQ;AAAA,MACjD;AAAA,IACF,CAAC;AAED,0BAAG,4CAA4C,YAAY;AACzD,YAAM,aAAa;AACnB,YAAM,aAAa,iBAAiB,YAAY,IAAI;AAEpD,YAAM,cAAc,IAAI,0BAA2B;AAAA,QACjD,MAAM,YAAY;AAChB,qBAAW,QAAQ,UAAU;AAC7B,qBAAW,MAAM;AAAA,QACnB;AAAA,MACF,CAAC;AAED,YAAM,mBAAe,6BAAe,EAAE,QAAQ,aAAa,YAAY,WAAW,CAAC;AACnF,YAAM,eAAe,MAAM,cAAc,YAAY;AAErD,gCAAO,aAAa,MAAM,EAAE,gBAAgB,CAAC;AAE7C,iBAAW,SAAS,cAAc;AAChC,kCAAO,MAAM,UAAU,EAAE,KAAK,UAAU;AACxC,kCAAO,MAAM,QAAQ,EAAE,KAAK,WAAW,QAAQ;AAAA,MACjD;AAAA,IACF,CAAC;AAED,0BAAG,uCAAuC,YAAY;AACpD,YAAM,YAAY;AAClB,YAAM,aAAa;AACnB,YAAM,SAAS,iBAAiB,WAAW,GAAG;AAC9C,YAAM,SAAS,iBAAiB,WAAW,GAAG;AAE9C,YAAM,cAAc,IAAI,0BAA2B;AAAA,QACjD,MAAM,YAAY;AAChB,qBAAW,QAAQ,MAAM;AACzB,qBAAW,QAAQ,MAAM;AACzB,qBAAW,MAAM;AAAA,QACnB;AAAA,MACF,CAAC;AAED,YAAM,mBAAe,6BAAe,EAAE,QAAQ,aAAa,WAAW,CAAC;AACvE,YAAM,eAAe,MAAM,cAAc,YAAY;AAErD,gCAAO,aAAa,MAAM,EAAE,gBAAgB,CAAC;AAE7C,iBAAW,SAAS,cAAc;AAChC,kCAAO,MAAM,UAAU,EAAE,KAAK,UAAU;AACxC,kCAAO,MAAM,QAAQ,EAAE,KAAK,OAAO,QAAQ;AAAA,MAC7C;AAAA,IACF,CAAC;AAED,0BAAG,8BAA8B,YAAY;AAC3C,YAAM,cAAc,IAAI,0BAA2B;AAAA,QACjD,MAAM,YAAY;AAChB,qBAAW,MAAM;AAAA,QACnB;AAAA,MACF,CAAC;AAED,YAAM,mBAAe,6BAAe,EAAE,QAAQ,aAAa,YAAY,MAAM,CAAC;AAC9E,YAAM,eAAe,MAAM,cAAc,YAAY;AAErD,gCAAO,YAAY,EAAE,QAAQ,CAAC,CAAC;AAAA,IACjC,CAAC;AAAA,EACH,CAAC;AACH,CAAC;","names":[]}
1
+ {"version":3,"sources":["../src/utils.test.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2024 LiveKit, Inc.\n//\n// SPDX-License-Identifier: Apache-2.0\nimport { AudioFrame } from '@livekit/rtc-node';\nimport { ReadableStream } from 'node:stream/web';\nimport { describe, expect, it } from 'vitest';\nimport { initializeLogger } from '../src/log.js';\nimport { Event, Task, TaskResult, delay, isPending, resampleStream } from '../src/utils.js';\n\ndescribe('utils', () => {\n // initialize logger\n initializeLogger({ pretty: true, level: 'debug' });\n\n describe('Task', () => {\n it('should execute task successfully and return result', async () => {\n const expectedResult = 'task completed';\n const task = Task.from(async () => {\n await delay(10);\n return expectedResult;\n });\n\n expect(task.done).toBe(false);\n const result = await task.result;\n expect(result).toBe(expectedResult);\n expect(task.done).toBe(true);\n });\n\n it('should handle task errors properly', async () => {\n const expectedError = new Error('Task failed');\n const task = Task.from(async () => {\n await delay(10);\n throw expectedError;\n });\n\n expect(task.done).toBe(false);\n await expect(task.result).rejects.toThrow(expectedError);\n expect(task.done).toBe(true);\n });\n\n it('should cancel task when cancel is called', async () => {\n let taskStarted = false;\n let taskCompleted = false;\n\n const task = Task.from(async (controller) => {\n taskStarted = true;\n await delay(100, { signal: controller.signal });\n taskCompleted = true;\n return 'should not complete';\n });\n\n // Wait a bit to ensure task starts\n await delay(10);\n expect(taskStarted).toBe(true);\n expect(task.done).toBe(false);\n\n // Cancel the task\n task.cancel();\n\n // The task should reject with AbortError\n try {\n await task.result;\n } catch (error: unknown) {\n expect((error as Error).name).toBe('AbortError');\n }\n\n expect(taskCompleted).toBe(false);\n expect(task.done).toBe(true);\n });\n\n it('should use provided AbortController', async () => {\n const controller = new AbortController();\n const task = Task.from(async (ctrl) => {\n expect(ctrl).toBe(controller);\n await delay(100, { signal: ctrl.signal });\n return 'completed';\n }, controller);\n\n await delay(10);\n controller.abort();\n\n try {\n await task.result;\n } catch (error: unknown) {\n expect((error as Error).name).toBe('AbortError');\n }\n\n expect(task.done).toBe(true);\n });\n\n it('should handle immediate resolution', async () => {\n const task = Task.from(async () => {\n return 'immediate';\n });\n\n const result = await task.result;\n expect(result).toBe('immediate');\n expect(task.done).toBe(true);\n });\n\n it('should handle immediate rejection', async () => {\n const expectedError = new Error('Immediate error');\n const task = Task.from(async () => {\n throw expectedError;\n });\n\n try {\n await task.result;\n } catch (error: unknown) {\n expect(error).toBe(expectedError);\n }\n\n expect(task.done).toBe(true);\n });\n\n it('should handle multiple calls to cancel', async () => {\n const task = Task.from(async (controller) => {\n await delay(100, { signal: controller.signal });\n return 'should not complete';\n });\n\n await delay(10);\n\n // Multiple cancellations should not cause issues\n task.cancel();\n task.cancel();\n task.cancel();\n\n try {\n await task.result;\n } catch (error: unknown) {\n expect((error as Error).name).toBe('AbortError');\n }\n\n expect(task.done).toBe(true);\n });\n\n it('should handle task that checks abort signal manually', async () => {\n const arr: number[] = [];\n const task = Task.from(async (controller) => {\n for (let i = 0; i < 10; i++) {\n if (controller.signal.aborted) {\n throw new Error('Task was aborted');\n }\n await delay(10);\n arr.push(i);\n }\n return 'completed';\n });\n\n await delay(39);\n task.cancel();\n\n expect(arr).toEqual([0, 1, 2]);\n try {\n await task.result;\n } catch (error: unknown) {\n expect((error as Error).message).toBe('Task was aborted');\n }\n\n expect(task.done).toBe(true);\n });\n\n it('should handle cleanup in finally block', async () => {\n let cleanupExecuted = false;\n\n const task = Task.from(async (controller) => {\n try {\n await delay(100, { signal: controller.signal });\n return 'completed';\n } finally {\n cleanupExecuted = true;\n }\n });\n\n await delay(10);\n task.cancel();\n\n try {\n await task.result;\n } catch {\n // Ignore the abort error\n }\n\n // Cleanup should still execute even when cancelled\n expect(cleanupExecuted).toBe(true);\n });\n\n it('should handle accessing result multiple times', async () => {\n const task = Task.from(async () => {\n await delay(10);\n return 'result';\n });\n\n const result1 = await task.result;\n const result2 = await task.result;\n const result3 = await task.result;\n\n expect(result1).toBe('result');\n expect(result2).toBe('result');\n expect(result3).toBe('result');\n expect(task.done).toBe(true);\n });\n\n it('should handle accessing result promise before completion', async () => {\n const task = Task.from(async () => {\n await delay(50);\n return 'delayed result';\n });\n\n // Get references to result promise before completion\n const resultPromise1 = task.result;\n const resultPromise2 = task.result;\n\n expect(task.done).toBe(false);\n\n // Both promises should resolve to the same value\n const [result1, result2] = await Promise.all([resultPromise1, resultPromise2]);\n\n expect(result1).toBe('delayed result');\n expect(result2).toBe('delayed result');\n expect(task.done).toBe(true);\n });\n\n it('should cancel child tasks when parent task is canceled', async () => {\n let parentStarted = false;\n let child1Started = false;\n let child2Started = false;\n let parentCompleted = false;\n let child1Completed = false;\n let child2Completed = false;\n\n let child1Task: Task<string> | undefined = undefined;\n let child2Task: Task<string> | undefined = undefined;\n\n const parentTask = Task.from(async (controller) => {\n parentStarted = true;\n\n // Create two child tasks using the parent's controller\n child1Task = Task.from(async (childController) => {\n child1Started = true;\n await delay(100, { signal: childController.signal });\n child1Completed = true;\n return 'child1';\n }, controller);\n\n child2Task = Task.from(async (childController) => {\n child2Started = true;\n await delay(100, { signal: childController.signal });\n child2Completed = true;\n return 'child2';\n }, controller);\n\n // Wait for both child tasks\n const results = await Promise.all([child1Task.result, child2Task.result]);\n parentCompleted = true;\n return results;\n });\n\n // Let tasks start\n await delay(20);\n\n // Verify tasks have started\n expect(parentStarted).toBe(true);\n expect(child1Started).toBe(true);\n expect(child2Started).toBe(true);\n\n // Cancel parent task\n parentTask.cancel();\n\n // Use Promise.allSettled to handle all promise settlements\n const [parentResult, child1Result, child2Result] = await Promise.allSettled([\n parentTask.result,\n child1Task!.result,\n child2Task!.result,\n ]);\n\n // Verify all tasks were rejected with AbortError\n expect(parentResult.status).toBe('rejected');\n expect((parentResult as PromiseRejectedResult).reason.name).toBe('AbortError');\n\n expect(child1Result.status).toBe('rejected');\n expect((child1Result as PromiseRejectedResult).reason.name).toBe('AbortError');\n\n expect(child2Result.status).toBe('rejected');\n expect((child2Result as PromiseRejectedResult).reason.name).toBe('AbortError');\n\n // Verify none of the tasks completed\n expect(parentCompleted).toBe(false);\n expect(child1Completed).toBe(false);\n expect(child2Completed).toBe(false);\n expect(parentTask.done).toBe(true);\n expect(child1Task!.done).toBe(true);\n expect(child2Task!.done).toBe(true);\n });\n\n it('should handle nested tasks that complete successfully', async () => {\n const results: string[] = [];\n\n const parentTask = Task.from(async (controller) => {\n results.push('parent-start');\n\n // Create first child task\n const child1Task = Task.from(async () => {\n results.push('child1-start');\n await delay(25);\n results.push('child1-end');\n return 'child1-result';\n }, controller);\n\n // Create second child task that depends on first\n const child2Task = Task.from(async (childController) => {\n results.push('child2-start');\n\n // Create a grandchild task\n const grandchildTask = Task.from(async () => {\n results.push('grandchild-start');\n await delay(10);\n results.push('grandchild-end');\n return 'grandchild-result';\n }, childController);\n\n const grandchildResult = await grandchildTask.result;\n await delay(10);\n results.push('child2-end');\n return `child2-result-with-${grandchildResult}`;\n }, controller);\n\n // Wait for all tasks\n const [child1Result, child2Result] = await Promise.all([\n child1Task.result,\n child2Task.result,\n ]);\n\n results.push('parent-end');\n return {\n parent: 'parent-result',\n child1: child1Result,\n child2: child2Result,\n };\n });\n\n // Wait for everything to complete\n const finalResult = await parentTask.result;\n\n // Verify results\n expect(finalResult).toEqual({\n parent: 'parent-result',\n child1: 'child1-result',\n child2: 'child2-result-with-grandchild-result',\n });\n\n // Verify execution order\n // Check important ordering constraints without being strict about parallel task ordering\n expect(results).toEqual([\n 'parent-start',\n 'child1-start',\n 'child2-start',\n 'grandchild-start',\n 'grandchild-end',\n 'child2-end',\n 'child1-end',\n 'parent-end',\n ]);\n\n // All tasks should be done\n expect(parentTask.done).toBe(true);\n });\n\n it('should propagate errors from nested tasks', async () => {\n let parentError: Error | null = null;\n let child1Completed = false;\n let child2Started = false;\n\n const parentTask = Task.from(async (controller) => {\n const child1Task = Task.from(async () => {\n await delay(20);\n throw new Error('child1 error');\n }, controller);\n\n const child2Task = Task.from(async () => {\n child2Started = true;\n await delay(30);\n child1Completed = true;\n return 'child2-result';\n }, controller);\n\n // This will throw when child1 fails\n const results = await Promise.all([child1Task.result, child2Task.result]);\n return results;\n });\n\n // Wait for the parent task to fail\n try {\n await parentTask.result;\n expect.fail('Parent task should have thrown');\n } catch (error: unknown) {\n parentError = error as Error;\n }\n\n // Verify the error propagated correctly\n expect(parentError?.message).toBe('child1 error');\n expect(child1Completed).toBe(false);\n expect(child2Started).toBe(true);\n expect(parentTask.done).toBe(true);\n });\n\n it('should cancel and wait for task completion', async () => {\n let taskCompleted = false;\n\n const task = Task.from(async (controller) => {\n await delay(5000, { signal: controller.signal });\n taskCompleted = true;\n return 'should not complete';\n });\n\n // Cancel and wait should complete quickly when task is aborted\n const start = Date.now();\n const result = await task.cancelAndWait(1000);\n const duration = Date.now() - start;\n\n expect(result).toBe(TaskResult.Aborted);\n expect(duration).toBeLessThan(100); // Should not wait for full timeout\n expect(taskCompleted).toBe(false);\n expect(task.done).toBe(true);\n });\n\n it('should timeout if task does not respond to cancellation', async () => {\n const task = Task.from(async () => {\n await delay(1000);\n });\n\n // This should timeout because the task ignores cancellation\n try {\n await task.cancelAndWait(200);\n expect.fail('Task should have timed out');\n } catch (error: unknown) {\n expect(error).instanceof(Error);\n expect((error as Error).message).toBe('Task cancellation timed out');\n }\n });\n\n it('should handle task that completes before timeout', async () => {\n const task = Task.from(async () => {\n await delay(50);\n });\n\n // Start the task\n await delay(10);\n\n // Cancel and wait - but task will complete normally before being canceled\n const result = await task.cancelAndWait(1000);\n\n // Task should have completed normally\n expect(result).toBe(TaskResult.Completed);\n expect(task.done).toBe(true);\n });\n\n it('should propagate non-abort errors from cancelAndWait', async () => {\n const task = Task.from(async () => {\n await delay(10);\n throw new TypeError('Custom error');\n });\n\n try {\n await task.cancelAndWait(1000);\n expect.fail('Task should have thrown');\n } catch (error: unknown) {\n expect((error as Error).message).toBe('Custom error');\n expect((error as Error).name).toBe('TypeError');\n }\n });\n\n it('should return undefined for Task.current outside task context', () => {\n expect(Task.current()).toBeUndefined();\n });\n\n it('should preserve Task.current inside a task across awaits', async () => {\n const task = Task.from(\n async () => {\n const currentAtStart = Task.current();\n await delay(5);\n const currentAfterAwait = Task.current();\n\n expect(currentAtStart).toBeDefined();\n expect(currentAfterAwait).toBe(currentAtStart);\n\n return currentAtStart;\n },\n undefined,\n 'current-context-test',\n );\n\n const currentFromResult = await task.result;\n expect(currentFromResult).toBe(task);\n });\n\n it('should isolate nested Task.current context and restore parent context', async () => {\n const parentTask = Task.from(\n async (controller) => {\n const parentCurrent = Task.current();\n expect(parentCurrent).toBeDefined();\n\n const childTask = Task.from(\n async () => {\n const childCurrentStart = Task.current();\n await delay(5);\n const childCurrentAfterAwait = Task.current();\n\n expect(childCurrentStart).toBeDefined();\n expect(childCurrentAfterAwait).toBe(childCurrentStart);\n expect(childCurrentStart).not.toBe(parentCurrent);\n\n return childCurrentStart;\n },\n controller,\n 'child-current-context-test',\n );\n\n const childCurrent = await childTask.result;\n const parentCurrentAfterChild = Task.current();\n\n expect(parentCurrentAfterChild).toBe(parentCurrent);\n\n return { parentCurrent, childCurrent };\n },\n undefined,\n 'parent-current-context-test',\n );\n\n const { parentCurrent, childCurrent } = await parentTask.result;\n expect(parentCurrent).toBe(parentTask);\n expect(childCurrent).not.toBe(parentCurrent);\n expect(Task.current()).toBeUndefined();\n });\n\n it('should always expose Task.current for concurrent task callbacks', async () => {\n const tasks = Array.from({ length: 25 }, (_, idx) =>\n Task.from(\n async () => {\n const currentAtStart = Task.current();\n await delay(1);\n const currentAfterAwait = Task.current();\n\n expect(currentAtStart).toBeDefined();\n expect(currentAfterAwait).toBe(currentAtStart);\n\n return currentAtStart;\n },\n undefined,\n `current-context-stress-${idx}`,\n ),\n );\n\n const currentTasks = await Promise.all(tasks.map((task) => task.result));\n currentTasks.forEach((currentTask, idx) => {\n expect(currentTask).toBe(tasks[idx]);\n });\n });\n });\n\n describe('Event', () => {\n it('wait resolves immediately when the event is already set', async () => {\n const event = new Event();\n event.set();\n\n const result = await event.wait();\n expect(result).toBe(true);\n });\n\n it('wait resolves after set is called', async () => {\n // check promise is pending\n const event = new Event();\n const waiterPromise = event.wait();\n\n await delay(10);\n expect(await isPending(waiterPromise)).toBe(true);\n\n // check promise is resolved after set is called\n event.set();\n const result = await waiterPromise;\n expect(result).toBe(true);\n });\n\n it('all waiters resolve once set is called', async () => {\n const event = new Event();\n const waiters = [event.wait(), event.wait(), event.wait()];\n\n await delay(10);\n const pendings = await Promise.all(waiters.map((w) => isPending(w)));\n expect(pendings).toEqual([true, true, true]);\n\n event.set();\n const results = await Promise.all(waiters);\n expect(results).toEqual([true, true, true]);\n });\n\n it('wait after 2 seconds is still pending before set', async () => {\n const event = new Event();\n const waiter = event.wait();\n\n await delay(2000);\n expect(await isPending(waiter)).toBe(true);\n\n event.set();\n const result = await waiter;\n expect(result).toBe(true);\n });\n\n it('wait after set and clear should be pending', async () => {\n const event = new Event();\n const waiterBeforeSet = event.wait();\n event.set();\n event.clear();\n\n const waiterAfterSet = event.wait();\n\n const result = await Promise.race([\n waiterBeforeSet.then(() => 'before'),\n waiterAfterSet.then(() => 'after'),\n ]);\n\n expect(result).toBe('before');\n expect(await isPending(waiterBeforeSet)).toBe(false);\n expect(await isPending(waiterAfterSet)).toBe(true);\n\n event.set();\n expect(await waiterAfterSet).toBe(true);\n });\n });\n\n describe('resampleStream', () => {\n const createAudioFrame = (sampleRate: number, samples: number, channels = 1): AudioFrame => {\n const data = new Int16Array(samples * channels);\n for (let i = 0; i < data.length; i++) {\n data[i] = Math.sin((i / samples) * Math.PI * 2) * 16000;\n }\n return new AudioFrame(data, sampleRate, channels, samples);\n };\n\n const streamToArray = async (stream: ReadableStream<AudioFrame>): Promise<AudioFrame[]> => {\n const reader = stream.getReader();\n const chunks: AudioFrame[] = [];\n try {\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n chunks.push(value);\n }\n } finally {\n reader.releaseLock();\n }\n return chunks;\n };\n\n it('should resample audio frames to target sample rate', async () => {\n const inputRate = 48000;\n const outputRate = 16000;\n const inputFrame = createAudioFrame(inputRate, 960); // 20ms at 48kHz\n\n const inputStream = new ReadableStream<AudioFrame>({\n start(controller) {\n controller.enqueue(inputFrame);\n controller.close();\n },\n });\n\n const outputStream = resampleStream({ stream: inputStream, outputRate });\n const outputFrames = await streamToArray(outputStream);\n\n expect(outputFrames.length).toBeGreaterThan(0);\n\n for (const frame of outputFrames) {\n expect(frame.sampleRate).toBe(outputRate);\n expect(frame.channels).toBe(inputFrame.channels);\n }\n });\n\n it('should handle same input and output rate', async () => {\n const sampleRate = 44100;\n const inputFrame = createAudioFrame(sampleRate, 1024);\n\n const inputStream = new ReadableStream<AudioFrame>({\n start(controller) {\n controller.enqueue(inputFrame);\n controller.close();\n },\n });\n\n const outputStream = resampleStream({ stream: inputStream, outputRate: sampleRate });\n const outputFrames = await streamToArray(outputStream);\n\n expect(outputFrames.length).toBeGreaterThan(0);\n\n for (const frame of outputFrames) {\n expect(frame.sampleRate).toBe(sampleRate);\n expect(frame.channels).toBe(inputFrame.channels);\n }\n });\n\n it('should handle multiple input frames', async () => {\n const inputRate = 32000;\n const outputRate = 48000;\n const frame1 = createAudioFrame(inputRate, 640);\n const frame2 = createAudioFrame(inputRate, 640);\n\n const inputStream = new ReadableStream<AudioFrame>({\n start(controller) {\n controller.enqueue(frame1);\n controller.enqueue(frame2);\n controller.close();\n },\n });\n\n const outputStream = resampleStream({ stream: inputStream, outputRate });\n const outputFrames = await streamToArray(outputStream);\n\n expect(outputFrames.length).toBeGreaterThan(0);\n\n for (const frame of outputFrames) {\n expect(frame.sampleRate).toBe(outputRate);\n expect(frame.channels).toBe(frame1.channels);\n }\n });\n\n it('should handle empty stream', async () => {\n const inputStream = new ReadableStream<AudioFrame>({\n start(controller) {\n controller.close();\n },\n });\n\n const outputStream = resampleStream({ stream: inputStream, outputRate: 44100 });\n const outputFrames = await streamToArray(outputStream);\n\n expect(outputFrames).toEqual([]);\n });\n });\n});\n"],"mappings":"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","names":["parentCurrent","childCurrent"]}
@@ -346,6 +346,77 @@ describe("utils", () => {
346
346
  expect(error.name).toBe("TypeError");
347
347
  }
348
348
  });
349
+ it("should return undefined for Task.current outside task context", () => {
350
+ expect(Task.current()).toBeUndefined();
351
+ });
352
+ it("should preserve Task.current inside a task across awaits", async () => {
353
+ const task = Task.from(
354
+ async () => {
355
+ const currentAtStart = Task.current();
356
+ await delay(5);
357
+ const currentAfterAwait = Task.current();
358
+ expect(currentAtStart).toBeDefined();
359
+ expect(currentAfterAwait).toBe(currentAtStart);
360
+ return currentAtStart;
361
+ },
362
+ void 0,
363
+ "current-context-test"
364
+ );
365
+ const currentFromResult = await task.result;
366
+ expect(currentFromResult).toBe(task);
367
+ });
368
+ it("should isolate nested Task.current context and restore parent context", async () => {
369
+ const parentTask = Task.from(
370
+ async (controller) => {
371
+ const parentCurrent2 = Task.current();
372
+ expect(parentCurrent2).toBeDefined();
373
+ const childTask = Task.from(
374
+ async () => {
375
+ const childCurrentStart = Task.current();
376
+ await delay(5);
377
+ const childCurrentAfterAwait = Task.current();
378
+ expect(childCurrentStart).toBeDefined();
379
+ expect(childCurrentAfterAwait).toBe(childCurrentStart);
380
+ expect(childCurrentStart).not.toBe(parentCurrent2);
381
+ return childCurrentStart;
382
+ },
383
+ controller,
384
+ "child-current-context-test"
385
+ );
386
+ const childCurrent2 = await childTask.result;
387
+ const parentCurrentAfterChild = Task.current();
388
+ expect(parentCurrentAfterChild).toBe(parentCurrent2);
389
+ return { parentCurrent: parentCurrent2, childCurrent: childCurrent2 };
390
+ },
391
+ void 0,
392
+ "parent-current-context-test"
393
+ );
394
+ const { parentCurrent, childCurrent } = await parentTask.result;
395
+ expect(parentCurrent).toBe(parentTask);
396
+ expect(childCurrent).not.toBe(parentCurrent);
397
+ expect(Task.current()).toBeUndefined();
398
+ });
399
+ it("should always expose Task.current for concurrent task callbacks", async () => {
400
+ const tasks = Array.from(
401
+ { length: 25 },
402
+ (_, idx) => Task.from(
403
+ async () => {
404
+ const currentAtStart = Task.current();
405
+ await delay(1);
406
+ const currentAfterAwait = Task.current();
407
+ expect(currentAtStart).toBeDefined();
408
+ expect(currentAfterAwait).toBe(currentAtStart);
409
+ return currentAtStart;
410
+ },
411
+ void 0,
412
+ `current-context-stress-${idx}`
413
+ )
414
+ );
415
+ const currentTasks = await Promise.all(tasks.map((task) => task.result));
416
+ currentTasks.forEach((currentTask, idx) => {
417
+ expect(currentTask).toBe(tasks[idx]);
418
+ });
419
+ });
349
420
  });
350
421
  describe("Event", () => {
351
422
  it("wait resolves immediately when the event is already set", async () => {