textmode.export.js 1.8.0 → 1.9.0-beta.1

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 (38) hide show
  1. package/README.md +7 -2
  2. package/dist/textmode.export.esm.js +1 -1
  3. package/dist/textmode.export.umd.js +1 -1
  4. package/dist/types/exporters/base/FileHandler.d.ts +1 -14
  5. package/dist/types/exporters/base/FilenamePolicy.d.ts +6 -0
  6. package/dist/types/exporters/base/FramePreparation.d.ts +7 -0
  7. package/dist/types/exporters/base/frame-sequence/ExclusiveCaptureGate.d.ts +7 -0
  8. package/dist/types/exporters/base/frame-sequence/FrameSchedule.d.ts +8 -0
  9. package/dist/types/exporters/{video/VideoFrameDriver.d.ts → base/frame-sequence/FrameSequenceDriver.d.ts} +5 -11
  10. package/dist/types/exporters/base/frame-sequence/errors.d.ts +12 -0
  11. package/dist/types/exporters/base/frame-sequence/index.d.ts +5 -0
  12. package/dist/types/exporters/base/frame-sequence/types.d.ts +20 -0
  13. package/dist/types/exporters/base/frame-sequence/withAbortableTimeout.d.ts +1 -0
  14. package/dist/types/exporters/base/index.d.ts +3 -0
  15. package/dist/types/exporters/gif/GIFExporter.d.ts +1 -1
  16. package/dist/types/exporters/gif/index.d.ts +0 -1
  17. package/dist/types/exporters/gif/types.d.ts +6 -12
  18. package/dist/types/exporters/json/JSONExporter.d.ts +2 -2
  19. package/dist/types/exporters/video/VideoEncodingPolicy.d.ts +2 -19
  20. package/dist/types/exporters/video/VideoExporter.d.ts +4 -6
  21. package/dist/types/exporters/video/VideoRecorder.d.ts +2 -1
  22. package/dist/types/exporters/video/errors.d.ts +1 -0
  23. package/dist/types/exporters/video/index.d.ts +1 -1
  24. package/dist/types/exporters/video/types.d.ts +104 -107
  25. package/dist/types/exporters/zip/FrameSerializerRegistry.d.ts +4 -0
  26. package/dist/types/exporters/zip/ZIPArchiveWriter.d.ts +21 -0
  27. package/dist/types/exporters/zip/ZIPExporter.d.ts +32 -0
  28. package/dist/types/exporters/zip/ZIPManifest.d.ts +12 -0
  29. package/dist/types/exporters/zip/errors.d.ts +14 -0
  30. package/dist/types/exporters/zip/index.d.ts +3 -0
  31. package/dist/types/exporters/zip/types.d.ts +177 -0
  32. package/dist/types/index.d.ts +34 -6
  33. package/dist/types/overlay/blades/VideoBlade.d.ts +3 -6
  34. package/dist/types/overlay/types.d.ts +2 -4
  35. package/dist/types/runtime/TextmodeExportController.d.ts +3 -0
  36. package/dist/types/types.d.ts +72 -11
  37. package/package.json +6 -3
  38. package/dist/types/exporters/gif/GIFRecorder.d.ts +0 -23
@@ -9,18 +9,5 @@ export declare class FileHandler {
9
9
  * @param blob The content to download
10
10
  * @param filename The filename to use for the downloaded file
11
11
  */
12
- $downloadFile(blob: Blob, filename: string | undefined): void;
13
- /**
14
- * Validates and sanitizes filename for safety and compatibility
15
- *
16
- * @param filename The filename to validate
17
- * @returns Sanitized filename
18
- */
19
- private _sanitizeFilename;
20
- /**
21
- * Generates a default filename with timestamp
22
- *
23
- * @returns Generated filename
24
- */
25
- private _generateDefaultFilename;
12
+ $downloadFile(blob: Blob, filename: string | undefined, extension?: `.${string}`): void;
26
13
  }
@@ -0,0 +1,6 @@
1
+ /** Central filename normalization and canonical-extension policy. */
2
+ export declare class FilenamePolicy {
3
+ $resolve(filename: string | undefined, extension: `.${string}`, createdAt?: Date): string;
4
+ $sanitizeStem(filename: string | undefined, createdAt?: Date, maximumBytes?: number): string;
5
+ $defaultStem(createdAt?: Date): string;
6
+ }
@@ -2,6 +2,13 @@
2
2
  export interface ExportFrameContext {
3
3
  frameIndex: number;
4
4
  frameCount: number;
5
+ /** Left edge of the output-frame interval. Alias of `timeSeconds`. */
6
+ startSeconds: number;
7
+ /** Center of the output-frame interval; use this to sample external media. */
8
+ centerSeconds: number;
9
+ /** Exclusive right edge of the output-frame interval. */
10
+ endSeconds: number;
11
+ /** @deprecated Use `startSeconds`. */
5
12
  timeSeconds: number;
6
13
  frameRate: number;
7
14
  signal?: AbortSignal;
@@ -0,0 +1,7 @@
1
+ /** Rejects overlapping deterministic captures for one installed plugin instance. */
2
+ export declare class ExclusiveCaptureGate {
3
+ private _active;
4
+ private _disposed;
5
+ acquire(): () => void;
6
+ dispose(): void;
7
+ }
@@ -0,0 +1,8 @@
1
+ export interface FrameTiming {
2
+ startSeconds: number;
3
+ centerSeconds: number;
4
+ endSeconds: number;
5
+ durationSeconds: number;
6
+ }
7
+ /** Produces one stable microsecond-rounded interval for an output frame. */
8
+ export declare function frameTiming(frameIndex: number, frameRate: number): FrameTiming;
@@ -1,13 +1,7 @@
1
1
  import type { Textmodifier } from 'textmode.js';
2
- import type { VideoRenderFrameOptions } from './types';
3
- export type PostDrawSubscription = (callback: () => void) => () => void;
4
- /**
5
- * Drives deterministic video export frames through public textmode APIs.
6
- *
7
- * The visible textmode canvas remains untouched. Each presented frame is copied
8
- * into a staging canvas sized for the requested video output.
9
- */
10
- export declare class VideoFrameDriver {
2
+ import type { FrameSequenceRenderOptions, FrameSequenceStagingSurface, PostDrawSubscription } from './types';
3
+ /** Drives deterministic export frames through public textmode.js lifecycle APIs. */
4
+ export declare class FrameSequenceDriver {
11
5
  readonly canvas: HTMLCanvasElement;
12
6
  private readonly _textmodifier;
13
7
  private readonly _registerPostDrawHook;
@@ -16,8 +10,8 @@ export declare class VideoFrameDriver {
16
10
  private _pendingFrame;
17
11
  private _syntheticFrameCount;
18
12
  private _syntheticMillis;
19
- constructor(textmodifier: Textmodifier, registerPostDrawHook: PostDrawSubscription, width: number, height: number);
20
- $render(options: VideoRenderFrameOptions): Promise<void>;
13
+ constructor(textmodifier: Textmodifier, registerPostDrawHook: PostDrawSubscription, stagingSurface?: FrameSequenceStagingSurface);
14
+ $render(options: FrameSequenceRenderOptions): Promise<void>;
21
15
  private _renderOneFrame;
22
16
  private _capturePendingFrame;
23
17
  private _createStagingCanvas;
@@ -0,0 +1,12 @@
1
+ export type FrameSequenceErrorCode = 'FRAME_SEQUENCE_ABORTED' | 'FRAME_SEQUENCE_TIMEOUT' | 'FRAME_SEQUENCE_BUSY' | 'FRAME_SEQUENCE_DISPOSED';
2
+ /** Internal error used by deterministic capture infrastructure. */
3
+ export declare class FrameSequenceError extends Error {
4
+ readonly code: FrameSequenceErrorCode;
5
+ readonly cause?: unknown;
6
+ constructor(code: FrameSequenceErrorCode, message: string, cause?: unknown);
7
+ }
8
+ export declare function createFrameSequenceAbortError(): FrameSequenceError;
9
+ export declare function createFrameSequenceTimeoutError(message: string, cause?: unknown): FrameSequenceError;
10
+ export declare function createFrameSequenceBusyError(): FrameSequenceError;
11
+ export declare function createFrameSequenceDisposedError(): FrameSequenceError;
12
+ export declare function isFrameSequenceAbortError(error: unknown): boolean;
@@ -0,0 +1,5 @@
1
+ export { ExclusiveCaptureGate } from './ExclusiveCaptureGate';
2
+ export { FrameSequenceDriver } from './FrameSequenceDriver';
3
+ export { frameTiming } from './FrameSchedule';
4
+ export { FrameSequenceError, createFrameSequenceAbortError, isFrameSequenceAbortError } from './errors';
5
+ export type { FrameSequenceDriverLike, FrameSequenceRenderOptions, FrameSequenceStagingSurface, PostDrawSubscription, } from './types';
@@ -0,0 +1,20 @@
1
+ import type { PrepareExportFrame } from '../FramePreparation';
2
+ export type PostDrawSubscription = (callback: () => void) => () => void;
3
+ export interface FrameSequenceStagingSurface {
4
+ width: number;
5
+ height: number;
6
+ }
7
+ export interface FrameSequenceRenderOptions {
8
+ frameCount: number;
9
+ frameRate: number;
10
+ signal?: AbortSignal;
11
+ prepareFrame?: PrepareExportFrame;
12
+ onFrame(frame: {
13
+ frameIndex: number;
14
+ canvas: HTMLCanvasElement;
15
+ }): Promise<void> | void;
16
+ }
17
+ export interface FrameSequenceDriverLike {
18
+ readonly canvas: HTMLCanvasElement;
19
+ $render(options: FrameSequenceRenderOptions): Promise<void>;
20
+ }
@@ -0,0 +1 @@
1
+ export declare function withAbortableFrameTimeout<T>(promise: Promise<T>, message: string, signal: AbortSignal | undefined, timeoutMs: number): Promise<T>;
@@ -1,6 +1,9 @@
1
1
  export { DataExtractor } from './DataExtractor';
2
2
  export { FileHandler } from './FileHandler';
3
+ export { FilenamePolicy } from './FilenamePolicy';
3
4
  export { getEncodedGlyphValueFromColor, resolveGlyphByEncodedValue } from './CharacterResolver';
4
5
  export { createLayerTargetProvider, getLayerTargetId, getLayerTargetOptions, resolveLayerExportTarget, resolveLayerStackExportTargets, } from './LayerTarget';
5
6
  export type { LayerExportOptions, LayerTargetOption, LayerTargetProvider, ResolvedLayerExportTarget, ResolvedLayerStackExportTarget, } from './LayerTarget';
6
7
  export type { ExportFrameContext, PrepareExportFrame } from './FramePreparation';
8
+ export { ExclusiveCaptureGate, FrameSequenceDriver, FrameSequenceError, createFrameSequenceAbortError, frameTiming, isFrameSequenceAbortError, } from './frame-sequence';
9
+ export type { FrameSequenceDriverLike, FrameSequenceRenderOptions, FrameSequenceStagingSurface, PostDrawSubscription, } from './frame-sequence';
@@ -1,5 +1,5 @@
1
1
  import type { Textmodifier } from 'textmode.js';
2
- import { type PostDrawSubscription } from '../video/VideoFrameDriver';
2
+ import { type PostDrawSubscription } from '../base';
3
3
  import type { GIFExportOptions } from './types';
4
4
  /** Deterministic, bounded-memory GIF exporter. */
5
5
  export declare class GIFExporter {
@@ -1,3 +1,2 @@
1
1
  export { GIFExporter } from './GIFExporter';
2
- export { GIFRecorder } from './GIFRecorder';
3
2
  export type { GIFExportOptions, GIFExportProgress, GIFGenerationOptions, GIFRecordingState } from './types';
@@ -1,21 +1,21 @@
1
1
  import type { PrepareExportFrame } from '../base';
2
2
  export type GIFRecordingState = 'idle' | 'recording' | 'encoding' | 'completed' | 'error';
3
3
  /**
4
- * Progress information emitted during the GIF export process.
4
+ * Progress information emitted while deterministic frames are captured and encoded as an animated GIF.
5
5
  *
6
- * @category Animation export
6
+ * @category GIF export
7
7
  *
8
8
  * @see {@link https://code.textmode.art/api/textmode.export.js/type-aliases/GIFExportProgress | GIFExportProgress API reference}
9
9
  */
10
10
  export type GIFExportProgress = {
11
11
  /**
12
- * Current state of the recording process.
12
+ * Current GIF capture or encoding state.
13
13
  *
14
14
  * @see {@link https://code.textmode.art/api/textmode.export.js/type-aliases/GIFExportProgress#state | GIFExportProgress.state API reference}
15
15
  */
16
16
  state: 'idle' | 'recording' | 'encoding' | 'completed' | 'error';
17
17
  /**
18
- * Number of frames that have been recorded so far.
18
+ * Number of frames captured so far.
19
19
  *
20
20
  * @see {@link https://code.textmode.art/api/textmode.export.js/type-aliases/GIFExportProgress#frameindex | GIFExportProgress.frameIndex API reference}
21
21
  */
@@ -34,9 +34,9 @@ export type GIFExportProgress = {
34
34
  message?: string;
35
35
  };
36
36
  /**
37
- * Options for exporting the textmode content to GIF format.
37
+ * Options for capturing deterministic textmode frames as an animated GIF.
38
38
  *
39
- * @category Animation export
39
+ * @category GIF export
40
40
  *
41
41
  * @see {@link https://code.textmode.art/api/textmode.export.js/type-aliases/GIFExportOptions | GIFExportOptions API reference}
42
42
  */
@@ -103,9 +103,3 @@ export interface GIFGenerationOptions {
103
103
  signal?: AbortSignal;
104
104
  prepareFrame?: PrepareExportFrame;
105
105
  }
106
- export interface GIFFrame {
107
- imageData: ImageData;
108
- width: number;
109
- height: number;
110
- delayMs?: number;
111
- }
@@ -41,7 +41,7 @@ export declare class JSONExporter {
41
41
  * @param options Export options
42
42
  * @returns Structured JSON document for the selected layer or layer stack
43
43
  */
44
- $generateJSONData(textmodifier: Textmodifier, options?: JSONExportOptions): TextmodeDocumentJSON;
44
+ $generateJSONData(textmodifier: Textmodifier, options?: JSONExportOptions, createdAt?: Date): TextmodeDocumentJSON;
45
45
  /**
46
46
  * Generates the serialized JSON string for the selected layer or layer stack.
47
47
  *
@@ -49,7 +49,7 @@ export declare class JSONExporter {
49
49
  * @param options Export options
50
50
  * @returns Serialized JSON string
51
51
  */
52
- $generateJSONString(textmodifier: Textmodifier, options?: JSONExportOptions): string;
52
+ $generateJSONString(textmodifier: Textmodifier, options?: JSONExportOptions, createdAt?: Date): string;
53
53
  /**
54
54
  * Exports the generated JSON to a downloadable file.
55
55
  *
@@ -1,20 +1,3 @@
1
- import type { VideoBitrateMode, VideoCodec, VideoContentHint, VideoEncodingPlan, VideoGenerationOptions } from './types';
2
- export declare const MAX_SAFE_IN_MEMORY_VIDEO_BYTES = 100000000;
3
- export declare const ULTRA_FALLBACK_BITS_PER_PIXEL_PER_FRAME = 0.5;
4
- export type VideoQualityDescriptor = {
5
- kind: 'named';
6
- level: 'medium' | 'high' | 'very-high';
7
- } | {
8
- kind: 'bitrate';
9
- bitrate: number;
10
- bitrateMode: VideoBitrateMode;
11
- } | {
12
- kind: 'ultra';
13
- bitrate: number;
14
- };
15
- export declare function resolveUltraFallbackBitrate(width: number, height: number, frameRate: number): number;
16
- export declare function estimateVideoOutputBytes(bitrate: number, frameCount: number, frameRate: number): number;
17
- export declare function getVideoQualityDescriptor(plan: VideoEncodingPlan): VideoQualityDescriptor;
18
- export declare function normalizeVideoContentHint(value: VideoContentHint | undefined): VideoContentHint;
1
+ import type { VideoCodec, VideoEncodingPlan, VideoGenerationOptions } from './types';
2
+ /** Resolves product-level format constraints independently of encoder probing. */
19
3
  export declare function createVideoEncodingPlan(options: VideoGenerationOptions, codec?: VideoCodec): VideoEncodingPlan;
20
- export declare function assertVideoOutputFitsMemory(plan: VideoEncodingPlan, allowLargeInMemory: boolean): void;
@@ -1,5 +1,5 @@
1
1
  import type { Textmodifier } from 'textmode.js';
2
- import { type PostDrawSubscription } from './VideoFrameDriver';
2
+ import { type PostDrawSubscription } from '../base';
3
3
  import type { VideoExportOptions } from './types';
4
4
  /** Main video exporter for the textmode.js library. */
5
5
  export declare class VideoExporter {
@@ -15,12 +15,10 @@ export declare class VideoExporter {
15
15
  private _applyDefaultOptions;
16
16
  private _positiveInteger;
17
17
  private _positiveNumber;
18
- private _bitrate;
19
- private _bitrateMode;
20
- private _contentHint;
21
- private _latencyMode;
18
+ private _quality;
19
+ private _isBitrateMode;
22
20
  private _hardwareAcceleration;
23
21
  private _keyFrameInterval;
24
22
  private _currentPixelDensity;
25
- private _withExtension;
23
+ private _createFileSystemDestination;
26
24
  }
@@ -2,10 +2,11 @@ import { type StreamTargetChunk } from 'mediabunny';
2
2
  import type { VideoExportProgress, VideoFrameDriverLike, VideoGenerationOptions } from './types';
3
3
  export type VideoOutputDestination = {
4
4
  kind: 'blob';
5
- allowLargeInMemory: boolean;
6
5
  } | {
7
6
  kind: 'stream';
8
7
  writable: WritableStream<StreamTargetChunk>;
8
+ /** Releases a destination selected before encoder probing starts. */
9
+ abort?: (reason?: unknown) => Promise<void>;
9
10
  };
10
11
  /** Records deterministic textmode frames through WebCodecs and muxes them with Mediabunny. */
11
12
  export declare class VideoRecorder {
@@ -7,3 +7,4 @@ export declare class VideoExportError extends Error {
7
7
  export declare function createAbortError(): VideoExportError;
8
8
  export declare function createTimeoutError(message: string, cause?: unknown): VideoExportError;
9
9
  export declare function isAbortError(error: unknown): boolean;
10
+ export declare function normalizeVideoExportError(error: unknown): VideoExportError;
@@ -1,2 +1,2 @@
1
1
  export { VideoExportError } from './errors';
2
- export type { VideoBitrateMode, VideoBitratePreset, VideoContentHint, VideoEncodingPlan, VideoExportErrorCode, VideoExportFormat, VideoExportOptions, VideoExportPhase, VideoFrameDriverLike, VideoHardwareAcceleration, VideoLatencyMode, VideoExportProgress, VideoGenerationOptions, VideoRecordingState, VideoRenderFrameOptions, } from './types';
2
+ export type { VideoBitrateMode, VideoEncodingPlan, VideoExportErrorCode, VideoExportFormat, VideoExportOptions, VideoExportPhase, VideoFrameDriverLike, VideoHardwareAcceleration, VideoQuality, VideoQualityLevel, VideoSaveDestination, VideoExportProgress, VideoGenerationOptions, VideoRecordingState, VideoRenderFrameOptions, } from './types';