@rohal12/twee-ts 1.11.0 → 1.13.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/dist/index.d.cts CHANGED
@@ -54,17 +54,23 @@ interface WatchOptions extends CompileToFileOptions {
54
54
  /** Called on build errors. */
55
55
  onError?: (error: Error) => void;
56
56
  }
57
- interface Diagnostic {
58
- level: 'warning' | 'error';
57
+ type Diagnostic = {
58
+ level: 'warning';
59
59
  message: string;
60
60
  file?: string;
61
61
  line?: number;
62
- }
62
+ } | {
63
+ level: 'error';
64
+ message: string;
65
+ file?: string;
66
+ line?: number;
67
+ fatal?: boolean;
68
+ };
63
69
  interface CompileResult {
64
70
  /** The compiled output string (HTML, Twee, JSON, etc.). */
65
71
  output: string;
66
- /** The parsed story model. */
67
- story: Story;
72
+ /** The parsed story model (read-only after compilation). */
73
+ story: ReadonlyStory;
68
74
  /** The format used for compilation (undefined for non-HTML modes). */
69
75
  format?: StoryFormatInfo;
70
76
  /** Collected diagnostics. */
@@ -94,6 +100,9 @@ interface Passage {
94
100
  metadata?: PassageMetadata;
95
101
  source?: SourceLocation;
96
102
  }
103
+ type IFID = string & {
104
+ readonly __brand: 'IFID';
105
+ };
97
106
  interface Twine1Metadata {
98
107
  settings: Map<string, string>;
99
108
  }
@@ -108,12 +117,25 @@ interface Twine2Metadata {
108
117
  }
109
118
  interface Story {
110
119
  name: string;
111
- ifid: string;
120
+ ifid: IFID;
112
121
  passages: Passage[];
113
- legacyIFID: string;
122
+ legacyIFID: IFID;
114
123
  twine1: Twine1Metadata;
115
124
  twine2: Twine2Metadata;
116
125
  }
126
+ type ReadonlyPassage = Readonly<Passage> & {
127
+ readonly tags: readonly string[];
128
+ };
129
+ type ReadonlyStory = Readonly<Omit<Story, 'passages' | 'twine1' | 'twine2'>> & {
130
+ readonly passages: readonly ReadonlyPassage[];
131
+ readonly twine1: Readonly<Omit<Twine1Metadata, 'settings'>> & {
132
+ readonly settings: ReadonlyMap<string, string>;
133
+ };
134
+ readonly twine2: Readonly<Omit<Twine2Metadata, 'options' | 'tagColors'>> & {
135
+ readonly options: ReadonlyMap<string, boolean>;
136
+ readonly tagColors: ReadonlyMap<string, string>;
137
+ };
138
+ };
117
139
  interface StoryFormatInfo {
118
140
  id: string;
119
141
  filename: string;
@@ -138,15 +160,16 @@ interface Twine2FormatJSON {
138
160
  url?: string;
139
161
  license?: string;
140
162
  }
141
- declare const enum ItemType {
142
- Error = 0,
143
- EOF = 1,
144
- Header = 2,
145
- Name = 3,
146
- Tags = 4,
147
- Metadata = 5,
148
- Content = 6
149
- }
163
+ declare const ItemType: {
164
+ readonly Error: 0;
165
+ readonly EOF: 1;
166
+ readonly Header: 2;
167
+ readonly Name: 3;
168
+ readonly Tags: 4;
169
+ readonly Metadata: 5;
170
+ readonly Content: 6;
171
+ };
172
+ type ItemType = (typeof ItemType)[keyof typeof ItemType];
150
173
  interface LexerItem {
151
174
  type: ItemType;
152
175
  line: number;
@@ -273,7 +296,38 @@ interface BrokenLink {
273
296
  * expect(map.deadEnds).not.toContain('Start');
274
297
  * ```
275
298
  */
276
- declare function storyInspect(story: Story): StoryMap;
299
+ declare function storyInspect(story: ReadonlyStory): StoryMap;
300
+
301
+ /**
302
+ * Story model + StoryData JSON marshal/unmarshal.
303
+ * Ported from story.go + storydata.go.
304
+ */
305
+
306
+ /**
307
+ * Builder that separates the mutable construction phase from the immutable consumption phase.
308
+ * During construction, the internal `Story` is mutable via `add()` and direct access.
309
+ * After `build()`, the story is returned as `ReadonlyStory`.
310
+ */
311
+ declare class StoryBuilder {
312
+ /** The mutable story, accessible during construction for loader functions. */
313
+ readonly story: Story;
314
+ constructor();
315
+ /** Add a passage, handling special passages (StoryData, StoryTitle, etc.). */
316
+ add(passage: Passage, diagnostics: Diagnostic[]): void;
317
+ /** Check if a passage name exists. */
318
+ has(name: string): boolean;
319
+ /** Finalize and return the story as read-only. */
320
+ build(): ReadonlyStory;
321
+ }
322
+
323
+ interface DecompileResult {
324
+ story: Story;
325
+ diagnostics: Diagnostic[];
326
+ }
327
+ /**
328
+ * Parse a Twine 2 or Twine 1 compiled HTML file back into a Story model.
329
+ */
330
+ declare function decompileHTML(html: string): DecompileResult;
277
331
 
278
332
  /**
279
333
  * Lint mode: compile + inspect story structure without producing output.
@@ -392,7 +446,9 @@ declare function parseSemver(v: string): [number, number, number] | null;
392
446
  declare function semverCompare(a: [number, number, number], b: [number, number, number]): number;
393
447
 
394
448
  /** Generate a new IFID (UUID v4, uppercase). */
395
- declare function generateIFID(): string;
449
+ declare function generateIFID(): IFID;
450
+ /** Validate and brand an IFID string. Throws on invalid input. */
451
+ declare function createIFID(value: string): IFID;
396
452
  /**
397
453
  * Validate an IFID string.
398
454
  * Accepts both bare UUIDs and UUID://...// wrapped format.
@@ -442,4 +498,4 @@ declare function getCacheSize(): {
442
498
  count: number;
443
499
  };
444
500
 
445
- export { type BrokenLink, CONFIG_FILENAME, type CachedFormatEntry, type CompileOptions, type CompileResult, type CompileStats, type CompileToFileOptions, type Diagnostic, type FileCacheEntry, type InlineSource, ItemType, type LexerItem, type LintResult, type OutputMode, type Passage, type PassageMetadata, type SFAIndex, type SFAIndexEntry, type SourceInput, type SourceLocation, type Story, type StoryFormatInfo, type StoryMap, TweeLexer, type TweeTsConfig, TweeTsError, type WatchOptions, type WordCountMethod, applyTagAliases, clearCachedFormats, compile, compileIncremental, compileToFile, discoverCachedFormats, discoverFormats, fetchAndCacheFormat, fetchDirectFormat, formatLintReport, generateIFID, getCacheDir, getCacheSize, getFormatSearchDirs, lint, listCachedFormats, loadConfig, loadConfigFile, parseFormatJSON, parseSemver, parseTwee, resolveRemoteFormat, scaffoldConfig, semverCompare, storyInspect, tweeLexer, validateConfig, validateIFID, watch };
501
+ export { type BrokenLink, CONFIG_FILENAME, type CachedFormatEntry, type CompileOptions, type CompileResult, type CompileStats, type CompileToFileOptions, type DecompileResult, type Diagnostic, type FileCacheEntry, type IFID, type InlineSource, ItemType, type LexerItem, type LintResult, type OutputMode, type Passage, type PassageMetadata, type ReadonlyPassage, type ReadonlyStory, type SFAIndex, type SFAIndexEntry, type SourceInput, type SourceLocation, type Story, StoryBuilder, type StoryFormatInfo, type StoryMap, TweeLexer, type TweeTsConfig, TweeTsError, type WatchOptions, type WordCountMethod, applyTagAliases, clearCachedFormats, compile, compileIncremental, compileToFile, createIFID, decompileHTML, discoverCachedFormats, discoverFormats, fetchAndCacheFormat, fetchDirectFormat, formatLintReport, generateIFID, getCacheDir, getCacheSize, getFormatSearchDirs, lint, listCachedFormats, loadConfig, loadConfigFile, parseFormatJSON, parseSemver, parseTwee, resolveRemoteFormat, scaffoldConfig, semverCompare, storyInspect, tweeLexer, validateConfig, validateIFID, watch };
package/dist/index.d.ts CHANGED
@@ -54,17 +54,23 @@ interface WatchOptions extends CompileToFileOptions {
54
54
  /** Called on build errors. */
55
55
  onError?: (error: Error) => void;
56
56
  }
57
- interface Diagnostic {
58
- level: 'warning' | 'error';
57
+ type Diagnostic = {
58
+ level: 'warning';
59
59
  message: string;
60
60
  file?: string;
61
61
  line?: number;
62
- }
62
+ } | {
63
+ level: 'error';
64
+ message: string;
65
+ file?: string;
66
+ line?: number;
67
+ fatal?: boolean;
68
+ };
63
69
  interface CompileResult {
64
70
  /** The compiled output string (HTML, Twee, JSON, etc.). */
65
71
  output: string;
66
- /** The parsed story model. */
67
- story: Story;
72
+ /** The parsed story model (read-only after compilation). */
73
+ story: ReadonlyStory;
68
74
  /** The format used for compilation (undefined for non-HTML modes). */
69
75
  format?: StoryFormatInfo;
70
76
  /** Collected diagnostics. */
@@ -94,6 +100,9 @@ interface Passage {
94
100
  metadata?: PassageMetadata;
95
101
  source?: SourceLocation;
96
102
  }
103
+ type IFID = string & {
104
+ readonly __brand: 'IFID';
105
+ };
97
106
  interface Twine1Metadata {
98
107
  settings: Map<string, string>;
99
108
  }
@@ -108,12 +117,25 @@ interface Twine2Metadata {
108
117
  }
109
118
  interface Story {
110
119
  name: string;
111
- ifid: string;
120
+ ifid: IFID;
112
121
  passages: Passage[];
113
- legacyIFID: string;
122
+ legacyIFID: IFID;
114
123
  twine1: Twine1Metadata;
115
124
  twine2: Twine2Metadata;
116
125
  }
126
+ type ReadonlyPassage = Readonly<Passage> & {
127
+ readonly tags: readonly string[];
128
+ };
129
+ type ReadonlyStory = Readonly<Omit<Story, 'passages' | 'twine1' | 'twine2'>> & {
130
+ readonly passages: readonly ReadonlyPassage[];
131
+ readonly twine1: Readonly<Omit<Twine1Metadata, 'settings'>> & {
132
+ readonly settings: ReadonlyMap<string, string>;
133
+ };
134
+ readonly twine2: Readonly<Omit<Twine2Metadata, 'options' | 'tagColors'>> & {
135
+ readonly options: ReadonlyMap<string, boolean>;
136
+ readonly tagColors: ReadonlyMap<string, string>;
137
+ };
138
+ };
117
139
  interface StoryFormatInfo {
118
140
  id: string;
119
141
  filename: string;
@@ -138,15 +160,16 @@ interface Twine2FormatJSON {
138
160
  url?: string;
139
161
  license?: string;
140
162
  }
141
- declare const enum ItemType {
142
- Error = 0,
143
- EOF = 1,
144
- Header = 2,
145
- Name = 3,
146
- Tags = 4,
147
- Metadata = 5,
148
- Content = 6
149
- }
163
+ declare const ItemType: {
164
+ readonly Error: 0;
165
+ readonly EOF: 1;
166
+ readonly Header: 2;
167
+ readonly Name: 3;
168
+ readonly Tags: 4;
169
+ readonly Metadata: 5;
170
+ readonly Content: 6;
171
+ };
172
+ type ItemType = (typeof ItemType)[keyof typeof ItemType];
150
173
  interface LexerItem {
151
174
  type: ItemType;
152
175
  line: number;
@@ -273,7 +296,38 @@ interface BrokenLink {
273
296
  * expect(map.deadEnds).not.toContain('Start');
274
297
  * ```
275
298
  */
276
- declare function storyInspect(story: Story): StoryMap;
299
+ declare function storyInspect(story: ReadonlyStory): StoryMap;
300
+
301
+ /**
302
+ * Story model + StoryData JSON marshal/unmarshal.
303
+ * Ported from story.go + storydata.go.
304
+ */
305
+
306
+ /**
307
+ * Builder that separates the mutable construction phase from the immutable consumption phase.
308
+ * During construction, the internal `Story` is mutable via `add()` and direct access.
309
+ * After `build()`, the story is returned as `ReadonlyStory`.
310
+ */
311
+ declare class StoryBuilder {
312
+ /** The mutable story, accessible during construction for loader functions. */
313
+ readonly story: Story;
314
+ constructor();
315
+ /** Add a passage, handling special passages (StoryData, StoryTitle, etc.). */
316
+ add(passage: Passage, diagnostics: Diagnostic[]): void;
317
+ /** Check if a passage name exists. */
318
+ has(name: string): boolean;
319
+ /** Finalize and return the story as read-only. */
320
+ build(): ReadonlyStory;
321
+ }
322
+
323
+ interface DecompileResult {
324
+ story: Story;
325
+ diagnostics: Diagnostic[];
326
+ }
327
+ /**
328
+ * Parse a Twine 2 or Twine 1 compiled HTML file back into a Story model.
329
+ */
330
+ declare function decompileHTML(html: string): DecompileResult;
277
331
 
278
332
  /**
279
333
  * Lint mode: compile + inspect story structure without producing output.
@@ -392,7 +446,9 @@ declare function parseSemver(v: string): [number, number, number] | null;
392
446
  declare function semverCompare(a: [number, number, number], b: [number, number, number]): number;
393
447
 
394
448
  /** Generate a new IFID (UUID v4, uppercase). */
395
- declare function generateIFID(): string;
449
+ declare function generateIFID(): IFID;
450
+ /** Validate and brand an IFID string. Throws on invalid input. */
451
+ declare function createIFID(value: string): IFID;
396
452
  /**
397
453
  * Validate an IFID string.
398
454
  * Accepts both bare UUIDs and UUID://...// wrapped format.
@@ -442,4 +498,4 @@ declare function getCacheSize(): {
442
498
  count: number;
443
499
  };
444
500
 
445
- export { type BrokenLink, CONFIG_FILENAME, type CachedFormatEntry, type CompileOptions, type CompileResult, type CompileStats, type CompileToFileOptions, type Diagnostic, type FileCacheEntry, type InlineSource, ItemType, type LexerItem, type LintResult, type OutputMode, type Passage, type PassageMetadata, type SFAIndex, type SFAIndexEntry, type SourceInput, type SourceLocation, type Story, type StoryFormatInfo, type StoryMap, TweeLexer, type TweeTsConfig, TweeTsError, type WatchOptions, type WordCountMethod, applyTagAliases, clearCachedFormats, compile, compileIncremental, compileToFile, discoverCachedFormats, discoverFormats, fetchAndCacheFormat, fetchDirectFormat, formatLintReport, generateIFID, getCacheDir, getCacheSize, getFormatSearchDirs, lint, listCachedFormats, loadConfig, loadConfigFile, parseFormatJSON, parseSemver, parseTwee, resolveRemoteFormat, scaffoldConfig, semverCompare, storyInspect, tweeLexer, validateConfig, validateIFID, watch };
501
+ export { type BrokenLink, CONFIG_FILENAME, type CachedFormatEntry, type CompileOptions, type CompileResult, type CompileStats, type CompileToFileOptions, type DecompileResult, type Diagnostic, type FileCacheEntry, type IFID, type InlineSource, ItemType, type LexerItem, type LintResult, type OutputMode, type Passage, type PassageMetadata, type ReadonlyPassage, type ReadonlyStory, type SFAIndex, type SFAIndexEntry, type SourceInput, type SourceLocation, type Story, StoryBuilder, type StoryFormatInfo, type StoryMap, TweeLexer, type TweeTsConfig, TweeTsError, type WatchOptions, type WordCountMethod, applyTagAliases, clearCachedFormats, compile, compileIncremental, compileToFile, createIFID, decompileHTML, discoverCachedFormats, discoverFormats, fetchAndCacheFormat, fetchDirectFormat, formatLintReport, generateIFID, getCacheDir, getCacheSize, getFormatSearchDirs, lint, listCachedFormats, loadConfig, loadConfigFile, parseFormatJSON, parseSemver, parseTwee, resolveRemoteFormat, scaffoldConfig, semverCompare, storyInspect, tweeLexer, validateConfig, validateIFID, watch };