textmode.export.js 1.9.0-beta.1 → 1.9.0-beta.2
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.
- package/README.md +4 -0
- package/dist/textmode.document.esm.js +1 -0
- package/dist/textmode.export.esm.js +1 -1
- package/dist/textmode.export.umd.js +1 -1
- package/dist/types/document/constants.d.ts +32 -0
- package/dist/types/document/decode-shapes.d.ts +4 -0
- package/dist/types/document/decode.d.ts +5 -0
- package/dist/types/document/index.d.ts +13 -0
- package/dist/types/document/parse.d.ts +3 -0
- package/dist/types/document/types.d.ts +209 -0
- package/dist/types/document/validation.d.ts +37 -0
- package/dist/types/exporters/base/LayerTarget.d.ts +0 -2
- package/dist/types/exporters/gif/types.d.ts +0 -4
- package/dist/types/exporters/image/types.d.ts +0 -2
- package/dist/types/exporters/json/types.d.ts +14 -204
- package/dist/types/exporters/svg/types.d.ts +1 -3
- package/dist/types/exporters/txt/types.d.ts +0 -2
- package/dist/types/exporters/video/types.d.ts +0 -20
- package/dist/types/exporters/zip/errors.d.ts +0 -1
- package/dist/types/exporters/zip/types.d.ts +0 -7
- package/dist/types/index.d.ts +3 -27
- package/dist/types/types.d.ts +0 -28
- package/package.json +46 -10
- package/protocol/textmode-document/2.0/SPECIFICATION.md +233 -0
- package/protocol/textmode-document/2.0/fixture.d.ts +3 -0
- package/protocol/textmode-document/2.0/fixtures/textmode-document-all-v2.json +94 -0
- package/protocol/textmode-document/2.0/fixtures/textmode-document-create-integration-v2.json +112 -0
- package/protocol/textmode-document/2.0/fixtures/textmode-document-selected-v2.json +86 -0
- package/protocol/textmode-document/2.0/fixtures/textmode-layer-all-v1.1.json +46 -0
- package/protocol/textmode-document/2.0/fixtures/textmode-layer-selected-v1.json +38 -0
- package/protocol/textmode-document/2.0/textmode-document-2.0.schema.d.ts +3 -0
- package/protocol/textmode-document/2.0/textmode-document-2.0.schema.json +171 -0
|
@@ -2,8 +2,6 @@ import type { FrameSequenceDriverLike, FrameSequenceRenderOptions, PrepareExport
|
|
|
2
2
|
/**
|
|
3
3
|
* High-level lifecycle state reported while a video export is captured, encoded, or completed.
|
|
4
4
|
*
|
|
5
|
-
* @category Video export
|
|
6
|
-
*
|
|
7
5
|
* @see {@link https://code.textmode.art/api/textmode.export.js/type-aliases/VideoRecordingState | VideoRecordingState API reference}
|
|
8
6
|
*/
|
|
9
7
|
export type VideoRecordingState = 'idle' | 'recording' | 'encoding' | 'completed' | 'error';
|
|
@@ -14,8 +12,6 @@ export type VideoRecordingState = 'idle' | 'recording' | 'encoding' | 'completed
|
|
|
14
12
|
* for buffered output. `rendering`, `encoding`, and `draining` remain available for compatibility with older progress
|
|
15
13
|
* producers.
|
|
16
14
|
*
|
|
17
|
-
* @category Video export
|
|
18
|
-
*
|
|
19
15
|
* @see {@link https://code.textmode.art/api/textmode.export.js/type-aliases/VideoExportPhase | VideoExportPhase API reference}
|
|
20
16
|
*/
|
|
21
17
|
export type VideoExportPhase = 'probing' | 'rendering' | 'capturing' | 'encoding' | 'draining' | 'writing' | 'finalizing';
|
|
@@ -26,8 +22,6 @@ export type VideoCodec = 'vp8' | 'vp9' | 'avc' | (string & {});
|
|
|
26
22
|
* Higher levels generally preserve more detail and produce larger, content-dependent files. Mediabunny may use
|
|
27
23
|
* quantizer-based encoding or a codec-adjusted bitrate, depending on codec and browser support.
|
|
28
24
|
*
|
|
29
|
-
* @category Video export
|
|
30
|
-
*
|
|
31
25
|
* @see {@link https://code.textmode.art/api/textmode.export.js/type-aliases/VideoQualityLevel | VideoQualityLevel API reference}
|
|
32
26
|
*/
|
|
33
27
|
export type VideoQualityLevel = 'very-low' | 'low' | 'medium' | 'high' | 'very-high';
|
|
@@ -49,8 +43,6 @@ export type VideoQualityLevel = 'very-low' | 'low' | 'medium' | 'high' | 'very-h
|
|
|
49
43
|
* await t.saveVideo({ quality: { bitrate: 8_000_000, bitrateMode: 'constant' } });
|
|
50
44
|
* ```
|
|
51
45
|
*
|
|
52
|
-
* @category Video export
|
|
53
|
-
*
|
|
54
46
|
* @see {@link https://code.textmode.art/api/textmode.export.js/type-aliases/VideoQuality | VideoQuality API reference}
|
|
55
47
|
*/
|
|
56
48
|
export type VideoQuality = VideoQualityLevel | {
|
|
@@ -66,8 +58,6 @@ export type VideoQuality = VideoQualityLevel | {
|
|
|
66
58
|
*
|
|
67
59
|
* This setting does not affect `toVideoBlob()`, which always returns an in-memory `Blob`.
|
|
68
60
|
*
|
|
69
|
-
* @category Video export
|
|
70
|
-
*
|
|
71
61
|
* @see {@link https://code.textmode.art/api/textmode.export.js/type-aliases/VideoSaveDestination | VideoSaveDestination API reference}
|
|
72
62
|
*/
|
|
73
63
|
export type VideoSaveDestination = 'download' | 'file-system';
|
|
@@ -77,8 +67,6 @@ export type VideoSaveDestination = 'download' | 'file-system';
|
|
|
77
67
|
* MP4 uses AVC/H.264 and requires even coded dimensions. WebM selects VP9 when available and falls back to VP8; it
|
|
78
68
|
* is the only format that can be requested with transparency.
|
|
79
69
|
*
|
|
80
|
-
* @category Video export
|
|
81
|
-
*
|
|
82
70
|
* @see {@link https://code.textmode.art/api/textmode.export.js/type-aliases/VideoExportFormat | VideoExportFormat API reference}
|
|
83
71
|
*/
|
|
84
72
|
export type VideoExportFormat = 'webm' | 'mp4';
|
|
@@ -92,8 +80,6 @@ export type VideoExportFormat = 'webm' | 'mp4';
|
|
|
92
80
|
*
|
|
93
81
|
* If omitted for an explicit target bitrate, Mediabunny uses `'variable'`.
|
|
94
82
|
*
|
|
95
|
-
* @category Video export
|
|
96
|
-
*
|
|
97
83
|
* @see {@link https://code.textmode.art/api/textmode.export.js/type-aliases/VideoBitrateMode | VideoBitrateMode API reference}
|
|
98
84
|
*/
|
|
99
85
|
export type VideoBitrateMode = 'variable' | 'constant';
|
|
@@ -106,8 +92,6 @@ export type VideoBitrateMode = 'variable' | 'constant';
|
|
|
106
92
|
* availability and output characteristics vary by device.
|
|
107
93
|
* - `'prefer-software'`: prefer CPU encoding, often more consistent across machines, but usually slower.
|
|
108
94
|
*
|
|
109
|
-
* @category Video export
|
|
110
|
-
*
|
|
111
95
|
* @see {@link https://code.textmode.art/api/textmode.export.js/type-aliases/VideoHardwareAcceleration | VideoHardwareAcceleration API reference}
|
|
112
96
|
*/
|
|
113
97
|
export type VideoHardwareAcceleration = 'no-preference' | 'prefer-hardware' | 'prefer-software';
|
|
@@ -115,8 +99,6 @@ export type VideoExportErrorCode = 'VIDEO_EXPORT_UNSUPPORTED' | 'VIDEO_CODEC_UNS
|
|
|
115
99
|
/**
|
|
116
100
|
* Progress information emitted while a deterministic video is probed, captured, and written.
|
|
117
101
|
*
|
|
118
|
-
* @category Video export
|
|
119
|
-
*
|
|
120
102
|
* @see {@link https://code.textmode.art/api/textmode.export.js/type-aliases/VideoExportProgress | VideoExportProgress API reference}
|
|
121
103
|
*/
|
|
122
104
|
export type VideoExportProgress = {
|
|
@@ -192,8 +174,6 @@ export type VideoExportProgress = {
|
|
|
192
174
|
/**
|
|
193
175
|
* Options for capturing deterministic textmode frames as MP4 or WebM video.
|
|
194
176
|
*
|
|
195
|
-
* @category Video export
|
|
196
|
-
*
|
|
197
177
|
* @see {@link https://code.textmode.art/api/textmode.export.js/type-aliases/VideoExportOptions | VideoExportOptions API reference}
|
|
198
178
|
*/
|
|
199
179
|
export type VideoExportOptions = {
|
|
@@ -2,7 +2,6 @@ import type { ZIPExportErrorCode } from './types';
|
|
|
2
2
|
/**
|
|
3
3
|
* Error raised by ZIP frame-sequence validation, capture, or archive creation.
|
|
4
4
|
*
|
|
5
|
-
* @category ZIP frame-sequence export
|
|
6
5
|
* @see {@link https://code.textmode.art/api/textmode.export.js/classes/ZIPExportError | ZIPExportError API reference}
|
|
7
6
|
*/
|
|
8
7
|
export declare class ZIPExportError extends Error {
|
|
@@ -6,28 +6,24 @@ import type { TXTExportOptions } from '../txt';
|
|
|
6
6
|
/**
|
|
7
7
|
* File format used for every frame in a ZIP frame-sequence export.
|
|
8
8
|
*
|
|
9
|
-
* @category ZIP frame-sequence export
|
|
10
9
|
* @see {@link https://code.textmode.art/api/textmode.export.js/type-aliases/ZIPFrameFormat | ZIPFrameFormat API reference}
|
|
11
10
|
*/
|
|
12
11
|
export type ZIPFrameFormat = 'png' | 'jpg' | 'webp' | 'svg' | 'json' | 'txt';
|
|
13
12
|
/**
|
|
14
13
|
* Lifecycle state reported by a ZIP frame-sequence export.
|
|
15
14
|
*
|
|
16
|
-
* @category ZIP frame-sequence export
|
|
17
15
|
* @see {@link https://code.textmode.art/api/textmode.export.js/type-aliases/ZIPExportState | ZIPExportState API reference}
|
|
18
16
|
*/
|
|
19
17
|
export type ZIPExportState = 'capturing' | 'finalizing' | 'completed' | 'error';
|
|
20
18
|
/**
|
|
21
19
|
* Machine-readable ZIP export failure category.
|
|
22
20
|
*
|
|
23
|
-
* @category ZIP frame-sequence export
|
|
24
21
|
* @see {@link https://code.textmode.art/api/textmode.export.js/type-aliases/ZIPExportErrorCode | ZIPExportErrorCode API reference}
|
|
25
22
|
*/
|
|
26
23
|
export type ZIPExportErrorCode = 'ZIP_EXPORT_INVALID_OPTIONS' | 'ZIP_EXPORT_ENCODING_UNSUPPORTED' | 'ZIP_EXPORT_TOO_LARGE' | 'ZIP_EXPORT_ABORTED' | 'ZIP_EXPORT_TIMEOUT' | 'ZIP_EXPORT_BUSY' | 'ZIP_EXPORT_DISPOSED' | 'ZIP_EXPORT_FAILED';
|
|
27
24
|
/**
|
|
28
25
|
* Progress information emitted while ZIP frames are captured and archived.
|
|
29
26
|
*
|
|
30
|
-
* @category ZIP frame-sequence export
|
|
31
27
|
* @see {@link https://code.textmode.art/api/textmode.export.js/interfaces/ZIPExportProgress | ZIPExportProgress API reference}
|
|
32
28
|
*/
|
|
33
29
|
export interface ZIPExportProgress {
|
|
@@ -65,7 +61,6 @@ export interface ZIPExportProgress {
|
|
|
65
61
|
/**
|
|
66
62
|
* Options shared by all ZIP frame formats.
|
|
67
63
|
*
|
|
68
|
-
* @category ZIP frame-sequence export
|
|
69
64
|
* @see {@link https://code.textmode.art/api/textmode.export.js/interfaces/ZIPCaptureOptions | ZIPCaptureOptions API reference}
|
|
70
65
|
*/
|
|
71
66
|
export interface ZIPCaptureOptions {
|
|
@@ -109,7 +104,6 @@ export interface ZIPCaptureOptions {
|
|
|
109
104
|
/**
|
|
110
105
|
* Format-specific options forwarded to each existing still exporter.
|
|
111
106
|
*
|
|
112
|
-
* @category ZIP frame-sequence export
|
|
113
107
|
* @see {@link https://code.textmode.art/api/textmode.export.js/interfaces/ZIPFrameOptionsMap | ZIPFrameOptionsMap API reference}
|
|
114
108
|
*/
|
|
115
109
|
export interface ZIPFrameOptionsMap {
|
|
@@ -123,7 +117,6 @@ export interface ZIPFrameOptionsMap {
|
|
|
123
117
|
/**
|
|
124
118
|
* Discriminated options for a deterministic ZIP frame-sequence export.
|
|
125
119
|
*
|
|
126
|
-
* @category ZIP frame-sequence export
|
|
127
120
|
* @see {@link https://code.textmode.art/api/textmode.export.js/type-aliases/ZIPExportOptions | ZIPExportOptions API reference}
|
|
128
121
|
*/
|
|
129
122
|
export type ZIPExportOptions = {
|
package/dist/types/index.d.ts
CHANGED
|
@@ -15,30 +15,6 @@
|
|
|
15
15
|
* or use the built-in export overlay. For recipes and format trade-offs, read
|
|
16
16
|
* the [Exporting guide](/docs/exporting).
|
|
17
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
18
|
* @showCategories
|
|
43
19
|
*/
|
|
44
20
|
import type { TextmodePlugin } from 'textmode.js';
|
|
@@ -48,7 +24,9 @@ export type { TextmodeExportAPI, ExportOverlayController } from './types';
|
|
|
48
24
|
export type { ImageExportOptions } from './exporters/image';
|
|
49
25
|
export type { SVGExportOptions } from './exporters/svg';
|
|
50
26
|
export type { TXTExportOptions } from './exporters/txt';
|
|
51
|
-
export
|
|
27
|
+
export { TEXTMODE_DOCUMENT_FORMAT, TEXTMODE_DOCUMENT_FORMAT_VERSION, TEXTMODE_OBJECT_ROWS_ENCODING } from './document';
|
|
28
|
+
export type { JSONExportTarget, TextmodeDocumentJSON, TextmodeDocumentTarget } from './document';
|
|
29
|
+
export type { JSONExportColorMode, JSONExportOptions } from './exporters/json';
|
|
52
30
|
export type { GIFExportOptions, GIFExportProgress } from './exporters/gif';
|
|
53
31
|
export { ZIPExportError } from './exporters/zip';
|
|
54
32
|
export type { ZIPCaptureOptions, ZIPExportErrorCode, ZIPExportOptions, ZIPExportProgress, ZIPExportState, ZIPFrameFormat, ZIPFrameOptionsMap, } from './exporters/zip';
|
|
@@ -57,8 +35,6 @@ export type { LayerExportOptions } from './exporters/base';
|
|
|
57
35
|
/**
|
|
58
36
|
* Default export plugin instance for the standard textmode.js workflow.
|
|
59
37
|
*
|
|
60
|
-
* @category Workflow
|
|
61
|
-
*
|
|
62
38
|
* @see {@link https://code.textmode.art/api/textmode.export.js/variables/ExportPlugin | ExportPlugin API reference}
|
|
63
39
|
*/
|
|
64
40
|
export declare const ExportPlugin: TextmodePlugin;
|
package/dist/types/types.d.ts
CHANGED
|
@@ -8,48 +8,36 @@ import type { ZIPExportOptions } from './exporters/zip';
|
|
|
8
8
|
/**
|
|
9
9
|
* Default TXT export fields controlled by the export overlay.
|
|
10
10
|
*
|
|
11
|
-
* @category Overlay
|
|
12
|
-
*
|
|
13
11
|
* @see {@link https://code.textmode.art/api/textmode.export.js/type-aliases/TXTOverlayDefaults | TXTOverlayDefaults API reference}
|
|
14
12
|
*/
|
|
15
13
|
export type TXTOverlayDefaults = Pick<TXTExportOptions, 'preserveTrailingSpaces' | 'emptyCharacter'>;
|
|
16
14
|
/**
|
|
17
15
|
* Default JSON export fields controlled by the export overlay.
|
|
18
16
|
*
|
|
19
|
-
* @category Overlay
|
|
20
|
-
*
|
|
21
17
|
* @see {@link https://code.textmode.art/api/textmode.export.js/type-aliases/JSONOverlayDefaults | JSONOverlayDefaults API reference}
|
|
22
18
|
*/
|
|
23
19
|
export type JSONOverlayDefaults = Pick<JSONExportOptions, 'target' | 'pretty' | 'includeMetadata' | 'colorMode'>;
|
|
24
20
|
/**
|
|
25
21
|
* Default image export fields controlled by the export overlay.
|
|
26
22
|
*
|
|
27
|
-
* @category Overlay
|
|
28
|
-
*
|
|
29
23
|
* @see {@link https://code.textmode.art/api/textmode.export.js/type-aliases/ImageOverlayDefaults | ImageOverlayDefaults API reference}
|
|
30
24
|
*/
|
|
31
25
|
export type ImageOverlayDefaults = Pick<ImageExportOptions, 'format' | 'scale'>;
|
|
32
26
|
/**
|
|
33
27
|
* Default SVG export fields controlled by the export overlay.
|
|
34
28
|
*
|
|
35
|
-
* @category Overlay
|
|
36
|
-
*
|
|
37
29
|
* @see {@link https://code.textmode.art/api/textmode.export.js/type-aliases/SVGOverlayDefaults | SVGOverlayDefaults API reference}
|
|
38
30
|
*/
|
|
39
31
|
export type SVGOverlayDefaults = Pick<SVGExportOptions, 'includeBackgroundRectangles' | 'drawMode' | 'strokeWidth'>;
|
|
40
32
|
/**
|
|
41
33
|
* Default GIF export fields controlled by the export overlay.
|
|
42
34
|
*
|
|
43
|
-
* @category Overlay
|
|
44
|
-
*
|
|
45
35
|
* @see {@link https://code.textmode.art/api/textmode.export.js/type-aliases/GIFOverlayDefaults | GIFOverlayDefaults API reference}
|
|
46
36
|
*/
|
|
47
37
|
export type GIFOverlayDefaults = Pick<GIFExportOptions, 'frameCount' | 'frameRate' | 'scale' | 'repeat'>;
|
|
48
38
|
/**
|
|
49
39
|
* Default video export fields controlled by the export overlay.
|
|
50
40
|
*
|
|
51
|
-
* @category Overlay
|
|
52
|
-
*
|
|
53
41
|
* @see {@link https://code.textmode.art/api/textmode.export.js/type-aliases/VideoOverlayDefaults | VideoOverlayDefaults API reference}
|
|
54
42
|
*/
|
|
55
43
|
export type VideoOverlayDefaults = Pick<VideoExportOptions, 'format' | 'frameCount' | 'frameRate' | 'quality' | 'hardwareAcceleration' | 'keyFrameInterval' | 'transparent'>;
|
|
@@ -63,8 +51,6 @@ export type VideoOverlayDefaults = Pick<VideoExportOptions, 'format' | 'frameCou
|
|
|
63
51
|
* {@link ExportOverlayController.getDefaults} and
|
|
64
52
|
* {@link ExportOverlayController.setDefaults}.
|
|
65
53
|
*
|
|
66
|
-
* @category Overlay
|
|
67
|
-
*
|
|
68
54
|
* @see {@link https://code.textmode.art/api/textmode.export.js/type-aliases/ExportDefaults | ExportDefaults API reference}
|
|
69
55
|
*/
|
|
70
56
|
export type ExportDefaults = {
|
|
@@ -88,8 +74,6 @@ export type ExportDefaults = {
|
|
|
88
74
|
* format's curated defaults. Top-level `format` changes the overlay's selected
|
|
89
75
|
* format. Omitted keys keep their current value.
|
|
90
76
|
*
|
|
91
|
-
* @category Overlay
|
|
92
|
-
*
|
|
93
77
|
* @example
|
|
94
78
|
* ```ts
|
|
95
79
|
* t.exportOverlay.setDefaults({ format: 'image', image: { scale: 2 }, gif: { frameRate: 30 } });
|
|
@@ -108,8 +92,6 @@ export type ExportDefaultsPatch = {
|
|
|
108
92
|
* `auto` means the overlay is using the library default offset from the
|
|
109
93
|
* textmode canvas. `custom` means the user or runtime API has moved it.
|
|
110
94
|
*
|
|
111
|
-
* @category Overlay
|
|
112
|
-
*
|
|
113
95
|
* @see {@link https://code.textmode.art/api/textmode.export.js/interfaces/ExportOverlayPosition | ExportOverlayPosition API reference}
|
|
114
96
|
*/
|
|
115
97
|
export interface ExportOverlayPosition {
|
|
@@ -120,8 +102,6 @@ export interface ExportOverlayPosition {
|
|
|
120
102
|
/**
|
|
121
103
|
* Canvas-relative placement coordinates for the export overlay UI.
|
|
122
104
|
*
|
|
123
|
-
* @category Overlay
|
|
124
|
-
*
|
|
125
105
|
* @see {@link https://code.textmode.art/api/textmode.export.js/interfaces/ExportOverlayPositionInput | ExportOverlayPositionInput API reference}
|
|
126
106
|
*/
|
|
127
107
|
export interface ExportOverlayPositionInput {
|
|
@@ -131,8 +111,6 @@ export interface ExportOverlayPositionInput {
|
|
|
131
111
|
/**
|
|
132
112
|
* Controller for managing the export overlay UI visibility at runtime.
|
|
133
113
|
*
|
|
134
|
-
* @category Overlay
|
|
135
|
-
*
|
|
136
114
|
* @see {@link https://code.textmode.art/api/textmode.export.js/interfaces/ExportOverlayController | ExportOverlayController API reference}
|
|
137
115
|
*/
|
|
138
116
|
export interface ExportOverlayController {
|
|
@@ -282,8 +260,6 @@ export interface ExportOverlayController {
|
|
|
282
260
|
/**
|
|
283
261
|
* Runtime export helpers that `ExportPlugin` attaches to the `Textmodifier` instance.
|
|
284
262
|
*
|
|
285
|
-
* @category Workflow
|
|
286
|
-
*
|
|
287
263
|
* @example
|
|
288
264
|
* {@includeCode ../examples/ExportPlugin/layerTargets/sketch.js}
|
|
289
265
|
*
|
|
@@ -514,8 +490,6 @@ export interface TextmodeExportAPI {
|
|
|
514
490
|
* @returns A promise that resolves after the archive download is initiated.
|
|
515
491
|
* @throws {Error} When validation, capture, serialization, archive writing, or download fails.
|
|
516
492
|
*
|
|
517
|
-
* @category ZIP frame-sequence export
|
|
518
|
-
*
|
|
519
493
|
* @example
|
|
520
494
|
* ```ts
|
|
521
495
|
* await t.saveZip({
|
|
@@ -540,8 +514,6 @@ export interface TextmodeExportAPI {
|
|
|
540
514
|
* @returns The completed `application/zip` blob.
|
|
541
515
|
* @throws {Error} When validation, capture, serialization, archive writing, or cancellation fails.
|
|
542
516
|
*
|
|
543
|
-
* @category ZIP frame-sequence export
|
|
544
|
-
*
|
|
545
517
|
* @example
|
|
546
518
|
* ```ts
|
|
547
519
|
* const archive = await t.toZipBlob({ format: 'svg', frameCount: 60, frameRate: 24 });
|
package/package.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "textmode.export.js",
|
|
3
|
-
"version": "1.9.0-beta.
|
|
3
|
+
"version": "1.9.0-beta.2",
|
|
4
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": {
|
|
8
8
|
"name": "node",
|
|
9
|
-
"version": "
|
|
9
|
+
"version": ">=24.0.0",
|
|
10
10
|
"onFail": "error"
|
|
11
11
|
},
|
|
12
12
|
"packageManager": {
|
|
@@ -23,6 +23,38 @@
|
|
|
23
23
|
"types": "./dist/types/index.d.ts",
|
|
24
24
|
"import": "./dist/textmode.export.esm.js",
|
|
25
25
|
"require": "./dist/textmode.export.umd.js"
|
|
26
|
+
},
|
|
27
|
+
"./document": {
|
|
28
|
+
"types": "./dist/types/document/index.d.ts",
|
|
29
|
+
"import": "./dist/textmode.document.esm.js"
|
|
30
|
+
},
|
|
31
|
+
"./schema": {
|
|
32
|
+
"types": "./protocol/textmode-document/2.0/textmode-document-2.0.schema.d.ts",
|
|
33
|
+
"default": "./protocol/textmode-document/2.0/textmode-document-2.0.schema.json"
|
|
34
|
+
},
|
|
35
|
+
"./document/schema/2.0": {
|
|
36
|
+
"types": "./protocol/textmode-document/2.0/textmode-document-2.0.schema.d.ts",
|
|
37
|
+
"default": "./protocol/textmode-document/2.0/textmode-document-2.0.schema.json"
|
|
38
|
+
},
|
|
39
|
+
"./document/fixtures/2.0/textmode-document-selected-v2.json": {
|
|
40
|
+
"types": "./protocol/textmode-document/2.0/fixture.d.ts",
|
|
41
|
+
"default": "./protocol/textmode-document/2.0/fixtures/textmode-document-selected-v2.json"
|
|
42
|
+
},
|
|
43
|
+
"./document/fixtures/2.0/textmode-document-all-v2.json": {
|
|
44
|
+
"types": "./protocol/textmode-document/2.0/fixture.d.ts",
|
|
45
|
+
"default": "./protocol/textmode-document/2.0/fixtures/textmode-document-all-v2.json"
|
|
46
|
+
},
|
|
47
|
+
"./document/fixtures/2.0/textmode-document-create-integration-v2.json": {
|
|
48
|
+
"types": "./protocol/textmode-document/2.0/fixture.d.ts",
|
|
49
|
+
"default": "./protocol/textmode-document/2.0/fixtures/textmode-document-create-integration-v2.json"
|
|
50
|
+
},
|
|
51
|
+
"./document/fixtures/2.0/textmode-layer-selected-v1.json": {
|
|
52
|
+
"types": "./protocol/textmode-document/2.0/fixture.d.ts",
|
|
53
|
+
"default": "./protocol/textmode-document/2.0/fixtures/textmode-layer-selected-v1.json"
|
|
54
|
+
},
|
|
55
|
+
"./document/fixtures/2.0/textmode-layer-all-v1.1.json": {
|
|
56
|
+
"types": "./protocol/textmode-document/2.0/fixture.d.ts",
|
|
57
|
+
"default": "./protocol/textmode-document/2.0/fixtures/textmode-layer-all-v1.1.json"
|
|
26
58
|
}
|
|
27
59
|
},
|
|
28
60
|
"sideEffects": [
|
|
@@ -30,15 +62,17 @@
|
|
|
30
62
|
"./dist/textmode.export.umd.js"
|
|
31
63
|
],
|
|
32
64
|
"files": [
|
|
33
|
-
"dist"
|
|
65
|
+
"dist",
|
|
66
|
+
"protocol/textmode-document/2.0"
|
|
34
67
|
],
|
|
35
68
|
"scripts": {
|
|
36
69
|
"prebuild": "npm run clean",
|
|
37
70
|
"clean": "rm -rf dist",
|
|
38
71
|
"dev": "textmode-build dev --port 5174 --host",
|
|
39
72
|
"build:bundle": "textmode-build build",
|
|
73
|
+
"build:document": "vite build --config vite.document.config.ts",
|
|
40
74
|
"build:types": "textmode-types build",
|
|
41
|
-
"build": "npm run build:bundle && npm run build:types",
|
|
75
|
+
"build": "npm run build:bundle && npm run build:document && npm run build:types",
|
|
42
76
|
"check": "npm run format:check && npm run lint && npm run lint:markdown && npm run typecheck && npm run docs:check && npm run test && npm run build && npm run types:verify",
|
|
43
77
|
"docs:links:add": "textmode-docs links add",
|
|
44
78
|
"docs:api:check": "textmode-docs api-check",
|
|
@@ -65,19 +99,21 @@
|
|
|
65
99
|
"dependencies": {
|
|
66
100
|
"fflate": "0.8.3",
|
|
67
101
|
"gifenc": "^1.0.1",
|
|
68
|
-
"mediabunny": "1.
|
|
102
|
+
"mediabunny": "1.56.1"
|
|
69
103
|
},
|
|
70
104
|
"devDependencies": {
|
|
71
|
-
"@textmode/build": "^0.1.
|
|
105
|
+
"@textmode/build": "^0.1.1",
|
|
72
106
|
"@textmode/docs": "^0.3.0",
|
|
73
|
-
"@textmode/lint": "^0.1.
|
|
107
|
+
"@textmode/lint": "^0.1.2",
|
|
74
108
|
"@textmode/release": "^0.2.0",
|
|
75
|
-
"@textmode/tsconfig": "^0.2.
|
|
76
|
-
"@types/node": "^
|
|
109
|
+
"@textmode/tsconfig": "^0.2.2",
|
|
110
|
+
"@types/node": "^26.4.1",
|
|
111
|
+
"ajv": "^8.20.0",
|
|
112
|
+
"ajv-formats": "^3.0.1",
|
|
77
113
|
"textmode.js": "^0.18.0",
|
|
78
114
|
"typescript": "^6.0.3",
|
|
79
115
|
"vite-plugin-css-injected-by-js": "^5.0.2",
|
|
80
|
-
"vitest": "^
|
|
116
|
+
"vitest": "^5.0.0"
|
|
81
117
|
},
|
|
82
118
|
"keywords": [
|
|
83
119
|
"textmode",
|
|
@@ -0,0 +1,233 @@
|
|
|
1
|
+
# Textmode document format 2.0
|
|
2
|
+
|
|
3
|
+
## Status
|
|
4
|
+
|
|
5
|
+
This document defines `textmode.document` version `2.0.0`. The JSON Schema is
|
|
6
|
+
published beside this specification and through the `textmode.export.js/schema`
|
|
7
|
+
and `textmode.export.js/document/schema/2.0` package subpaths. The schema's
|
|
8
|
+
`$id` is a stable identifier, not a hosted download URL. The runtime codec is
|
|
9
|
+
available from the ESM-only `textmode.export.js/document` subpath. The five
|
|
10
|
+
canonical JSON fixtures in this directory are available through subpaths such
|
|
11
|
+
as `textmode.export.js/document/fixtures/2.0/textmode-document-selected-v2.json`.
|
|
12
|
+
Use the JSON import mechanism required by your runtime or bundler.
|
|
13
|
+
|
|
14
|
+
The format represents editable cell data. It does not represent final rendered
|
|
15
|
+
pixels, post-processing, an editor project, or authored animation.
|
|
16
|
+
|
|
17
|
+
## Encoding
|
|
18
|
+
|
|
19
|
+
A textmode document is a UTF-8 JSON object. Producers should follow the I-JSON
|
|
20
|
+
profile in RFC 7493:
|
|
21
|
+
|
|
22
|
+
- object member names are unique;
|
|
23
|
+
- integers remain within the interoperable safe range;
|
|
24
|
+
- non-finite numbers are not emitted;
|
|
25
|
+
- timestamps use an uppercase, timezone-qualified RFC 3339 representation.
|
|
26
|
+
|
|
27
|
+
The media type is `application/json`. `.textmode.json` is a suggested filename
|
|
28
|
+
suffix; existing exporter downloads use `.json` by default. Extensions and
|
|
29
|
+
media types are discovery hints; consumers must route a decoded object using
|
|
30
|
+
its `format` member.
|
|
31
|
+
|
|
32
|
+
## Root discriminator
|
|
33
|
+
|
|
34
|
+
Every v2 document contains:
|
|
35
|
+
|
|
36
|
+
```json
|
|
37
|
+
{
|
|
38
|
+
"format": "textmode.document",
|
|
39
|
+
"formatVersion": "2.0.0",
|
|
40
|
+
"target": "selected"
|
|
41
|
+
}
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
`target` is an on-disk shape discriminator:
|
|
45
|
+
|
|
46
|
+
- `selected` contains one cell snapshot in `layer`;
|
|
47
|
+
- `all` contains a layer stack in `layers`.
|
|
48
|
+
|
|
49
|
+
It is not an instruction to an exporter and must not be extended with temporal
|
|
50
|
+
values such as `animation`. Authored animation requires a distinct document or
|
|
51
|
+
container format.
|
|
52
|
+
|
|
53
|
+
## Version compatibility
|
|
54
|
+
|
|
55
|
+
The version is SemVer-shaped for release communication. Version 2 does not
|
|
56
|
+
define reader negotiation or a formal extension mechanism. Consumers therefore
|
|
57
|
+
accept only explicitly tested versions and migrations; they must not assume an
|
|
58
|
+
unknown `2.x` version is compatible.
|
|
59
|
+
|
|
60
|
+
For a supported version, consumers ignore unknown ordinary object members.
|
|
61
|
+
They reject unknown values of tagged members such as `format`, `target`, and
|
|
62
|
+
`encoding` because those values change interpretation.
|
|
63
|
+
|
|
64
|
+
Version 2 does not define `extensionsUsed`, `extensionsRequired`, extension
|
|
65
|
+
namespacing, or an extension registry. A later revision must define those
|
|
66
|
+
rules before claiming extension compatibility.
|
|
67
|
+
|
|
68
|
+
## Selected cell snapshot
|
|
69
|
+
|
|
70
|
+
The `selected` shape contains:
|
|
71
|
+
|
|
72
|
+
- legacy grid pixel extent in `canvas`;
|
|
73
|
+
- logical grid dimensions and cell metrics in `grid`;
|
|
74
|
+
- an informational source ID and complete cell rows in `layer`.
|
|
75
|
+
|
|
76
|
+
This shape is a cell snapshot, not a lossless layer document. It does not carry
|
|
77
|
+
visibility, opacity, blend mode, offsets, layer rotation, or font identity.
|
|
78
|
+
|
|
79
|
+
## Layer stack
|
|
80
|
+
|
|
81
|
+
The `all` shape contains one or more layers. Each layer includes:
|
|
82
|
+
|
|
83
|
+
- informational ID;
|
|
84
|
+
- visibility and opacity;
|
|
85
|
+
- blend mode name;
|
|
86
|
+
- x/y offsets and z rotation;
|
|
87
|
+
- logical grid and cell metrics;
|
|
88
|
+
- complete cell rows.
|
|
89
|
+
|
|
90
|
+
The order of `layers` is the stack order emitted by the producer.
|
|
91
|
+
|
|
92
|
+
## Canvas field
|
|
93
|
+
|
|
94
|
+
The v2 field named `canvas` is the grid pixel extent, not necessarily the HTML
|
|
95
|
+
canvas or final output surface. Its values obey:
|
|
96
|
+
|
|
97
|
+
```text
|
|
98
|
+
canvas.width = grid.cols × grid.cellWidth
|
|
99
|
+
canvas.height = grid.rows × grid.cellHeight
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
For an `all` document, the root extent is derived from the first layer's grid.
|
|
103
|
+
Consumers must not infer composite placement or clipping from this field.
|
|
104
|
+
|
|
105
|
+
A future major format may replace this legacy name with `gridPixelSize`; v2
|
|
106
|
+
semantics must not be changed in place.
|
|
107
|
+
|
|
108
|
+
## Cell encoding
|
|
109
|
+
|
|
110
|
+
Version 2 defines one encoding:
|
|
111
|
+
|
|
112
|
+
```json
|
|
113
|
+
{
|
|
114
|
+
"encoding": "object-rows-v1",
|
|
115
|
+
"rows": []
|
|
116
|
+
}
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
The encoding is dense and row-major:
|
|
120
|
+
|
|
121
|
+
- `rows.length` equals `grid.rows`;
|
|
122
|
+
- every row length equals `grid.cols`;
|
|
123
|
+
- a cell's `x` equals its array index within the row;
|
|
124
|
+
- a cell's `y` equals the row index;
|
|
125
|
+
- every grid coordinate is present, including transparent cells.
|
|
126
|
+
|
|
127
|
+
Consumers reject coordinate disagreement rather than silently repairing or
|
|
128
|
+
reordering cells.
|
|
129
|
+
|
|
130
|
+
## Glyph identity
|
|
131
|
+
|
|
132
|
+
`character` contains a non-empty, bounded, well-formed Unicode glyph string.
|
|
133
|
+
Vector fonts commonly use one Unicode scalar, while tileset maps may use an
|
|
134
|
+
extended grapheme cluster containing combining marks, variation selectors, or
|
|
135
|
+
zero-width joiners. Unpaired surrogates are invalid. The default codec budget
|
|
136
|
+
is 64 Unicode scalar values per glyph string.
|
|
137
|
+
|
|
138
|
+
No Unicode normalization is implied. Consumers preserve the string exactly and
|
|
139
|
+
apply product-specific representability rules after protocol decoding.
|
|
140
|
+
|
|
141
|
+
## Colors
|
|
142
|
+
|
|
143
|
+
Foreground and background colors use either:
|
|
144
|
+
|
|
145
|
+
- `#RRGGBB`, whose alpha is implicitly 255;
|
|
146
|
+
- `#RRGGBBAA`;
|
|
147
|
+
- `{ "r": 0, "g": 0, "b": 0, "a": 255 }` with integer channels from
|
|
148
|
+
0 through 255.
|
|
149
|
+
|
|
150
|
+
The canonical decoder normalizes colors to RGBA channel objects.
|
|
151
|
+
|
|
152
|
+
A cell is visually empty only when both foreground and background alpha are
|
|
153
|
+
zero. A space with a visible background remains meaningful cell data.
|
|
154
|
+
|
|
155
|
+
## Transforms
|
|
156
|
+
|
|
157
|
+
Every cell contains:
|
|
158
|
+
|
|
159
|
+
- `invert`: boolean;
|
|
160
|
+
- `flipX`: boolean;
|
|
161
|
+
- `flipY`: boolean;
|
|
162
|
+
- `rotation`: finite degrees.
|
|
163
|
+
|
|
164
|
+
The canonical decoder normalizes rotation into `[0, 360)`. It therefore
|
|
165
|
+
normalizes both `360` and `-360` to `0` and `-90` to `270`.
|
|
166
|
+
|
|
167
|
+
Consumers must reject unsupported meaningful transforms instead of
|
|
168
|
+
approximating them. In particular, swapping foreground and background is not a
|
|
169
|
+
general replacement for inversion when alpha is present.
|
|
170
|
+
|
|
171
|
+
## Metadata
|
|
172
|
+
|
|
173
|
+
Metadata is optional and informational:
|
|
174
|
+
|
|
175
|
+
```json
|
|
176
|
+
{
|
|
177
|
+
"createdAt": "2026-08-28T12:00:00.000Z",
|
|
178
|
+
"generator": {
|
|
179
|
+
"name": "textmode.export.js",
|
|
180
|
+
"version": "1.8.1"
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
`generator.name` identifies the producer and is not restricted to
|
|
186
|
+
`textmode.export.js`. If metadata is present, `createdAt` must be a real
|
|
187
|
+
calendar date and time in the uppercase, timezone-qualified RFC 3339 profile:
|
|
188
|
+
seconds are required, fractional seconds are optional, and leap seconds are
|
|
189
|
+
not supported in version 2. The decoder preserves valid timestamps as written.
|
|
190
|
+
|
|
191
|
+
Consumers must not use metadata to select executable behavior, fetch resources,
|
|
192
|
+
or bypass document validation.
|
|
193
|
+
|
|
194
|
+
## Safety limits
|
|
195
|
+
|
|
196
|
+
The shared codec enforces structural safety limits and accepts caller-supplied
|
|
197
|
+
budgets. Product-specific policy belongs to the product. For example,
|
|
198
|
+
`create.textmode.art` may accept fewer cells than another document consumer.
|
|
199
|
+
|
|
200
|
+
Consumers should:
|
|
201
|
+
|
|
202
|
+
- check file bytes before reading;
|
|
203
|
+
- cap total layers and total decoded cells;
|
|
204
|
+
- use checked multiplication for grid dimensions;
|
|
205
|
+
- bound identifiers and metadata strings;
|
|
206
|
+
- parse large files away from latency-sensitive UI work;
|
|
207
|
+
- abort work when the owning import session is cancelled.
|
|
208
|
+
|
|
209
|
+
Documents never authorize URL fetching, font installation, or code execution.
|
|
210
|
+
|
|
211
|
+
## Legacy migration
|
|
212
|
+
|
|
213
|
+
The compatibility decoder recognizes:
|
|
214
|
+
|
|
215
|
+
- `textmode.layer@1.0.0` as a selected cell snapshot;
|
|
216
|
+
- `textmode.layer@1.1.0` as a layer stack.
|
|
217
|
+
|
|
218
|
+
Both migrate to the canonical v2 union and return a migration warning. Callers
|
|
219
|
+
may disable legacy decoding.
|
|
220
|
+
|
|
221
|
+
## JSON Schema and runtime decoder
|
|
222
|
+
|
|
223
|
+
The JSON Schema describes the portable structure and is suitable for
|
|
224
|
+
documentation and general tooling. The runtime decoder remains authoritative
|
|
225
|
+
for:
|
|
226
|
+
|
|
227
|
+
- cross-field row and grid invariants;
|
|
228
|
+
- grid pixel extent equality;
|
|
229
|
+
- total resource budgets;
|
|
230
|
+
- well-formed and bounded glyph-string validation;
|
|
231
|
+
- rotation and color normalization;
|
|
232
|
+
- legacy migration;
|
|
233
|
+
- stable error codes and JSON paths.
|