tempest-react-sdk 0.55.0 → 0.56.0

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 (33) hide show
  1. package/README.md +74 -73
  2. package/dist/components/AudioPlayer/AudioPlayer.cjs +1 -1
  3. package/dist/components/AudioPlayer/AudioPlayer.js +6 -6
  4. package/dist/components/VideoPlayer/VideoPlayer.cjs +2 -0
  5. package/dist/components/VideoPlayer/VideoPlayer.cjs.map +1 -0
  6. package/dist/components/VideoPlayer/VideoPlayer.js +229 -0
  7. package/dist/components/VideoPlayer/VideoPlayer.js.map +1 -0
  8. package/dist/components/VideoPlayer/VideoPlayer.module.cjs +2 -0
  9. package/dist/components/VideoPlayer/VideoPlayer.module.cjs.map +1 -0
  10. package/dist/components/VideoPlayer/VideoPlayer.module.js +19 -0
  11. package/dist/components/VideoPlayer/VideoPlayer.module.js.map +1 -0
  12. package/dist/components/VideoPlayer/playback-rates.cjs +2 -0
  13. package/dist/components/VideoPlayer/playback-rates.cjs.map +1 -0
  14. package/dist/components/VideoPlayer/playback-rates.js +11 -0
  15. package/dist/components/VideoPlayer/playback-rates.js.map +1 -0
  16. package/dist/imaging/exceptions.cjs +1 -1
  17. package/dist/imaging/exceptions.cjs.map +1 -1
  18. package/dist/imaging/exceptions.js +5 -1
  19. package/dist/imaging/exceptions.js.map +1 -1
  20. package/dist/imaging/frame.cjs +2 -0
  21. package/dist/imaging/frame.cjs.map +1 -0
  22. package/dist/imaging/frame.js +82 -0
  23. package/dist/imaging/frame.js.map +1 -0
  24. package/dist/imaging.cjs +1 -1
  25. package/dist/imaging.d.ts +611 -494
  26. package/dist/imaging.js +10 -9
  27. package/dist/styles/VideoPlayer.css +23 -0
  28. package/dist/styles/media.css +22 -0
  29. package/dist/styles.css +1 -1
  30. package/dist/tempest-react-sdk.cjs +1 -1
  31. package/dist/tempest-react-sdk.d.ts +142 -23
  32. package/dist/tempest-react-sdk.js +213 -211
  33. package/package.json +1 -1
@@ -0,0 +1 @@
1
+ {"version":3,"file":"frame.js","names":[],"sources":["../../src/imaging/frame.ts"],"sourcesContent":["/**\n * Reading one frame out of a `<video>`, at the instant you asked for.\n *\n * The current frame needs nothing from this file: `createImageBitmap` takes a\n * video element, so `resizeImage(video)` already works. A **chosen** instant is\n * the part every app writes by hand and writes wrong:\n *\n * ```ts\n * video.currentTime = 12.5;\n * await new Promise((r) => video.addEventListener(\"seeked\", r, { once: true }));\n * ctx.drawImage(video, 0, 0); // may draw the PREVIOUS frame\n * ```\n *\n * `seeked` says the seek finished, not that the frame for the new position is\n * composited and readable by `drawImage`. The symptom is the worst kind: it\n * works on the machine it was written on and produces the neighbouring frame\n * elsewhere, with no error and no log.\n *\n * `requestVideoFrameCallback` is the only signal that reports a frame having\n * been **presented** — and measuring it, 2026-09-04 in Chromium, settled how it\n * can be used here: it fires while the video **plays** and does **not** fire\n * for a seek on a paused element. So blocking a seek on it would stall every\n * capture for the whole timeout and then proceed anyway. Instead:\n *\n * - Capturing from a **playing** video waits for the next presented frame, so\n * the pixels are demonstrably fresh. That is the screen-recording print.\n * - Capturing at an **instant** waits for `seeked` and then two animation\n * frames, which is what a browser offers for a paused element.\n * - Capturing the current frame of a **paused** video waits for nothing: the\n * frame on screen already is the frame.\n *\n * `confirmed` in the result says which of those happened, so a caller can tell\n * a demonstrably fresh frame from a best-effort one instead of guessing. A\n * seek-based capture reporting `confirmed: false` is the normal case, not a\n * warning sign.\n *\n * Three more traps come along for the ride:\n *\n * - **A recording may arrive with no duration.** `MediaRecorder` does not\n * guarantee a duration in the WebM header, so the blob `useVideoRecorder`\n * just handed you may report `Infinity` — and the video an app most wants to\n * grab a frame from is exactly that one. Seeking past the end forces the\n * browser to demux to the last frame, after which it knows the length; that\n * probe runs here rather than in every caller. Chromium was measured writing\n * the duration for a one-shot recording, so this is for the paths that omit\n * it — chunked `timeslice` recording, and other engines.\n * - **A cross-origin video taints the canvas**, and the failure surfaces far\n * from its cause, so it is re-thrown saying what to set.\n * - **Moving `currentTime` moves the player** somebody is watching; `restore`\n * puts it back, and touches only what actually moved.\n */\n\nimport { FrameSeekError, ImageDecodeError } from \"./exceptions\";\nimport { resizeImage } from \"./transform\";\nimport type { CaptureFrameOptions, CapturedFrame } from \"./types\";\n\n/** How long a seek and the frame after it may take, in milliseconds. */\nexport const DEFAULT_FRAME_TIMEOUT_MS = 3000;\n\n/** `HTMLMediaElement.HAVE_CURRENT_DATA` — there are pixels for the current position. */\nconst HAVE_CURRENT_DATA = 2;\n\n/** Below this, in seconds, a seek to `currentTime` is a seek to where we already are. */\nconst SAME_FRAME_EPSILON = 0.001;\n\n/**\n * How long to wait for a presented frame, in milliseconds.\n *\n * Its own budget, not the caller's `timeoutMs`: this wait is an optimisation on\n * freshness, and a video playing at 24 fps presents one every 42 ms. Spending\n * seconds here would stall the capture for a guarantee the platform may simply\n * not be able to give.\n */\nconst FRAME_SETTLE_MS = 200;\n\n/**\n * A video element that reports presented frames.\n *\n * Declared structurally rather than by augmenting `HTMLVideoElement`: this is a\n * published package, and widening a lib interface would widen it for every\n * consumer, in every file, whether they load a polyfill or not.\n *\n * The two members are one capability. The spec defines them together, so a\n * runtime with `requestVideoFrameCallback` and no `cancelVideoFrameCallback`\n * does not exist — guarding the second separately would add a branch no test\n * can honestly reach.\n */\ntype FrameCallbackVideo = HTMLVideoElement & {\n requestVideoFrameCallback: (callback: (now: number) => void) => number;\n cancelVideoFrameCallback: (handle: number) => void;\n};\n\n/**\n * Whether this element reports presented frames.\n *\n * @param video The element to test.\n * @returns `true` when the frame callback pair is available.\n */\nfunction reportsFrames(video: HTMLVideoElement): video is FrameCallbackVideo {\n return typeof (video as Partial<FrameCallbackVideo>).requestVideoFrameCallback === \"function\";\n}\n\n/** Seek target that forces a demux to the end, to learn an unknown duration. */\nconst PAST_THE_END_SECONDS = 1e101;\n\n/** The `AbortError` a caller's `signal` produces. */\nfunction abortError(): DOMException {\n return new DOMException(\"The frame capture was aborted.\", \"AbortError\");\n}\n\n/**\n * Wait for one media event, and clean up on every exit.\n *\n * @param video The element to listen on.\n * @param type The event to wait for.\n * @param timeoutMs How long to wait.\n * @param signal Optional abort signal.\n * @param whenLate Message for the {@link FrameSeekError} on timeout.\n * @returns Resolves when the event fires.\n * @throws {@link FrameSeekError} when the timeout is reached.\n */\nfunction onceEvent(\n video: HTMLVideoElement,\n type: string,\n timeoutMs: number,\n signal: AbortSignal | undefined,\n whenLate: string,\n): Promise<void> {\n return new Promise<void>((resolve, reject) => {\n const finish = (settle: () => void): void => {\n clearTimeout(timer);\n video.removeEventListener(type, onEvent);\n signal?.removeEventListener(\"abort\", onAbort);\n settle();\n };\n const onEvent = (): void => finish(resolve);\n const onAbort = (): void => finish(() => reject(abortError()));\n\n const timer = setTimeout(\n () => finish(() => reject(new FrameSeekError(whenLate))),\n timeoutMs,\n );\n video.addEventListener(type, onEvent);\n signal?.addEventListener(\"abort\", onAbort);\n });\n}\n\n/**\n * Wait for the next frame the compositor presents.\n *\n * Only ever called for a **playing** element, because that is the only state in\n * which the callback fires — measured, not assumed. The timeout is the escape\n * for a hidden tab, which presents nothing at all.\n *\n * @param video A playing element that reports presented frames.\n * @returns `true` when a frame was presented, `false` when the wait expired.\n */\nfunction nextPresentedFrame(video: FrameCallbackVideo): Promise<boolean> {\n return new Promise<boolean>((resolve) => {\n const timer = setTimeout(() => {\n video.cancelVideoFrameCallback(handle);\n resolve(false);\n }, FRAME_SETTLE_MS);\n const handle = video.requestVideoFrameCallback(() => {\n clearTimeout(timer);\n resolve(true);\n });\n });\n}\n\n/**\n * Let the compositor catch up after a seek on a paused element.\n *\n * Two animation frames is what a browser offers here: the frame callback does\n * not fire for a paused seek, so there is nothing to confirm against. A runtime\n * with no animation frames at all gets a macrotask — enough for a test\n * environment, not a promise about pixels.\n *\n * @returns Resolves once the wait is over. Never a confirmation.\n */\nfunction settleAfterSeek(): Promise<void> {\n if (typeof requestAnimationFrame === \"function\") {\n return new Promise<void>((resolve) => {\n requestAnimationFrame(() => requestAnimationFrame(() => resolve()));\n });\n }\n return new Promise<void>((resolve) => setTimeout(resolve, 0));\n}\n\n/**\n * Wait for the freshest frame this element's state allows, and say which.\n *\n * @param video The element about to be read.\n * @param seeked Whether a seek just moved it.\n * @returns `true` when a presented frame was observed.\n */\nasync function awaitReadableFrame(video: HTMLVideoElement, seeked: boolean): Promise<boolean> {\n if (!video.paused && reportsFrames(video)) return await nextPresentedFrame(video);\n if (seeked) await settleAfterSeek();\n return false;\n}\n\n/**\n * Whether the element is fed by a live stream rather than by a file.\n *\n * A truthiness check rather than `!== null`: the property is absent in\n * environments that model only part of `HTMLMediaElement`, where comparing\n * against `null` would read every element as live.\n *\n * @param video The element to test.\n * @returns `true` when a `MediaStream` is playing into it.\n */\nfunction isLiveStream(video: HTMLVideoElement): boolean {\n return Boolean(video.srcObject);\n}\n\n/**\n * The video's length in seconds, probing for it when the header lacks one.\n *\n * `MediaRecorder` does not guarantee a duration in the WebM it produces, so a\n * recording can report `Infinity` until something forces the browser to demux\n * to the end. That is what the seek past the end does — the same hack the\n * `AudioPlayer` uses, for the same reason: the value is not in the file.\n *\n * @param video The element to measure.\n * @param timeoutMs How long the probe may take.\n * @param signal Optional abort signal.\n * @returns The duration in seconds.\n * @throws {@link FrameSeekError} when the element is a live stream, or the\n * probe produced no duration.\n */\nasync function resolveDuration(\n video: HTMLVideoElement,\n timeoutMs: number,\n signal: AbortSignal | undefined,\n): Promise<number> {\n if (Number.isFinite(video.duration)) return video.duration;\n\n if (isLiveStream(video)) {\n throw new FrameSeekError(\n \"This element is playing a live MediaStream, which has no timeline to seek: \" +\n \"there is no instant but now. Leave `atMs` out to capture the frame on screen.\",\n );\n }\n\n const probed = onceEvent(\n video,\n \"timeupdate\",\n timeoutMs,\n signal,\n `The video reported no duration and the probe for it did not answer within ` +\n `${timeoutMs}ms, so there is no timeline to seek on.`,\n );\n video.currentTime = PAST_THE_END_SECONDS;\n await probed;\n\n if (!Number.isFinite(video.duration)) {\n throw new FrameSeekError(\n \"This video still reports no duration after seeking past its end, so it has \" +\n \"no seekable timeline — a live HLS or DASH source behaves this way. Leave \" +\n \"`atMs` out to capture the frame on screen.\",\n );\n }\n return video.duration;\n}\n\n/**\n * Move the video to an instant, and wait for that instant's frame.\n *\n * @param video The element to move.\n * @param atMs The instant, in milliseconds. Clamped to the duration.\n * @param timeoutMs How long the seek and the frame may take.\n * @param signal Optional abort signal.\n * @returns Whether a presented frame confirmed the new position.\n * @throws {@link FrameSeekError} when the video has no seekable timeline, or\n * the seek did not land in time.\n */\nasync function seekTo(\n video: HTMLVideoElement,\n atMs: number,\n timeoutMs: number,\n signal: AbortSignal | undefined,\n): Promise<boolean> {\n const duration = await resolveDuration(video, timeoutMs, signal);\n\n const target = Math.min(Math.max(atMs / 1000, 0), duration);\n if (Math.abs(video.currentTime - target) < SAME_FRAME_EPSILON) {\n return await awaitReadableFrame(video, false);\n }\n\n const seeked = onceEvent(\n video,\n \"seeked\",\n timeoutMs,\n signal,\n `The video did not finish seeking to ${target.toFixed(3)}s within ${timeoutMs}ms. ` +\n \"Nothing was captured: a frame from the wrong instant is indistinguishable \" +\n \"from a correct one downstream.\",\n );\n video.currentTime = target;\n await seeked;\n return await awaitReadableFrame(video, true);\n}\n\n/**\n * Re-throw a tainted-canvas failure saying what to fix.\n *\n * A cross-origin video without `crossOrigin` taints everything it is drawn\n * into, and the `SecurityError` then arrives from the encoder — one call away\n * from the element that caused it, wrapped in whatever the decode said.\n *\n * @param error What the imaging pipeline threw.\n * @returns The error to throw instead.\n */\nfunction explained(error: unknown): unknown {\n const names = [error, (error as { cause?: unknown } | null)?.cause].map((candidate) =>\n typeof candidate === \"object\" && candidate !== null && \"name\" in candidate\n ? String((candidate as { name: unknown }).name)\n : \"\",\n );\n if (!names.includes(\"SecurityError\")) return error;\n return new ImageDecodeError(\n \"The video is cross-origin, so reading its pixels is not allowed. Set \" +\n 'crossOrigin=\"anonymous\" on the element before the source loads, and serve the ' +\n \"video with a permissive Access-Control-Allow-Origin.\",\n { cause: error },\n );\n}\n\n/**\n * Put playback back where the capture found it, touching only what moved.\n *\n * Each half is guarded because writing `currentTime` **is** a seek, even when\n * the value is unchanged: a capture that was refused before it moved anything\n * — a live stream, an abort — would otherwise perturb the player it never\n * touched. And a capture that paused without needing to move still has to let\n * go of the pause.\n *\n * @param video The element to restore.\n * @param time Where `currentTime` was.\n * @param wasPlaying Whether it was playing before the capture paused it.\n */\nfunction restorePlayback(video: HTMLVideoElement, time: number, wasPlaying: boolean): void {\n if (video.currentTime !== time) video.currentTime = time;\n if (wasPlaying && video.paused) void Promise.resolve(video.play()).catch(() => undefined);\n}\n\n/**\n * Capture a frame from a video as encoded image bytes.\n *\n * Without `atMs` it reads the frame on screen, which is what a screen or camera\n * recording wants — a print of what is being recorded. With `atMs` it seeks,\n * waits for that instant's frame to be presented, captures, and puts the player\n * back.\n *\n * @example Print of a screen recording in progress\n * ```ts\n * const shot = await captureFrame(videoRef.current!, {\n * type: \"image/webp\",\n * quality: 0.9,\n * });\n * await shareOrDownloadBlob(shot.blob, \"print.webp\");\n * ```\n *\n * @example A poster from ten seconds in, scaled down\n * ```ts\n * const poster = await captureFrame(video, { atMs: 10_000, width: 640 });\n * setPosterUrl(URL.createObjectURL(poster.blob));\n * console.log(`landed on ${poster.atMs}ms`);\n * ```\n *\n * @param video The element to read. It needs data — the capture waits for\n * `loadeddata` when the element has none yet.\n * @param options Instant, output box, format, and how long to wait.\n * @returns The encoded frame, the instant it actually came from, and whether a\n * presented frame confirmed that instant.\n * @throws {@link FrameSeekError} when the video has no data or no timeline in\n * time, or the seek did not land.\n * @throws {@link ImageDecodeError} when the pixels cannot be read — a\n * cross-origin video without `crossOrigin` is the common one.\n * @throws {@link ImageEncodeError} when the canvas produces no bytes.\n */\nexport async function captureFrame(\n video: HTMLVideoElement,\n options: CaptureFrameOptions = {},\n): Promise<CapturedFrame> {\n const timeoutMs = options.timeoutMs ?? DEFAULT_FRAME_TIMEOUT_MS;\n if (options.signal?.aborted === true) throw abortError();\n\n if (video.readyState < HAVE_CURRENT_DATA) {\n await onceEvent(\n video,\n \"loadeddata\",\n timeoutMs,\n options.signal,\n `The video had no frame to read within ${timeoutMs}ms (readyState ` +\n `${video.readyState}). Give it a source, or wait for it yourself.`,\n );\n }\n\n const { atMs: requestedMs } = options;\n const previousTime = video.currentTime;\n const wasPlaying = !video.paused;\n\n try {\n let confirmed: boolean;\n if (requestedMs === undefined) {\n confirmed = await awaitReadableFrame(video, false);\n } else {\n if (wasPlaying) video.pause();\n confirmed = await seekTo(video, requestedMs, timeoutMs, options.signal);\n }\n\n const atMs = video.currentTime * 1000;\n const encoded = await resizeImage(video, options);\n return { ...encoded, atMs, confirmed };\n } catch (error) {\n throw explained(error);\n } finally {\n if (options.restore !== false) restorePlayback(video, previousTime, wasPlaying);\n }\n}\n"],"mappings":"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"}
package/dist/imaging.cjs CHANGED
@@ -1 +1 @@
1
- Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("./imaging/exceptions.cjs"),t=require("./imaging/canvas.cjs"),n=require("./imaging/decode.cjs"),r=require("./imaging/encode.cjs"),i=require("./imaging/transform.cjs"),a=require("./imaging/compress.cjs"),o=require("./imaging/thumbnails.cjs"),s=require("./imaging/use-image-processing.cjs");exports.DEFAULT_BACKGROUND=i.DEFAULT_BACKGROUND,exports.DEFAULT_COMPRESS_STEPS=a.DEFAULT_COMPRESS_STEPS,exports.DEFAULT_MAX_QUALITY=a.DEFAULT_MAX_QUALITY,exports.DEFAULT_MIN_QUALITY=a.DEFAULT_MIN_QUALITY,exports.DEFAULT_QUALITY=r.DEFAULT_QUALITY,exports.DEFAULT_TYPE=r.DEFAULT_TYPE,exports.ImageDecodeError=e.ImageDecodeError,exports.ImageEncodeError=e.ImageEncodeError,exports.ImagingError=e.ImagingError,exports.ImagingUnavailableError=e.ImagingUnavailableError,exports.UnsupportedImageTypeError=e.UnsupportedImageTypeError,exports.bestSupportedType=r.bestSupportedType,exports.compressToTarget=a.compressToTarget,exports.createSurface=t.createSurface,exports.createThumbnails=o.createThumbnails,exports.cropImage=i.cropImage,exports.decodeImage=n.decodeImage,exports.drawScaled=t.drawScaled,exports.encodeImage=r.encodeImage,exports.flipImage=i.flipImage,exports.getContext=t.getContext,exports.readImageInfo=n.readImageInfo,exports.resizeImage=i.resizeImage,exports.rotateImage=i.rotateImage,exports.supportsImageType=r.supportsImageType,exports.useImagePreview=s.useImagePreview,exports.useImageProcessing=s.useImageProcessing;
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("./imaging/exceptions.cjs"),t=require("./imaging/canvas.cjs"),n=require("./imaging/decode.cjs"),r=require("./imaging/encode.cjs"),i=require("./imaging/transform.cjs"),a=require("./imaging/compress.cjs"),o=require("./imaging/frame.cjs"),s=require("./imaging/thumbnails.cjs"),c=require("./imaging/use-image-processing.cjs");exports.DEFAULT_BACKGROUND=i.DEFAULT_BACKGROUND,exports.DEFAULT_COMPRESS_STEPS=a.DEFAULT_COMPRESS_STEPS,exports.DEFAULT_FRAME_TIMEOUT_MS=o.DEFAULT_FRAME_TIMEOUT_MS,exports.DEFAULT_MAX_QUALITY=a.DEFAULT_MAX_QUALITY,exports.DEFAULT_MIN_QUALITY=a.DEFAULT_MIN_QUALITY,exports.DEFAULT_QUALITY=r.DEFAULT_QUALITY,exports.DEFAULT_TYPE=r.DEFAULT_TYPE,exports.FrameSeekError=e.FrameSeekError,exports.ImageDecodeError=e.ImageDecodeError,exports.ImageEncodeError=e.ImageEncodeError,exports.ImagingError=e.ImagingError,exports.ImagingUnavailableError=e.ImagingUnavailableError,exports.UnsupportedImageTypeError=e.UnsupportedImageTypeError,exports.bestSupportedType=r.bestSupportedType,exports.captureFrame=o.captureFrame,exports.compressToTarget=a.compressToTarget,exports.createSurface=t.createSurface,exports.createThumbnails=s.createThumbnails,exports.cropImage=i.cropImage,exports.decodeImage=n.decodeImage,exports.drawScaled=t.drawScaled,exports.encodeImage=r.encodeImage,exports.flipImage=i.flipImage,exports.getContext=t.getContext,exports.readImageInfo=n.readImageInfo,exports.resizeImage=i.resizeImage,exports.rotateImage=i.rotateImage,exports.supportsImageType=r.supportsImageType,exports.useImagePreview=c.useImagePreview,exports.useImageProcessing=c.useImageProcessing;