@enslo/sd-metadata 2.1.0 โ†’ 2.2.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.
package/docs/types.md ADDED
@@ -0,0 +1,799 @@
1
+ # Type Documentation
2
+
3
+ ๐ŸŒ **[ๆ—ฅๆœฌ่ชž็‰ˆใฏใ“ใกใ‚‰](./types.ja.md)**
4
+
5
+ Complete type reference for `@enslo/sd-metadata`.
6
+
7
+ ## Table of Contents
8
+
9
+ - [Core Types](#core-types)
10
+ - [`ParseResult`](#parseresult)
11
+ - [`BaseMetadata`](#basemetadata)
12
+ - [`GenerationMetadata`](#generationmetadata)
13
+ - [`GenerationSoftware`](#generationsoftware)
14
+ - [`EmbedMetadata`](#embedmetadata)
15
+ - [`RawMetadata`](#rawmetadata)
16
+ - [`WriteResult`](#writeresult)
17
+ - [Metadata Types](#metadata-types)
18
+ - [`StandardMetadata`](#standardmetadata)
19
+ - [`NovelAIMetadata`](#novelaimetadata)
20
+ - [`ComfyUIMetadata`](#comfyuimetadata)
21
+ - [Settings Types](#settings-types)
22
+ - [`ModelSettings`](#modelsettings)
23
+ - [`SamplingSettings`](#samplingsettings)
24
+ - [`HiresSettings`](#hiressettings)
25
+ - [`UpscaleSettings`](#upscalesettings)
26
+ - [`CharacterPrompt`](#characterprompt)
27
+ - [ComfyUI Types](#comfyui-types)
28
+ - [`ComfyNodeGraph`](#comfynodegraph)
29
+ - [`ComfyNode`](#comfynode)
30
+ - [`ComfyNodeInputValue`](#comfynodeinputvalue)
31
+ - [`ComfyNodeReference`](#comfynodereference)
32
+ - [Format-Specific Types](#format-specific-types)
33
+ - [`PngTextChunk`](#pngtextchunk)
34
+ - [`TExtChunk`](#textchunk)
35
+ - [`ITXtChunk`](#itxtchunk)
36
+ - [`MetadataSegment`](#metadatasegment)
37
+ - [`MetadataSegmentSource`](#metadatasegmentsource)
38
+
39
+ ---
40
+
41
+ ## Core Types
42
+
43
+ ### `ParseResult`
44
+
45
+ The result type returned by the `read()` function.
46
+
47
+ ```typescript
48
+ type ParseResult =
49
+ | { status: 'success'; metadata: GenerationMetadata; raw: RawMetadata }
50
+ | { status: 'unrecognized'; raw: RawMetadata }
51
+ | { status: 'empty' }
52
+ | { status: 'invalid'; message?: string };
53
+ ```
54
+
55
+ **Status Values:**
56
+
57
+ - **`success`**: Metadata was successfully parsed
58
+ - `metadata`: Unified metadata object
59
+ - `raw`: Original format-specific data for round-trip conversion
60
+ - **`unrecognized`**: Image has metadata but format is not recognized
61
+ - `raw`: Original metadata is preserved
62
+ - **`empty`**: No metadata found in the image
63
+ - **`invalid`**: Corrupted or unsupported image format
64
+ - `message`: Optional error description
65
+
66
+ **Example:**
67
+
68
+ ```typescript
69
+ import { read } from '@enslo/sd-metadata';
70
+
71
+ const result = read(imageData);
72
+
73
+ switch (result.status) {
74
+ case 'success':
75
+ console.log(`Generated by ${result.metadata.software}`);
76
+ console.log(`Prompt: ${result.metadata.prompt}`);
77
+ break;
78
+
79
+ case 'unrecognized':
80
+ console.log('Unknown metadata format');
81
+ break;
82
+
83
+ case 'empty':
84
+ console.log('No metadata');
85
+ break;
86
+
87
+ case 'invalid':
88
+ console.error(`Invalid image: ${result.message}`);
89
+ break;
90
+ }
91
+ ```
92
+
93
+ ---
94
+
95
+ ### `BaseMetadata`
96
+
97
+ Common fields shared by all metadata types. This is the foundation for both `GenerationMetadata` variants and `EmbedMetadata`.
98
+
99
+ ```typescript
100
+ export interface BaseMetadata {
101
+ /** Positive prompt */
102
+ prompt: string;
103
+ /** Negative prompt */
104
+ negativePrompt: string;
105
+ /** Image width in pixels */
106
+ width: number;
107
+ /** Image height in pixels */
108
+ height: number;
109
+ /** Model settings */
110
+ model?: ModelSettings;
111
+ /** Sampling settings */
112
+ sampling?: SamplingSettings;
113
+ /** Hires.fix settings (if applied) */
114
+ hires?: HiresSettings;
115
+ /** Upscale settings (if applied) */
116
+ upscale?: UpscaleSettings;
117
+ }
118
+ ```
119
+
120
+ **Example:**
121
+
122
+ ```typescript
123
+ import type { BaseMetadata } from '@enslo/sd-metadata';
124
+
125
+ // Use BaseMetadata when you only need common generation fields
126
+ function displayMetadata(meta: BaseMetadata) {
127
+ console.log('Prompt:', meta.prompt);
128
+ console.log('Size:', meta.width, 'x', meta.height);
129
+ console.log('Model:', meta.model?.name);
130
+ }
131
+ ```
132
+
133
+ ---
134
+
135
+ ### `GenerationMetadata`
136
+
137
+ Unified metadata structure. Discriminated union of all supported metadata types. All variants extend `BaseMetadata`.
138
+
139
+ ```typescript
140
+ type GenerationMetadata =
141
+ | NovelAIMetadata
142
+ | ComfyUIMetadata
143
+ | StandardMetadata;
144
+ ```
145
+
146
+ **Metadata Type Mapping:**
147
+
148
+ | Metadata Type | `software` values |
149
+ | ------------- | ----------------- |
150
+ | `StandardMetadata` | `'sd-webui'` \| `'sd-next'` \| `'forge'` \| `'forge-classic'` \| `'forge-neo'` \| `'reforge'` \| `'easy-reforge'` \| `'invokeai'` \| `'civitai'` \| `'hf-space'` \| `'easydiffusion'` \| `'fooocus'` \| `'ruined-fooocus'` \| `'draw-things'` |
151
+ | `NovelAIMetadata` | `'novelai'` |
152
+ | `ComfyUIMetadata` | `'comfyui'` \| `'tensorart'` \| `'stability-matrix'` \| `'swarmui'` |
153
+
154
+ **Type narrowing example:**
155
+
156
+ ```typescript
157
+ if (metadata.software === 'novelai') {
158
+ // TypeScript knows metadata is NovelAIMetadata
159
+ console.log(metadata.characterPrompts);
160
+ }
161
+
162
+ if (metadata.software === 'comfyui' ||
163
+ metadata.software === 'tensorart' ||
164
+ metadata.software === 'stability-matrix' ||
165
+ metadata.software === 'swarmui') {
166
+ // TypeScript knows metadata is ComfyUIMetadata
167
+ if (metadata.nodes) {
168
+ console.log('Has workflow:', Object.keys(metadata.nodes).length);
169
+ }
170
+ }
171
+ ```
172
+
173
+ ---
174
+
175
+ ### `GenerationSoftware`
176
+
177
+ String literal union of all supported software identifiers. Used as the discriminator for `GenerationMetadata` and as the key type for `softwareLabels`.
178
+
179
+ ```typescript
180
+ type GenerationSoftware =
181
+ | 'novelai'
182
+ | 'comfyui'
183
+ | 'swarmui'
184
+ | 'tensorart'
185
+ | 'stability-matrix'
186
+ | 'invokeai'
187
+ | 'sd-webui'
188
+ | 'forge'
189
+ | 'forge-classic'
190
+ | 'forge-neo'
191
+ | 'reforge'
192
+ | 'easy-reforge'
193
+ | 'sd-next'
194
+ | 'civitai'
195
+ | 'hf-space'
196
+ | 'easydiffusion'
197
+ | 'fooocus'
198
+ | 'ruined-fooocus'
199
+ | 'draw-things';
200
+ ```
201
+
202
+ **Example:**
203
+
204
+ ```typescript
205
+ import { softwareLabels } from '@enslo/sd-metadata';
206
+ import type { GenerationSoftware } from '@enslo/sd-metadata';
207
+
208
+ function displaySoftware(software: GenerationSoftware): string {
209
+ return softwareLabels[software];
210
+ }
211
+ ```
212
+
213
+ ---
214
+
215
+ ### `EmbedMetadata`
216
+
217
+ User-created custom metadata for the `embed()` and `stringify()` functions. While `GenerationMetadata` represents parsed output from a known AI tool, `EmbedMetadata` is designed for composing metadata from scratch. Extends `BaseMetadata` with optional NovelAI character prompts and arbitrary key-value extras for the settings line.
218
+
219
+ ```typescript
220
+ export type EmbedMetadata = BaseMetadata &
221
+ Pick<NovelAIMetadata, 'characterPrompts'> & {
222
+ extras?: Record<string, string | number>;
223
+ };
224
+ ```
225
+
226
+ **Example:**
227
+
228
+ ```typescript
229
+ import { embed } from '@enslo/sd-metadata';
230
+ import type { EmbedMetadata } from '@enslo/sd-metadata';
231
+
232
+ const metadata: EmbedMetadata = {
233
+ prompt: 'masterpiece, 1girl',
234
+ negativePrompt: 'lowres',
235
+ width: 512,
236
+ height: 768,
237
+ sampling: { steps: 20, sampler: 'Euler a', cfg: 7, seed: 12345 },
238
+ model: { name: 'model.safetensors' },
239
+ extras: { Version: 'v1.0' },
240
+ };
241
+
242
+ const result = embed(imageData, metadata);
243
+ ```
244
+
245
+ ---
246
+
247
+ ### `RawMetadata`
248
+
249
+ Preserves the original metadata structure for lossless round-trip conversion.
250
+
251
+ ```typescript
252
+ type RawMetadata =
253
+ | { format: 'png'; chunks: PngTextChunk[] }
254
+ | { format: 'jpeg'; segments: MetadataSegment[] }
255
+ | { format: 'webp'; segments: MetadataSegment[] };
256
+ ```
257
+
258
+ **Why is this needed?**
259
+
260
+ When you read metadata from an image and convert it to a different format (e.g., PNG โ†’ JPEG), `RawMetadata` preserves the original structure. This allows you to convert back to the original format without losing any information.
261
+
262
+ **Round-trip conversion example:**
263
+
264
+ ```typescript
265
+ import { read, write } from '@enslo/sd-metadata';
266
+ import { convertImageFormat } from 'some-image-library';
267
+
268
+ // Read metadata from PNG
269
+ const pngData = readFileSync('image.png');
270
+ const parseResult = read(pngData);
271
+
272
+ if (parseResult.status === 'success') {
273
+ // Convert image to JPEG
274
+ const jpegImageData = convertImageFormat(pngData, 'jpeg');
275
+
276
+ // Write metadata to JPEG
277
+ const jpegWithMeta = write(jpegImageData, parseResult);
278
+
279
+ // Later: convert back to PNG
280
+ const pngImageData = convertImageFormat(jpegWithMeta.value, 'png');
281
+ const pngWithMeta = write(pngImageData, parseResult);
282
+
283
+ // Original PNG metadata structure is fully preserved!
284
+ }
285
+ ```
286
+
287
+ Without `raw`, metadata would be converted to a generic format and lose format-specific details when converting back.
288
+
289
+ ---
290
+
291
+ ### `WriteResult`
292
+
293
+ Result type returned by the `write()` function.
294
+
295
+ ```typescript
296
+ export type WriteResult =
297
+ | { ok: true; value: Uint8Array; warning?: WriteWarning }
298
+ | { ok: false; error: { type: string; message?: string } };
299
+ ```
300
+
301
+ **Success:**
302
+
303
+ ```typescript
304
+ if (result.ok) {
305
+ saveFile('output.png', result.value);
306
+ if (result.warning) {
307
+ console.warn('Metadata was dropped:', result.warning.reason);
308
+ }
309
+ }
310
+ ```
311
+
312
+ **Error:**
313
+
314
+ ```typescript
315
+ if (!result.ok) {
316
+ console.error(`Write failed: ${result.error.type}`);
317
+ if (result.error.message) {
318
+ console.error(result.error.message);
319
+ }
320
+ }
321
+ ```
322
+
323
+ **Error Types:**
324
+
325
+ - `unsupportedFormat`: Image format not supported
326
+ - `conversionFailed`: Metadata conversion failed
327
+ - `writeFailed`: Failed to write metadata to image
328
+
329
+ ### `WriteWarning`
330
+
331
+ Warning type for write operations.
332
+
333
+ ```typescript
334
+ export type WriteWarning = {
335
+ type: 'metadataDropped';
336
+ reason: 'unrecognizedCrossFormat';
337
+ };
338
+ ```
339
+
340
+ Returned when metadata was intentionally dropped during a write operation (e.g., unrecognized metadata with cross-format conversion).
341
+
342
+ ---
343
+
344
+ ## Metadata Types
345
+
346
+ ### `StandardMetadata`
347
+
348
+ Standard parameters format used by most SD tools.
349
+
350
+ ```typescript
351
+ export interface StandardMetadata extends BaseMetadata {
352
+ software:
353
+ | 'sd-webui'
354
+ | 'forge'
355
+ | 'forge-classic'
356
+ | 'forge-neo'
357
+ | 'reforge'
358
+ | 'easy-reforge'
359
+ | 'sd-next'
360
+ | 'invokeai'
361
+ | 'civitai'
362
+ | 'hf-space'
363
+ | 'easydiffusion'
364
+ | 'fooocus'
365
+ | 'ruined-fooocus'
366
+ | 'draw-things';
367
+ }
368
+ ```
369
+
370
+ Inherits all fields from `BaseMetadata`. This is the most common metadata type, representing baseline generation metadata without tool-specific extensions. Many tools use this structure, including SD WebUI, Forge family (Forge, Forge Classic, Forge Neo, reForge, EasyReforge), SD.Next, InvokeAI, and others.
371
+
372
+ **Example:**
373
+
374
+ ```typescript
375
+ if (metadata.software === 'forge' || metadata.software === 'sd-webui') {
376
+ console.log('Using standard format metadata');
377
+ console.log('Sampler:', metadata.sampling?.sampler);
378
+ console.log('Steps:', metadata.sampling?.steps);
379
+ }
380
+ ```
381
+
382
+ ---
383
+
384
+ ### `NovelAIMetadata`
385
+
386
+ Metadata specific to NovelAI-generated images.
387
+
388
+ ```typescript
389
+ export interface NovelAIMetadata extends BaseMetadata {
390
+ software: 'novelai';
391
+ /** V4 character prompts (when using character placement) */
392
+ characterPrompts?: CharacterPrompt[];
393
+ /** Use character coordinates for placement */
394
+ useCoords?: boolean;
395
+ /** Use character order */
396
+ useOrder?: boolean;
397
+ }
398
+ ```
399
+
400
+ **Unique Features:**
401
+
402
+ - **Character Placement (V4)**: NovelAI V4 supports placing multiple characters at specific coordinates
403
+ - `characterPrompts`: Array of character-specific prompts with optional positions
404
+ - `useCoords`, `useOrder`: Control character placement behavior
405
+
406
+ **Example:**
407
+
408
+ ```typescript
409
+ if (metadata.software === 'novelai' && metadata.characterPrompts) {
410
+ metadata.characterPrompts.forEach(char => {
411
+ console.log(`Character: ${char.prompt}`);
412
+ if (char.center) {
413
+ console.log(` Position: (${char.center.x}, ${char.center.y})`);
414
+ }
415
+ });
416
+ }
417
+ ```
418
+
419
+ ---
420
+
421
+ ### `ComfyUIMetadata`
422
+
423
+ Metadata from ComfyUI and compatible tools (TensorArt, Stability Matrix, SwarmUI).
424
+
425
+ ```typescript
426
+ export type ComfyUIMetadata =
427
+ | BasicComfyUIMetadata
428
+ | SwarmUIMetadata;
429
+
430
+ // Internal types:
431
+ interface BasicComfyUIMetadata extends BaseMetadata {
432
+ software: 'comfyui' | 'tensorart' | 'stability-matrix';
433
+ nodes: ComfyNodeGraph; // required
434
+ }
435
+
436
+ interface SwarmUIMetadata extends BaseMetadata {
437
+ software: 'swarmui';
438
+ nodes?: ComfyNodeGraph; // optional
439
+ }
440
+ ```
441
+
442
+ **Unique Features:**
443
+
444
+ - **ComfyUI/TensorArt/Stability Matrix**: `nodes` is always present in all formats
445
+ - **SwarmUI**: `nodes` may be present in all formats when converted from PNG (extended support)
446
+
447
+ **Example:**
448
+
449
+ ```typescript
450
+ if (metadata.software === 'comfyui') {
451
+ // nodes is guaranteed to exist for ComfyUI
452
+ console.log('Node count:', Object.keys(metadata.nodes).length);
453
+ }
454
+
455
+ if (metadata.software === 'swarmui') {
456
+ // nodes might not exist for native SwarmUI JPEG/WebP
457
+ // but will be present if converted from PNG
458
+ if (metadata.nodes) {
459
+ console.log('Has workflow (PNG or converted)');
460
+ } else {
461
+ console.log('Native JPEG/WebP: Parameters only');
462
+ }
463
+ }
464
+
465
+ // Type narrowing works across all ComfyUI-compatible tools
466
+ if (metadata.software === 'comfyui' ||
467
+ metadata.software === 'tensorart' ||
468
+ metadata.software === 'stability-matrix' ||
469
+ metadata.software === 'swarmui') {
470
+ // TypeScript knows metadata is ComfyUIMetadata
471
+ // But you need to check metadata.nodes before using it
472
+ if (metadata.nodes) {
473
+ // Find checkpoint node
474
+ for (const [nodeId, node] of Object.entries(metadata.nodes)) {
475
+ if (node.class_type === 'CheckpointLoaderSimple') {
476
+ console.log('Model:', node.inputs.ckpt_name);
477
+ }
478
+ }
479
+ }
480
+ }
481
+ ```
482
+
483
+ ## Settings Types
484
+
485
+ ### `ModelSettings`
486
+
487
+ Model configuration used for image generation.
488
+
489
+ ```typescript
490
+ export interface ModelSettings {
491
+ /** Model name (e.g., "sd_xl_base_1.0.safetensors") */
492
+ name?: string;
493
+ /** Model hash for verification */
494
+ hash?: string;
495
+ /** VAE (Variational AutoEncoder) name */
496
+ vae?: string;
497
+ }
498
+ ```
499
+
500
+ **Example:**
501
+
502
+ ```typescript
503
+ if (metadata.model) {
504
+ console.log('Model:', metadata.model.name);
505
+ console.log('Hash:', metadata.model.hash);
506
+ console.log('VAE:', metadata.model.vae || 'Default');
507
+ }
508
+ ```
509
+
510
+ ---
511
+
512
+ ### `SamplingSettings`
513
+
514
+ Sampling parameters used during generation.
515
+
516
+ ```typescript
517
+ export interface SamplingSettings {
518
+ /** Sampler algorithm (e.g., "Euler a", "DPM++ 2M Karras") */
519
+ sampler?: string;
520
+ /** Scheduler type (if separate from sampler) */
521
+ scheduler?: string;
522
+ /** Number of sampling steps */
523
+ steps?: number;
524
+ /** CFG (Classifier Free Guidance) scale */
525
+ cfg?: number;
526
+ /** Random seed for reproducibility */
527
+ seed?: number;
528
+ /** CLIP skip layers */
529
+ clipSkip?: number;
530
+ /** Denoising strength (ComfyUI only). Omitted when 1.0 (txt2img default) */
531
+ denoise?: number;
532
+ }
533
+ ```
534
+
535
+ **Example:**
536
+
537
+ ```typescript
538
+ if (metadata.sampling) {
539
+ console.log('Sampler:', metadata.sampling.sampler);
540
+ console.log('Steps:', metadata.sampling.steps);
541
+ console.log('CFG Scale:', metadata.sampling.cfg);
542
+ console.log('Seed:', metadata.sampling.seed);
543
+ }
544
+ ```
545
+
546
+ ---
547
+
548
+ ### `HiresSettings`
549
+
550
+ Hires.fix (high-resolution fix) settings.
551
+
552
+ ```typescript
553
+ export interface HiresSettings {
554
+ /** Upscale factor */
555
+ scale?: number;
556
+ /** Upscaler name */
557
+ upscaler?: string;
558
+ /** Hires steps */
559
+ steps?: number;
560
+ /** Hires denoising strength */
561
+ denoise?: number;
562
+ }
563
+ ```
564
+
565
+ Applied during generation to improve high-resolution output quality.
566
+
567
+ ---
568
+
569
+ ### `UpscaleSettings`
570
+
571
+ Post-generation upscale settings.
572
+
573
+ ```typescript
574
+ export interface UpscaleSettings {
575
+ /** Upscaler name */
576
+ upscaler?: string;
577
+ /** Scale factor */
578
+ scale?: number;
579
+ }
580
+ ```
581
+
582
+ Applied after initial generation as a separate upscaling step.
583
+
584
+ ---
585
+
586
+ ### `CharacterPrompt`
587
+
588
+ Character positioning for NovelAI V4 images.
589
+
590
+ ```typescript
591
+ export interface CharacterPrompt {
592
+ /** Character-specific prompt */
593
+ prompt: string;
594
+ /** Character position in image (normalized 0-1) */
595
+ center?: { x: number; y: number };
596
+ }
597
+ ```
598
+
599
+ **Example:**
600
+
601
+ ```typescript
602
+ const character: CharacterPrompt = {
603
+ prompt: "1girl, long hair, blue eyes",
604
+ center: { x: 0.3, y: 0.5 } // Left side, vertically centered
605
+ };
606
+ ```
607
+
608
+ ---
609
+
610
+ ## ComfyUI Types
611
+
612
+ ### `ComfyNodeGraph`
613
+
614
+ Map of node IDs to their corresponding node data.
615
+
616
+ ```typescript
617
+ export type ComfyNodeGraph = Record<string, ComfyNode>;
618
+ ```
619
+
620
+ **Example:**
621
+
622
+ ```typescript
623
+ const graph: ComfyNodeGraph = {
624
+ "CheckpointLoader_Base": { /* ... */ },
625
+ "KSampler_Primary": { /* ... */ },
626
+ "SaveImage_Final": { /* ... */ }
627
+ };
628
+ ```
629
+
630
+ ---
631
+
632
+ ### `ComfyNode`
633
+
634
+ A single node in the ComfyUI workflow graph.
635
+
636
+ ```typescript
637
+ export interface ComfyNode {
638
+ /** Node class type (e.g., "CheckpointLoaderSimple", "KSampler") */
639
+ class_type: string;
640
+ /** Node inputs */
641
+ inputs: Record<string, ComfyNodeInputValue>;
642
+ /** Node metadata (ComfyUI only) */
643
+ _meta?: {
644
+ /** Node title for display */
645
+ title?: string;
646
+ };
647
+ /** Change detection hash (rare, for caching) */
648
+ is_changed?: string[] | null;
649
+ }
650
+ ```
651
+
652
+ **Example:**
653
+
654
+ ```typescript
655
+ const ksampler: ComfyNode = {
656
+ class_type: "KSampler",
657
+ inputs: {
658
+ model: ["CheckpointLoader", 0],
659
+ seed: 12345,
660
+ steps: 20,
661
+ cfg: 7.0,
662
+ sampler_name: "euler_a",
663
+ scheduler: "normal",
664
+ denoise: 1.0
665
+ },
666
+ _meta: {
667
+ title: "Primary Sampler"
668
+ }
669
+ };
670
+ ```
671
+
672
+ ---
673
+
674
+ ### `ComfyNodeInputValue`
675
+
676
+ Possible values for node inputs.
677
+
678
+ ```typescript
679
+ export type ComfyNodeInputValue =
680
+ | string
681
+ | number
682
+ | boolean
683
+ | ComfyNodeReference
684
+ | ComfyNodeInputValue[];
685
+ ```
686
+
687
+ Can be a primitive value, a reference to another node, or an array.
688
+
689
+ ---
690
+
691
+ ### `ComfyNodeReference`
692
+
693
+ Reference to another node's output.
694
+
695
+ ```typescript
696
+ export type ComfyNodeReference = [nodeId: string, outputIndex: number];
697
+ ```
698
+
699
+ **Example:**
700
+
701
+ ```typescript
702
+ const modelReference: ComfyNodeReference = ["CheckpointLoader_Base", 0];
703
+
704
+ // Used in node inputs:
705
+ {
706
+ model: ["CheckpointLoader_Base", 0], // References output 0 of CheckpointLoader_Base
707
+ positive: ["CLIPTextEncode_Positive", 0]
708
+ }
709
+ ```
710
+
711
+ ---
712
+
713
+ ## Format-Specific Types
714
+
715
+ > **Note:** These types are mainly for advanced use cases or internal implementation details. Most users don't need to work with these types directly.
716
+
717
+ ### `PngTextChunk`
718
+
719
+ PNG text chunk types (tEXt or iTXt).
720
+
721
+ ```typescript
722
+ export type PngTextChunk = TExtChunk | ITXtChunk;
723
+ ```
724
+
725
+ ---
726
+
727
+ ### `TExtChunk`
728
+
729
+ PNG tEXt chunk (Latin-1 encoded).
730
+
731
+ ```typescript
732
+ export interface TExtChunk {
733
+ type: 'tEXt';
734
+ /** Chunk keyword (e.g., "parameters", "Comment") */
735
+ keyword: string;
736
+ /** Text content */
737
+ text: string;
738
+ }
739
+ ```
740
+
741
+ ---
742
+
743
+ ### `ITXtChunk`
744
+
745
+ PNG iTXt chunk (UTF-8 international text).
746
+
747
+ ```typescript
748
+ export interface ITXtChunk {
749
+ type: 'iTXt';
750
+ /** Chunk keyword */
751
+ keyword: string;
752
+ /** Compression flag (0=uncompressed, 1=compressed) */
753
+ compressionFlag: number;
754
+ /** Compression method (0=zlib/deflate) */
755
+ compressionMethod: number;
756
+ /** Language tag (BCP 47) */
757
+ languageTag: string;
758
+ /** Translated keyword */
759
+ translatedKeyword: string;
760
+ /** Text content */
761
+ text: string;
762
+ }
763
+ ```
764
+
765
+ ---
766
+
767
+ ### `MetadataSegment`
768
+
769
+ JPEG/WebP metadata segment with source tracking.
770
+
771
+ ```typescript
772
+ export interface MetadataSegment {
773
+ /** Source location of this segment */
774
+ source: MetadataSegmentSource;
775
+ /** Raw metadata string */
776
+ data: string;
777
+ }
778
+ ```
779
+
780
+ Used for round-trip conversion to write metadata back to the correct location.
781
+
782
+ ---
783
+
784
+ ### `MetadataSegmentSource`
785
+
786
+ Source location of a metadata segment.
787
+
788
+ ```typescript
789
+ export type MetadataSegmentSource =
790
+ | { type: 'exifUserComment' }
791
+ | { type: 'exifImageDescription'; prefix?: string }
792
+ | { type: 'exifMake'; prefix?: string }
793
+ | { type: 'jpegCom' }
794
+ | { type: 'xmpPacket' };
795
+ ```
796
+
797
+ Tracks where the metadata came from in JPEG/WebP files for accurate round-tripping.
798
+
799
+ ---