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
@@ -5,15 +5,41 @@
5
5
  *
6
6
  * ## Choose an output
7
7
  *
8
- * Use **canvas capture** for the exact image on screen: PNG, JPEG, WebP, GIF,
9
- * or video preserve compositing, filters, shaders, and post-processing. Use
10
- * **layer data export** when the artwork should stay editable or machine
11
- * readable: TXT, SVG, and JSON read from the selected layer, while JSON can
12
- * also describe the full layer stack.
8
+ * Use **canvas capture** for the rendered image on screen: PNG, JPEG, WebP,
9
+ * GIF, and video preserve compositing, filters, shaders, and post-processing.
10
+ * Use **layer data export** when the artwork should stay editable or machine
11
+ * readable: TXT and SVG read from the selected layer, while JSON can describe
12
+ * either the selected layer or the full layer stack.
13
13
  *
14
14
  * Start with {@link ExportPlugin}, then call the helpers added to your sketch
15
15
  * or use the built-in export overlay. For recipes and format trade-offs, read
16
16
  * the [Exporting guide](/docs/exporting).
17
+ *
18
+ * @categoryDescription Workflow
19
+ * Install the plugin and use the export helpers added to a textmode.js sketch.
20
+ *
21
+ * @categoryDescription Canvas capture
22
+ * Export a still image from the rendered canvas.
23
+ *
24
+ * @categoryDescription GIF export
25
+ * Capture deterministic frames and encode an animated GIF.
26
+ *
27
+ * @categoryDescription Video export
28
+ * Capture deterministic frames and encode MP4 or WebM video with Mediabunny.
29
+ *
30
+ * @categoryDescription ZIP frame-sequence export
31
+ * Capture deterministic PNG, JPEG, WebP, SVG, JSON, or TXT frames in a code-only ZIP archive.
32
+ *
33
+ * @categoryDescription Layer data export
34
+ * Export selected-layer text or vector data as TXT or SVG.
35
+ *
36
+ * @categoryDescription JSON document data
37
+ * Export selected-layer or full-stack document data as JSON.
38
+ *
39
+ * @categoryDescription Overlay
40
+ * Configure and control the built-in export overlay.
41
+ *
42
+ * @showCategories
17
43
  */
18
44
  import type { TextmodePlugin } from 'textmode.js';
19
45
  import './augmentations';
@@ -24,7 +50,9 @@ export type { SVGExportOptions } from './exporters/svg';
24
50
  export type { TXTExportOptions } from './exporters/txt';
25
51
  export type { JSONExportColorMode, JSONExportOptions, JSONExportTarget, TextmodeDocumentJSON } from './exporters/json';
26
52
  export type { GIFExportOptions, GIFExportProgress } from './exporters/gif';
27
- export type { VideoBitrateMode, VideoBitratePreset, VideoContentHint, VideoExportFormat, VideoExportOptions, VideoExportPhase, VideoExportProgress, VideoHardwareAcceleration, VideoLatencyMode, VideoRecordingState, } from './exporters/video';
53
+ export { ZIPExportError } from './exporters/zip';
54
+ export type { ZIPCaptureOptions, ZIPExportErrorCode, ZIPExportOptions, ZIPExportProgress, ZIPExportState, ZIPFrameFormat, ZIPFrameOptionsMap, } from './exporters/zip';
55
+ export type { VideoBitrateMode, VideoExportFormat, VideoExportOptions, VideoExportPhase, VideoExportProgress, VideoHardwareAcceleration, VideoQuality, VideoQualityLevel, VideoSaveDestination, VideoRecordingState, } from './exporters/video';
28
56
  export type { LayerExportOptions } from './exporters/base';
29
57
  /**
30
58
  * Default export plugin instance for the standard textmode.js workflow.
@@ -3,11 +3,9 @@ import type { BladeConfig } from './Blade';
3
3
  import { Blade } from './Blade';
4
4
  export declare class VideoBlade extends Blade<VideoExportOptions> {
5
5
  private formatSelect;
6
- private bitrateSelect;
6
+ private qualitySelect;
7
7
  private frameRateInput;
8
8
  private frameCountInput;
9
- private bitrateModeSelect;
10
- private latencyModeSelect;
11
9
  private hardwareAccelerationSelect;
12
10
  private keyFrameIntervalInput;
13
11
  private transparencyInput;
@@ -27,13 +25,12 @@ export declare class VideoBlade extends Blade<VideoExportOptions> {
27
25
  private syncStatus;
28
26
  private resolvePlannedFrameCount;
29
27
  private applyDefaults;
30
- private resolveBitratePreset;
31
- private readonly handleBitrateChange;
28
+ private resolveQuality;
29
+ private readonly handleQualityChange;
32
30
  private readonly handleEstimateChange;
33
31
  private syncReadyStatus;
34
32
  private readonly handleFormatChange;
35
33
  private syncOutputEstimate;
36
- private formatBytes;
37
34
  protected _onUnmount(): void;
38
35
  private syncTransparencyAvailability;
39
36
  }
@@ -2,7 +2,7 @@ import type { ImageExportOptions } from '../exporters/image';
2
2
  import type { TXTExportOptions } from '../exporters/txt';
3
3
  import type { SVGExportOptions } from '../exporters/svg';
4
4
  import type { GIFExportOptions } from '../exporters/gif';
5
- import type { VideoBitratePreset, VideoExportOptions } from '../exporters/video';
5
+ import type { VideoExportOptions } from '../exporters/video';
6
6
  import type { JSONExportOptions } from '../exporters/json';
7
7
  export type ExportFormat = 'txt' | 'json' | 'image' | 'gif' | 'video' | 'svg';
8
8
  export type ExportOptionsMap = {
@@ -18,9 +18,7 @@ export type JSONOverlayDefaults = Pick<JSONExportOptions, 'target' | 'pretty' |
18
18
  export type ImageOverlayDefaults = Pick<ImageExportOptions, 'format' | 'scale'>;
19
19
  export type SVGOverlayDefaults = Pick<SVGExportOptions, 'includeBackgroundRectangles' | 'drawMode' | 'strokeWidth'>;
20
20
  export type GIFOverlayDefaults = Pick<GIFExportOptions, 'frameCount' | 'frameRate' | 'scale' | 'repeat'>;
21
- export type VideoOverlayDefaults = Pick<VideoExportOptions, 'format' | 'frameCount' | 'frameRate' | 'bitrateMode' | 'latencyMode' | 'hardwareAcceleration' | 'keyFrameInterval' | 'transparent'> & {
22
- bitrate?: VideoBitratePreset;
23
- };
21
+ export type VideoOverlayDefaults = Pick<VideoExportOptions, 'format' | 'frameCount' | 'frameRate' | 'quality' | 'hardwareAcceleration' | 'keyFrameInterval' | 'transparent'>;
24
22
  /**
25
23
  * Curated default options for every export format.
26
24
  *
@@ -12,6 +12,7 @@ export declare class TextmodeExportController {
12
12
  readonly api: TextmodeExportAPI;
13
13
  private readonly _registerPostDrawHook;
14
14
  private readonly _activeOperations;
15
+ private readonly _captureGate;
15
16
  private readonly _overlayController;
16
17
  private readonly _stopOverlayRefresh;
17
18
  private _disposed;
@@ -19,6 +20,8 @@ export declare class TextmodeExportController {
19
20
  dispose(): void;
20
21
  private _createOverlayAPI;
21
22
  private _runOperation;
23
+ private _runCaptureOperation;
24
+ private _emitZIPGateError;
22
25
  private _assertLive;
23
26
  }
24
27
  export {};
@@ -2,8 +2,9 @@ import type { ImageExportOptions } from './exporters/image';
2
2
  import type { TXTExportOptions } from './exporters/txt';
3
3
  import type { SVGExportOptions } from './exporters/svg';
4
4
  import type { GIFExportOptions } from './exporters/gif';
5
- import type { VideoBitratePreset, VideoExportOptions } from './exporters/video';
5
+ import type { VideoExportOptions } from './exporters/video';
6
6
  import type { JSONExportOptions, TextmodeDocumentJSON } from './exporters/json';
7
+ import type { ZIPExportOptions } from './exporters/zip';
7
8
  /**
8
9
  * Default TXT export fields controlled by the export overlay.
9
10
  *
@@ -51,9 +52,7 @@ export type GIFOverlayDefaults = Pick<GIFExportOptions, 'frameCount' | 'frameRat
51
52
  *
52
53
  * @see {@link https://code.textmode.art/api/textmode.export.js/type-aliases/VideoOverlayDefaults | VideoOverlayDefaults API reference}
53
54
  */
54
- export type VideoOverlayDefaults = Pick<VideoExportOptions, 'format' | 'frameCount' | 'frameRate' | 'bitrateMode' | 'latencyMode' | 'hardwareAcceleration' | 'keyFrameInterval' | 'transparent'> & {
55
- bitrate?: VideoBitratePreset;
56
- };
55
+ export type VideoOverlayDefaults = Pick<VideoExportOptions, 'format' | 'frameCount' | 'frameRate' | 'quality' | 'hardwareAcceleration' | 'keyFrameInterval' | 'transparent'>;
57
56
  /**
58
57
  * Per-format default options used to seed the overlay UI inputs at mount time
59
58
  * and after a {@link ExportOverlayController.resetDefaults} call.
@@ -463,15 +462,29 @@ export interface TextmodeExportAPI {
463
462
  *
464
463
  * @example
465
464
  * ```ts
466
- * await t.saveVideo({ frameCount: 240, frameRate: 60, filename: 'capture' });
465
+ * // Mediabunny's qualitative quality levels produce content-dependent file sizes.
467
466
  * await t.saveVideo({
468
467
  * format: 'webm',
469
- * bitrate: 'high',
470
- * bitrateMode: 'variable',
471
- * latencyMode: 'quality',
472
- * keyFrameInterval: 2,
468
+ * quality: 'very-high',
469
+ * frameCount: 240,
470
+ * frameRate: 60,
471
+ * filename: 'high-quality-capture',
472
+ * });
473
+ *
474
+ * // Request a target bitrate and rate-control mode.
475
+ * await t.saveVideo({
476
+ * quality: { bitrate: 8_000_000, bitrateMode: 'variable' },
477
+ * frameCount: 240,
478
+ * frameRate: 60,
479
+ * filename: 'target-bitrate-capture',
480
+ * });
481
+ *
482
+ * // Stream directly to a user-selected file when the browser supports it.
483
+ * await t.saveVideo({
484
+ * destination: 'file-system',
485
+ * quality: 'high',
473
486
  * frameCount: 240,
474
- * filename: 'capture',
487
+ * frameRate: 60,
475
488
  * });
476
489
  * ```
477
490
  *
@@ -479,7 +492,9 @@ export interface TextmodeExportAPI {
479
492
  */
480
493
  saveVideo(options?: VideoExportOptions): Promise<void>;
481
494
  /**
482
- * Generates a video blob without downloading it.
495
+ * Generates an in-memory video blob without downloading it.
496
+ *
497
+ * `destination` is only used by {@link saveVideo}; this method always buffers and returns a `Blob`.
483
498
  *
484
499
  * @example
485
500
  * ```ts
@@ -489,4 +504,50 @@ export interface TextmodeExportAPI {
489
504
  * @see {@link https://code.textmode.art/api/textmode.export.js/interfaces/TextmodeExportAPI#tovideoblob | TextmodeExportAPI.toVideoBlob API reference}
490
505
  */
491
506
  toVideoBlob(options?: VideoExportOptions): Promise<Blob>;
507
+ /**
508
+ * Captures and downloads a deterministic frame sequence as a ZIP archive.
509
+ *
510
+ * The archive contains a versioned manifest followed by one-based, zero-padded frame files. ZIP export is available
511
+ * through code only and does not appear in the export overlay.
512
+ *
513
+ * @param options Required archive format, deterministic capture controls, and per-frame exporter options.
514
+ * @returns A promise that resolves after the archive download is initiated.
515
+ * @throws {Error} When validation, capture, serialization, archive writing, or download fails.
516
+ *
517
+ * @category ZIP frame-sequence export
518
+ *
519
+ * @example
520
+ * ```ts
521
+ * await t.saveZip({
522
+ * format: 'png',
523
+ * filename: 'orbit-frames',
524
+ * frameCount: 120,
525
+ * frameRate: 30,
526
+ * frameOptions: { scale: 2 },
527
+ * });
528
+ * ```
529
+ *
530
+ * @see {@link https://code.textmode.art/api/textmode.export.js/interfaces/TextmodeExportAPI#savezip | TextmodeExportAPI.saveZip API reference}
531
+ */
532
+ saveZip(options: ZIPExportOptions): Promise<void>;
533
+ /**
534
+ * Captures a deterministic frame sequence as an in-memory ZIP archive without downloading it.
535
+ *
536
+ * Peak memory includes the completed ZIP because this method returns a `Blob`; individual uncompressed frame
537
+ * payloads are serialized and released sequentially.
538
+ *
539
+ * @param options Required archive format, deterministic capture controls, and per-frame exporter options.
540
+ * @returns The completed `application/zip` blob.
541
+ * @throws {Error} When validation, capture, serialization, archive writing, or cancellation fails.
542
+ *
543
+ * @category ZIP frame-sequence export
544
+ *
545
+ * @example
546
+ * ```ts
547
+ * const archive = await t.toZipBlob({ format: 'svg', frameCount: 60, frameRate: 24 });
548
+ * ```
549
+ *
550
+ * @see {@link https://code.textmode.art/api/textmode.export.js/interfaces/TextmodeExportAPI#tozipblob | TextmodeExportAPI.toZipBlob API reference}
551
+ */
552
+ toZipBlob(options: ZIPExportOptions): Promise<Blob>;
492
553
  }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "textmode.export.js",
3
- "version": "1.8.0",
4
- "description": "Export plugin for textmode.js - Save your creations as images, GIFs, videos, SVG, JSON, and plain text.",
3
+ "version": "1.9.0-beta.1",
4
+ "description": "Export plugin for textmode.js - Save images, GIFs, videos, SVG, JSON, text, and ZIP frame sequences.",
5
5
  "type": "module",
6
6
  "devEngines": {
7
7
  "runtime": {
@@ -63,8 +63,9 @@
63
63
  "textmode.js": "^0.18.0"
64
64
  },
65
65
  "dependencies": {
66
+ "fflate": "0.8.3",
66
67
  "gifenc": "^1.0.1",
67
- "mediabunny": "^1.52.3"
68
+ "mediabunny": "1.55.2"
68
69
  },
69
70
  "devDependencies": {
70
71
  "@textmode/build": "^0.1.0",
@@ -94,6 +95,8 @@
94
95
  "png",
95
96
  "jpg",
96
97
  "webp",
98
+ "zip",
99
+ "frame-sequence",
97
100
  "creative-coding",
98
101
  "canvas"
99
102
  ],
@@ -1,23 +0,0 @@
1
- import type { PostDrawSubscription } from '../video/VideoFrameDriver';
2
- import type { GIFExportProgress, GIFFrame, GIFGenerationOptions } from './types';
3
- /**
4
- * Records frames from a canvas for GIF generation.
5
- * Captures frames at specified intervals using textmode.js post-draw hooks.
6
- */
7
- export declare class GIFRecorder {
8
- /** Reusable canvas for frame scaling */
9
- private _canvas?;
10
- /** Reusable 2D context for frame scaling */
11
- private _ctx?;
12
- /**
13
- * Records a sequence of frames from the provided canvas.
14
- *
15
- * @param canvas - Source canvas to capture frames from
16
- * @param options - Frame generation options (rate, count, scale)
17
- * @param registerPostDrawHook - Hook registration function from textmode.js API
18
- * @param onProgress - Optional callback for recording progress updates
19
- * @returns Promise resolving to array of captured frames
20
- * @throws {Error} If frame capture fails
21
- */
22
- $record(canvas: HTMLCanvasElement, options: GIFGenerationOptions, registerPostDrawHook: PostDrawSubscription, onProgress?: (progress: GIFExportProgress) => void): Promise<GIFFrame[]>;
23
- }