@livekit/agents 1.0.49 → 1.0.51
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +12 -10
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +13 -13
- package/dist/index.d.ts +13 -13
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +11 -10
- package/dist/index.js.map +1 -1
- package/dist/inference/api_protos.d.cts +67 -67
- package/dist/inference/api_protos.d.ts +67 -67
- package/dist/inference/llm.cjs +10 -8
- package/dist/inference/llm.cjs.map +1 -1
- package/dist/inference/llm.d.cts +1 -1
- package/dist/inference/llm.d.ts +1 -1
- package/dist/inference/llm.d.ts.map +1 -1
- package/dist/inference/llm.js +3 -7
- package/dist/inference/llm.js.map +1 -1
- package/dist/inference/stt.cjs +20 -12
- package/dist/inference/stt.cjs.map +1 -1
- package/dist/inference/stt.d.cts +3 -2
- package/dist/inference/stt.d.ts +3 -2
- package/dist/inference/stt.d.ts.map +1 -1
- package/dist/inference/stt.js +20 -12
- package/dist/inference/stt.js.map +1 -1
- package/dist/inference/stt.test.cjs +14 -0
- package/dist/inference/stt.test.cjs.map +1 -1
- package/dist/inference/stt.test.js +14 -0
- package/dist/inference/stt.test.js.map +1 -1
- package/dist/inference/tts.cjs +13 -4
- package/dist/inference/tts.cjs.map +1 -1
- package/dist/inference/tts.d.cts +2 -1
- package/dist/inference/tts.d.ts +2 -1
- package/dist/inference/tts.d.ts.map +1 -1
- package/dist/inference/tts.js +13 -4
- package/dist/inference/tts.js.map +1 -1
- package/dist/inference/tts.test.cjs +10 -0
- package/dist/inference/tts.test.cjs.map +1 -1
- package/dist/inference/tts.test.js +10 -0
- package/dist/inference/tts.test.js.map +1 -1
- package/dist/inference/utils.cjs +5 -5
- package/dist/inference/utils.cjs.map +1 -1
- package/dist/inference/utils.js +1 -1
- package/dist/inference/utils.js.map +1 -1
- package/dist/ipc/job_proc_lazy_main.cjs +13 -4
- package/dist/ipc/job_proc_lazy_main.cjs.map +1 -1
- package/dist/ipc/job_proc_lazy_main.js +13 -4
- package/dist/ipc/job_proc_lazy_main.js.map +1 -1
- package/dist/language.cjs +394 -0
- package/dist/language.cjs.map +1 -0
- package/dist/language.d.cts +15 -0
- package/dist/language.d.ts +15 -0
- package/dist/language.d.ts.map +1 -0
- package/dist/language.js +363 -0
- package/dist/language.js.map +1 -0
- package/dist/language.test.cjs +43 -0
- package/dist/language.test.cjs.map +1 -0
- package/dist/language.test.js +49 -0
- package/dist/language.test.js.map +1 -0
- package/dist/stream/deferred_stream.cjs +6 -2
- package/dist/stream/deferred_stream.cjs.map +1 -1
- package/dist/stream/deferred_stream.d.ts.map +1 -1
- package/dist/stream/deferred_stream.js +6 -2
- package/dist/stream/deferred_stream.js.map +1 -1
- package/dist/stt/stt.cjs.map +1 -1
- package/dist/stt/stt.d.cts +2 -1
- package/dist/stt/stt.d.ts +2 -1
- package/dist/stt/stt.d.ts.map +1 -1
- package/dist/stt/stt.js.map +1 -1
- package/dist/version.cjs +1 -1
- package/dist/version.js +1 -1
- package/dist/voice/agent_activity.cjs +4 -1
- package/dist/voice/agent_activity.cjs.map +1 -1
- package/dist/voice/agent_activity.d.ts.map +1 -1
- package/dist/voice/agent_activity.js +4 -1
- package/dist/voice/agent_activity.js.map +1 -1
- package/dist/voice/agent_activity.test.cjs +135 -0
- package/dist/voice/agent_activity.test.cjs.map +1 -0
- package/dist/voice/agent_activity.test.js +134 -0
- package/dist/voice/agent_activity.test.js.map +1 -0
- package/dist/voice/audio_recognition.cjs.map +1 -1
- package/dist/voice/audio_recognition.d.cts +3 -2
- package/dist/voice/audio_recognition.d.ts +3 -2
- package/dist/voice/audio_recognition.d.ts.map +1 -1
- package/dist/voice/audio_recognition.js.map +1 -1
- package/dist/voice/events.cjs.map +1 -1
- package/dist/voice/events.d.cts +3 -2
- package/dist/voice/events.d.ts +3 -2
- package/dist/voice/events.d.ts.map +1 -1
- package/dist/voice/events.js.map +1 -1
- package/package.json +1 -1
- package/src/index.ts +13 -15
- package/src/inference/llm.ts +3 -8
- package/src/inference/stt.test.ts +17 -0
- package/src/inference/stt.ts +22 -14
- package/src/inference/tts.test.ts +12 -0
- package/src/inference/tts.ts +14 -5
- package/src/inference/utils.ts +1 -1
- package/src/ipc/job_proc_lazy_main.ts +15 -4
- package/src/language.test.ts +62 -0
- package/src/language.ts +380 -0
- package/src/stream/deferred_stream.ts +5 -1
- package/src/stt/stt.ts +2 -1
- package/src/voice/agent_activity.test.ts +194 -0
- package/src/voice/agent_activity.ts +11 -1
- package/src/voice/audio_recognition.ts +4 -3
- package/src/voice/events.ts +3 -2
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/ipc/job_proc_lazy_main.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2024 LiveKit, Inc.\n//\n// SPDX-License-Identifier: Apache-2.0\nimport { Room, RoomEvent, dispose } from '@livekit/rtc-node';\nimport { EventEmitter, once } from 'node:events';\nimport { pathToFileURL } from 'node:url';\nimport type { Logger } from 'pino';\nimport { type Agent, isAgent } from '../generator.js';\nimport { JobContext, JobProcess, type RunningJobInfo, runWithJobContextAsync } from '../job.js';\nimport { initializeLogger, log } from '../log.js';\nimport { Future, shortuuid } from '../utils.js';\nimport { defaultInitializeProcessFunc } from '../worker.js';\nimport type { InferenceExecutor } from './inference_executor.js';\nimport type { IPCMessage } from './message.js';\n\nconst ORPHANED_TIMEOUT = 15 * 1000;\n\nconst safeSend = (msg: IPCMessage): boolean => {\n if (process.connected && process.send) {\n process.send(msg);\n return true;\n }\n return false;\n};\n\ntype JobTask = {\n ctx: JobContext;\n task: Promise<void>;\n};\n\nclass PendingInference {\n promise = new Promise<{ requestId: string; data: unknown; error?: Error }>((resolve) => {\n this.resolve = resolve; // this is how JavaScript lets you resolve promises externally\n });\n resolve(arg: { requestId: string; data: unknown; error?: Error }) {\n arg; // useless call to counteract TypeScript E6133\n }\n}\n\nclass InfClient implements InferenceExecutor {\n #requests: { [id: string]: PendingInference } = {};\n\n constructor() {\n process.on('message', (msg: IPCMessage) => {\n switch (msg.case) {\n case 'inferenceResponse':\n const fut = this.#requests[msg.value.requestId];\n delete this.#requests[msg.value.requestId];\n if (!fut) {\n log().child({ resp: msg.value }).warn('received unexpected inference response');\n return;\n }\n fut.resolve(msg.value);\n break;\n }\n });\n }\n\n async doInference(method: string, data: unknown): Promise<unknown> {\n const requestId = shortuuid('inference_job_');\n if (!safeSend({ case: 'inferenceRequest', value: { requestId, method, data } })) {\n throw new Error('IPC channel closed');\n }\n\n this.#requests[requestId] = new PendingInference();\n const resp = await this.#requests[requestId]!.promise;\n if (resp.error) {\n throw new Error(`inference of ${method} failed: ${resp.error.message}`);\n }\n return resp.data;\n }\n}\n\nconst startJob = (\n proc: JobProcess,\n func: (ctx: JobContext) => Promise<void>,\n info: RunningJobInfo,\n closeEvent: EventEmitter,\n logger: Logger,\n joinFuture: Future,\n): JobTask => {\n let connect = false;\n let shutdown = false;\n\n const room = new Room();\n room.on(RoomEvent.Disconnected, () => {\n if (!shutdown) {\n closeEvent.emit('close', false);\n }\n });\n\n const onConnect = () => {\n connect = true;\n };\n const onShutdown = (reason: string) => {\n shutdown = true;\n closeEvent.emit('close', true, reason);\n };\n\n const ctx = new JobContext(proc, info, room, onConnect, onShutdown, new InfClient());\n\n const task = (async () => {\n const unconnectedTimeout = setTimeout(() => {\n if (!(connect || shutdown)) {\n logger.warn(\n 'room not connect after job_entry was called after 10 seconds, ',\n 'did you forget to call ctx.connect()?',\n );\n }\n }, 10000);\n\n // Run the job function within the AsyncLocalStorage context\n await runWithJobContextAsync(ctx, async () => {\n const { tracer, traceTypes } = await import('../telemetry/index.js');\n return tracer.startActiveSpan(\n async (span) => {\n span.setAttribute(traceTypes.ATTR_JOB_ID, info.job.id);\n span.setAttribute(traceTypes.ATTR_AGENT_NAME, info.job.agentName);\n span.setAttribute(traceTypes.ATTR_ROOM_NAME, info.job.room?.name ?? '');\n return func(ctx);\n },\n { name: 'job_entrypoint' },\n );\n }).finally(() => {\n clearTimeout(unconnectedTimeout);\n });\n\n await once(closeEvent, 'close').then((close) => {\n logger.debug('shutting down');\n shutdown = true;\n safeSend({ case: 'exiting', value: { reason: close[1] } });\n });\n\n // Close the primary agent session if it exists\n if (ctx._primaryAgentSession) {\n await ctx._primaryAgentSession.close();\n }\n\n // Generate and save/upload session report\n await ctx._onSessionEnd();\n\n await room.disconnect();\n logger.debug('disconnected from room');\n\n const shutdownTasks = [];\n for (const callback of ctx.shutdownCallbacks) {\n shutdownTasks.push(callback());\n }\n await Promise.all(shutdownTasks).catch((error) =>\n logger.error({ error }, 'error while shutting down the job'),\n );\n\n safeSend({ case: 'done', value: undefined });\n joinFuture.resolve();\n })();\n\n return { ctx, task };\n};\n\n(async () => {\n if (process.send) {\n const join = new Future();\n\n // process.argv:\n // [0] `node'\n // [1] import.meta.filename\n // [2] import.meta.filename of function containing entry file\n const moduleFile = process.argv[2];\n const agent: Agent = await import(pathToFileURL(moduleFile!).pathname).then((module) => {\n // Handle both ESM (module.default is the agent) and CJS (module.default.default is the agent)\n const agent =\n typeof module.default === 'function' || isAgent(module.default)\n ? module.default\n : module.default?.default;\n if (agent === undefined || !isAgent(agent)) {\n throw new Error(`Unable to load agent: Missing or invalid default export in ${moduleFile}`);\n }\n return agent;\n });\n if (!agent.prewarm) {\n agent.prewarm = defaultInitializeProcessFunc;\n }\n\n // don't do anything on C-c\n // this is handled in cli, triggering a termination of all child processes at once.\n process.on('SIGINT', () => {\n logger.debug('SIGINT received in job proc');\n });\n\n // don't do anything on SIGTERM\n // Render uses SIGTERM in autoscale, this ensures the processes are properly drained if needed\n process.on('SIGTERM', () => {\n logger.debug('SIGTERM received in job proc');\n });\n\n await once(process, 'message').then(([msg]: IPCMessage[]) => {\n msg = msg!;\n if (msg.case !== 'initializeRequest') {\n throw new Error('first message must be InitializeRequest');\n }\n initializeLogger(msg.value.loggerOptions);\n });\n const proc = new JobProcess();\n let logger = log().child({ pid: proc.pid });\n\n process.on('unhandledRejection', (reason) => {\n logger.debug({ error: reason }, 'Unhandled promise rejection');\n });\n\n logger.debug('initializing job runner');\n await agent.prewarm(proc);\n logger.debug('job runner initialized');\n safeSend({ case: 'initializeResponse', value: undefined });\n\n let job: JobTask | undefined = undefined;\n const closeEvent = new EventEmitter();\n\n const orphanedTimeout = setTimeout(() => {\n logger.warn('job process orphaned, shutting down.');\n join.resolve();\n }, ORPHANED_TIMEOUT);\n\n const messageHandler = (msg: IPCMessage) => {\n switch (msg.case) {\n case 'pingRequest': {\n orphanedTimeout.refresh();\n safeSend({\n case: 'pongResponse',\n value: { lastTimestamp: msg.value.timestamp, timestamp: Date.now() },\n });\n break;\n }\n case 'startJobRequest': {\n if (job) {\n throw new Error('job task already running');\n }\n\n logger = logger.child({ jobID: msg.value.runningJob.job.id });\n\n job = startJob(proc, agent.entry, msg.value.runningJob, closeEvent, logger, join);\n logger.debug('job started');\n break;\n }\n case 'shutdownRequest': {\n if (!job) {\n join.resolve();\n }\n closeEvent.emit('close', 'shutdownRequest');\n clearTimeout(orphanedTimeout);\n process.off('message', messageHandler);\n }\n }\n };\n\n process.on('message', messageHandler);\n\n await join.await;\n\n // Dispose native FFI resources (Rust FfiServer, tokio runtimes, libwebrtc)\n // before process.exit() to prevent libc++abi mutex crash during teardown.\n // Without this, process.exit() can kill the process while native threads are\n // still running, causing: \"mutex lock failed: Invalid argument\"\n // See: https://github.com/livekit/node-sdks/issues/564\n try {\n await dispose();\n logger.debug('native resources disposed');\n } catch (error) {\n logger.warn({ error }, 'failed to dispose native resources');\n }\n\n logger.debug('Job process shutdown');\n process.exit(0);\n }\n})();\n"],"mappings":"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","names":["module","agent"]}
|
|
1
|
+
{"version":3,"sources":["../../src/ipc/job_proc_lazy_main.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2024 LiveKit, Inc.\n//\n// SPDX-License-Identifier: Apache-2.0\nimport { Room, RoomEvent, dispose } from '@livekit/rtc-node';\nimport { EventEmitter, once } from 'node:events';\nimport { pathToFileURL } from 'node:url';\nimport type { Logger } from 'pino';\nimport { type Agent, isAgent } from '../generator.js';\nimport { JobContext, JobProcess, type RunningJobInfo, runWithJobContextAsync } from '../job.js';\nimport { initializeLogger, log } from '../log.js';\nimport { Future, shortuuid } from '../utils.js';\nimport { defaultInitializeProcessFunc } from '../worker.js';\nimport type { InferenceExecutor } from './inference_executor.js';\nimport type { IPCMessage } from './message.js';\n\nconst ORPHANED_TIMEOUT = 15 * 1000;\n\nconst safeSend = (msg: IPCMessage): boolean => {\n try {\n if (process.connected && process.send) {\n process.send(msg);\n return true;\n }\n return false;\n } catch (error) {\n // Channel closed is expected during graceful shutdown\n // Log at debug level to avoid noise in production logs\n if (error instanceof Error && error.message.includes('Channel closed')) {\n log().debug({ msgCase: msg.case }, 'IPC channel closed, message not sent');\n } else {\n log().error({ error, msgCase: msg.case }, 'IPC send failed unexpectedly');\n }\n return false;\n }\n};\n\ntype JobTask = {\n ctx: JobContext;\n task: Promise<void>;\n};\n\nclass PendingInference {\n promise = new Promise<{ requestId: string; data: unknown; error?: Error }>((resolve) => {\n this.resolve = resolve; // this is how JavaScript lets you resolve promises externally\n });\n resolve(arg: { requestId: string; data: unknown; error?: Error }) {\n arg; // useless call to counteract TypeScript E6133\n }\n}\n\nclass InfClient implements InferenceExecutor {\n #requests: { [id: string]: PendingInference } = {};\n\n constructor() {\n process.on('message', (msg: IPCMessage) => {\n switch (msg.case) {\n case 'inferenceResponse':\n const fut = this.#requests[msg.value.requestId];\n delete this.#requests[msg.value.requestId];\n if (!fut) {\n log().child({ resp: msg.value }).warn('received unexpected inference response');\n return;\n }\n fut.resolve(msg.value);\n break;\n }\n });\n }\n\n async doInference(method: string, data: unknown): Promise<unknown> {\n const requestId = shortuuid('inference_job_');\n if (!safeSend({ case: 'inferenceRequest', value: { requestId, method, data } })) {\n throw new Error('IPC channel closed');\n }\n\n this.#requests[requestId] = new PendingInference();\n const resp = await this.#requests[requestId]!.promise;\n if (resp.error) {\n throw new Error(`inference of ${method} failed: ${resp.error.message}`);\n }\n return resp.data;\n }\n}\n\nconst startJob = (\n proc: JobProcess,\n func: (ctx: JobContext) => Promise<void>,\n info: RunningJobInfo,\n closeEvent: EventEmitter,\n logger: Logger,\n joinFuture: Future,\n): JobTask => {\n let connect = false;\n let shutdown = false;\n\n const room = new Room();\n room.on(RoomEvent.Disconnected, () => {\n if (!shutdown) {\n closeEvent.emit('close', false);\n }\n });\n\n const onConnect = () => {\n connect = true;\n };\n const onShutdown = (reason: string) => {\n shutdown = true;\n closeEvent.emit('close', true, reason);\n };\n\n const ctx = new JobContext(proc, info, room, onConnect, onShutdown, new InfClient());\n\n const task = (async () => {\n const unconnectedTimeout = setTimeout(() => {\n if (!(connect || shutdown)) {\n logger.warn(\n 'room not connect after job_entry was called after 10 seconds, ',\n 'did you forget to call ctx.connect()?',\n );\n }\n }, 10000);\n\n // Run the job function within the AsyncLocalStorage context\n await runWithJobContextAsync(ctx, async () => {\n const { tracer, traceTypes } = await import('../telemetry/index.js');\n return tracer.startActiveSpan(\n async (span) => {\n span.setAttribute(traceTypes.ATTR_JOB_ID, info.job.id);\n span.setAttribute(traceTypes.ATTR_AGENT_NAME, info.job.agentName);\n span.setAttribute(traceTypes.ATTR_ROOM_NAME, info.job.room?.name ?? '');\n return func(ctx);\n },\n { name: 'job_entrypoint' },\n );\n }).finally(() => {\n clearTimeout(unconnectedTimeout);\n });\n\n await once(closeEvent, 'close').then((close) => {\n logger.debug('shutting down');\n shutdown = true;\n safeSend({ case: 'exiting', value: { reason: close[1] } });\n });\n\n // Close the primary agent session if it exists\n if (ctx._primaryAgentSession) {\n await ctx._primaryAgentSession.close();\n }\n\n // Generate and save/upload session report\n await ctx._onSessionEnd();\n\n await room.disconnect();\n logger.debug('disconnected from room');\n\n const shutdownTasks = [];\n for (const callback of ctx.shutdownCallbacks) {\n shutdownTasks.push(callback());\n }\n await Promise.all(shutdownTasks).catch((error) =>\n logger.error({ error }, 'error while shutting down the job'),\n );\n\n safeSend({ case: 'done', value: undefined });\n joinFuture.resolve();\n })();\n\n return { ctx, task };\n};\n\n(async () => {\n if (process.send) {\n const join = new Future();\n\n // process.argv:\n // [0] `node'\n // [1] import.meta.filename\n // [2] import.meta.filename of function containing entry file\n const moduleFile = process.argv[2];\n const agent: Agent = await import(pathToFileURL(moduleFile!).pathname).then((module) => {\n // Handle both ESM (module.default is the agent) and CJS (module.default.default is the agent)\n const agent =\n typeof module.default === 'function' || isAgent(module.default)\n ? module.default\n : module.default?.default;\n if (agent === undefined || !isAgent(agent)) {\n throw new Error(`Unable to load agent: Missing or invalid default export in ${moduleFile}`);\n }\n return agent;\n });\n if (!agent.prewarm) {\n agent.prewarm = defaultInitializeProcessFunc;\n }\n\n // don't do anything on C-c\n // this is handled in cli, triggering a termination of all child processes at once.\n process.on('SIGINT', () => {\n logger.debug('SIGINT received in job proc');\n });\n\n // don't do anything on SIGTERM\n // Render uses SIGTERM in autoscale, this ensures the processes are properly drained if needed\n process.on('SIGTERM', () => {\n logger.debug('SIGTERM received in job proc');\n });\n\n await once(process, 'message').then(([msg]: IPCMessage[]) => {\n msg = msg!;\n if (msg.case !== 'initializeRequest') {\n throw new Error('first message must be InitializeRequest');\n }\n initializeLogger(msg.value.loggerOptions);\n });\n const proc = new JobProcess();\n let logger = log().child({ pid: proc.pid });\n\n process.on('unhandledRejection', (reason) => {\n logger.debug({ error: reason }, 'Unhandled promise rejection');\n });\n\n logger.debug('initializing job runner');\n await agent.prewarm(proc);\n logger.debug('job runner initialized');\n safeSend({ case: 'initializeResponse', value: undefined });\n\n let job: JobTask | undefined = undefined;\n const closeEvent = new EventEmitter();\n\n const orphanedTimeout = setTimeout(() => {\n logger.warn('job process orphaned, shutting down.');\n join.resolve();\n }, ORPHANED_TIMEOUT);\n\n const messageHandler = (msg: IPCMessage) => {\n switch (msg.case) {\n case 'pingRequest': {\n orphanedTimeout.refresh();\n safeSend({\n case: 'pongResponse',\n value: { lastTimestamp: msg.value.timestamp, timestamp: Date.now() },\n });\n break;\n }\n case 'startJobRequest': {\n if (job) {\n throw new Error('job task already running');\n }\n\n logger = logger.child({ jobID: msg.value.runningJob.job.id });\n\n job = startJob(proc, agent.entry, msg.value.runningJob, closeEvent, logger, join);\n logger.debug('job started');\n break;\n }\n case 'shutdownRequest': {\n if (!job) {\n join.resolve();\n }\n closeEvent.emit('close', 'shutdownRequest');\n clearTimeout(orphanedTimeout);\n process.off('message', messageHandler);\n }\n }\n };\n\n process.on('message', messageHandler);\n\n await join.await;\n\n // Dispose native FFI resources (Rust FfiServer, tokio runtimes, libwebrtc)\n // before process.exit() to prevent libc++abi mutex crash during teardown.\n // Without this, process.exit() can kill the process while native threads are\n // still running, causing: \"mutex lock failed: Invalid argument\"\n // See: https://github.com/livekit/node-sdks/issues/564\n try {\n await dispose();\n logger.debug('native resources disposed');\n } catch (error) {\n logger.warn({ error }, 'failed to dispose native resources');\n }\n\n logger.debug('Job process shutdown');\n process.exit(0);\n }\n})();\n"],"mappings":"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","names":["module","agent"]}
|
|
@@ -8,11 +8,20 @@ import { Future, shortuuid } from "../utils.js";
|
|
|
8
8
|
import { defaultInitializeProcessFunc } from "../worker.js";
|
|
9
9
|
const ORPHANED_TIMEOUT = 15 * 1e3;
|
|
10
10
|
const safeSend = (msg) => {
|
|
11
|
-
|
|
12
|
-
process.send
|
|
13
|
-
|
|
11
|
+
try {
|
|
12
|
+
if (process.connected && process.send) {
|
|
13
|
+
process.send(msg);
|
|
14
|
+
return true;
|
|
15
|
+
}
|
|
16
|
+
return false;
|
|
17
|
+
} catch (error) {
|
|
18
|
+
if (error instanceof Error && error.message.includes("Channel closed")) {
|
|
19
|
+
log().debug({ msgCase: msg.case }, "IPC channel closed, message not sent");
|
|
20
|
+
} else {
|
|
21
|
+
log().error({ error, msgCase: msg.case }, "IPC send failed unexpectedly");
|
|
22
|
+
}
|
|
23
|
+
return false;
|
|
14
24
|
}
|
|
15
|
-
return false;
|
|
16
25
|
};
|
|
17
26
|
class PendingInference {
|
|
18
27
|
promise = new Promise((resolve) => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/ipc/job_proc_lazy_main.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2024 LiveKit, Inc.\n//\n// SPDX-License-Identifier: Apache-2.0\nimport { Room, RoomEvent, dispose } from '@livekit/rtc-node';\nimport { EventEmitter, once } from 'node:events';\nimport { pathToFileURL } from 'node:url';\nimport type { Logger } from 'pino';\nimport { type Agent, isAgent } from '../generator.js';\nimport { JobContext, JobProcess, type RunningJobInfo, runWithJobContextAsync } from '../job.js';\nimport { initializeLogger, log } from '../log.js';\nimport { Future, shortuuid } from '../utils.js';\nimport { defaultInitializeProcessFunc } from '../worker.js';\nimport type { InferenceExecutor } from './inference_executor.js';\nimport type { IPCMessage } from './message.js';\n\nconst ORPHANED_TIMEOUT = 15 * 1000;\n\nconst safeSend = (msg: IPCMessage): boolean => {\n if (process.connected && process.send) {\n process.send(msg);\n return true;\n }\n return false;\n};\n\ntype JobTask = {\n ctx: JobContext;\n task: Promise<void>;\n};\n\nclass PendingInference {\n promise = new Promise<{ requestId: string; data: unknown; error?: Error }>((resolve) => {\n this.resolve = resolve; // this is how JavaScript lets you resolve promises externally\n });\n resolve(arg: { requestId: string; data: unknown; error?: Error }) {\n arg; // useless call to counteract TypeScript E6133\n }\n}\n\nclass InfClient implements InferenceExecutor {\n #requests: { [id: string]: PendingInference } = {};\n\n constructor() {\n process.on('message', (msg: IPCMessage) => {\n switch (msg.case) {\n case 'inferenceResponse':\n const fut = this.#requests[msg.value.requestId];\n delete this.#requests[msg.value.requestId];\n if (!fut) {\n log().child({ resp: msg.value }).warn('received unexpected inference response');\n return;\n }\n fut.resolve(msg.value);\n break;\n }\n });\n }\n\n async doInference(method: string, data: unknown): Promise<unknown> {\n const requestId = shortuuid('inference_job_');\n if (!safeSend({ case: 'inferenceRequest', value: { requestId, method, data } })) {\n throw new Error('IPC channel closed');\n }\n\n this.#requests[requestId] = new PendingInference();\n const resp = await this.#requests[requestId]!.promise;\n if (resp.error) {\n throw new Error(`inference of ${method} failed: ${resp.error.message}`);\n }\n return resp.data;\n }\n}\n\nconst startJob = (\n proc: JobProcess,\n func: (ctx: JobContext) => Promise<void>,\n info: RunningJobInfo,\n closeEvent: EventEmitter,\n logger: Logger,\n joinFuture: Future,\n): JobTask => {\n let connect = false;\n let shutdown = false;\n\n const room = new Room();\n room.on(RoomEvent.Disconnected, () => {\n if (!shutdown) {\n closeEvent.emit('close', false);\n }\n });\n\n const onConnect = () => {\n connect = true;\n };\n const onShutdown = (reason: string) => {\n shutdown = true;\n closeEvent.emit('close', true, reason);\n };\n\n const ctx = new JobContext(proc, info, room, onConnect, onShutdown, new InfClient());\n\n const task = (async () => {\n const unconnectedTimeout = setTimeout(() => {\n if (!(connect || shutdown)) {\n logger.warn(\n 'room not connect after job_entry was called after 10 seconds, ',\n 'did you forget to call ctx.connect()?',\n );\n }\n }, 10000);\n\n // Run the job function within the AsyncLocalStorage context\n await runWithJobContextAsync(ctx, async () => {\n const { tracer, traceTypes } = await import('../telemetry/index.js');\n return tracer.startActiveSpan(\n async (span) => {\n span.setAttribute(traceTypes.ATTR_JOB_ID, info.job.id);\n span.setAttribute(traceTypes.ATTR_AGENT_NAME, info.job.agentName);\n span.setAttribute(traceTypes.ATTR_ROOM_NAME, info.job.room?.name ?? '');\n return func(ctx);\n },\n { name: 'job_entrypoint' },\n );\n }).finally(() => {\n clearTimeout(unconnectedTimeout);\n });\n\n await once(closeEvent, 'close').then((close) => {\n logger.debug('shutting down');\n shutdown = true;\n safeSend({ case: 'exiting', value: { reason: close[1] } });\n });\n\n // Close the primary agent session if it exists\n if (ctx._primaryAgentSession) {\n await ctx._primaryAgentSession.close();\n }\n\n // Generate and save/upload session report\n await ctx._onSessionEnd();\n\n await room.disconnect();\n logger.debug('disconnected from room');\n\n const shutdownTasks = [];\n for (const callback of ctx.shutdownCallbacks) {\n shutdownTasks.push(callback());\n }\n await Promise.all(shutdownTasks).catch((error) =>\n logger.error({ error }, 'error while shutting down the job'),\n );\n\n safeSend({ case: 'done', value: undefined });\n joinFuture.resolve();\n })();\n\n return { ctx, task };\n};\n\n(async () => {\n if (process.send) {\n const join = new Future();\n\n // process.argv:\n // [0] `node'\n // [1] import.meta.filename\n // [2] import.meta.filename of function containing entry file\n const moduleFile = process.argv[2];\n const agent: Agent = await import(pathToFileURL(moduleFile!).pathname).then((module) => {\n // Handle both ESM (module.default is the agent) and CJS (module.default.default is the agent)\n const agent =\n typeof module.default === 'function' || isAgent(module.default)\n ? module.default\n : module.default?.default;\n if (agent === undefined || !isAgent(agent)) {\n throw new Error(`Unable to load agent: Missing or invalid default export in ${moduleFile}`);\n }\n return agent;\n });\n if (!agent.prewarm) {\n agent.prewarm = defaultInitializeProcessFunc;\n }\n\n // don't do anything on C-c\n // this is handled in cli, triggering a termination of all child processes at once.\n process.on('SIGINT', () => {\n logger.debug('SIGINT received in job proc');\n });\n\n // don't do anything on SIGTERM\n // Render uses SIGTERM in autoscale, this ensures the processes are properly drained if needed\n process.on('SIGTERM', () => {\n logger.debug('SIGTERM received in job proc');\n });\n\n await once(process, 'message').then(([msg]: IPCMessage[]) => {\n msg = msg!;\n if (msg.case !== 'initializeRequest') {\n throw new Error('first message must be InitializeRequest');\n }\n initializeLogger(msg.value.loggerOptions);\n });\n const proc = new JobProcess();\n let logger = log().child({ pid: proc.pid });\n\n process.on('unhandledRejection', (reason) => {\n logger.debug({ error: reason }, 'Unhandled promise rejection');\n });\n\n logger.debug('initializing job runner');\n await agent.prewarm(proc);\n logger.debug('job runner initialized');\n safeSend({ case: 'initializeResponse', value: undefined });\n\n let job: JobTask | undefined = undefined;\n const closeEvent = new EventEmitter();\n\n const orphanedTimeout = setTimeout(() => {\n logger.warn('job process orphaned, shutting down.');\n join.resolve();\n }, ORPHANED_TIMEOUT);\n\n const messageHandler = (msg: IPCMessage) => {\n switch (msg.case) {\n case 'pingRequest': {\n orphanedTimeout.refresh();\n safeSend({\n case: 'pongResponse',\n value: { lastTimestamp: msg.value.timestamp, timestamp: Date.now() },\n });\n break;\n }\n case 'startJobRequest': {\n if (job) {\n throw new Error('job task already running');\n }\n\n logger = logger.child({ jobID: msg.value.runningJob.job.id });\n\n job = startJob(proc, agent.entry, msg.value.runningJob, closeEvent, logger, join);\n logger.debug('job started');\n break;\n }\n case 'shutdownRequest': {\n if (!job) {\n join.resolve();\n }\n closeEvent.emit('close', 'shutdownRequest');\n clearTimeout(orphanedTimeout);\n process.off('message', messageHandler);\n }\n }\n };\n\n process.on('message', messageHandler);\n\n await join.await;\n\n // Dispose native FFI resources (Rust FfiServer, tokio runtimes, libwebrtc)\n // before process.exit() to prevent libc++abi mutex crash during teardown.\n // Without this, process.exit() can kill the process while native threads are\n // still running, causing: \"mutex lock failed: Invalid argument\"\n // See: https://github.com/livekit/node-sdks/issues/564\n try {\n await dispose();\n logger.debug('native resources disposed');\n } catch (error) {\n logger.warn({ error }, 'failed to dispose native resources');\n }\n\n logger.debug('Job process shutdown');\n process.exit(0);\n }\n})();\n"],"mappings":"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","names":["agent"]}
|
|
1
|
+
{"version":3,"sources":["../../src/ipc/job_proc_lazy_main.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2024 LiveKit, Inc.\n//\n// SPDX-License-Identifier: Apache-2.0\nimport { Room, RoomEvent, dispose } from '@livekit/rtc-node';\nimport { EventEmitter, once } from 'node:events';\nimport { pathToFileURL } from 'node:url';\nimport type { Logger } from 'pino';\nimport { type Agent, isAgent } from '../generator.js';\nimport { JobContext, JobProcess, type RunningJobInfo, runWithJobContextAsync } from '../job.js';\nimport { initializeLogger, log } from '../log.js';\nimport { Future, shortuuid } from '../utils.js';\nimport { defaultInitializeProcessFunc } from '../worker.js';\nimport type { InferenceExecutor } from './inference_executor.js';\nimport type { IPCMessage } from './message.js';\n\nconst ORPHANED_TIMEOUT = 15 * 1000;\n\nconst safeSend = (msg: IPCMessage): boolean => {\n try {\n if (process.connected && process.send) {\n process.send(msg);\n return true;\n }\n return false;\n } catch (error) {\n // Channel closed is expected during graceful shutdown\n // Log at debug level to avoid noise in production logs\n if (error instanceof Error && error.message.includes('Channel closed')) {\n log().debug({ msgCase: msg.case }, 'IPC channel closed, message not sent');\n } else {\n log().error({ error, msgCase: msg.case }, 'IPC send failed unexpectedly');\n }\n return false;\n }\n};\n\ntype JobTask = {\n ctx: JobContext;\n task: Promise<void>;\n};\n\nclass PendingInference {\n promise = new Promise<{ requestId: string; data: unknown; error?: Error }>((resolve) => {\n this.resolve = resolve; // this is how JavaScript lets you resolve promises externally\n });\n resolve(arg: { requestId: string; data: unknown; error?: Error }) {\n arg; // useless call to counteract TypeScript E6133\n }\n}\n\nclass InfClient implements InferenceExecutor {\n #requests: { [id: string]: PendingInference } = {};\n\n constructor() {\n process.on('message', (msg: IPCMessage) => {\n switch (msg.case) {\n case 'inferenceResponse':\n const fut = this.#requests[msg.value.requestId];\n delete this.#requests[msg.value.requestId];\n if (!fut) {\n log().child({ resp: msg.value }).warn('received unexpected inference response');\n return;\n }\n fut.resolve(msg.value);\n break;\n }\n });\n }\n\n async doInference(method: string, data: unknown): Promise<unknown> {\n const requestId = shortuuid('inference_job_');\n if (!safeSend({ case: 'inferenceRequest', value: { requestId, method, data } })) {\n throw new Error('IPC channel closed');\n }\n\n this.#requests[requestId] = new PendingInference();\n const resp = await this.#requests[requestId]!.promise;\n if (resp.error) {\n throw new Error(`inference of ${method} failed: ${resp.error.message}`);\n }\n return resp.data;\n }\n}\n\nconst startJob = (\n proc: JobProcess,\n func: (ctx: JobContext) => Promise<void>,\n info: RunningJobInfo,\n closeEvent: EventEmitter,\n logger: Logger,\n joinFuture: Future,\n): JobTask => {\n let connect = false;\n let shutdown = false;\n\n const room = new Room();\n room.on(RoomEvent.Disconnected, () => {\n if (!shutdown) {\n closeEvent.emit('close', false);\n }\n });\n\n const onConnect = () => {\n connect = true;\n };\n const onShutdown = (reason: string) => {\n shutdown = true;\n closeEvent.emit('close', true, reason);\n };\n\n const ctx = new JobContext(proc, info, room, onConnect, onShutdown, new InfClient());\n\n const task = (async () => {\n const unconnectedTimeout = setTimeout(() => {\n if (!(connect || shutdown)) {\n logger.warn(\n 'room not connect after job_entry was called after 10 seconds, ',\n 'did you forget to call ctx.connect()?',\n );\n }\n }, 10000);\n\n // Run the job function within the AsyncLocalStorage context\n await runWithJobContextAsync(ctx, async () => {\n const { tracer, traceTypes } = await import('../telemetry/index.js');\n return tracer.startActiveSpan(\n async (span) => {\n span.setAttribute(traceTypes.ATTR_JOB_ID, info.job.id);\n span.setAttribute(traceTypes.ATTR_AGENT_NAME, info.job.agentName);\n span.setAttribute(traceTypes.ATTR_ROOM_NAME, info.job.room?.name ?? '');\n return func(ctx);\n },\n { name: 'job_entrypoint' },\n );\n }).finally(() => {\n clearTimeout(unconnectedTimeout);\n });\n\n await once(closeEvent, 'close').then((close) => {\n logger.debug('shutting down');\n shutdown = true;\n safeSend({ case: 'exiting', value: { reason: close[1] } });\n });\n\n // Close the primary agent session if it exists\n if (ctx._primaryAgentSession) {\n await ctx._primaryAgentSession.close();\n }\n\n // Generate and save/upload session report\n await ctx._onSessionEnd();\n\n await room.disconnect();\n logger.debug('disconnected from room');\n\n const shutdownTasks = [];\n for (const callback of ctx.shutdownCallbacks) {\n shutdownTasks.push(callback());\n }\n await Promise.all(shutdownTasks).catch((error) =>\n logger.error({ error }, 'error while shutting down the job'),\n );\n\n safeSend({ case: 'done', value: undefined });\n joinFuture.resolve();\n })();\n\n return { ctx, task };\n};\n\n(async () => {\n if (process.send) {\n const join = new Future();\n\n // process.argv:\n // [0] `node'\n // [1] import.meta.filename\n // [2] import.meta.filename of function containing entry file\n const moduleFile = process.argv[2];\n const agent: Agent = await import(pathToFileURL(moduleFile!).pathname).then((module) => {\n // Handle both ESM (module.default is the agent) and CJS (module.default.default is the agent)\n const agent =\n typeof module.default === 'function' || isAgent(module.default)\n ? module.default\n : module.default?.default;\n if (agent === undefined || !isAgent(agent)) {\n throw new Error(`Unable to load agent: Missing or invalid default export in ${moduleFile}`);\n }\n return agent;\n });\n if (!agent.prewarm) {\n agent.prewarm = defaultInitializeProcessFunc;\n }\n\n // don't do anything on C-c\n // this is handled in cli, triggering a termination of all child processes at once.\n process.on('SIGINT', () => {\n logger.debug('SIGINT received in job proc');\n });\n\n // don't do anything on SIGTERM\n // Render uses SIGTERM in autoscale, this ensures the processes are properly drained if needed\n process.on('SIGTERM', () => {\n logger.debug('SIGTERM received in job proc');\n });\n\n await once(process, 'message').then(([msg]: IPCMessage[]) => {\n msg = msg!;\n if (msg.case !== 'initializeRequest') {\n throw new Error('first message must be InitializeRequest');\n }\n initializeLogger(msg.value.loggerOptions);\n });\n const proc = new JobProcess();\n let logger = log().child({ pid: proc.pid });\n\n process.on('unhandledRejection', (reason) => {\n logger.debug({ error: reason }, 'Unhandled promise rejection');\n });\n\n logger.debug('initializing job runner');\n await agent.prewarm(proc);\n logger.debug('job runner initialized');\n safeSend({ case: 'initializeResponse', value: undefined });\n\n let job: JobTask | undefined = undefined;\n const closeEvent = new EventEmitter();\n\n const orphanedTimeout = setTimeout(() => {\n logger.warn('job process orphaned, shutting down.');\n join.resolve();\n }, ORPHANED_TIMEOUT);\n\n const messageHandler = (msg: IPCMessage) => {\n switch (msg.case) {\n case 'pingRequest': {\n orphanedTimeout.refresh();\n safeSend({\n case: 'pongResponse',\n value: { lastTimestamp: msg.value.timestamp, timestamp: Date.now() },\n });\n break;\n }\n case 'startJobRequest': {\n if (job) {\n throw new Error('job task already running');\n }\n\n logger = logger.child({ jobID: msg.value.runningJob.job.id });\n\n job = startJob(proc, agent.entry, msg.value.runningJob, closeEvent, logger, join);\n logger.debug('job started');\n break;\n }\n case 'shutdownRequest': {\n if (!job) {\n join.resolve();\n }\n closeEvent.emit('close', 'shutdownRequest');\n clearTimeout(orphanedTimeout);\n process.off('message', messageHandler);\n }\n }\n };\n\n process.on('message', messageHandler);\n\n await join.await;\n\n // Dispose native FFI resources (Rust FfiServer, tokio runtimes, libwebrtc)\n // before process.exit() to prevent libc++abi mutex crash during teardown.\n // Without this, process.exit() can kill the process while native threads are\n // still running, causing: \"mutex lock failed: Invalid argument\"\n // See: https://github.com/livekit/node-sdks/issues/564\n try {\n await dispose();\n logger.debug('native resources disposed');\n } catch (error) {\n logger.warn({ error }, 'failed to dispose native resources');\n }\n\n logger.debug('Job process shutdown');\n process.exit(0);\n }\n})();\n"],"mappings":"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","names":["agent"]}
|
|
@@ -0,0 +1,394 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
var language_exports = {};
|
|
20
|
+
__export(language_exports, {
|
|
21
|
+
KNOWN_LANGUAGE_CODES: () => KNOWN_LANGUAGE_CODES,
|
|
22
|
+
areLanguagesEquivalent: () => areLanguagesEquivalent,
|
|
23
|
+
asLanguageCode: () => asLanguageCode,
|
|
24
|
+
getBaseLanguage: () => getBaseLanguage,
|
|
25
|
+
getIsoLanguage: () => getIsoLanguage,
|
|
26
|
+
getLanguageRegion: () => getLanguageRegion,
|
|
27
|
+
normalizeLanguage: () => normalizeLanguage,
|
|
28
|
+
toLanguageName: () => toLanguageName
|
|
29
|
+
});
|
|
30
|
+
module.exports = __toCommonJS(language_exports);
|
|
31
|
+
const KNOWN_LANGUAGE_CODES = [
|
|
32
|
+
"af",
|
|
33
|
+
"am",
|
|
34
|
+
"ar",
|
|
35
|
+
"as",
|
|
36
|
+
"az",
|
|
37
|
+
"be",
|
|
38
|
+
"bg",
|
|
39
|
+
"bn",
|
|
40
|
+
"bs",
|
|
41
|
+
"ca",
|
|
42
|
+
"cs",
|
|
43
|
+
"cy",
|
|
44
|
+
"da",
|
|
45
|
+
"de",
|
|
46
|
+
"el",
|
|
47
|
+
"en",
|
|
48
|
+
"es",
|
|
49
|
+
"et",
|
|
50
|
+
"eu",
|
|
51
|
+
"fa",
|
|
52
|
+
"ff",
|
|
53
|
+
"fi",
|
|
54
|
+
"fr",
|
|
55
|
+
"ga",
|
|
56
|
+
"gl",
|
|
57
|
+
"gu",
|
|
58
|
+
"ha",
|
|
59
|
+
"he",
|
|
60
|
+
"hi",
|
|
61
|
+
"hr",
|
|
62
|
+
"hu",
|
|
63
|
+
"hy",
|
|
64
|
+
"id",
|
|
65
|
+
"ig",
|
|
66
|
+
"is",
|
|
67
|
+
"it",
|
|
68
|
+
"ja",
|
|
69
|
+
"jv",
|
|
70
|
+
"ka",
|
|
71
|
+
"kk",
|
|
72
|
+
"km",
|
|
73
|
+
"kn",
|
|
74
|
+
"ko",
|
|
75
|
+
"ku",
|
|
76
|
+
"ky",
|
|
77
|
+
"lb",
|
|
78
|
+
"lg",
|
|
79
|
+
"ln",
|
|
80
|
+
"lo",
|
|
81
|
+
"lt",
|
|
82
|
+
"lv",
|
|
83
|
+
"mi",
|
|
84
|
+
"mk",
|
|
85
|
+
"ml",
|
|
86
|
+
"mn",
|
|
87
|
+
"mr",
|
|
88
|
+
"ms",
|
|
89
|
+
"mt",
|
|
90
|
+
"my",
|
|
91
|
+
"ne",
|
|
92
|
+
"nl",
|
|
93
|
+
"no",
|
|
94
|
+
"ny",
|
|
95
|
+
"oc",
|
|
96
|
+
"or",
|
|
97
|
+
"pa",
|
|
98
|
+
"pl",
|
|
99
|
+
"ps",
|
|
100
|
+
"pt",
|
|
101
|
+
"ro",
|
|
102
|
+
"ru",
|
|
103
|
+
"sd",
|
|
104
|
+
"sk",
|
|
105
|
+
"sl",
|
|
106
|
+
"sn",
|
|
107
|
+
"so",
|
|
108
|
+
"sq",
|
|
109
|
+
"sr",
|
|
110
|
+
"sv",
|
|
111
|
+
"sw",
|
|
112
|
+
"ta",
|
|
113
|
+
"te",
|
|
114
|
+
"tg",
|
|
115
|
+
"th",
|
|
116
|
+
"tl",
|
|
117
|
+
"tr",
|
|
118
|
+
"uk",
|
|
119
|
+
"ur",
|
|
120
|
+
"uz",
|
|
121
|
+
"vi",
|
|
122
|
+
"wo",
|
|
123
|
+
"xh",
|
|
124
|
+
"yo",
|
|
125
|
+
"zh",
|
|
126
|
+
"zu"
|
|
127
|
+
];
|
|
128
|
+
function asLanguageCode(language) {
|
|
129
|
+
return language;
|
|
130
|
+
}
|
|
131
|
+
const ISO_639_3_TO_1 = {
|
|
132
|
+
afr: "af",
|
|
133
|
+
amh: "am",
|
|
134
|
+
ara: "ar",
|
|
135
|
+
hye: "hy",
|
|
136
|
+
asm: "as",
|
|
137
|
+
ast: void 0,
|
|
138
|
+
aze: "az",
|
|
139
|
+
bel: "be",
|
|
140
|
+
ben: "bn",
|
|
141
|
+
bos: "bs",
|
|
142
|
+
bul: "bg",
|
|
143
|
+
mya: "my",
|
|
144
|
+
yue: void 0,
|
|
145
|
+
cat: "ca",
|
|
146
|
+
ceb: void 0,
|
|
147
|
+
cmn: "zh",
|
|
148
|
+
nya: "ny",
|
|
149
|
+
hrv: "hr",
|
|
150
|
+
ces: "cs",
|
|
151
|
+
dan: "da",
|
|
152
|
+
nld: "nl",
|
|
153
|
+
eng: "en",
|
|
154
|
+
est: "et",
|
|
155
|
+
fil: void 0,
|
|
156
|
+
fin: "fi",
|
|
157
|
+
fra: "fr",
|
|
158
|
+
ful: "ff",
|
|
159
|
+
glg: "gl",
|
|
160
|
+
lug: "lg",
|
|
161
|
+
kat: "ka",
|
|
162
|
+
deu: "de",
|
|
163
|
+
ell: "el",
|
|
164
|
+
guj: "gu",
|
|
165
|
+
hau: "ha",
|
|
166
|
+
heb: "he",
|
|
167
|
+
hin: "hi",
|
|
168
|
+
hun: "hu",
|
|
169
|
+
isl: "is",
|
|
170
|
+
ibo: "ig",
|
|
171
|
+
ind: "id",
|
|
172
|
+
gle: "ga",
|
|
173
|
+
ita: "it",
|
|
174
|
+
jpn: "ja",
|
|
175
|
+
jav: "jv",
|
|
176
|
+
kea: void 0,
|
|
177
|
+
kan: "kn",
|
|
178
|
+
kaz: "kk",
|
|
179
|
+
khm: "km",
|
|
180
|
+
kor: "ko",
|
|
181
|
+
kur: "ku",
|
|
182
|
+
kir: "ky",
|
|
183
|
+
lao: "lo",
|
|
184
|
+
lav: "lv",
|
|
185
|
+
lin: "ln",
|
|
186
|
+
lit: "lt",
|
|
187
|
+
luo: void 0,
|
|
188
|
+
ltz: "lb",
|
|
189
|
+
mkd: "mk",
|
|
190
|
+
msa: "ms",
|
|
191
|
+
mal: "ml",
|
|
192
|
+
mlt: "mt",
|
|
193
|
+
zho: "zh",
|
|
194
|
+
mri: "mi",
|
|
195
|
+
mar: "mr",
|
|
196
|
+
mon: "mn",
|
|
197
|
+
nep: "ne",
|
|
198
|
+
nso: void 0,
|
|
199
|
+
nor: "no",
|
|
200
|
+
oci: "oc",
|
|
201
|
+
ori: "or",
|
|
202
|
+
pus: "ps",
|
|
203
|
+
fas: "fa",
|
|
204
|
+
pol: "pl",
|
|
205
|
+
por: "pt",
|
|
206
|
+
pan: "pa",
|
|
207
|
+
ron: "ro",
|
|
208
|
+
rus: "ru",
|
|
209
|
+
srp: "sr",
|
|
210
|
+
sna: "sn",
|
|
211
|
+
snd: "sd",
|
|
212
|
+
slk: "sk",
|
|
213
|
+
slv: "sl",
|
|
214
|
+
som: "so",
|
|
215
|
+
spa: "es",
|
|
216
|
+
swa: "sw",
|
|
217
|
+
swe: "sv",
|
|
218
|
+
tam: "ta",
|
|
219
|
+
tgk: "tg",
|
|
220
|
+
tel: "te",
|
|
221
|
+
tha: "th",
|
|
222
|
+
tur: "tr",
|
|
223
|
+
ukr: "uk",
|
|
224
|
+
umb: void 0,
|
|
225
|
+
urd: "ur",
|
|
226
|
+
uzb: "uz",
|
|
227
|
+
vie: "vi",
|
|
228
|
+
cym: "cy",
|
|
229
|
+
wol: "wo",
|
|
230
|
+
xho: "xh",
|
|
231
|
+
zul: "zu"
|
|
232
|
+
};
|
|
233
|
+
const LANGUAGE_NAMES_TO_CODE = {
|
|
234
|
+
afrikaans: "af",
|
|
235
|
+
albanian: "sq",
|
|
236
|
+
amharic: "am",
|
|
237
|
+
arabic: "ar",
|
|
238
|
+
armenian: "hy",
|
|
239
|
+
azerbaijani: "az",
|
|
240
|
+
basque: "eu",
|
|
241
|
+
belarusian: "be",
|
|
242
|
+
bengali: "bn",
|
|
243
|
+
bosnian: "bs",
|
|
244
|
+
bulgarian: "bg",
|
|
245
|
+
burmese: "my",
|
|
246
|
+
catalan: "ca",
|
|
247
|
+
chinese: "zh",
|
|
248
|
+
croatian: "hr",
|
|
249
|
+
czech: "cs",
|
|
250
|
+
danish: "da",
|
|
251
|
+
dutch: "nl",
|
|
252
|
+
english: "en",
|
|
253
|
+
estonian: "et",
|
|
254
|
+
finnish: "fi",
|
|
255
|
+
french: "fr",
|
|
256
|
+
galician: "gl",
|
|
257
|
+
georgian: "ka",
|
|
258
|
+
german: "de",
|
|
259
|
+
greek: "el",
|
|
260
|
+
gujarati: "gu",
|
|
261
|
+
hausa: "ha",
|
|
262
|
+
hebrew: "he",
|
|
263
|
+
hindi: "hi",
|
|
264
|
+
hungarian: "hu",
|
|
265
|
+
icelandic: "is",
|
|
266
|
+
indonesian: "id",
|
|
267
|
+
irish: "ga",
|
|
268
|
+
italian: "it",
|
|
269
|
+
japanese: "ja",
|
|
270
|
+
javanese: "jv",
|
|
271
|
+
kannada: "kn",
|
|
272
|
+
kazakh: "kk",
|
|
273
|
+
khmer: "km",
|
|
274
|
+
korean: "ko",
|
|
275
|
+
kurdish: "ku",
|
|
276
|
+
kyrgyz: "ky",
|
|
277
|
+
lao: "lo",
|
|
278
|
+
latvian: "lv",
|
|
279
|
+
lingala: "ln",
|
|
280
|
+
lithuanian: "lt",
|
|
281
|
+
luxembourgish: "lb",
|
|
282
|
+
macedonian: "mk",
|
|
283
|
+
malay: "ms",
|
|
284
|
+
malayalam: "ml",
|
|
285
|
+
maltese: "mt",
|
|
286
|
+
maori: "mi",
|
|
287
|
+
marathi: "mr",
|
|
288
|
+
mongolian: "mn",
|
|
289
|
+
nepali: "ne",
|
|
290
|
+
norwegian: "no",
|
|
291
|
+
occitan: "oc",
|
|
292
|
+
oriya: "or",
|
|
293
|
+
pashto: "ps",
|
|
294
|
+
persian: "fa",
|
|
295
|
+
polish: "pl",
|
|
296
|
+
portuguese: "pt",
|
|
297
|
+
punjabi: "pa",
|
|
298
|
+
romanian: "ro",
|
|
299
|
+
russian: "ru",
|
|
300
|
+
serbian: "sr",
|
|
301
|
+
shona: "sn",
|
|
302
|
+
sindhi: "sd",
|
|
303
|
+
slovak: "sk",
|
|
304
|
+
slovene: "sl",
|
|
305
|
+
slovenian: "sl",
|
|
306
|
+
somali: "so",
|
|
307
|
+
spanish: "es",
|
|
308
|
+
swahili: "sw",
|
|
309
|
+
swedish: "sv",
|
|
310
|
+
tagalog: "tl",
|
|
311
|
+
tamil: "ta",
|
|
312
|
+
tajik: "tg",
|
|
313
|
+
telugu: "te",
|
|
314
|
+
thai: "th",
|
|
315
|
+
turkish: "tr",
|
|
316
|
+
ukrainian: "uk",
|
|
317
|
+
urdu: "ur",
|
|
318
|
+
uzbek: "uz",
|
|
319
|
+
vietnamese: "vi",
|
|
320
|
+
welsh: "cy",
|
|
321
|
+
wolof: "wo",
|
|
322
|
+
xhosa: "xh",
|
|
323
|
+
yoruba: "yo",
|
|
324
|
+
zulu: "zu"
|
|
325
|
+
};
|
|
326
|
+
const CODE_TO_LANGUAGE_NAME = Object.fromEntries(
|
|
327
|
+
Object.entries(LANGUAGE_NAMES_TO_CODE).map(([name, code]) => [code, name])
|
|
328
|
+
);
|
|
329
|
+
CODE_TO_LANGUAGE_NAME.sl = "slovene";
|
|
330
|
+
function normalizeLanguage(language) {
|
|
331
|
+
const lowered = language.trim().toLowerCase();
|
|
332
|
+
if (lowered === "") {
|
|
333
|
+
return asLanguageCode("");
|
|
334
|
+
}
|
|
335
|
+
if (lowered in LANGUAGE_NAMES_TO_CODE) {
|
|
336
|
+
return asLanguageCode(LANGUAGE_NAMES_TO_CODE[lowered]);
|
|
337
|
+
}
|
|
338
|
+
if (lowered in ISO_639_3_TO_1) {
|
|
339
|
+
return asLanguageCode(ISO_639_3_TO_1[lowered] ?? lowered);
|
|
340
|
+
}
|
|
341
|
+
const parts = lowered.replaceAll("_", "-").split("-");
|
|
342
|
+
if (parts.length >= 2) {
|
|
343
|
+
const [base, ...rest] = parts;
|
|
344
|
+
return asLanguageCode(
|
|
345
|
+
[
|
|
346
|
+
base,
|
|
347
|
+
...rest.map((part) => {
|
|
348
|
+
if (part.length === 4) {
|
|
349
|
+
return part.charAt(0).toUpperCase() + part.slice(1);
|
|
350
|
+
}
|
|
351
|
+
return part.toUpperCase();
|
|
352
|
+
})
|
|
353
|
+
].join("-")
|
|
354
|
+
);
|
|
355
|
+
}
|
|
356
|
+
return asLanguageCode(lowered);
|
|
357
|
+
}
|
|
358
|
+
function getBaseLanguage(language) {
|
|
359
|
+
const normalized = normalizeLanguage(language);
|
|
360
|
+
const [base = ""] = normalized.split("-");
|
|
361
|
+
return ISO_639_3_TO_1[base] ?? base;
|
|
362
|
+
}
|
|
363
|
+
function getIsoLanguage(language) {
|
|
364
|
+
const normalized = normalizeLanguage(language);
|
|
365
|
+
const region = getLanguageRegion(normalized);
|
|
366
|
+
const baseLanguage = getBaseLanguage(normalized);
|
|
367
|
+
return region ? `${baseLanguage}-${region}` : baseLanguage;
|
|
368
|
+
}
|
|
369
|
+
function getLanguageRegion(language) {
|
|
370
|
+
const normalized = normalizeLanguage(language);
|
|
371
|
+
const [, ...parts] = normalized.split("-");
|
|
372
|
+
return parts.find((part) => part.length === 2);
|
|
373
|
+
}
|
|
374
|
+
function toLanguageName(language) {
|
|
375
|
+
return CODE_TO_LANGUAGE_NAME[getBaseLanguage(language)];
|
|
376
|
+
}
|
|
377
|
+
function areLanguagesEquivalent(left, right) {
|
|
378
|
+
if (left == null || right == null) {
|
|
379
|
+
return left === right;
|
|
380
|
+
}
|
|
381
|
+
return normalizeLanguage(left) === normalizeLanguage(right);
|
|
382
|
+
}
|
|
383
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
384
|
+
0 && (module.exports = {
|
|
385
|
+
KNOWN_LANGUAGE_CODES,
|
|
386
|
+
areLanguagesEquivalent,
|
|
387
|
+
asLanguageCode,
|
|
388
|
+
getBaseLanguage,
|
|
389
|
+
getIsoLanguage,
|
|
390
|
+
getLanguageRegion,
|
|
391
|
+
normalizeLanguage,
|
|
392
|
+
toLanguageName
|
|
393
|
+
});
|
|
394
|
+
//# sourceMappingURL=language.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/language.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2026 LiveKit, Inc.\n//\n// SPDX-License-Identifier: Apache-2.0\n\nexport const KNOWN_LANGUAGE_CODES = [\n 'af',\n 'am',\n 'ar',\n 'as',\n 'az',\n 'be',\n 'bg',\n 'bn',\n 'bs',\n 'ca',\n 'cs',\n 'cy',\n 'da',\n 'de',\n 'el',\n 'en',\n 'es',\n 'et',\n 'eu',\n 'fa',\n 'ff',\n 'fi',\n 'fr',\n 'ga',\n 'gl',\n 'gu',\n 'ha',\n 'he',\n 'hi',\n 'hr',\n 'hu',\n 'hy',\n 'id',\n 'ig',\n 'is',\n 'it',\n 'ja',\n 'jv',\n 'ka',\n 'kk',\n 'km',\n 'kn',\n 'ko',\n 'ku',\n 'ky',\n 'lb',\n 'lg',\n 'ln',\n 'lo',\n 'lt',\n 'lv',\n 'mi',\n 'mk',\n 'ml',\n 'mn',\n 'mr',\n 'ms',\n 'mt',\n 'my',\n 'ne',\n 'nl',\n 'no',\n 'ny',\n 'oc',\n 'or',\n 'pa',\n 'pl',\n 'ps',\n 'pt',\n 'ro',\n 'ru',\n 'sd',\n 'sk',\n 'sl',\n 'sn',\n 'so',\n 'sq',\n 'sr',\n 'sv',\n 'sw',\n 'ta',\n 'te',\n 'tg',\n 'th',\n 'tl',\n 'tr',\n 'uk',\n 'ur',\n 'uz',\n 'vi',\n 'wo',\n 'xh',\n 'yo',\n 'zh',\n 'zu',\n] as const;\n\nexport type KnownLanguageCode = (typeof KNOWN_LANGUAGE_CODES)[number];\n\ndeclare const languageCodeBrand: unique symbol;\n\nexport type LanguageCode = string & { readonly [languageCodeBrand]: 'LanguageCode' };\n\nexport function asLanguageCode(language: string): LanguageCode {\n return language as LanguageCode;\n}\n\nconst ISO_639_3_TO_1: Record<string, string | undefined> = {\n afr: 'af',\n amh: 'am',\n ara: 'ar',\n hye: 'hy',\n asm: 'as',\n ast: undefined,\n aze: 'az',\n bel: 'be',\n ben: 'bn',\n bos: 'bs',\n bul: 'bg',\n mya: 'my',\n yue: undefined,\n cat: 'ca',\n ceb: undefined,\n cmn: 'zh',\n nya: 'ny',\n hrv: 'hr',\n ces: 'cs',\n dan: 'da',\n nld: 'nl',\n eng: 'en',\n est: 'et',\n fil: undefined,\n fin: 'fi',\n fra: 'fr',\n ful: 'ff',\n glg: 'gl',\n lug: 'lg',\n kat: 'ka',\n deu: 'de',\n ell: 'el',\n guj: 'gu',\n hau: 'ha',\n heb: 'he',\n hin: 'hi',\n hun: 'hu',\n isl: 'is',\n ibo: 'ig',\n ind: 'id',\n gle: 'ga',\n ita: 'it',\n jpn: 'ja',\n jav: 'jv',\n kea: undefined,\n kan: 'kn',\n kaz: 'kk',\n khm: 'km',\n kor: 'ko',\n kur: 'ku',\n kir: 'ky',\n lao: 'lo',\n lav: 'lv',\n lin: 'ln',\n lit: 'lt',\n luo: undefined,\n ltz: 'lb',\n mkd: 'mk',\n msa: 'ms',\n mal: 'ml',\n mlt: 'mt',\n zho: 'zh',\n mri: 'mi',\n mar: 'mr',\n mon: 'mn',\n nep: 'ne',\n nso: undefined,\n nor: 'no',\n oci: 'oc',\n ori: 'or',\n pus: 'ps',\n fas: 'fa',\n pol: 'pl',\n por: 'pt',\n pan: 'pa',\n ron: 'ro',\n rus: 'ru',\n srp: 'sr',\n sna: 'sn',\n snd: 'sd',\n slk: 'sk',\n slv: 'sl',\n som: 'so',\n spa: 'es',\n swa: 'sw',\n swe: 'sv',\n tam: 'ta',\n tgk: 'tg',\n tel: 'te',\n tha: 'th',\n tur: 'tr',\n ukr: 'uk',\n umb: undefined,\n urd: 'ur',\n uzb: 'uz',\n vie: 'vi',\n cym: 'cy',\n wol: 'wo',\n xho: 'xh',\n zul: 'zu',\n};\n\nconst LANGUAGE_NAMES_TO_CODE: Record<string, string> = {\n afrikaans: 'af',\n albanian: 'sq',\n amharic: 'am',\n arabic: 'ar',\n armenian: 'hy',\n azerbaijani: 'az',\n basque: 'eu',\n belarusian: 'be',\n bengali: 'bn',\n bosnian: 'bs',\n bulgarian: 'bg',\n burmese: 'my',\n catalan: 'ca',\n chinese: 'zh',\n croatian: 'hr',\n czech: 'cs',\n danish: 'da',\n dutch: 'nl',\n english: 'en',\n estonian: 'et',\n finnish: 'fi',\n french: 'fr',\n galician: 'gl',\n georgian: 'ka',\n german: 'de',\n greek: 'el',\n gujarati: 'gu',\n hausa: 'ha',\n hebrew: 'he',\n hindi: 'hi',\n hungarian: 'hu',\n icelandic: 'is',\n indonesian: 'id',\n irish: 'ga',\n italian: 'it',\n japanese: 'ja',\n javanese: 'jv',\n kannada: 'kn',\n kazakh: 'kk',\n khmer: 'km',\n korean: 'ko',\n kurdish: 'ku',\n kyrgyz: 'ky',\n lao: 'lo',\n latvian: 'lv',\n lingala: 'ln',\n lithuanian: 'lt',\n luxembourgish: 'lb',\n macedonian: 'mk',\n malay: 'ms',\n malayalam: 'ml',\n maltese: 'mt',\n maori: 'mi',\n marathi: 'mr',\n mongolian: 'mn',\n nepali: 'ne',\n norwegian: 'no',\n occitan: 'oc',\n oriya: 'or',\n pashto: 'ps',\n persian: 'fa',\n polish: 'pl',\n portuguese: 'pt',\n punjabi: 'pa',\n romanian: 'ro',\n russian: 'ru',\n serbian: 'sr',\n shona: 'sn',\n sindhi: 'sd',\n slovak: 'sk',\n slovene: 'sl',\n slovenian: 'sl',\n somali: 'so',\n spanish: 'es',\n swahili: 'sw',\n swedish: 'sv',\n tagalog: 'tl',\n tamil: 'ta',\n tajik: 'tg',\n telugu: 'te',\n thai: 'th',\n turkish: 'tr',\n ukrainian: 'uk',\n urdu: 'ur',\n uzbek: 'uz',\n vietnamese: 'vi',\n welsh: 'cy',\n wolof: 'wo',\n xhosa: 'xh',\n yoruba: 'yo',\n zulu: 'zu',\n};\n\nconst CODE_TO_LANGUAGE_NAME: Record<string, string> = Object.fromEntries(\n Object.entries(LANGUAGE_NAMES_TO_CODE).map(([name, code]) => [code, name]),\n);\n\nCODE_TO_LANGUAGE_NAME.sl = 'slovene';\n\nexport function normalizeLanguage(language: string): LanguageCode {\n const lowered = language.trim().toLowerCase();\n if (lowered === '') {\n return asLanguageCode('');\n }\n\n if (lowered in LANGUAGE_NAMES_TO_CODE) {\n return asLanguageCode(LANGUAGE_NAMES_TO_CODE[lowered]!);\n }\n\n if (lowered in ISO_639_3_TO_1) {\n return asLanguageCode(ISO_639_3_TO_1[lowered] ?? lowered);\n }\n\n const parts = lowered.replaceAll('_', '-').split('-');\n if (parts.length >= 2) {\n const [base, ...rest] = parts;\n return asLanguageCode(\n [\n base,\n ...rest.map((part) => {\n if (part.length === 4) {\n return part.charAt(0).toUpperCase() + part.slice(1);\n }\n return part.toUpperCase();\n }),\n ].join('-'),\n );\n }\n\n return asLanguageCode(lowered);\n}\n\nexport function getBaseLanguage(language: string): string {\n const normalized = normalizeLanguage(language);\n const [base = ''] = normalized.split('-');\n return ISO_639_3_TO_1[base] ?? base;\n}\n\nexport function getIsoLanguage(language: string): string {\n const normalized = normalizeLanguage(language);\n const region = getLanguageRegion(normalized);\n const baseLanguage = getBaseLanguage(normalized);\n return region ? `${baseLanguage}-${region}` : baseLanguage;\n}\n\nexport function getLanguageRegion(language: string): string | undefined {\n const normalized = normalizeLanguage(language);\n const [, ...parts] = normalized.split('-');\n return parts.find((part) => part.length === 2);\n}\n\nexport function toLanguageName(language: string): string | undefined {\n return CODE_TO_LANGUAGE_NAME[getBaseLanguage(language)];\n}\n\nexport function areLanguagesEquivalent(\n left: string | null | undefined,\n right: string | null | undefined,\n): boolean {\n if (left == null || right == null) {\n return left === right;\n }\n return normalizeLanguage(left) === normalizeLanguage(right);\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAIO,MAAM,uBAAuB;AAAA,EAClC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAQO,SAAS,eAAe,UAAgC;AAC7D,SAAO;AACT;AAEA,MAAM,iBAAqD;AAAA,EACzD,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA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","names":[]}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export declare const KNOWN_LANGUAGE_CODES: readonly ["af", "am", "ar", "as", "az", "be", "bg", "bn", "bs", "ca", "cs", "cy", "da", "de", "el", "en", "es", "et", "eu", "fa", "ff", "fi", "fr", "ga", "gl", "gu", "ha", "he", "hi", "hr", "hu", "hy", "id", "ig", "is", "it", "ja", "jv", "ka", "kk", "km", "kn", "ko", "ku", "ky", "lb", "lg", "ln", "lo", "lt", "lv", "mi", "mk", "ml", "mn", "mr", "ms", "mt", "my", "ne", "nl", "no", "ny", "oc", "or", "pa", "pl", "ps", "pt", "ro", "ru", "sd", "sk", "sl", "sn", "so", "sq", "sr", "sv", "sw", "ta", "te", "tg", "th", "tl", "tr", "uk", "ur", "uz", "vi", "wo", "xh", "yo", "zh", "zu"];
|
|
2
|
+
export type KnownLanguageCode = (typeof KNOWN_LANGUAGE_CODES)[number];
|
|
3
|
+
declare const languageCodeBrand: unique symbol;
|
|
4
|
+
export type LanguageCode = string & {
|
|
5
|
+
readonly [languageCodeBrand]: 'LanguageCode';
|
|
6
|
+
};
|
|
7
|
+
export declare function asLanguageCode(language: string): LanguageCode;
|
|
8
|
+
export declare function normalizeLanguage(language: string): LanguageCode;
|
|
9
|
+
export declare function getBaseLanguage(language: string): string;
|
|
10
|
+
export declare function getIsoLanguage(language: string): string;
|
|
11
|
+
export declare function getLanguageRegion(language: string): string | undefined;
|
|
12
|
+
export declare function toLanguageName(language: string): string | undefined;
|
|
13
|
+
export declare function areLanguagesEquivalent(left: string | null | undefined, right: string | null | undefined): boolean;
|
|
14
|
+
export {};
|
|
15
|
+
//# sourceMappingURL=language.d.ts.map
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export declare const KNOWN_LANGUAGE_CODES: readonly ["af", "am", "ar", "as", "az", "be", "bg", "bn", "bs", "ca", "cs", "cy", "da", "de", "el", "en", "es", "et", "eu", "fa", "ff", "fi", "fr", "ga", "gl", "gu", "ha", "he", "hi", "hr", "hu", "hy", "id", "ig", "is", "it", "ja", "jv", "ka", "kk", "km", "kn", "ko", "ku", "ky", "lb", "lg", "ln", "lo", "lt", "lv", "mi", "mk", "ml", "mn", "mr", "ms", "mt", "my", "ne", "nl", "no", "ny", "oc", "or", "pa", "pl", "ps", "pt", "ro", "ru", "sd", "sk", "sl", "sn", "so", "sq", "sr", "sv", "sw", "ta", "te", "tg", "th", "tl", "tr", "uk", "ur", "uz", "vi", "wo", "xh", "yo", "zh", "zu"];
|
|
2
|
+
export type KnownLanguageCode = (typeof KNOWN_LANGUAGE_CODES)[number];
|
|
3
|
+
declare const languageCodeBrand: unique symbol;
|
|
4
|
+
export type LanguageCode = string & {
|
|
5
|
+
readonly [languageCodeBrand]: 'LanguageCode';
|
|
6
|
+
};
|
|
7
|
+
export declare function asLanguageCode(language: string): LanguageCode;
|
|
8
|
+
export declare function normalizeLanguage(language: string): LanguageCode;
|
|
9
|
+
export declare function getBaseLanguage(language: string): string;
|
|
10
|
+
export declare function getIsoLanguage(language: string): string;
|
|
11
|
+
export declare function getLanguageRegion(language: string): string | undefined;
|
|
12
|
+
export declare function toLanguageName(language: string): string | undefined;
|
|
13
|
+
export declare function areLanguagesEquivalent(left: string | null | undefined, right: string | null | undefined): boolean;
|
|
14
|
+
export {};
|
|
15
|
+
//# sourceMappingURL=language.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"language.d.ts","sourceRoot":"","sources":["../src/language.ts"],"names":[],"mappings":"AAIA,eAAO,MAAM,oBAAoB,qkBAgGvB,CAAC;AAEX,MAAM,MAAM,iBAAiB,GAAG,CAAC,OAAO,oBAAoB,CAAC,CAAC,MAAM,CAAC,CAAC;AAEtE,OAAO,CAAC,MAAM,iBAAiB,EAAE,OAAO,MAAM,CAAC;AAE/C,MAAM,MAAM,YAAY,GAAG,MAAM,GAAG;IAAE,QAAQ,CAAC,CAAC,iBAAiB,CAAC,EAAE,cAAc,CAAA;CAAE,CAAC;AAErF,wBAAgB,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,YAAY,CAE7D;AA6MD,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,GAAG,YAAY,CA+BhE;AAED,wBAAgB,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAIxD;AAED,wBAAgB,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAKvD;AAED,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAItE;AAED,wBAAgB,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAEnE;AAED,wBAAgB,sBAAsB,CACpC,IAAI,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,EAC/B,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAC/B,OAAO,CAKT"}
|