export const CANVAS_IMAGE_TASK_QUEUE_CONFIG_KEY = "canvas_image_task_queue_config"; export const DEFAULT_CANVAS_IMAGE_TASK_CONCURRENCY = 1; export const MAX_CANVAS_IMAGE_TASK_CONCURRENCY = 100; export interface CanvasImageTaskQueueConfig { concurrency: number; } function clampConcurrency(value: number) { return Math.min( MAX_CANVAS_IMAGE_TASK_CONCURRENCY, Math.max(DEFAULT_CANVAS_IMAGE_TASK_CONCURRENCY, Math.floor(value)) ); } function parseConcurrencyCandidate(value: unknown): number | null { if (typeof value === "number" && Number.isFinite(value)) { return clampConcurrency(value); } if (typeof value === "string" && value.trim()) { const parsed = Number.parseInt(value.trim(), 10); if (Number.isFinite(parsed)) { return clampConcurrency(parsed); } } return null; } export function normalizeCanvasImageTaskQueueConfig( value: unknown, options?: { envConcurrency?: unknown } ): CanvasImageTaskQueueConfig { const raw = value && typeof value === "object" && !Array.isArray(value) ? (value as Record) : {}; const candidates = [ raw.concurrency, raw.maxConcurrency, raw.maxConcurrent, typeof value === "number" || typeof value === "string" ? value : undefined, options?.envConcurrency, ]; for (const candidate of candidates) { const parsed = parseConcurrencyCandidate(candidate); if (parsed !== null) { return { concurrency: parsed }; } } return { concurrency: DEFAULT_CANVAS_IMAGE_TASK_CONCURRENCY }; }