{"version":3,"file":"useTimelineMediaSyncInternal.mjs","names":[],"sources":["../../../../src/hooks/playback/internal/useTimelineMediaSyncInternal.ts"],"sourcesContent":["import { useActiveLayers } from '#react/hooks/clips/useActiveLayers';\nimport type {\n  TimelineCommandResult,\n  ActiveLayerResult,\n  ActiveLayerSelector,\n  PlaybackOptions,\n  TimelineMediaSyncAdapter,\n} from '@techsquidtv/canvas-timeline-core';\nimport { useTimelineEngine } from '#react/hooks/core/useTimelineEngine';\nimport {\n  MediaClockOwnership,\n  startMediaClockPlayback,\n} from '#react/hooks/playback/internal/mediaClockOwnership';\nimport { createMediaPlayFailure } from '#react/hooks/playback/internal/mediaPlayResult';\nimport type { TimelineMediaPlayResult } from '#react/hooks/playback/internal/mediaPlayResult';\nimport { MediaSynchronizationQueue } from '#react/hooks/playback/internal/mediaSynchronizationQueue';\nimport { usePausedMediaPreviewSynchronization } from '#react/hooks/playback/internal/pausedMediaPreviewScheduler';\nimport { useTimelineMediaPlaybackInternal } from '#react/hooks/playback/internal/useTimelineMediaPlaybackInternal';\nimport { toMediaError, withMediaCauseMessage } from '#react/hooks/playback/mediaError';\nimport type { UseTimelineMediaPlaybackOptions } from '#react/hooks/playback/useTimelineMediaPlayback';\nimport { TimelineMediaError } from '@techsquidtv/canvas-timeline-core';\nimport type { RationalTime } from '@techsquidtv/canvas-timeline-utils';\nimport { useCallback, useEffect, useMemo, useRef, useState } from 'react';\n/**\n * Options for high-level timeline media synchronization.\n *\n * @remarks\n *\n * The `layers` record names the media outputs your adapter can synchronize.\n * Those names flow through `LayerName`, allowing `activeLayers.primary.visuals`\n * or `activeLayers.layers.audio` to stay typed from the same object.\n * Each value is an {@link ActiveLayerSelector} passed through active layer\n * lookup before adapter callbacks receive an {@link ActiveLayerResult}.\n *\n * @template LayerName - Named media layer keys inferred from `layers`.\n */\nexport interface UseTimelineMediaSyncOptions<LayerName extends string = string> {\n  /** Whether the external adapter can accept a playback request for configured media. */\n  ready?: boolean;\n  /** Optional sequence frame rate used to lock media playback to project frames. */\n  frameRate?: UseTimelineMediaPlaybackOptions<LayerName>['frameRate'];\n  /** Core playback range and looping policy captured when each playback run begins. */\n  playbackOptions?: Omit<PlaybackOptions, 'clock'>;\n  /** Named active layer selectors used by the external media surface. */\n  layers: Record<LayerName, ActiveLayerSelector>;\n  /** External media adapter callbacks. */\n  adapter: TimelineMediaSyncAdapter<LayerName>;\n  /**\n   * Stable identity for the adapter resource lifetime.\n   *\n   * @remarks\n   *\n   * Pass the underlying controller or element-backed adapter when replacing it\n   * must cancel pending playback and release its clock. Omit this for an inline\n   * callback facade whose object identity may change on every render.\n   */\n  adapterIdentity?: object;\n  /** Receives structured media failures with a stable machine-readable reason. */\n  onError?: (error: TimelineMediaError) => void;\n}\n\n/**\n * Result returned from a media-synchronized timeline play request.\n *\n * This high-level media adapter result is intentionally richer than\n * `TimelineCommandResult` because failures include user-facing adapter messages\n * in addition to machine-readable reasons.\n */\nexport type { TimelineMediaPlayResult } from '#react/hooks/playback/internal/mediaPlayResult';\n\n/**\n * Result returned by `useTimelineMediaSync`.\n *\n * @remarks\n *\n * Use the commands in this result for media-aware transport controls. The\n * `activeLayers` snapshot is useful for custom status panels, preview badges,\n * and adapter diagnostics.\n *\n * @template LayerName - Named media layer keys from\n * {@link UseTimelineMediaSyncOptions.layers}.\n */\nexport interface UseTimelineMediaSyncResult<LayerName extends string = string> {\n  /** Active layers at the current playhead time. */\n  activeLayers: ActiveLayerResult<LayerName>;\n  /** Whether synchronized timeline and external media playback is currently running. */\n  playing: boolean;\n  /** Current synchronized playback speed multiplier. */\n  playbackRate: number;\n  /** Starts external media playback and then advances the timeline from that clock. */\n  play: () => Promise<TimelineMediaPlayResult>;\n  /** Stops synchronized timeline/media playback and pauses external media state. */\n  pause: () => TimelineCommandResult;\n  /** Updates both clock rates and resolves after active layers resynchronize. */\n  setPlaybackRate: (playbackRate: number) => Promise<TimelineCommandResult>;\n}\n\n/**\n * High-level synchronization for external media surfaces.\n *\n * @remarks\n *\n * The hook remains media-library agnostic: apps provide an adapter for decoding,\n * rendering, and audio scheduling, while the hook handles active layer lookup,\n * first-content seeking, external-clock playback, rate changes, and pause state.\n * It builds on {@link useTimelineMediaPlayback} for external-clock playback.\n * High-level `playbackOptions.loop` is translated into an adapter seek and clock\n * restart at the range start. Errors are delivered as {@link TimelineMediaError}\n * values and play commands also return a discriminated result.\n * Paused previews, startup, loop realignment, layer synchronization, and rate\n * changes share one ordered adapter-operation queue so older asynchronous media\n * work cannot overwrite a newer timeline position.\n * Replacing the adapter cancels an in-flight start, stops a clock owned by the\n * previous adapter, pauses timeline transport, and primes the replacement for\n * the current paused preview position.\n * For packaged adapters, prefer the higher-level HTML and Mediabunny hooks first;\n * use this hook when you are building a custom clock or preview surface.\n *\n * @param options - External media adapter, readiness state, active layers, and callbacks.\n * @template LayerName - Named media layer keys inferred from `options.layers`,\n * such as `\"visuals\" | \"audio\"`.\n * @returns Media transport state, active layer data, and synchronized playback commands.\n *\n * @example\n * ```tsx\n * import { useMemo, useRef } from 'react';\n * import { useTimelineMediaSync } from '@techsquidtv/canvas-timeline-react';\n *\n * const previewLayerSelectors = {\n *   visuals: { trackKind: 'visual', sourceId: 'source-1' },\n *   audio: { trackKind: 'audio', sourceId: 'source-1' },\n * } as const;\n *\n * export function CustomMediaPreview() {\n *   const mediaTimeRef = useRef(0);\n *   const layers = useMemo(() => previewLayerSelectors, []);\n *   const mediaSync = useTimelineMediaSync({\n *     ready: true,\n *     layers,\n *     adapter: {\n *       getClockTime: () => mediaTimeRef.current,\n *       startClock: (timelineTime, playbackRate) => {\n *         mediaTimeRef.current = timelineTime.v / timelineTime.r;\n *         console.info(`Start media at ${playbackRate}x`);\n *         return true;\n *       },\n *       stopClock: () => {\n *         console.info('Pause external media');\n *       },\n *       syncLayers: ({ activeLayers }) => {\n *         const visualClip = activeLayers.primary.visuals?.clip;\n *         console.info(visualClip ? `Render ${visualClip.id}` : 'No visual clip');\n *       },\n *     },\n *   });\n *\n *   return (\n *     <button type=\"button\" onClick={() => void mediaSync.play()}>\n *       {mediaSync.playing ? 'Playing' : 'Play'}\n *     </button>\n *   );\n * }\n * ```\n *\n * @see {@link ActiveLayerSelector}\n * @see {@link ActiveLayerResult}\n * @see {@link useTimelineMediaPlayback}\n * @see {@link https://canvastimeline.com/demos/media-preview-sync | Mediabunny media sync demo}\n * @see {@link https://canvastimeline.com/demos/html-media-sync | HTML media sync demo}\n */\nexport function useTimelineMediaSync<LayerName extends string = string>(\n  options: UseTimelineMediaSyncOptions<LayerName>\n): UseTimelineMediaSyncResult<LayerName> {\n  const {\n    adapter,\n    adapterIdentity,\n    frameRate,\n    layers,\n    onError,\n    playbackOptions,\n    ready = true,\n  } = options;\n  const engine = useTimelineEngine();\n  const activeLayers = useActiveLayers<LayerName>({ layers });\n  const adapterRef = useRef(adapter);\n  const adapterIdentityRef = useRef(adapterIdentity);\n  const readyRef = useRef(ready);\n  const onErrorRef = useRef(onError);\n  const [clockOwnership] = useState(\n    () => new MediaClockOwnership<LayerName, TimelineMediaPlayResult>()\n  );\n  const clockOwnershipRef = useRef(clockOwnership);\n  const [adapterOperationQueue] = useState(() => new MediaSynchronizationQueue());\n  const { loop: shouldLoop = false, ...externalPlaybackOptions } = playbackOptions ?? {};\n\n  const captureAdapterOperation = useCallback(\n    () => adapterOperationQueue.capture(adapterIdentityRef.current),\n    [adapterOperationQueue]\n  );\n\n  const isCurrentAdapterOperation = useCallback(\n    (token: ReturnType<MediaSynchronizationQueue['capture']>) =>\n      adapterOperationQueue.isCurrent(token, adapterIdentityRef.current),\n    [adapterOperationQueue]\n  );\n\n  const invalidateAdapterOperations = useCallback(() => {\n    adapterOperationQueue.invalidate();\n  }, [adapterOperationQueue]);\n\n  const enqueueAdapterOperation = useCallback(\n    <Result>(operation: () => Promise<Result>) => adapterOperationQueue.enqueue(operation),\n    [adapterOperationQueue]\n  );\n\n  const synchronizationRunner = useMemo(\n    () => ({\n      run: <Result>(operation: () => Promise<Result>, superseded: () => Result) => {\n        return adapterOperationQueue.run(() => adapterIdentityRef.current, operation, superseded);\n      },\n    }),\n    [adapterOperationQueue]\n  );\n\n  const stopSynchronizedClock = useCallback(() => {\n    clockOwnershipRef.current.stopOwnedClock();\n  }, []);\n\n  const adapterSyncLayers = adapter.syncLayers;\n\n  const syncPlaybackOptions: UseTimelineMediaPlaybackOptions<LayerName> = {\n    frameRate,\n    playbackOptions: externalPlaybackOptions,\n    getClockTime: adapter.getClockTime,\n    stopClock: stopSynchronizedClock,\n    setClockRate: adapter.setClockRate,\n    layers,\n    syncLayers:\n      adapterSyncLayers === undefined\n        ? undefined\n        : (details) => {\n            const token = captureAdapterOperation();\n            const synchronize = async () => {\n              if (!isCurrentAdapterOperation(token)) {\n                return;\n              }\n              try {\n                await adapterRef.current.syncLayers?.(details);\n              } catch (syncError) {\n                if (!isCurrentAdapterOperation(token)) {\n                  return;\n                }\n                throw syncError;\n              }\n              if (!isCurrentAdapterOperation(token)) {\n                return;\n              }\n            };\n            return synchronize();\n          },\n    onStatus: adapter.onStatus,\n    onError: (syncError) => {\n      onErrorRef.current?.(\n        syncError instanceof TimelineMediaError\n          ? syncError\n          : new TimelineMediaError(\n              'sync-failed',\n              withMediaCauseMessage('Media synchronization failed.', syncError),\n              { cause: syncError }\n            )\n      );\n    },\n    ...(shouldLoop && {\n      loop: (timelineTime: RationalTime, loopLayers: ActiveLayerResult<LayerName>) => {\n        const loopOwner = clockOwnershipRef.current.owner;\n        if (loopOwner === null) {\n          return;\n        }\n        const token = captureAdapterOperation();\n        return enqueueAdapterOperation(async () => {\n          const stillOwnsClock = () =>\n            isCurrentAdapterOperation(token) &&\n            clockOwnershipRef.current.owner === loopOwner &&\n            engine.getState().playing;\n          if (!stillOwnsClock()) {\n            return;\n          }\n\n          let restarted: boolean;\n          try {\n            await loopOwner.adapter.seek?.(timelineTime, loopLayers);\n            if (!stillOwnsClock()) {\n              return;\n            }\n            restarted = await loopOwner.adapter.startClock(timelineTime, engine.getPlaybackRate());\n          } catch (loopError) {\n            if (!stillOwnsClock()) {\n              return;\n            }\n            const cause = toMediaError(loopError);\n            const error = new TimelineMediaError(\n              'loop-failed',\n              withMediaCauseMessage('Media clock could not restart after looping.', cause),\n              { cause }\n            );\n            throw error;\n          }\n          if (!stillOwnsClock()) {\n            loopOwner.adapter.stopClock?.();\n            return;\n          }\n          if (!restarted) {\n            const error = new TimelineMediaError(\n              'loop-failed',\n              'Media clock could not restart after looping.'\n            );\n            throw error;\n          }\n        });\n      },\n    }),\n  };\n  const syncPlayback = useTimelineMediaPlaybackInternal(syncPlaybackOptions, synchronizationRunner);\n  const pauseSynchronizedPlayback = syncPlayback.pause;\n\n  useEffect(() => {\n    const sameAdapterIdentity = Object.is(adapterIdentityRef.current, adapterIdentity);\n    clockOwnershipRef.current.updateAdapter(adapter, sameAdapterIdentity);\n    adapterRef.current = adapter;\n    readyRef.current = ready;\n    onErrorRef.current = onError;\n  }, [adapter, adapterIdentity, layers, onError, ready, syncPlayback.playing]);\n\n  useEffect(() => {\n    clockOwnershipRef.current.clearOwnerWhenIdle(syncPlayback.playing);\n  }, [syncPlayback.playing]);\n\n  const hasPendingPlaybackStart = useCallback(() => clockOwnershipRef.current.pending !== null, []);\n  const pausedPreview = usePausedMediaPreviewSynchronization({\n    engine,\n    adapter,\n    adapterIdentity,\n    layers,\n    ready,\n    playing: syncPlayback.playing,\n    hasPendingPlaybackStart,\n    operationQueue: adapterOperationQueue,\n    onError,\n  });\n  const cancelScheduledSeek = pausedPreview.cancel;\n\n  const cancelPendingPlaybackStart = useCallback(() => {\n    return clockOwnershipRef.current.cancelPendingStart(invalidateAdapterOperations);\n  }, [invalidateAdapterOperations]);\n\n  useEffect(() => {\n    if (ready) {\n      return;\n    }\n\n    invalidateAdapterOperations();\n    cancelScheduledSeek();\n    const cancelledPendingStart = cancelPendingPlaybackStart();\n    if (clockOwnershipRef.current.owner !== null) {\n      if (cancelledPendingStart) {\n        clockOwnershipRef.current.clearOwner();\n      }\n      pauseSynchronizedPlayback();\n    }\n  }, [\n    cancelPendingPlaybackStart,\n    cancelScheduledSeek,\n    invalidateAdapterOperations,\n    pauseSynchronizedPlayback,\n    ready,\n  ]);\n\n  useEffect(() => {\n    if (Object.is(adapterIdentityRef.current, adapterIdentity)) {\n      return;\n    }\n\n    adapterIdentityRef.current = adapterIdentity;\n    invalidateAdapterOperations();\n    const shouldPrimeAdapter = ready && adapter.seek !== undefined;\n    pausedPreview.resetForAdapter(shouldPrimeAdapter);\n    const cancelledPendingStart = cancelPendingPlaybackStart();\n    const previousOwner = clockOwnershipRef.current.owner;\n    if (previousOwner !== null) {\n      if (cancelledPendingStart) {\n        clockOwnershipRef.current.clearOwner();\n      }\n      pauseSynchronizedPlayback();\n    }\n  }, [\n    adapter,\n    adapterIdentity,\n    cancelPendingPlaybackStart,\n    invalidateAdapterOperations,\n    pausedPreview,\n    ready,\n    pauseSynchronizedPlayback,\n  ]);\n\n  useEffect(\n    () => () => {\n      invalidateAdapterOperations();\n      cancelPendingPlaybackStart();\n    },\n    [cancelPendingPlaybackStart, invalidateAdapterOperations]\n  );\n\n  const startPlayback = useCallback(\n    (generation: number) =>\n      startMediaClockPlayback({\n        engine,\n        generation,\n        frameRate,\n        layers,\n        playbackOptions,\n        ownership: clockOwnershipRef.current,\n        operationQueue: adapterOperationQueue,\n        getAdapter: () => adapterRef.current,\n        getAdapterIdentity: () => adapterIdentityRef.current,\n        isReady: () => readyRef.current,\n        playTimeline: syncPlayback.play,\n        onError: onErrorRef.current,\n      }),\n    [adapterOperationQueue, engine, frameRate, layers, playbackOptions, syncPlayback.play]\n  );\n\n  const play = useCallback((): Promise<TimelineMediaPlayResult> => {\n    if (engine.getState().playing) {\n      if (clockOwnershipRef.current.owner !== null) {\n        return Promise.resolve({ ok: true, time: engine.getTime() });\n      }\n      return Promise.resolve(\n        createMediaPlayFailure(\n          'timeline-failed',\n          'Timeline playback is already controlled by another clock.',\n          onErrorRef.current\n        )\n      );\n    }\n\n    cancelScheduledSeek();\n    return clockOwnershipRef.current.queueStart(adapter, startPlayback);\n  }, [adapter, cancelScheduledSeek, engine, startPlayback]);\n\n  const pause = useCallback(() => {\n    invalidateAdapterOperations();\n    const cancelledPendingStart = cancelPendingPlaybackStart();\n    const result = syncPlayback.pause();\n    if (!cancelledPendingStart) {\n      clockOwnershipRef.current.clearOwner();\n    }\n    return result;\n  }, [cancelPendingPlaybackStart, invalidateAdapterOperations, syncPlayback]);\n\n  const setPlaybackRate = useCallback(\n    (playbackRate: number) => syncPlayback.setPlaybackRate(playbackRate),\n    [syncPlayback]\n  );\n\n  return useMemo(\n    () => ({\n      /** Active layers at the current playhead time. */\n      activeLayers,\n      /** Whether synchronized timeline/media playback is currently running. */\n      playing: syncPlayback.playing,\n      /** Current synchronized playback speed multiplier. */\n      playbackRate: syncPlayback.playbackRate,\n      /** Starts external media playback and then advances the timeline from that clock. */\n      play,\n      /** Stops synchronized timeline/media playback. */\n      pause,\n      /** Updates both the external clock rate and the timeline playback rate. */\n      setPlaybackRate,\n    }),\n    [activeLayers, pause, play, setPlaybackRate, syncPlayback.playing, syncPlayback.playbackRate]\n  );\n}\n"],"mappings":"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"}