@meframe/core 0.0.2 → 0.0.4

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 (193) hide show
  1. package/dist/Meframe.d.ts.map +1 -1
  2. package/dist/Meframe.js +6 -4
  3. package/dist/Meframe.js.map +1 -1
  4. package/dist/cache/CacheManager.d.ts +2 -2
  5. package/dist/cache/CacheManager.d.ts.map +1 -1
  6. package/dist/cache/CacheManager.js +4 -3
  7. package/dist/cache/CacheManager.js.map +1 -1
  8. package/dist/cache/l1/VideoL1Cache.d.ts +2 -2
  9. package/dist/cache/l1/VideoL1Cache.d.ts.map +1 -1
  10. package/dist/cache/l1/VideoL1Cache.js +13 -8
  11. package/dist/cache/l1/VideoL1Cache.js.map +1 -1
  12. package/dist/config/defaults.d.ts.map +1 -1
  13. package/dist/config/defaults.js +3 -1
  14. package/dist/config/defaults.js.map +1 -1
  15. package/dist/config/types.d.ts +6 -0
  16. package/dist/config/types.d.ts.map +1 -1
  17. package/dist/controllers/PlaybackController.d.ts +7 -8
  18. package/dist/controllers/PlaybackController.d.ts.map +1 -1
  19. package/dist/controllers/PlaybackController.js +56 -76
  20. package/dist/controllers/PlaybackController.js.map +1 -1
  21. package/dist/controllers/types.d.ts +2 -3
  22. package/dist/controllers/types.d.ts.map +1 -1
  23. package/dist/event/events.d.ts +1 -4
  24. package/dist/event/events.d.ts.map +1 -1
  25. package/dist/event/events.js.map +1 -1
  26. package/dist/model/CompositionModel.d.ts +1 -0
  27. package/dist/model/CompositionModel.d.ts.map +1 -1
  28. package/dist/model/CompositionModel.js +2 -0
  29. package/dist/model/CompositionModel.js.map +1 -1
  30. package/dist/model/patch.d.ts +6 -2
  31. package/dist/model/patch.d.ts.map +1 -1
  32. package/dist/model/patch.js +76 -2
  33. package/dist/model/patch.js.map +1 -1
  34. package/dist/model/types.d.ts +1 -0
  35. package/dist/model/types.d.ts.map +1 -1
  36. package/dist/orchestrator/CompositionPlanner.d.ts +8 -7
  37. package/dist/orchestrator/CompositionPlanner.d.ts.map +1 -1
  38. package/dist/orchestrator/CompositionPlanner.js +33 -56
  39. package/dist/orchestrator/CompositionPlanner.js.map +1 -1
  40. package/dist/orchestrator/Orchestrator.d.ts +0 -1
  41. package/dist/orchestrator/Orchestrator.d.ts.map +1 -1
  42. package/dist/orchestrator/Orchestrator.js +40 -19
  43. package/dist/orchestrator/Orchestrator.js.map +1 -1
  44. package/dist/orchestrator/VideoClipSession.d.ts +3 -5
  45. package/dist/orchestrator/VideoClipSession.d.ts.map +1 -1
  46. package/dist/orchestrator/VideoClipSession.js +66 -69
  47. package/dist/orchestrator/VideoClipSession.js.map +1 -1
  48. package/dist/orchestrator/types.d.ts +2 -0
  49. package/dist/orchestrator/types.d.ts.map +1 -1
  50. package/dist/stages/compose/GlobalAudioSession.d.ts +6 -0
  51. package/dist/stages/compose/GlobalAudioSession.d.ts.map +1 -1
  52. package/dist/stages/compose/GlobalAudioSession.js +17 -1
  53. package/dist/stages/compose/GlobalAudioSession.js.map +1 -1
  54. package/dist/stages/compose/types.d.ts +2 -1
  55. package/dist/stages/compose/types.d.ts.map +1 -1
  56. package/dist/stages/demux/MP4Demuxer.d.ts +0 -1
  57. package/dist/stages/demux/MP4Demuxer.d.ts.map +1 -1
  58. package/dist/stages/load/ResourceLoader.d.ts +22 -1
  59. package/dist/stages/load/ResourceLoader.d.ts.map +1 -1
  60. package/dist/stages/load/ResourceLoader.js +71 -25
  61. package/dist/stages/load/ResourceLoader.js.map +1 -1
  62. package/dist/stages/load/TaskManager.d.ts +1 -1
  63. package/dist/stages/load/TaskManager.d.ts.map +1 -1
  64. package/dist/stages/load/TaskManager.js +3 -2
  65. package/dist/stages/load/TaskManager.js.map +1 -1
  66. package/dist/stages/load/types.d.ts +2 -0
  67. package/dist/stages/load/types.d.ts.map +1 -1
  68. package/dist/utils/time-utils.d.ts +3 -2
  69. package/dist/utils/time-utils.d.ts.map +1 -1
  70. package/dist/utils/time-utils.js +2 -1
  71. package/dist/utils/time-utils.js.map +1 -1
  72. package/dist/vite-plugin.d.ts +5 -3
  73. package/dist/vite-plugin.d.ts.map +1 -1
  74. package/dist/vite-plugin.js +109 -52
  75. package/dist/vite-plugin.js.map +1 -1
  76. package/dist/worker/WorkerPool.d.ts +9 -0
  77. package/dist/worker/WorkerPool.d.ts.map +1 -1
  78. package/dist/worker/WorkerPool.js +32 -5
  79. package/dist/worker/WorkerPool.js.map +1 -1
  80. package/dist/{stages/demux → workers}/MP4Demuxer.js +4 -13
  81. package/dist/workers/MP4Demuxer.js.map +1 -0
  82. package/dist/workers/WorkerChannel.js +486 -0
  83. package/dist/workers/WorkerChannel.js.map +1 -0
  84. package/dist/{assets/video-demux.worker-D019I7GQ.js → workers/mp4box.all.js} +4 -912
  85. package/dist/workers/mp4box.all.js.map +1 -0
  86. package/dist/{assets/audio-compose.worker-nGVvHD5Q.js → workers/stages/compose/audio-compose.worker.js} +7 -481
  87. package/dist/workers/stages/compose/audio-compose.worker.js.map +1 -0
  88. package/dist/{assets/video-compose.worker-DPzsC21d.js → workers/stages/compose/video-compose.worker.js} +120 -562
  89. package/dist/workers/stages/compose/video-compose.worker.js.map +1 -0
  90. package/dist/{assets/decode.worker-DpWHsc7R.js → workers/stages/decode/decode.worker.js} +7 -481
  91. package/dist/workers/stages/decode/decode.worker.js.map +1 -0
  92. package/dist/{stages → workers/stages}/demux/audio-demux.worker.js +184 -4
  93. package/dist/workers/stages/demux/audio-demux.worker.js.map +1 -0
  94. package/dist/{stages → workers/stages}/demux/video-demux.worker.js +2 -3
  95. package/dist/workers/stages/demux/video-demux.worker.js.map +1 -0
  96. package/dist/{stages → workers/stages}/encode/encode.worker.js +238 -4
  97. package/dist/workers/stages/encode/encode.worker.js.map +1 -0
  98. package/dist/{stages/mux/MP4Muxer.js → workers/stages/mux/mux.worker.js} +244 -5
  99. package/dist/workers/stages/mux/mux.worker.js.map +1 -0
  100. package/package.json +21 -21
  101. package/dist/assets/audio-compose.worker-nGVvHD5Q.js.map +0 -1
  102. package/dist/assets/audio-demux.worker-xwWBtbAe.js +0 -8299
  103. package/dist/assets/audio-demux.worker-xwWBtbAe.js.map +0 -1
  104. package/dist/assets/decode.worker-DpWHsc7R.js.map +0 -1
  105. package/dist/assets/encode.worker-nfOb3kw6.js +0 -1026
  106. package/dist/assets/encode.worker-nfOb3kw6.js.map +0 -1
  107. package/dist/assets/mux.worker-uEMQY066.js +0 -8019
  108. package/dist/assets/mux.worker-uEMQY066.js.map +0 -1
  109. package/dist/assets/video-compose.worker-DPzsC21d.js.map +0 -1
  110. package/dist/assets/video-demux.worker-D019I7GQ.js.map +0 -1
  111. package/dist/controllers/PreviewHandle.d.ts +0 -25
  112. package/dist/controllers/PreviewHandle.d.ts.map +0 -1
  113. package/dist/controllers/PreviewHandle.js +0 -45
  114. package/dist/controllers/PreviewHandle.js.map +0 -1
  115. package/dist/model/dirty-range.js +0 -220
  116. package/dist/model/dirty-range.js.map +0 -1
  117. package/dist/model/types.js +0 -5
  118. package/dist/model/types.js.map +0 -1
  119. package/dist/plugins/BackpressureMonitor.js +0 -62
  120. package/dist/plugins/BackpressureMonitor.js.map +0 -1
  121. package/dist/stages/compose/AudioDucker.js +0 -161
  122. package/dist/stages/compose/AudioDucker.js.map +0 -1
  123. package/dist/stages/compose/AudioMixer.js +0 -373
  124. package/dist/stages/compose/AudioMixer.js.map +0 -1
  125. package/dist/stages/compose/FilterProcessor.js +0 -226
  126. package/dist/stages/compose/FilterProcessor.js.map +0 -1
  127. package/dist/stages/compose/LayerRenderer.js +0 -215
  128. package/dist/stages/compose/LayerRenderer.js.map +0 -1
  129. package/dist/stages/compose/TransitionProcessor.js +0 -189
  130. package/dist/stages/compose/TransitionProcessor.js.map +0 -1
  131. package/dist/stages/compose/VideoComposer.js +0 -186
  132. package/dist/stages/compose/VideoComposer.js.map +0 -1
  133. package/dist/stages/compose/audio-compose.worker.d.ts +0 -79
  134. package/dist/stages/compose/audio-compose.worker.d.ts.map +0 -1
  135. package/dist/stages/compose/audio-compose.worker.js +0 -540
  136. package/dist/stages/compose/audio-compose.worker.js.map +0 -1
  137. package/dist/stages/compose/audio-compose.worker2.js +0 -5
  138. package/dist/stages/compose/audio-compose.worker2.js.map +0 -1
  139. package/dist/stages/compose/video-compose.worker.d.ts +0 -60
  140. package/dist/stages/compose/video-compose.worker.d.ts.map +0 -1
  141. package/dist/stages/compose/video-compose.worker.js +0 -379
  142. package/dist/stages/compose/video-compose.worker.js.map +0 -1
  143. package/dist/stages/compose/video-compose.worker2.js +0 -5
  144. package/dist/stages/compose/video-compose.worker2.js.map +0 -1
  145. package/dist/stages/decode/AudioChunkDecoder.js +0 -82
  146. package/dist/stages/decode/AudioChunkDecoder.js.map +0 -1
  147. package/dist/stages/decode/BaseDecoder.js +0 -130
  148. package/dist/stages/decode/BaseDecoder.js.map +0 -1
  149. package/dist/stages/decode/VideoChunkDecoder.js +0 -199
  150. package/dist/stages/decode/VideoChunkDecoder.js.map +0 -1
  151. package/dist/stages/decode/decode.worker.d.ts +0 -70
  152. package/dist/stages/decode/decode.worker.d.ts.map +0 -1
  153. package/dist/stages/decode/decode.worker.js +0 -423
  154. package/dist/stages/decode/decode.worker.js.map +0 -1
  155. package/dist/stages/decode/decode.worker2.js +0 -5
  156. package/dist/stages/decode/decode.worker2.js.map +0 -1
  157. package/dist/stages/demux/MP3FrameParser.js +0 -186
  158. package/dist/stages/demux/MP3FrameParser.js.map +0 -1
  159. package/dist/stages/demux/MP4Demuxer.js.map +0 -1
  160. package/dist/stages/demux/audio-demux.worker.d.ts +0 -51
  161. package/dist/stages/demux/audio-demux.worker.d.ts.map +0 -1
  162. package/dist/stages/demux/audio-demux.worker.js.map +0 -1
  163. package/dist/stages/demux/audio-demux.worker2.js +0 -5
  164. package/dist/stages/demux/audio-demux.worker2.js.map +0 -1
  165. package/dist/stages/demux/video-demux.worker.d.ts +0 -51
  166. package/dist/stages/demux/video-demux.worker.d.ts.map +0 -1
  167. package/dist/stages/demux/video-demux.worker.js.map +0 -1
  168. package/dist/stages/demux/video-demux.worker2.js +0 -5
  169. package/dist/stages/demux/video-demux.worker2.js.map +0 -1
  170. package/dist/stages/encode/AudioChunkEncoder.js +0 -37
  171. package/dist/stages/encode/AudioChunkEncoder.js.map +0 -1
  172. package/dist/stages/encode/BaseEncoder.js +0 -164
  173. package/dist/stages/encode/BaseEncoder.js.map +0 -1
  174. package/dist/stages/encode/VideoChunkEncoder.js +0 -50
  175. package/dist/stages/encode/VideoChunkEncoder.js.map +0 -1
  176. package/dist/stages/encode/encode.worker.d.ts +0 -3
  177. package/dist/stages/encode/encode.worker.d.ts.map +0 -1
  178. package/dist/stages/encode/encode.worker.js.map +0 -1
  179. package/dist/stages/encode/encode.worker2.js +0 -5
  180. package/dist/stages/encode/encode.worker2.js.map +0 -1
  181. package/dist/stages/mux/MP4Muxer.js.map +0 -1
  182. package/dist/stages/mux/mux.worker.d.ts +0 -65
  183. package/dist/stages/mux/mux.worker.d.ts.map +0 -1
  184. package/dist/stages/mux/mux.worker.js +0 -219
  185. package/dist/stages/mux/mux.worker.js.map +0 -1
  186. package/dist/stages/mux/mux.worker2.js +0 -5
  187. package/dist/stages/mux/mux.worker2.js.map +0 -1
  188. package/dist/stages/mux/utils.js +0 -34
  189. package/dist/stages/mux/utils.js.map +0 -1
  190. package/dist/worker/worker-registry.d.ts +0 -12
  191. package/dist/worker/worker-registry.d.ts.map +0 -1
  192. package/dist/worker/worker-registry.js +0 -20
  193. package/dist/worker/worker-registry.js.map +0 -1
@@ -1 +0,0 @@
1
- {"version":3,"file":"video-compose.worker-DPzsC21d.js","sources":["../src/worker/types.ts","../src/worker/worker-retry.ts","../src/worker/transferable-helper.ts","../src/worker/WorkerChannel.ts","../src/model/types.ts","../src/utils/time-utils.ts","../src/stages/compose/LayerRenderer.ts","../src/stages/compose/TransitionProcessor.ts","../src/stages/compose/FilterProcessor.ts","../src/stages/compose/VideoComposer.ts","../src/stages/compose/video-compose.worker.ts"],"sourcesContent":["/**\n * Worker Communication Protocol Types\n * Define standard message types and protocols for worker communication\n */\n\n// A port-like object that supports postMessage/onmessage used by WorkerChannel\nexport type PortLike = MessagePort | DedicatedWorkerGlobalScope | Worker;\n\n/**\n * Worker types in the pipeline\n */\nexport type WorkerType =\n | 'videoDemux'\n | 'audioDemux'\n | 'decode'\n | 'videoCompose'\n | 'audioCompose'\n | 'encode'\n | 'mux';\n\nexport interface WorkerConfigurePayload<T = any> {\n config: T;\n initial: boolean;\n}\n\n/**\n * Worker state definition\n */\nexport interface WorkerStateInfo {\n state: 'idle' | 'busy' | 'error' | 'terminated';\n taskCount: number;\n lastError?: string;\n}\n\n/**\n * Worker status for all workers\n */\nexport type WorkerStatus = Record<WorkerType, WorkerStateInfo>;\n\n/**\n * Worker wrapper interface\n */\nexport interface IWorker {\n readonly type: WorkerType;\n readonly state: WorkerStateInfo;\n\n initialize(): Promise<void>;\n terminate(): Promise<void>;\n restart(): Promise<void>;\n\n postMessage(message: any, transfer?: Transferable[]): void;\n on(event: string, handler: (data: any) => void): void;\n off(event: string, handler: (data: any) => void): void;\n}\n\n// Message types for different workers\nexport enum WorkerMessageType {\n // Init = 'init', // configure, { initial: true }\n Ready = 'ready',\n Error = 'error',\n Dispose = 'dispose',\n Configure = 'configure',\n LoadResource = 'load_resource',\n ResourceLoaded = 'resource_loaded',\n ResourceProgress = 'resource_progress',\n ConfigureDemux = 'configure_demux',\n AppendBuffer = 'append_buffer',\n DemuxSamples = 'demux_samples',\n FlushDemux = 'flush_demux',\n ConfigureDecode = 'configure_decode',\n DecodeChunk = 'decode_chunk',\n DecodedFrame = 'decoded_frame',\n SeekGop = 'seek_gop',\n SetComposition = 'set_composition',\n ApplyPatch = 'apply_patch',\n RenderFrame = 'render_frame',\n ComposeFrameReady = 'compose_frame_ready',\n ConfigureEncode = 'configure_encode',\n EncodeFrame = 'encode_frame',\n EncodeAudio = 'encode_audio',\n EncodedChunk = 'encoded_chunk',\n FlushEncode = 'flush_encode',\n ConfigureMux = 'configure_mux',\n AddChunk = 'add_chunk',\n FinishMux = 'finish_mux',\n MuxComplete = 'mux_complete',\n PerformanceStats = 'performance_stats',\n RenderWindow = 'renderWindow',\n AudioTrackAdd = 'audio_track:add',\n AudioTrackRemove = 'audio_track:remove',\n AudioTrackUpdate = 'audio_track:update',\n}\n\n// Base message structure\nexport interface WorkerMessage<T = any> {\n type: WorkerMessageType;\n id: string; // Unique message ID for request-response pairing\n payload?: T;\n transfer?: Transferable[]; // Objects to transfer ownership\n timestamp: number;\n}\n\n// Response message structure\nexport interface WorkerResponse<T = any> {\n id: string; // Matches request ID\n success: boolean;\n result?: T;\n error?: WorkerError;\n timestamp: number;\n}\n\n// Error structure\nexport interface WorkerError {\n code: string;\n message: string;\n details?: any;\n stack?: string;\n}\n\n// Worker configuration\nexport interface WorkerConfig {\n name: string;\n workerUrl?: string;\n capabilities?: string[];\n maxRetries?: number;\n timeout?: number;\n}\n\n// Message handler type\nexport type MessageHandler<T = any, R = any> = (\n payload: T,\n transfer?: Transferable[]\n) => Promise<R> | R;\n\n// Message handler registry\nexport interface MessageHandlers {\n [key: string]: MessageHandler;\n}\n\n/**\n * Unified stream connection message for the data plane\n * Used by the stream-pipeline refactor to reduce message surface\n */\nexport interface ConnectMsg {\n direction: 'upstream';\n port: MessagePort;\n streamType: 'video' | 'audio' | 'frame' | 'chunk';\n clipId?: string;\n trackId?: string;\n}\n\n// Transferable types used in workers\nexport interface TransferableFrame {\n frame: VideoFrame;\n timestamp: number;\n duration?: number;\n}\n\nexport interface TransferableChunk {\n chunk: EncodedVideoChunk | EncodedAudioChunk;\n timestamp: number;\n duration?: number;\n trackId: string;\n}\n\nexport interface TransferableBuffer {\n buffer: ArrayBuffer;\n offset?: number;\n length?: number;\n}\n\n// Worker state\nexport enum WorkerState {\n Idle = 'idle',\n Initializing = 'initializing',\n Ready = 'ready',\n Processing = 'processing',\n Error = 'error',\n Disposed = 'disposed',\n}\n\n// Performance metrics\nexport interface WorkerPerformanceStats {\n workerId: string;\n workerName: string;\n messagesProcessed: number;\n averageProcessingTime: number;\n maxProcessingTime: number;\n errorCount: number;\n queueSize: number;\n memoryUsage?: number;\n}\n\n// Request tracking\nexport interface PendingRequest {\n id: string;\n type: WorkerMessageType;\n timestamp: number;\n timeout?: number;\n resolve: (value: any) => void;\n reject: (error: any) => void;\n retryCount?: number;\n maxRetries?: number;\n}\n\n// Stream support\nexport interface StreamConfig {\n highWaterMark?: number;\n strategy?: QueuingStrategy;\n}\n\n// Worker pool settings\nexport interface WorkerPoolSettings {\n maxWorkers?: number;\n workerIdleTimeout?: number;\n enableSharedArrayBuffer?: boolean;\n enableOffscreenCanvas?: boolean;\n}\n\n// Message priority levels\nexport enum MessagePriority {\n Low = 0,\n Normal = 1,\n High = 2,\n Critical = 3,\n}\n\n// Priority message\nexport interface PriorityMessage<T = any> extends WorkerMessage<T> {\n priority: MessagePriority;\n}\n","/**\n * Retry utility for worker communication\n * Provides configurable retry logic with exponential backoff\n */\n\nimport { WorkerMessageType } from './types';\n\nexport interface RetryConfig {\n maxRetries: number;\n initialDelay?: number; // Initial delay in ms\n maxDelay?: number; // Max delay in ms\n backoffFactor?: number; // Exponential backoff factor\n retryableErrors?: string[]; // Error codes that can be retried\n}\n\nexport interface RetryContext {\n attempt: number;\n maxRetries: number;\n lastError?: Error;\n messageType: WorkerMessageType;\n}\n\n/**\n * Default retry configuration\n */\nexport const defaultRetryConfig: Required<RetryConfig> = {\n maxRetries: 3,\n initialDelay: 100,\n maxDelay: 5000,\n backoffFactor: 2,\n retryableErrors: ['TIMEOUT', 'NETWORK_ERROR', 'WORKER_BUSY'],\n};\n\n/**\n * Calculate delay for next retry attempt\n */\nexport function calculateRetryDelay(attempt: number, config: RetryConfig): number {\n const { initialDelay = 100, maxDelay = 5000, backoffFactor = 2 } = config;\n\n const delay = initialDelay * Math.pow(backoffFactor, attempt - 1);\n return Math.min(delay, maxDelay);\n}\n\n/**\n * Check if error is retryable\n */\nexport function isRetryableError(error: Error | any, config: RetryConfig): boolean {\n const { retryableErrors = defaultRetryConfig.retryableErrors } = config;\n\n if (!error) return false;\n\n // Check error code\n const errorCode = error.code || error.name;\n if (errorCode && retryableErrors.includes(errorCode)) {\n return true;\n }\n\n // Check error message for known patterns\n const message = error.message || '';\n if (message.includes('timeout') || message.includes('Timeout')) {\n return true;\n }\n\n return false;\n}\n\n/**\n * Execute function with retry logic\n */\nexport async function withRetry<T>(\n fn: () => Promise<T>,\n config: RetryConfig\n // context?: Partial<RetryContext>\n): Promise<T> {\n const { maxRetries } = config;\n let lastError: Error | undefined;\n\n for (let attempt = 1; attempt <= maxRetries; attempt++) {\n try {\n return await fn();\n } catch (error) {\n lastError = error as Error;\n\n // Check if error is retryable\n if (!isRetryableError(error, config)) {\n throw error;\n }\n\n // Check if we've exhausted retries\n if (attempt === maxRetries) {\n throw error;\n }\n\n // Calculate and apply delay\n const delay = calculateRetryDelay(attempt, config);\n await sleep(delay);\n }\n }\n\n // This should never be reached, but TypeScript needs it\n throw lastError || new Error('Retry failed');\n}\n\n/**\n * Sleep for specified milliseconds\n */\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\n/**\n * Create a retry wrapper for a specific operation\n */\nexport function createRetryWrapper<T extends (...args: any[]) => Promise<any>>(\n fn: T,\n config: RetryConfig\n): T {\n return (async (...args: Parameters<T>) => {\n return withRetry(() => fn(...args), config);\n }) as T;\n}\n","/**\n * Utility functions for handling Transferable objects\n * Simplifies the process of transferring ownership of objects between workers\n */\n\n/**\n * Check if an object is transferable\n */\nexport function isTransferable(obj: any): obj is Transferable {\n return (\n obj instanceof ArrayBuffer ||\n obj instanceof MessagePort ||\n (typeof ImageBitmap !== 'undefined' && obj instanceof ImageBitmap) ||\n (typeof OffscreenCanvas !== 'undefined' && obj instanceof OffscreenCanvas) ||\n (typeof ReadableStream !== 'undefined' && obj instanceof ReadableStream) ||\n (typeof WritableStream !== 'undefined' && obj instanceof WritableStream) ||\n (typeof TransformStream !== 'undefined' && obj instanceof TransformStream)\n );\n}\n\n/**\n * Recursively find transferable objects in a payload\n */\nfunction findTransferables(obj: any, transferables: Transferable[]): void {\n if (!obj || typeof obj !== 'object') {\n return;\n }\n\n // Check if object itself is transferable\n if (isTransferable(obj)) {\n transferables.push(obj);\n return;\n }\n\n // Check VideoFrame\n if (obj instanceof VideoFrame) {\n transferables.push(obj);\n return;\n }\n\n // Check AudioData\n if (typeof AudioData !== 'undefined' && obj instanceof AudioData) {\n transferables.push(obj);\n return;\n }\n\n // EncodedVideoChunk and EncodedAudioChunk are not transferable\n if (\n (typeof EncodedVideoChunk !== 'undefined' && obj instanceof EncodedVideoChunk) ||\n (typeof EncodedAudioChunk !== 'undefined' && obj instanceof EncodedAudioChunk)\n ) {\n return;\n }\n\n // Recursively check object properties\n if (Array.isArray(obj)) {\n for (const item of obj) {\n findTransferables(item, transferables);\n }\n } else {\n for (const key in obj) {\n if (Object.prototype.hasOwnProperty.call(obj, key)) {\n findTransferables(obj[key], transferables);\n }\n }\n }\n}\n\n/**\n * Extract transferable objects from a payload\n */\nexport function extractTransferables(payload: any): Transferable[] {\n const transferables: Transferable[] = [];\n findTransferables(payload, transferables);\n return transferables;\n}\n\n/**\n * Wrap VideoFrame for transfer with metadata\n */\nexport function wrapVideoFrame(frame: VideoFrame) {\n return {\n frame,\n metadata: {\n timestamp: frame.timestamp,\n duration: frame.duration,\n codedWidth: frame.codedWidth,\n codedHeight: frame.codedHeight,\n displayWidth: frame.displayWidth,\n displayHeight: frame.displayHeight,\n format: frame.format,\n },\n };\n}\n\n/**\n * Wrap AudioData for transfer with metadata\n */\nexport function wrapAudioData(audio: AudioData) {\n return {\n audio,\n metadata: {\n timestamp: audio.timestamp,\n duration: audio.duration,\n numberOfFrames: audio.numberOfFrames,\n numberOfChannels: audio.numberOfChannels,\n sampleRate: audio.sampleRate,\n format: audio.format,\n },\n };\n}\n\n/**\n * Convert EncodedVideoChunk to transferable format\n */\nexport function encodedVideoChunkToTransferable(chunk: EncodedVideoChunk) {\n const data = new ArrayBuffer(chunk.byteLength);\n chunk.copyTo(new Uint8Array(data));\n\n return {\n data,\n type: chunk.type,\n timestamp: chunk.timestamp,\n duration: chunk.duration,\n };\n}\n\n/**\n * Convert EncodedAudioChunk to transferable format\n */\nexport function encodedAudioChunkToTransferable(chunk: EncodedAudioChunk) {\n const data = new ArrayBuffer(chunk.byteLength);\n chunk.copyTo(new Uint8Array(data));\n\n return {\n data,\n type: chunk.type,\n timestamp: chunk.timestamp,\n duration: chunk.duration,\n };\n}\n\n/**\n * Recreate EncodedVideoChunk from transferable format\n */\nexport function transferableToEncodedVideoChunk(transferable: {\n data: ArrayBuffer;\n type: 'key' | 'delta';\n timestamp: number;\n duration?: number;\n}): EncodedVideoChunk {\n return new EncodedVideoChunk({\n type: transferable.type,\n timestamp: transferable.timestamp,\n duration: transferable.duration,\n data: transferable.data,\n });\n}\n\n/**\n * Recreate EncodedAudioChunk from transferable format\n */\nexport function transferableToEncodedAudioChunk(transferable: {\n data: ArrayBuffer;\n type: 'key' | 'delta';\n timestamp: number;\n duration?: number;\n}): EncodedAudioChunk {\n return new EncodedAudioChunk({\n type: transferable.type,\n timestamp: transferable.timestamp,\n duration: transferable.duration,\n data: transferable.data,\n });\n}\n\n/**\n * Transfer OffscreenCanvas control to worker\n */\nexport function transferCanvas(canvas: HTMLCanvasElement): OffscreenCanvas {\n return canvas.transferControlToOffscreen();\n}\n\n/**\n * Create a transferable stream pair\n */\nexport function createStreamPair<T>(): {\n readable: ReadableStream<T>;\n writable: WritableStream<T>;\n} {\n const { readable, writable } = new TransformStream<T>();\n return { readable, writable };\n}\n","/**\n * WorkerChannel - MessageChannel wrapper for worker communication\n * Provides type-safe message passing with automatic serialization/deserialization\n */\n\nimport {\n WorkerMessage,\n WorkerResponse,\n WorkerError,\n WorkerMessageType,\n PendingRequest,\n MessageHandler,\n MessageHandlers,\n WorkerState,\n PortLike,\n} from './types';\nimport { withRetry, RetryConfig, defaultRetryConfig } from './worker-retry';\nimport { isTransferable, extractTransferables } from './transferable-helper';\n\nexport interface WorkerChannelConfig {\n name: string;\n timeout?: number; // Default timeout in milliseconds\n maxRetries?: number; // Default max retries\n}\n\nexport class WorkerChannel {\n name: string;\n port: PortLike;\n pendingRequests = new Map<string, PendingRequest>();\n messageHandlers: MessageHandlers = {};\n state: WorkerState = WorkerState.Idle;\n defaultTimeout: number;\n defaultMaxRetries: number;\n\n constructor(port: PortLike, config: WorkerChannelConfig) {\n this.name = config.name;\n this.port = port;\n this.defaultTimeout = config.timeout ?? 30000; // 30 seconds default\n this.defaultMaxRetries = config.maxRetries ?? 3;\n\n this.setupMessageHandler();\n this.state = WorkerState.Ready;\n }\n\n /**\n * Send a message and wait for response with retry support\n */\n async send<T = any, R = any>(\n type: WorkerMessageType,\n payload?: T,\n options?: {\n timeout?: number;\n maxRetries?: number;\n transfer?: Transferable[];\n retryConfig?: Partial<RetryConfig>;\n }\n ): Promise<R> {\n const maxRetries = options?.maxRetries ?? this.defaultMaxRetries;\n\n // Create retry config\n const retryConfig: RetryConfig = {\n ...defaultRetryConfig,\n maxRetries,\n ...options?.retryConfig,\n };\n\n // Wrap send logic for retry\n return withRetry(() => this.sendOnce<T, R>(type, payload, options), retryConfig);\n }\n\n /**\n * Send a message once (without retry)\n */\n private async sendOnce<T = any, R = any>(\n type: WorkerMessageType,\n payload?: T,\n options?: {\n timeout?: number;\n transfer?: Transferable[];\n }\n ): Promise<R> {\n const id = this.generateMessageId();\n const timeout = options?.timeout ?? this.defaultTimeout;\n\n const message: WorkerMessage<T> = {\n type,\n id,\n payload,\n timestamp: Date.now(),\n };\n\n return new Promise((resolve, reject) => {\n const request: PendingRequest = {\n id,\n type,\n timestamp: Date.now(),\n timeout,\n resolve,\n reject,\n };\n\n this.pendingRequests.set(id, request);\n\n // Set timeout\n const timeoutId = setTimeout(() => {\n const pending = this.pendingRequests.get(id);\n if (pending) {\n this.pendingRequests.delete(id);\n const error = new Error(`Request timeout: ${id} ${type} (${timeout}ms)`);\n (error as any).code = 'TIMEOUT';\n pending.reject(error);\n }\n }, timeout);\n\n // Store timeout ID for cleanup\n (request as any).timeoutId = timeoutId;\n // Send message\n if (options?.transfer) {\n this.port.postMessage(message, options.transfer);\n } else {\n this.port.postMessage(message);\n }\n });\n }\n\n /**\n * Send a message without waiting for response\n */\n post<T = any>(type: WorkerMessageType, payload?: T, transfer?: Transferable[]): void {\n const message: WorkerMessage<T> = {\n type,\n id: this.generateMessageId(),\n payload,\n timestamp: Date.now(),\n };\n\n if (transfer) {\n this.port.postMessage(message, transfer);\n } else {\n this.port.postMessage(message);\n }\n }\n\n /**\n * Register a message handler\n */\n on<T = any, R = any>(type: WorkerMessageType, handler: MessageHandler<T, R>): void {\n this.messageHandlers[type] = handler;\n }\n\n /**\n * Unregister a message handler\n */\n off(type: WorkerMessageType): void {\n delete this.messageHandlers[type];\n }\n\n /**\n * Dispose the channel\n */\n dispose(): void {\n this.state = WorkerState.Disposed;\n\n // Clear all pending requests\n for (const [, request] of this.pendingRequests) {\n if ((request as any).timeoutId) {\n clearTimeout((request as any).timeoutId);\n }\n request.reject(new Error('Channel disposed'));\n }\n this.pendingRequests.clear();\n\n // Remove message handler\n this.port.onmessage = null;\n }\n\n /**\n * Setup message handler for incoming messages\n */\n private setupMessageHandler(): void {\n this.port.onmessage = async (event: MessageEvent) => {\n const data = event.data;\n\n // Handle response messages\n if (this.isResponse(data)) {\n this.handleResponse(data as WorkerResponse);\n return;\n }\n\n // Handle request messages\n if (this.isRequest(data)) {\n await this.handleRequest(data as WorkerMessage);\n return;\n }\n };\n }\n\n /**\n * Handle incoming request\n */\n private async handleRequest(message: WorkerMessage): Promise<void> {\n const handler = this.messageHandlers[message.type];\n\n if (!handler) {\n // Send error response if no handler registered\n this.sendResponse(message.id, false, null, {\n code: 'NO_HANDLER',\n message: `No handler registered for message type: ${message.type}`,\n });\n return;\n }\n\n this.state = WorkerState.Processing;\n\n // Handler execution with error handling at framework level\n Promise.resolve()\n .then(() => handler(message.payload, message.transfer))\n .then((result) => {\n this.sendResponse(message.id, true, result);\n this.state = WorkerState.Ready;\n })\n .catch((error) => {\n const workerError: WorkerError = {\n code: 'HANDLER_ERROR',\n message: error instanceof Error ? error.message : String(error),\n stack: error instanceof Error ? error.stack : undefined,\n };\n this.sendResponse(message.id, false, null, workerError);\n this.state = WorkerState.Ready;\n });\n }\n\n /**\n * Handle incoming response\n */\n private handleResponse(response: WorkerResponse): void {\n const request = this.pendingRequests.get(response.id);\n if (!request) {\n return; // Response for unknown request\n }\n\n this.pendingRequests.delete(response.id);\n\n // Clear timeout\n if ((request as any).timeoutId) {\n clearTimeout((request as any).timeoutId);\n }\n\n if (response.success) {\n request.resolve(response.result);\n } else {\n const error = new Error(response.error?.message || 'Unknown error');\n if (response.error) {\n Object.assign(error, response.error);\n }\n request.reject(error);\n }\n }\n\n /**\n * Send a response message\n */\n private sendResponse(id: string, success: boolean, result?: any, error?: WorkerError): void {\n let transfer: Transferable[] = [];\n if (isTransferable(result)) {\n // Still include reference so caller can access the transferred object\n transfer.push(result);\n }\n const response: WorkerResponse = {\n id,\n success,\n result,\n error,\n timestamp: Date.now(),\n };\n\n this.port.postMessage(response, transfer);\n }\n\n /**\n * Check if message is a response\n */\n private isResponse(data: any): boolean {\n return (\n data && typeof data === 'object' && 'id' in data && 'success' in data && !('type' in data)\n );\n }\n\n /**\n * Check if message is a request\n */\n private isRequest(data: any): boolean {\n return data && typeof data === 'object' && 'id' in data && 'type' in data;\n }\n\n /**\n * Generate unique message ID\n */\n private generateMessageId(): string {\n return `${this.name}-${Date.now()}-${Math.random().toString(36).substring(2, 11)}`;\n }\n\n /**\n * Send a notification message without waiting for response\n * Alias for post() method for compatibility\n */\n notify<T = any>(type: WorkerMessageType | string, payload?: T, transfer?: Transferable[]): void {\n this.post(type as WorkerMessageType, payload, transfer);\n }\n\n /**\n * Register a message handler\n * Alias for on() method for compatibility\n */\n registerHandler<T = any, R = any>(\n type: WorkerMessageType | string,\n handler: MessageHandler<T, R>\n ): void {\n this.on(type as WorkerMessageType, handler);\n }\n\n /**\n * Send a ReadableStream to another worker\n * Automatically handles transferable streams vs chunk-by-chunk fallback\n */\n async sendStream<T = Uint8Array>(\n stream: ReadableStream<T>,\n metadata?: {\n type?: string;\n url?: string;\n streamId?: string;\n [key: string]: any;\n }\n ): Promise<void> {\n const streamId = metadata?.streamId || this.generateMessageId();\n // Check if streams are transferable in this environment\n if (isTransferable(stream)) {\n // Direct stream transfer (preferred)\n this.port.postMessage(\n {\n type: 'stream_transfer',\n ...metadata,\n stream,\n streamId,\n },\n [stream] // Transfer ownership\n );\n } else {\n // Fallback: chunk-by-chunk transfer\n await this.streamChunks(stream, streamId, metadata);\n }\n }\n\n /**\n * Stream chunks from a ReadableStream (fallback when transfer is not supported)\n */\n private async streamChunks<T = Uint8Array>(\n stream: ReadableStream<T>,\n streamId: string,\n metadata?: Record<string, any>\n ): Promise<void> {\n const reader = stream.getReader();\n\n // Send stream start notification\n this.post('stream_start' as WorkerMessageType, {\n streamId,\n ...metadata,\n mode: 'chunk_transfer',\n });\n\n try {\n while (true) {\n const { done, value } = await reader.read();\n\n if (done) {\n // Send stream end notification\n this.post('stream_end' as WorkerMessageType, {\n streamId,\n ...metadata,\n });\n break;\n }\n\n // Send chunk with transfer - use extractTransferables for complex objects\n const transfer: Transferable[] = [];\n if (value instanceof ArrayBuffer) {\n transfer.push(value);\n } else if (value instanceof Uint8Array) {\n transfer.push(value.buffer);\n } else if (typeof AudioData !== 'undefined' && value instanceof AudioData) {\n transfer.push(value as unknown as Transferable);\n } else if (typeof VideoFrame !== 'undefined' && value instanceof VideoFrame) {\n transfer.push(value as unknown as Transferable);\n } else if (typeof value === 'object' && value !== null) {\n // For wrapped objects (e.g., {frame: VideoFrame, metadata...}), extract transferables\n const extracted = extractTransferables(value);\n transfer.push(...extracted);\n }\n\n this.post(\n 'stream_chunk' as WorkerMessageType,\n {\n streamId,\n chunk: value,\n ...metadata,\n },\n transfer\n );\n }\n } catch (error) {\n // Send error notification\n this.post('stream_error' as WorkerMessageType, {\n streamId,\n error: error instanceof Error ? error.message : String(error),\n ...metadata,\n });\n throw error;\n } finally {\n reader.releaseLock();\n }\n }\n\n /**\n * Receive a stream from another worker\n * Handles both transferable streams and chunk-by-chunk reconstruction\n */\n async receiveStream<T = Uint8Array>(\n onStream: (stream: ReadableStream<T>, metadata?: Record<string, any>) => void\n ): Promise<void> {\n const chunkedStreams = new Map<\n string,\n {\n controller: ReadableStreamDefaultController<T>;\n metadata?: Record<string, any>;\n }\n >();\n\n // Intercept stream messages via onmessage to avoid extra event plumbing\n const prev = this.port.onmessage as any;\n // Use function assignment with explicit type to satisfy esbuild parser\n const handler: (event: MessageEvent) => void = (event) => {\n const raw = (event as any).data;\n const envelopeType = raw?.type;\n const hasPayload = raw && typeof raw === 'object' && 'payload' in raw;\n const payload = hasPayload ? (raw as any).payload : raw;\n\n if (envelopeType === 'stream_transfer' && (payload as any)?.stream) {\n onStream((payload as any).stream, payload);\n return;\n }\n if (envelopeType === 'stream_start' && (payload as any)?.streamId) {\n const stream = new ReadableStream<T>({\n start(controller) {\n chunkedStreams.set((payload as any).streamId, { controller, metadata: payload });\n },\n });\n onStream(stream, payload);\n return;\n }\n if (\n envelopeType === 'stream_chunk' &&\n (payload as any)?.streamId &&\n chunkedStreams.has((payload as any).streamId)\n ) {\n const s = chunkedStreams.get((payload as any).streamId);\n if (s) s.controller.enqueue((payload as any).chunk as T);\n return;\n }\n if (\n envelopeType === 'stream_end' &&\n (payload as any)?.streamId &&\n chunkedStreams.has((payload as any).streamId)\n ) {\n const s = chunkedStreams.get((payload as any).streamId);\n if (s) {\n s.controller.close();\n chunkedStreams.delete((payload as any).streamId);\n }\n return;\n }\n if (\n envelopeType === 'stream_error' &&\n (payload as any)?.streamId &&\n chunkedStreams.has((payload as any).streamId)\n ) {\n const s = chunkedStreams.get((payload as any).streamId);\n if (s) {\n s.controller.error(new Error(String((payload as any).error || 'stream error')));\n chunkedStreams.delete((payload as any).streamId);\n }\n return;\n }\n\n // Delegate non-stream messages to previous handler\n if (typeof prev === 'function') prev.call(this.port, event);\n };\n this.port.onmessage = handler as any;\n }\n}\n","// All time values in microseconds (µs)\nexport type TimeUs = number; // 1 second = 1_000_000 µs\n\n// Helper constants\nexport const MICROSECONDS_PER_SECOND = 1_000_000;\nexport const MICROSECONDS_PER_MILLISECOND = 1_000;\n\n// ────── Root Object ──────\nexport interface CompositionModelData {\n version: '1.0';\n fps: 24 | 25 | 30 | 60;\n durationUs: TimeUs;\n\n tracks: Track[];\n resources: Record<string, Resource>;\n\n renderConfig?: RenderConfig;\n\n ext?: Record<string, unknown>;\n}\n\nexport interface RenderConfig {\n width: number;\n height: number;\n backgroundColor?: string;\n}\n\n// ────── Track ──────\nexport interface Track {\n id: string;\n kind: 'video' | 'audio' | 'caption' | 'fx';\n clips: Clip[];\n\n effects?: Effect[];\n duckingRules?: DuckingRule[];\n}\n\n// ────── Clip ──────\nexport interface Clip {\n id: string;\n resourceId: string;\n startUs: TimeUs;\n durationUs: TimeUs;\n trackId?: string;\n trackKind?: 'video' | 'audio' | 'caption' | 'fx';\n\n trimStartUs?: TimeUs;\n trimEndUs?: TimeUs;\n\n effects?: Effect[];\n attachments?: Attachment[];\n\n transitionIn?: Transition;\n transitionOut?: Transition;\n}\n\n// ────── Resource ──────\nexport interface Resource {\n id: string;\n type: 'video' | 'image' | 'audio' | 'json' | string;\n uri: string;\n metadata?: Record<string, unknown>;\n clipIds?: string[];\n // Runtime state maintained by engine\n state?: 'pending' | 'loading' | 'ready' | 'error';\n}\n\n// ────── Common Structures ──────\nexport interface Effect {\n id: string;\n effectType: 'filter' | 'lut' | 'animation' | string;\n params?: Record<string, unknown>;\n}\n\nexport interface Transition {\n id: string;\n transitionType: 'fade' | 'wipe' | 'slide' | string;\n durationUs: TimeUs;\n curve?: 'linear' | 'ease-in' | 'ease-out' | string;\n params?: Record<string, unknown>;\n}\n\nexport interface Attachment {\n id: string;\n kind: 'caption' | 'sticker' | 'mask' | string;\n startUs: TimeUs;\n durationUs: TimeUs;\n data: Record<string, unknown>;\n}\n\nexport interface DuckingRule {\n targetTrackKind: 'voice' | 'audio' | string;\n ratio: number;\n attackMs: number;\n releaseMs: number;\n}\n\n// ────── Patch System ──────\nexport interface CompositionPatch {\n operations: PatchOperation[];\n metadata?: {\n timestamp: number;\n source?: string;\n version?: string;\n };\n}\n\nexport type PatchOperation =\n | TrackOperation\n | ClipOperation\n | ResourceOperation\n | AttachmentOperation\n | TransitionOperation\n | EffectOperation\n | RenderConfigOperation;\n\n// Track operations\nexport interface TrackOperation {\n type: 'addTrack' | 'updateTrack' | 'removeTrack';\n trackId?: string;\n track?: Partial<Track>;\n}\n\n// Clip operations\nexport interface ClipOperation {\n type: 'addClip' | 'updateClip' | 'removeClip' | 'moveClip';\n trackId: string;\n clipId?: string;\n clip?: Partial<Clip>;\n targetTrackId?: string;\n targetStartUs?: TimeUs;\n}\n\n// Resource operations\nexport interface ResourceOperation {\n type: 'addResource' | 'updateResource' | 'removeResource';\n resourceId: string;\n resource?: Partial<Resource>;\n}\n\n// Attachment operations\nexport interface AttachmentOperation {\n type: 'addAttachment' | 'updateAttachment' | 'removeAttachment';\n trackId: string;\n clipId: string;\n attachmentId?: string;\n attachment?: Partial<Attachment>;\n}\n\n// Transition operations\nexport interface TransitionOperation {\n type: 'addTransition' | 'updateTransition' | 'removeTransition';\n trackId: string;\n clipId: string;\n position: 'in' | 'out';\n transition?: Partial<Transition>;\n}\n\n// Render config operations\nexport interface RenderConfigOperation {\n type: 'updateRenderConfig';\n renderConfig?: Partial<RenderConfig>;\n}\n\n// Effect operations\nexport interface EffectOperation {\n type: 'addEffect' | 'updateEffect' | 'removeEffect';\n targetType: 'track' | 'clip';\n targetId: string;\n effectId?: string;\n effect?: Partial<Effect>;\n}\n\n// ────── Dirty Range ──────\nexport interface DirtyRange {\n trackId: string;\n startUs: TimeUs;\n endUs: TimeUs;\n reason: string;\n}\n\n// ────── Validation ──────\nexport interface ValidationError {\n path: string;\n message: string;\n value: any;\n}\n","import type { TimeUs } from '../model/types';\nimport { MICROSECONDS_PER_SECOND } from '../model/types';\n\nexport type QuantizeStrategy = 'nearest' | 'floor' | 'ceil';\n\nconst DEFAULT_FPS = 30;\n\nexport const DEFAULT_FRAME_TOLERANCE_US: TimeUs = 33_333;\n\nexport function normalizeFps(value?: number): number {\n if (!Number.isFinite(value) || (value as number) <= 0) {\n return DEFAULT_FPS;\n }\n return value as number;\n}\n\nexport function frameDurationFromFps(fps?: number): TimeUs {\n const normalized = normalizeFps(fps);\n const duration = MICROSECONDS_PER_SECOND / normalized;\n return Math.max(Math.round(duration), 1);\n}\n\nexport function frameIndexFromTimestamp(\n baseTimestampUs: TimeUs,\n timestampUs: TimeUs,\n fps?: number,\n strategy: QuantizeStrategy = 'nearest'\n): number {\n const frameDurationUs = frameDurationFromFps(fps);\n if (frameDurationUs <= 0) {\n return 0;\n }\n\n const delta = timestampUs - baseTimestampUs;\n const rawIndex = delta / frameDurationUs;\n\n if (!Number.isFinite(rawIndex)) {\n return 0;\n }\n\n switch (strategy) {\n case 'floor':\n return Math.floor(rawIndex);\n case 'ceil':\n return Math.ceil(rawIndex);\n default:\n return Math.round(rawIndex);\n }\n}\n\nexport function quantizeTimestampToFrame(\n timestampUs: TimeUs,\n baseTimestampUs: TimeUs,\n fps?: number,\n strategy: QuantizeStrategy = 'nearest'\n): TimeUs {\n const frameDurationUs = frameDurationFromFps(fps);\n const index = frameIndexFromTimestamp(baseTimestampUs, timestampUs, fps, strategy);\n return baseTimestampUs + index * frameDurationUs;\n}\n\nexport function isTimestampWithinFrame(\n targetTimeUs: TimeUs,\n frameTimestampUs: TimeUs,\n frameDurationUs: TimeUs,\n toleranceUs: TimeUs = DEFAULT_FRAME_TOLERANCE_US\n): boolean {\n if (!Number.isFinite(frameTimestampUs)) {\n return false;\n }\n\n const delta = Math.abs(targetTimeUs - frameTimestampUs);\n if (delta <= toleranceUs) {\n return true;\n }\n\n if (frameDurationUs > 0 && frameTimestampUs <= targetTimeUs) {\n return targetTimeUs < frameTimestampUs + frameDurationUs;\n }\n\n return false;\n}\n","import type { Layer, VideoLayer, ImageLayer, TextLayer, Transform2D, MaskConfig } from './types';\n\n/**\n * LayerRenderer - Handles rendering of individual layers\n * Single responsibility: Draw a single layer to the canvas context\n */\nexport class LayerRenderer {\n private ctx: OffscreenCanvasRenderingContext2D;\n private width: number;\n private height: number;\n\n constructor(ctx: OffscreenCanvasRenderingContext2D, width: number, height: number) {\n this.ctx = ctx;\n this.width = width;\n this.height = height;\n this.ensureHighQualityRendering();\n }\n\n private ensureHighQualityRendering(): void {\n this.ctx.imageSmoothingEnabled = true;\n this.ctx.imageSmoothingQuality = 'high';\n }\n\n /**\n * Render a single layer with all its properties\n */\n async renderLayer(layer: Layer): Promise<void> {\n if (!layer.visible || layer.opacity <= 0) return;\n\n this.ctx.save();\n\n try {\n this.ensureHighQualityRendering();\n\n // Apply layer properties\n this.ctx.globalAlpha = layer.opacity;\n\n if (layer.blendMode) {\n this.ctx.globalCompositeOperation = layer.blendMode;\n }\n\n if (layer.transform) {\n this.applyTransform(layer.transform);\n }\n\n // Render based on layer type\n switch (layer.type) {\n case 'video':\n await this.renderVideoLayer(layer as VideoLayer);\n break;\n case 'image':\n await this.renderImageLayer(layer as ImageLayer);\n break;\n case 'text':\n await this.renderTextLayer(layer as TextLayer);\n break;\n }\n\n // Apply mask if present\n if (layer.mask) {\n this.applyMask(layer.mask);\n }\n } finally {\n this.ctx.restore();\n }\n }\n\n private applyTransform(transform: Transform2D): void {\n const centerX = this.width * (transform.anchorX ?? 0.5);\n const centerY = this.height * (transform.anchorY ?? 0.5);\n\n this.ctx.translate(transform.x + centerX, transform.y + centerY);\n\n if (transform.rotation) {\n this.ctx.rotate(transform.rotation);\n }\n\n this.ctx.scale(transform.scaleX, transform.scaleY);\n\n if (transform.skewX || transform.skewY) {\n this.ctx.transform(1, transform.skewY ?? 0, transform.skewX ?? 0, 1, 0, 0);\n }\n\n this.ctx.translate(-centerX, -centerY);\n }\n\n private async renderVideoLayer(layer: VideoLayer): Promise<void> {\n const { videoFrame, crop } = layer;\n\n // Get video dimensions\n const videoWidth = videoFrame.displayWidth || videoFrame.codedWidth;\n const videoHeight = videoFrame.displayHeight || videoFrame.codedHeight;\n\n // Calculate scaling to fit (contain mode - preserve aspect ratio)\n const scaleX = this.width / videoWidth;\n const scaleY = this.height / videoHeight;\n\n // Use the smaller scale to ensure entire video fits\n const scale = Math.min(scaleX, scaleY);\n\n // Calculate final render dimensions\n const renderWidth = Math.round(videoWidth * scale);\n const renderHeight = Math.round(videoHeight * scale);\n\n // Center the video\n const renderX = Math.round((this.width - renderWidth) / 2);\n const renderY = Math.round((this.height - renderHeight) / 2);\n\n if (crop) {\n this.ctx.drawImage(\n videoFrame,\n crop.x,\n crop.y,\n crop.width,\n crop.height,\n renderX,\n renderY,\n renderWidth,\n renderHeight\n );\n } else {\n this.ctx.drawImage(videoFrame, renderX, renderY, renderWidth, renderHeight);\n }\n }\n\n private async renderImageLayer(layer: ImageLayer): Promise<void> {\n const { source, crop } = layer;\n\n // Handle ImageData by putting it on canvas first\n if (source instanceof ImageData) {\n if (crop) {\n // For ImageData with crop, we need to extract the cropped region\n const tempCanvas = new OffscreenCanvas(crop.width, crop.height);\n const tempCtx = tempCanvas.getContext('2d')!;\n tempCtx.putImageData(source, -crop.x, -crop.y);\n this.ctx.drawImage(tempCanvas, 0, 0, this.width, this.height);\n } else {\n // Put ImageData directly\n this.ctx.putImageData(source, 0, 0);\n }\n } else {\n // ImageBitmap can be drawn directly\n if (!source) {\n return;\n }\n if (crop) {\n this.ctx.drawImage(\n source,\n crop.x,\n crop.y,\n crop.width,\n crop.height,\n 0,\n 0,\n this.width,\n this.height\n );\n } else {\n this.ctx.drawImage(source, 0, 0, this.width, this.height);\n }\n }\n }\n\n private async renderTextLayer(layer: TextLayer): Promise<void> {\n const fontSize = layer.fontSize ?? 16;\n const fontFamily = layer.fontFamily ?? 'sans-serif';\n const fontWeight = layer.fontWeight ?? 'normal';\n const fontStyle = layer.fontStyle ?? 'normal';\n\n this.ctx.font = `${fontStyle} ${fontWeight} ${fontSize}px ${fontFamily}`;\n this.ctx.fillStyle = layer.color ?? '#000000';\n this.ctx.textAlign = layer.textAlign ?? 'left';\n this.ctx.textBaseline = layer.verticalAlign ?? 'top';\n\n // Apply letter spacing if supported\n if (layer.letterSpacing && typeof (this.ctx as any).letterSpacing !== 'undefined') {\n (this.ctx as any).letterSpacing = `${layer.letterSpacing}px`;\n }\n\n // Ensure high-quality text rendering\n this.ensureHighQualityRendering();\n\n // Calculate position with sub-pixel adjustment for sharper rendering\n const baseX = this.calculateTextX(layer.textAlign);\n const baseY = this.calculateTextY(layer.verticalAlign, fontSize);\n const x = Math.round(baseX) + 0.5;\n const y = Math.round(baseY) + 0.5;\n\n // Apply shadow before rendering text (if needed)\n if (layer.shadow) {\n this.ctx.shadowColor = layer.shadow.color;\n this.ctx.shadowOffsetX = layer.shadow.offsetX;\n this.ctx.shadowOffsetY = layer.shadow.offsetY;\n this.ctx.shadowBlur = layer.shadow.blur;\n }\n\n // Render stroke with enhanced quality (multi-layer approach)\n if (layer.strokeColor && layer.strokeWidth && layer.strokeWidth > 0) {\n this.drawEnhancedStroke(layer.text, x, y, layer.strokeColor, layer.strokeWidth);\n }\n\n // Render fill text\n this.ctx.fillText(layer.text, x, y);\n\n // Reset shadow\n if (layer.shadow) {\n this.ctx.shadowColor = 'transparent';\n this.ctx.shadowOffsetX = 0;\n this.ctx.shadowOffsetY = 0;\n this.ctx.shadowBlur = 0;\n }\n }\n\n /**\n * Draw enhanced multi-layer stroke for better text visibility\n */\n private drawEnhancedStroke(\n text: string,\n x: number,\n y: number,\n strokeColor: string,\n strokeWidth: number\n ): void {\n this.ctx.save();\n\n this.ctx.strokeStyle = strokeColor;\n this.ctx.lineJoin = 'round';\n this.ctx.lineCap = 'round';\n this.ctx.miterLimit = 2;\n\n // Multi-layer stroke for enhanced visibility without excessive thickness\n const layers = [1.1, 1.0];\n layers.forEach((multiplier) => {\n this.ctx.lineWidth = strokeWidth * multiplier;\n this.ctx.strokeText(text, x, y);\n });\n\n this.ctx.restore();\n }\n\n private calculateTextX(align?: 'left' | 'center' | 'right'): number {\n switch (align) {\n case 'center':\n return this.width / 2;\n case 'right':\n return this.width;\n default:\n return 0;\n }\n }\n\n private calculateTextY(align?: 'top' | 'middle' | 'bottom', fontSize: number = 16): number {\n switch (align) {\n case 'middle':\n return this.height / 2;\n case 'bottom':\n // Place text at 85% height to avoid bottom edge, similar to SubtitleComposer's 70% position\n return this.height * 0.85;\n default:\n return fontSize;\n }\n }\n\n private applyMask(mask: MaskConfig): void {\n this.ctx.globalCompositeOperation = mask.invert ? 'source-out' : 'destination-in';\n\n if (mask.source) {\n this.ctx.drawImage(mask.source, 0, 0, this.width, this.height);\n } else if (mask.shape === 'circle') {\n this.ctx.beginPath();\n this.ctx.arc(\n this.width / 2,\n this.height / 2,\n Math.min(this.width, this.height) / 2,\n 0,\n Math.PI * 2\n );\n this.ctx.fill();\n }\n }\n\n updateDimensions(width: number, height: number): void {\n this.width = width;\n this.height = height;\n this.ensureHighQualityRendering();\n }\n}\n","import type { TransitionEffect } from './types';\n\n/**\n * TransitionProcessor - Handles transition effects between frames/scenes\n * Single responsibility: Apply transition transformations to canvas context\n */\nexport class TransitionProcessor {\n private width: number;\n private height: number;\n\n constructor(width: number, height: number) {\n this.width = width;\n this.height = height;\n }\n\n /**\n * Apply transition effect to the canvas context\n * Returns true if transition was applied, false if not needed\n */\n applyTransition(ctx: OffscreenCanvasRenderingContext2D, transition: TransitionEffect): boolean {\n if (!transition || transition.progress <= 0) return false;\n\n const progress = this.calculateEasedProgress(transition.progress, transition.easing);\n\n switch (transition.type) {\n case 'fade':\n return this.applyFade(ctx, progress);\n case 'slide':\n return this.applySlide(ctx, progress, transition.direction);\n case 'wipe':\n return this.applyWipe(ctx, progress, transition.direction);\n case 'zoom':\n return this.applyZoom(ctx, progress, transition.direction);\n case 'rotate':\n return this.applyRotate(ctx, progress);\n case 'dissolve':\n return this.applyDissolve(ctx, progress);\n default:\n return false;\n }\n }\n\n private calculateEasedProgress(\n progress: number,\n easing?: 'linear' | 'ease-in' | 'ease-out' | 'ease-in-out'\n ): number {\n switch (easing) {\n case 'ease-in':\n return progress * progress;\n case 'ease-out':\n return 1 - (1 - progress) * (1 - progress);\n case 'ease-in-out':\n return progress < 0.5 ? 2 * progress * progress : 1 - Math.pow(-2 * progress + 2, 2) / 2;\n default:\n return progress;\n }\n }\n\n private applyFade(ctx: OffscreenCanvasRenderingContext2D, progress: number): boolean {\n ctx.globalAlpha = progress;\n return true;\n }\n\n private applySlide(\n ctx: OffscreenCanvasRenderingContext2D,\n progress: number,\n direction?: 'left' | 'right' | 'up' | 'down' | 'in' | 'out'\n ): boolean {\n const distance = 1 - progress;\n\n switch (direction) {\n case 'left':\n ctx.translate(-this.width * distance, 0);\n break;\n case 'right':\n ctx.translate(this.width * distance, 0);\n break;\n case 'up':\n ctx.translate(0, -this.height * distance);\n break;\n case 'down':\n ctx.translate(0, this.height * distance);\n break;\n default:\n ctx.translate(-this.width * distance, 0);\n }\n\n return true;\n }\n\n private applyWipe(\n ctx: OffscreenCanvasRenderingContext2D,\n progress: number,\n direction?: 'left' | 'right' | 'up' | 'down' | 'in' | 'out'\n ): boolean {\n ctx.save();\n ctx.beginPath();\n\n switch (direction) {\n case 'left':\n ctx.rect(0, 0, this.width * progress, this.height);\n break;\n case 'right':\n ctx.rect(this.width * (1 - progress), 0, this.width * progress, this.height);\n break;\n case 'up':\n ctx.rect(0, 0, this.width, this.height * progress);\n break;\n case 'down':\n ctx.rect(0, this.height * (1 - progress), this.width, this.height * progress);\n break;\n default:\n ctx.rect(0, 0, this.width * progress, this.height);\n }\n\n ctx.clip();\n return true;\n }\n\n private applyZoom(\n ctx: OffscreenCanvasRenderingContext2D,\n progress: number,\n direction?: 'left' | 'right' | 'up' | 'down' | 'in' | 'out'\n ): boolean {\n const scale = direction === 'out' ? 1 + (1 - progress) : progress;\n const centerX = this.width / 2;\n const centerY = this.height / 2;\n\n ctx.translate(centerX, centerY);\n ctx.scale(scale, scale);\n ctx.translate(-centerX, -centerY);\n\n if (direction === 'out') {\n ctx.globalAlpha = progress;\n }\n\n return true;\n }\n\n private applyRotate(ctx: OffscreenCanvasRenderingContext2D, progress: number): boolean {\n const rotation = (1 - progress) * Math.PI * 2;\n const centerX = this.width / 2;\n const centerY = this.height / 2;\n\n ctx.translate(centerX, centerY);\n ctx.rotate(rotation);\n ctx.translate(-centerX, -centerY);\n\n return true;\n }\n\n private applyDissolve(ctx: OffscreenCanvasRenderingContext2D, progress: number): boolean {\n // Simple dissolve using alpha\n ctx.globalAlpha = progress;\n ctx.globalCompositeOperation = 'multiply';\n return true;\n }\n\n /**\n * Create a transition mask for advanced effects\n */\n createTransitionMask(transition: TransitionEffect, canvas: OffscreenCanvas): ImageData | null {\n const ctx = canvas.getContext('2d');\n if (!ctx) return null;\n\n const imageData = ctx.createImageData(this.width, this.height);\n const data = imageData.data;\n const progress = this.calculateEasedProgress(transition.progress, transition.easing);\n\n // Generate gradient mask based on transition type\n for (let y = 0; y < this.height; y++) {\n for (let x = 0; x < this.width; x++) {\n const index = (y * this.width + x) * 4;\n let alpha = 255;\n\n switch (transition.type) {\n case 'wipe':\n alpha = this.calculateWipeAlpha(x, y, progress, transition.direction);\n break;\n case 'dissolve':\n // Random noise dissolve\n alpha = Math.random() < progress ? 255 : 0;\n break;\n default:\n alpha = Math.floor(255 * progress);\n }\n\n data[index] = 255; // R\n data[index + 1] = 255; // G\n data[index + 2] = 255; // B\n data[index + 3] = alpha; // A\n }\n }\n\n return imageData;\n }\n\n private calculateWipeAlpha(\n x: number,\n y: number,\n progress: number,\n direction?: 'left' | 'right' | 'up' | 'down' | 'in' | 'out'\n ): number {\n let position = 0;\n\n switch (direction) {\n case 'left':\n position = x / this.width;\n break;\n case 'right':\n position = 1 - x / this.width;\n break;\n case 'up':\n position = y / this.height;\n break;\n case 'down':\n position = 1 - y / this.height;\n break;\n case 'in': {\n // Radial wipe from center\n const cx = x - this.width / 2;\n const cy = y - this.height / 2;\n const maxDist = Math.sqrt(this.width * this.width + this.height * this.height) / 2;\n position = Math.sqrt(cx * cx + cy * cy) / maxDist;\n break;\n }\n case 'out': {\n // Radial wipe to center\n const cx2 = x - this.width / 2;\n const cy2 = y - this.height / 2;\n const maxDist2 = Math.sqrt(this.width * this.width + this.height * this.height) / 2;\n position = 1 - Math.sqrt(cx2 * cx2 + cy2 * cy2) / maxDist2;\n break;\n }\n default:\n position = x / this.width;\n }\n\n return position < progress ? 255 : 0;\n }\n\n updateDimensions(width: number, height: number): void {\n this.width = width;\n this.height = height;\n }\n}\n","import type { VisualFilter } from './types';\n\n/**\n * FilterProcessor - Handles visual filters and effects\n * Single responsibility: Apply CSS filters and custom shader effects\n */\nexport class FilterProcessor {\n private filterCache = new Map<string, string>();\n\n /**\n * Apply filters to canvas context\n * Combines multiple filters into a single CSS filter string for performance\n */\n applyFilters(ctx: OffscreenCanvasRenderingContext2D, filters: VisualFilter[]): void {\n if (!filters || filters.length === 0) {\n ctx.filter = 'none';\n return;\n }\n\n // Generate cache key\n const cacheKey = this.generateCacheKey(filters);\n\n // Check cache\n let filterString = this.filterCache.get(cacheKey);\n\n if (!filterString) {\n filterString = this.buildFilterString(filters);\n this.filterCache.set(cacheKey, filterString);\n }\n\n ctx.filter = filterString;\n }\n\n /**\n * Build CSS filter string from filter array\n */\n private buildFilterString(filters: VisualFilter[]): string {\n const filterStrings: string[] = [];\n\n for (const filter of filters) {\n const filterStr = this.buildSingleFilter(filter);\n if (filterStr) {\n filterStrings.push(filterStr);\n }\n }\n\n return filterStrings.length > 0 ? filterStrings.join(' ') : 'none';\n }\n\n private buildSingleFilter(filter: VisualFilter): string | null {\n switch (filter.type) {\n case 'blur':\n return `blur(${filter.value ?? 0}px)`;\n\n case 'brightness':\n return `brightness(${filter.value ?? 1})`;\n\n case 'contrast':\n return `contrast(${filter.value ?? 1})`;\n\n case 'grayscale':\n return `grayscale(${filter.value ?? 0})`;\n\n case 'hue-rotate':\n return `hue-rotate(${filter.value ?? 0}deg)`;\n\n case 'saturate':\n return `saturate(${filter.value ?? 1})`;\n\n case 'sepia':\n return `sepia(${filter.value ?? 0})`;\n\n case 'custom':\n return this.buildCustomFilter(filter);\n\n default:\n console.warn(`Unknown filter type: ${filter.type}`);\n return null;\n }\n }\n\n /**\n * Build custom filter from params\n */\n private buildCustomFilter(filter: VisualFilter): string | null {\n if (!filter.params) return null;\n\n const { type, ...params } = filter.params;\n\n switch (type) {\n case 'drop-shadow':\n return `drop-shadow(${params.offsetX}px ${params.offsetY}px ${params.blur}px ${params.color})`;\n\n case 'opacity':\n return `opacity(${params.value})`;\n\n case 'invert':\n return `invert(${params.value})`;\n\n default:\n return null;\n }\n }\n\n /**\n * Apply color matrix transformation for advanced effects\n * This allows for more complex color manipulations than CSS filters\n */\n applyColorMatrix(imageData: ImageData, matrix: number[]): ImageData {\n if (matrix.length !== 20) {\n throw new Error('Color matrix must have 20 values (4x5 matrix)');\n }\n\n const data = imageData.data;\n const length = data.length;\n\n for (let i = 0; i < length; i += 4) {\n const r = data[i]!;\n const g = data[i + 1]!;\n const b = data[i + 2]!;\n const a = data[i + 3]!;\n const m = matrix;\n\n // Apply matrix transformation\n data[i] = this.clamp(r * m[0]! + g * m[1]! + b * m[2]! + a * m[3]! + m[4]! * 255);\n data[i + 1] = this.clamp(r * m[5]! + g * m[6]! + b * m[7]! + a * m[8]! + m[9]! * 255);\n data[i + 2] = this.clamp(r * m[10]! + g * m[11]! + b * m[12]! + a * m[13]! + m[14]! * 255);\n data[i + 3] = this.clamp(r * m[15]! + g * m[16]! + b * m[17]! + a * m[18]! + m[19]! * 255);\n }\n\n return imageData;\n }\n\n /**\n * Predefined color matrices for common effects\n */\n getPresetMatrix(preset: string): number[] | null {\n switch (preset) {\n case 'vintage':\n return [\n 0.393, 0.769, 0.189, 0, 0, 0.349, 0.686, 0.168, 0, 0, 0.272, 0.534, 0.131, 0, 0, 0, 0, 0,\n 1, 0,\n ];\n\n case 'noir':\n return [\n 0.25, 0.25, 0.25, 0, 0, 0.25, 0.25, 0.25, 0, 0, 0.25, 0.25, 0.25, 0, 0, 0, 0, 0, 1, 0,\n ];\n\n case 'cool':\n return [0.8, 0, 0, 0, 0, 0, 0.9, 0, 0, 0, 0, 0, 1.2, 0, 0, 0, 0, 0, 1, 0];\n\n case 'warm':\n return [1.2, 0, 0, 0, 0, 0, 1.1, 0, 0, 0, 0, 0, 0.8, 0, 0, 0, 0, 0, 1, 0];\n\n default:\n return null;\n }\n }\n\n /**\n * Apply Gaussian blur manually (for cases where CSS filter is not enough)\n */\n applyGaussianBlur(imageData: ImageData, radius: number): ImageData {\n // Simplified box blur approximation of Gaussian blur\n const output = new ImageData(\n new Uint8ClampedArray(imageData.data),\n imageData.width,\n imageData.height\n );\n\n const width = imageData.width;\n const height = imageData.height;\n const data = imageData.data;\n const outData = output.data;\n\n // Horizontal pass\n for (let y = 0; y < height; y++) {\n for (let x = 0; x < width; x++) {\n let r = 0,\n g = 0,\n b = 0,\n a = 0;\n let count = 0;\n\n for (let dx = -radius; dx <= radius; dx++) {\n const nx = Math.min(Math.max(x + dx, 0), width - 1);\n const idx = (y * width + nx) * 4;\n r += data[idx]!;\n g += data[idx + 1]!;\n b += data[idx + 2]!;\n a += data[idx + 3]!;\n count++;\n }\n\n const idx = (y * width + x) * 4;\n outData[idx] = r / count;\n outData[idx + 1] = g / count;\n outData[idx + 2] = b / count;\n outData[idx + 3] = a / count;\n }\n }\n\n // Vertical pass\n for (let x = 0; x < width; x++) {\n for (let y = 0; y < height; y++) {\n let r = 0,\n g = 0,\n b = 0,\n a = 0;\n let count = 0;\n\n for (let dy = -radius; dy <= radius; dy++) {\n const ny = Math.min(Math.max(y + dy, 0), height - 1);\n const idx = (ny * width + x) * 4;\n r += outData[idx]!;\n g += outData[idx + 1]!;\n b += outData[idx + 2]!;\n a += outData[idx + 3]!;\n count++;\n }\n\n const idx = (y * width + x) * 4;\n data[idx] = r / count;\n data[idx + 1] = g / count;\n data[idx + 2] = b / count;\n data[idx + 3] = a / count;\n }\n }\n\n return imageData;\n }\n\n private clamp(value: number): number {\n return Math.min(255, Math.max(0, Math.round(value)));\n }\n\n private generateCacheKey(filters: VisualFilter[]): string {\n return filters.map((f) => `${f.type}:${f.value ?? 'default'}`).join('|');\n }\n\n clearCache(): void {\n this.filterCache.clear();\n }\n\n getCacheSize(): number {\n return this.filterCache.size;\n }\n}\n","import type {\n VideoComposeConfig,\n ComposeRequest,\n ComposeResult,\n TransitionEffect,\n VideoLayer,\n ComposeTimelineContext,\n} from './types';\nimport { frameDurationFromFps } from '../../utils/time-utils';\nimport { LayerRenderer } from './LayerRenderer';\nimport { TransitionProcessor } from './TransitionProcessor';\nimport { FilterProcessor } from './FilterProcessor';\nimport { ClipInstructionSet } from './instructions';\n\ninterface ComposeStreams {\n composeStream: WritableStream<ComposeRequest>;\n cacheStream: ReadableStream<VideoFrame>;\n}\n\n/**\n * VideoComposer - Main visual composition orchestrator\n */\nexport class VideoComposer {\n readonly config: Required<VideoComposeConfig>;\n readonly canvas: OffscreenCanvas;\n\n private ctx: OffscreenCanvasRenderingContext2D;\n private layerRenderer: LayerRenderer;\n private transitionProcessor: TransitionProcessor;\n private filterProcessor: FilterProcessor;\n private timelineContext: ComposeTimelineContext;\n\n constructor(config: VideoComposeConfig) {\n this.config = this.applyDefaults(config);\n this.canvas = new OffscreenCanvas(this.config.width, this.config.height);\n\n const ctx = this.canvas.getContext('2d', {\n alpha: true,\n desynchronized: true,\n willReadFrequently: false,\n colorSpace: 'srgb',\n });\n\n if (!ctx) {\n throw new Error('Failed to create 2D rendering context');\n }\n\n this.ctx = ctx;\n this.ctx.imageSmoothingEnabled = this.config.enableSmoothing;\n this.ctx.imageSmoothingQuality = 'high';\n\n this.layerRenderer = new LayerRenderer(ctx, this.config.width, this.config.height);\n this.transitionProcessor = new TransitionProcessor(this.config.width, this.config.height);\n this.filterProcessor = new FilterProcessor();\n this.timelineContext = this.config.timeline;\n }\n\n private applyDefaults(config: VideoComposeConfig): Required<VideoComposeConfig> {\n return {\n width: config.width || 720,\n height: config.height || 1280,\n fps: config.fps || 30,\n backgroundColor: config.backgroundColor ?? '#000',\n renderer: config.renderer ?? 'canvas2d',\n enableSmoothing: config.enableSmoothing ?? true,\n enableHardwareAcceleration: config.enableHardwareAcceleration ?? true,\n revision: config.revision ?? 0,\n inputHighWaterMark: config.inputHighWaterMark ?? 3,\n outputHighWaterMark: config.outputHighWaterMark ?? 1,\n maxLayers: config.maxLayers ?? 100,\n timeline: config.timeline ?? {\n clipId: 'default',\n trackId: 'main',\n clipStartUs: 0,\n clipDurationUs: Infinity,\n compositionFps: 30,\n },\n };\n }\n\n createStreams(_instruction?: ClipInstructionSet): ComposeStreams {\n if (_instruction?.baseConfig.timeline) {\n this.timelineContext = _instruction.baseConfig.timeline;\n }\n\n // Always create new streams for each clip\n // ReadableStreams can only be consumed once\n const stream = new TransformStream<ComposeRequest, any>(\n {\n transform: async (request, controller) => {\n // console.log('[VideoComposer] transform', request, controller.desiredSize);\n const result = await this.composeFrame(request);\n controller.enqueue({\n frame: result.frame,\n metadata: result.metadata,\n });\n },\n\n flush: async () => {\n this.filterProcessor.clearCache();\n },\n },\n {\n highWaterMark: this.config.inputHighWaterMark,\n },\n {\n highWaterMark: this.config.outputHighWaterMark,\n }\n );\n // const [encodeStream, cacheStream] = stream.readable.tee();\n return {\n composeStream: stream.writable,\n cacheStream: stream.readable,\n };\n }\n\n async composeFrame(request: ComposeRequest): Promise<ComposeResult> {\n if (request.layers.length > this.config.maxLayers) {\n throw new Error(`Too many layers: ${request.layers.length} > ${this.config.maxLayers}`);\n }\n\n this.clearCanvas();\n // const sortedLayers = this.sortLayers(request.layers);\n\n if (request.transition) {\n this.ctx.save();\n this.transitionProcessor.applyTransition(this.ctx, request.transition);\n }\n\n for (const layer of request.layers) {\n if (!layer.visible || layer.opacity <= 0) {\n // Close video frame for invisible layers\n if ((layer as any).type === 'video') {\n const vf = (layer as VideoLayer).videoFrame;\n vf?.close?.();\n }\n continue;\n }\n\n try {\n if (layer.filters && layer.filters.length > 0) {\n this.ctx.save();\n this.filterProcessor.applyFilters(this.ctx, layer.filters);\n }\n\n await this.layerRenderer.renderLayer(layer);\n\n if (layer.filters && layer.filters.length > 0) {\n this.ctx.restore();\n }\n } finally {\n // Always close video frame after rendering (or on error)\n if ((layer as any).type === 'video') {\n const vf = (layer as VideoLayer).videoFrame;\n vf?.close?.();\n }\n }\n }\n\n if (request.transition) {\n this.ctx.restore();\n }\n\n const frame = await this.createOutputFrame(request.timeUs);\n\n const gopSerial = (request as any).gopSerial;\n const isKeyframe = (request as any).isKeyframe;\n\n return {\n frame,\n timeUs: request.timeUs,\n metadata: {\n layerCount: request.layers.length,\n renderTime: 0,\n gpuAccelerated:\n this.config.enableHardwareAcceleration && this.config.renderer !== 'canvas2d',\n ...(typeof gopSerial === 'number' && { gopSerial }),\n ...(typeof isKeyframe === 'boolean' && { isKeyframe }),\n },\n };\n }\n\n async composeTransition(\n fromRequest: ComposeRequest,\n toRequest: ComposeRequest,\n transition: TransitionEffect\n ): Promise<ComposeResult> {\n await this.composeFrame(fromRequest);\n\n const toFrameRequest = {\n ...toRequest,\n transition,\n };\n\n return this.composeFrame(toFrameRequest);\n }\n\n private clearCanvas(): void {\n if (this.config.backgroundColor) {\n this.ctx.fillStyle = this.config.backgroundColor;\n this.ctx.fillRect(0, 0, this.config.width, this.config.height);\n } else {\n this.ctx.clearRect(0, 0, this.config.width, this.config.height);\n }\n }\n\n // private sortLayers(layers: Layer[]): Layer[] {\n // return [...layers].sort((a, b) => a.zIndex - b.zIndex);\n // }\n\n private async createOutputFrame(timeUs: number): Promise<VideoFrame> {\n const duration = frameDurationFromFps(this.timelineContext.compositionFps);\n const frame = new VideoFrame(this.canvas, {\n timestamp: timeUs,\n duration,\n alpha: 'discard',\n visibleRect: { x: 0, y: 0, width: this.canvas.width, height: this.canvas.height },\n });\n return frame;\n }\n\n updateConfig(config: Partial<VideoComposeConfig>): void {\n Object.assign(this.config, this.applyDefaults({ ...this.config, ...config }));\n\n if (config.width || config.height) {\n this.canvas.width = this.config.width;\n this.canvas.height = this.config.height;\n this.layerRenderer.updateDimensions(this.config.width, this.config.height);\n this.transitionProcessor.updateDimensions(this.config.width, this.config.height);\n }\n\n if (config.enableSmoothing !== undefined) {\n this.ctx.imageSmoothingEnabled = this.config.enableSmoothing;\n }\n\n if (config.timeline) {\n this.timelineContext = config.timeline;\n }\n }\n\n dispose(): void {\n this.filterProcessor.clearCache();\n }\n}\n","import { WorkerChannel } from '../../worker/WorkerChannel';\nimport { WorkerMessageType, WorkerState } from '../../worker/types';\nimport { VideoComposer } from './VideoComposer';\nimport type { VideoComposeConfig, ComposeRequest, Layer } from './types';\nimport type {\n ClipInstructionSet,\n SerializedLayerPlan,\n SerializedTransitionPlan,\n SerializedImageLayerPayload,\n SerializedTextLayerPayload,\n} from './instructions';\nimport {\n frameDurationFromFps,\n frameIndexFromTimestamp,\n quantizeTimestampToFrame,\n} from '../../utils/time-utils';\nimport type { TimeUs } from '../../model/types';\n\nfunction resolveActiveLayers(\n layers: SerializedLayerPlan[],\n timestamp: number,\n _frame: VideoFrame\n): SerializedLayerPlan[] {\n return layers.filter((layer) => {\n if (layer.status !== 'ready') {\n return false;\n }\n return layer.activeRanges.some(\n (range) => timestamp >= range.startUs && timestamp < range.endUs\n );\n });\n}\n\nfunction materializeLayer(layer: SerializedLayerPlan, frame: VideoFrame): Layer {\n const baseLayer: Layer = {\n id: layer.layerId,\n type: layer.type as any,\n zIndex: layer.zIndex ?? 0,\n visible: true,\n opacity: layer.opacity ?? 1,\n };\n\n if (layer.type === 'video') {\n return {\n ...baseLayer,\n type: 'video',\n videoFrame: frame,\n } as Layer;\n }\n\n if (layer.type === 'text') {\n const payload = layer.payload as SerializedTextLayerPayload;\n return {\n ...baseLayer,\n type: 'text',\n text: payload.text,\n fontFamily: payload.fontFamily,\n fontSize: payload.fontSize,\n fontWeight: payload.fontWeight,\n color: payload.color,\n strokeColor: payload.strokeColor,\n strokeWidth: payload.strokeWidth,\n lineHeight: payload.lineHeight,\n textAlign: payload.align,\n verticalAlign: 'bottom', // Subtitles positioned at bottom\n } as Layer;\n }\n\n if (layer.type === 'image') {\n const payload = layer.payload as SerializedImageLayerPayload;\n const source = payload.bitmapHandle ?? null;\n if (source) {\n return {\n ...baseLayer,\n type: 'image',\n source,\n } as Layer;\n }\n }\n\n return baseLayer;\n}\n\n/**\n * VideoComposeWorker - Visual composition in the pipeline\n * Receives decoded video frames and outputs composed frames\n *\n * Pipeline: DecodeWorker → VideoComposeWorker → EncodeWorker\n *\n * Features:\n * - Multi-layer composition with Canvas2D/WebGL\n * - Transition effects and filters\n * - Text and image overlay support\n * - Stream-based processing with configurable backpressure\n */\nexport class VideoComposeWorker {\n private channel: WorkerChannel;\n private composer: VideoComposer | null = null;\n private composeStream: TransformStream<ComposeRequest, VideoFrame> | null = null;\n\n private downstreamPorts = new Map<string, MessagePort>();\n private upstreamPorts = new Map<string, MessagePort>();\n private instructionRegistry = new Map<string, ClipInstructionSet>();\n private pendingReplay = new Map<string, { startUs: number; endUs: number; revision: number }>();\n private streamState = new Map<string, StreamState>();\n\n constructor() {\n // Initialize WorkerChannel\n this.channel = new WorkerChannel(self as any, {\n name: 'VideoComposeWorker',\n timeout: 30000,\n });\n\n this.setupHandlers();\n }\n\n private setupHandlers(): void {\n // Register message handlers\n this.channel.registerHandler('configure', this.handleConfigure.bind(this));\n this.channel.registerHandler('connect' as any, this.handleConnect.bind(this));\n this.channel.registerHandler('flush', this.handleFlush.bind(this));\n // this.channel.registerHandler('get_stream', this.handleGetStream.bind(this));\n this.channel.registerHandler('get_stats', this.handleGetStats.bind(this));\n this.channel.registerHandler('install_instructions', this.handleInstallInstructions.bind(this));\n this.channel.registerHandler('sync_clip', this.handleSyncClip.bind(this));\n this.channel.registerHandler('dispose_clip', this.handleDisposeClip.bind(this));\n this.channel.registerHandler(WorkerMessageType.Dispose, this.handleDispose.bind(this));\n }\n\n /**\n * Unified connect handler used by stream pipeline\n */\n private async handleConnect(payload: {\n direction: 'upstream' | 'downstream';\n port: MessagePort;\n streamType: 'video' | 'audio' | 'frame' | 'chunk';\n clipId?: string;\n }): Promise<{ success: boolean }> {\n const { port, direction, clipId = 'default' } = payload;\n if (direction === 'upstream') {\n this.upstreamPorts.set(clipId, port);\n const channel = new WorkerChannel(port, {\n name: 'VideoCompose-Decode',\n timeout: 30000,\n });\n channel.receiveStream(this.handleReceiveStream.bind(this));\n }\n if (direction === 'downstream') {\n this.downstreamPorts.set(clipId, port);\n }\n return { success: true };\n }\n\n /**\n * Configure composer\n * According to docs/impl/14-config, only reinitialize when initial=true\n */\n private async handleConfigure(payload: {\n config: VideoComposeConfig;\n initial?: boolean;\n }): Promise<{\n success: boolean;\n config: VideoComposeConfig;\n }> {\n const { config, initial } = payload;\n\n const hasValidDimensions = config.width > 0 && config.height > 0;\n const hasValidFps = config.fps > 0;\n\n if (!hasValidDimensions || !hasValidFps) {\n throw new Error(\n `VideoComposeWorker: invalid canvas config width=${config.width}, height=${config.height}, fps=${config.fps}`\n );\n }\n\n // Set worker state to ready on initial configuration\n if (initial) {\n this.channel.state = WorkerState.Ready;\n }\n\n if (initial || !this.composer) {\n // Initial configuration or composer doesn't exist\n if (this.composer) {\n this.composer.dispose();\n this.composeStream = null;\n }\n\n // Create new composer\n this.composer = new VideoComposer(config);\n } else {\n // Just update configuration\n this.composer.updateConfig(config);\n }\n\n // Notify configuration complete\n this.channel.notify('configured', {\n config: this.composer.config,\n initialized: initial || false,\n });\n\n return {\n success: true,\n config: this.composer.config,\n };\n }\n\n private async handleReceiveStream(\n stream: ReadableStream,\n metadata?: Record<string, any>\n ): Promise<void> {\n const { clipId = 'default' } = metadata || {};\n\n if (!this.composer) {\n console.error('[VideoComposeWorker] Composer not configured');\n return;\n }\n\n const instruction = this.instructionRegistry.get(clipId);\n if (!instruction) {\n console.warn('[VideoComposeWorker] No instructions for clip', clipId);\n return;\n }\n\n // TODO: ENCODE\n // const downstreamPort = this.downstreamPorts.get(clipId);\n // if (downstreamPort) {\n // const channel = new WorkerChannel(downstreamPort, {\n // name: 'VideoCompose-Encoder',\n // timeout: 30000,\n // });\n // channel.sendStream(encodeStream, {\n // streamType: 'video',\n // ...metadata,\n // });\n // }\n\n const filteredStream = stream.pipeThrough(\n new TransformStream<any, ComposeRequest>({\n transform: (wrappedFrame, controller) => {\n try {\n // Extract frame and metadata from wrapped object\n const frame = wrappedFrame.frame || wrappedFrame;\n const gopSerial = wrappedFrame.gopSerial;\n const isKeyframe = wrappedFrame.isKeyframe;\n\n const timestamp = frame.timestamp ?? 0;\n if (this.shouldSkipFrame(clipId, timestamp)) {\n frame.close();\n return;\n }\n\n const request = this.buildComposeRequest(clipId, instruction, frame, timestamp);\n if (!request) {\n frame.close();\n return;\n }\n (request as any).gopSerial = gopSerial;\n (request as any).isKeyframe = isKeyframe;\n controller.enqueue(request);\n } catch (error) {\n const frame = wrappedFrame.frame || wrappedFrame;\n frame?.close?.();\n throw error;\n }\n },\n })\n );\n\n const { composeStream, cacheStream } = this.composer.createStreams();\n this.channel.sendStream(cacheStream, metadata);\n\n filteredStream.pipeTo(composeStream).catch((error) => {\n console.error('[VideoComposeWorker] compose stream error', clipId, error);\n });\n }\n\n // private handleGetStream(): ReadableStream<VideoFrame> | undefined {\n // return this.composer?.createStreams()?.cacheStream;\n // }\n\n /**\n * Flush the composition pipeline\n */\n private async handleFlush(): Promise<{ success: boolean }> {\n try {\n // Flush any pending frames in the stream\n // The stream will handle this automatically\n\n this.channel.notify('flush_complete', {});\n return { success: true };\n } catch (error: any) {\n throw {\n code: 'FLUSH_ERROR',\n message: error.message,\n };\n }\n }\n\n /**\n * Get composer statistics\n */\n private async handleGetStats(): Promise<{\n configured: boolean;\n config?: VideoComposeConfig;\n streaming: boolean;\n }> {\n return {\n configured: this.composer !== null,\n config: this.composer?.config,\n streaming: this.composeStream !== null,\n };\n }\n\n /**\n * Dispose worker and cleanup resources\n */\n private async handleDispose(): Promise<{ success: boolean }> {\n // Dispose composer\n if (this.composer) {\n this.composer.dispose();\n this.composer = null;\n }\n\n this.composeStream = null;\n\n // Close connections\n this.downstreamPorts.get('default')?.close();\n this.upstreamPorts.get('default')?.close();\n this.downstreamPorts.clear();\n this.upstreamPorts.clear();\n\n this.channel.state = WorkerState.Disposed;\n\n return { success: true };\n }\n\n private async handleInstallInstructions(data: ClipInstructionSet): Promise<{ success: boolean }> {\n const { clipId, revision } = data;\n const current = this.instructionRegistry.get(clipId);\n if (current && current.revision > revision) {\n return { success: false };\n }\n\n this.instructionRegistry.set(clipId, data);\n return { success: true };\n }\n\n private async handleSyncClip(payload: {\n clipId: string;\n revision: number;\n range: { startUs: number; endUs: number };\n }): Promise<{ success: boolean }> {\n const { clipId, revision, range } = payload;\n const current = this.instructionRegistry.get(clipId);\n if (!current || current.revision > revision) {\n return { success: false };\n }\n\n this.pendingReplay.set(clipId, { ...range, revision });\n this.channel.notify('sync_ack', { clipId, revision });\n return { success: true };\n }\n\n private async handleDisposeClip(payload: { clipId: string }): Promise<{ success: boolean }> {\n const { clipId } = payload;\n this.instructionRegistry.delete(clipId);\n this.pendingReplay.delete(clipId);\n this.downstreamPorts.get(clipId)?.close();\n this.upstreamPorts.get(clipId)?.close();\n this.downstreamPorts.delete(clipId);\n this.upstreamPorts.delete(clipId);\n return { success: true };\n }\n\n /**\n * Check if frame should be skipped (outside dirty range)\n * Returns true if frame is NOT in the dirty range and should use cached version\n */\n private shouldSkipFrame(clipId: string, timestamp: number): boolean {\n const dirtyRange = this.pendingReplay.get(clipId);\n if (!dirtyRange) {\n return false; // No dirty range, don't skip (first render or no updates)\n }\n\n // Frame is within dirty range → don't skip, re-compose\n if (timestamp >= dirtyRange.startUs && timestamp <= dirtyRange.endUs) {\n return false;\n }\n\n // Passed dirty range end → clean up\n if (timestamp > dirtyRange.endUs) {\n this.pendingReplay.delete(clipId);\n }\n\n // Frame outside dirty range → skip, use cache\n return true;\n }\n\n private buildComposeRequest(\n clipId: string,\n instruction: ClipInstructionSet,\n frame: VideoFrame,\n _timestamp: number\n ): ComposeRequest | null {\n const normalizedTime = this.computeTimelineTimestamp(clipId, frame, instruction.baseConfig);\n const clipStartUs = instruction.baseConfig.timeline?.clipStartUs ?? 0;\n const clipDurationUs = instruction.baseConfig.timeline?.clipDurationUs ?? Infinity;\n const clipEndUs = clipStartUs + clipDurationUs;\n\n // Check if frame is within clip boundary\n if (normalizedTime < clipStartUs || normalizedTime >= clipEndUs) {\n return null;\n }\n\n const clipRelativeTime = normalizedTime - clipStartUs;\n const activeLayers = resolveActiveLayers(instruction.layers, clipRelativeTime, frame);\n\n if (!activeLayers.length) {\n return null;\n }\n const layers = activeLayers.map((layer) => materializeLayer(layer, frame));\n return {\n timeUs: normalizedTime,\n layers,\n transition: VideoComposeWorker.buildTransition(\n instruction.transitions,\n clipRelativeTime,\n instruction.baseConfig.timeline\n ),\n };\n }\n\n private static buildTransition(\n transitions: SerializedTransitionPlan[],\n timeUs: TimeUs,\n _timeline?: VideoComposeConfig['timeline']\n ) {\n const entry = transitions.find((transition) => {\n const { startUs, endUs } = transition.range;\n return timeUs >= startUs && timeUs < endUs;\n });\n if (!entry) {\n return undefined;\n }\n const durationUs = entry.range.endUs - entry.range.startUs;\n const progress = durationUs > 0 ? (timeUs - entry.range.startUs) / durationUs : 0;\n return {\n type: entry.params.type,\n progress: Math.min(Math.max(progress, 0), 1),\n easing: entry.params.easing,\n params: entry.params.payload,\n direction: entry.params.payload?.direction,\n } as any;\n }\n\n private computeTimelineTimestamp(\n clipId: string,\n frame: VideoFrame,\n config: VideoComposeConfig\n ): TimeUs {\n const key = clipId;\n let state = this.streamState.get(key);\n if (!state) {\n state = {\n baseTimestamp: null,\n lastSourceTimestamp: null,\n nextFrameIndex: 0,\n };\n this.streamState.set(key, state);\n }\n\n const timeline = config.timeline;\n if (!timeline) {\n const ts = frame.timestamp ?? 0;\n state.lastSourceTimestamp = frame.timestamp ?? null;\n return ts;\n }\n\n const { clipStartUs, compositionFps } = timeline;\n const sourceTimestamp = frame.timestamp ?? null;\n\n // Detect stream reset (e.g., after seek)\n if (\n sourceTimestamp !== null &&\n state.lastSourceTimestamp !== null &&\n sourceTimestamp < state.lastSourceTimestamp\n ) {\n state.baseTimestamp = null;\n state.nextFrameIndex = 0;\n }\n\n // Initialize base timestamp (should be 0 or close to 0 after demuxer normalization)\n if (state.baseTimestamp === null) {\n state.baseTimestamp = sourceTimestamp ?? 0;\n state.nextFrameIndex = 0;\n\n // Warn if base is not near zero (indicates demuxer normalization issue)\n if (state.baseTimestamp > 1000) {\n console.warn(\n `[VideoComposeWorker] First frame timestamp is ${state.baseTimestamp}us, expected ~0. ` +\n `Check MP4Demuxer normalization.`\n );\n }\n }\n\n // Since demuxer normalizes to 0, we can directly calculate frame index\n const frameDuration = frameDurationFromFps(compositionFps);\n let frameIndex = state.nextFrameIndex;\n\n if (sourceTimestamp !== null) {\n // Calculate frame index from normalized timestamp\n const approxIndex = frameIndexFromTimestamp(\n state.baseTimestamp,\n sourceTimestamp,\n compositionFps,\n 'nearest'\n );\n frameIndex = Math.max(frameIndex, approxIndex);\n }\n\n // Map to timeline position\n const rawTimeline = clipStartUs + frameIndex * frameDuration;\n const timelineTime = quantizeTimestampToFrame(\n rawTimeline,\n clipStartUs,\n compositionFps,\n 'nearest'\n );\n\n state.nextFrameIndex = frameIndex + 1;\n state.lastSourceTimestamp = sourceTimestamp;\n\n return timelineTime;\n }\n}\n\ninterface StreamState {\n baseTimestamp: number | null;\n lastSourceTimestamp: number | null;\n nextFrameIndex: number;\n}\n\n// Initialize worker\nconst worker = new VideoComposeWorker();\n\n// Handle worker termination\nself.addEventListener('beforeunload', () => {\n worker['handleDispose']();\n});\n\nexport default null; // Required for TypeScript worker compilation\n"],"names":["WorkerMessageType","WorkerState","idx"],"mappings":"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"}