@rohal12/twee-ts 1.16.1 → 1.17.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.
package/dist/index.d.cts CHANGED
@@ -55,9 +55,12 @@ interface CompileToFileOptions extends CompileOptions {
55
55
  outFile: string;
56
56
  }
57
57
  interface WatchOptions extends CompileToFileOptions {
58
- /** Called after each successful rebuild. */
58
+ /**
59
+ * Called after each build is written, including one whose diagnostics report errors. A build
60
+ * that changes made while it ran have superseded is neither written nor reported.
61
+ */
59
62
  onBuild?: (result: CompileResult) => void;
60
- /** Called on build errors. */
63
+ /** Called when a build fails with a fatal error (nothing is written). */
61
64
  onError?: (error: Error) => void;
62
65
  }
63
66
  type Diagnostic = {
@@ -142,6 +145,37 @@ type ReadonlyStory = Readonly<Omit<Story, 'passages' | 'twine1' | 'twine2'>> & {
142
145
  readonly tagColors: ReadonlyMap<string, string>;
143
146
  };
144
147
  };
148
+ type OmittingTag = 'Twine.private' | 'script' | 'stylesheet';
149
+ type PassageOmission = {
150
+ readonly kind: 'special-name';
151
+ readonly name: 'StoryData' | 'StoryTitle';
152
+ } | {
153
+ readonly kind: 'tag';
154
+ readonly tag: OmittingTag;
155
+ } | {
156
+ readonly kind: 'empty-story-settings';
157
+ };
158
+ /** The output whose rules decide which passages a story emits as passages. */
159
+ type PassageOutputTarget = 'twine1' | 'twine2';
160
+ interface DecompileOptions {
161
+ /**
162
+ * Trim whitespace at both ends of passage text (and of the Twine 2 story stylesheet and script),
163
+ * as the Twee lexer does. When false, the stored text is kept exactly. Default: true.
164
+ */
165
+ readonly trim?: boolean;
166
+ }
167
+ interface InspectOptions {
168
+ /**
169
+ * Check link destinations against this output's passage rules. A link to a passage that the
170
+ * output leaves out (in Twine 2: `script`, `stylesheet` and `Twine.private` passages,
171
+ * StoryData, StoryTitle and an empty StorySettings; in Twine 1: `Twine.private` passages) is
172
+ * then a broken link, and says why. The passages it leaves out also give no links, as their
173
+ * text never reaches the player, except script passages, which Twine 2 output runs. Without a
174
+ * target, every source passage gives links, and a link is broken only when no passage has its
175
+ * name.
176
+ */
177
+ readonly target?: PassageOutputTarget;
178
+ }
145
179
  interface StoryFormatInfo {
146
180
  id: string;
147
181
  filename: string;
@@ -242,10 +276,18 @@ export declare function compileToFile(options: CompileToFileOptions): Promise<Co
242
276
  /**
243
277
  * Compile with incremental caching support.
244
278
  * Plugins and advanced users can manage their own cache and changed-file tracking.
279
+ *
280
+ * Without `changedFiles`, a cached file is reused while its modification time is unchanged.
281
+ * With it, a file it names (by the path source discovery gives it, relative to the working
282
+ * directory) is always reparsed, whatever its modification time, and every other cached
283
+ * file is reused as it is.
245
284
  */
246
285
  export declare function compileIncremental(options: CompileOptions, cache: Map<string, FileCacheEntry>, changedFiles?: ReadonlySet<string>): Promise<CompileResult>;
247
286
  /**
248
- * Watch for file changes and recompile.
287
+ * Watch for file changes and recompile. Every build is written to `outFile`, including
288
+ * one whose diagnostics report errors. Builds run one at a time: changes made during a
289
+ * build go into one follow-up build after it, and the superseded build is neither
290
+ * written nor reported.
249
291
  */
250
292
  export declare function watch(options: WatchOptions): Promise<AbortController>;
251
293
  //#endregion
@@ -268,10 +310,16 @@ interface StoryMap {
268
310
  * Parses `[[target]]`, `[[display->target]]`, `[[target<-display]]`, `[[display|target]]`,
269
311
  * each with or without a setter (`[[display|target][$x to 1]]`), and SugarCube's
270
312
  * `<<goto "target">>` / `<<link "display" "target">>`, read as SugarCube 2 reads them
271
- * (see `sugarcube-macros.ts`). Links and calls in comments are not read.
313
+ * (see `sugarcube-macros.ts`). Links and calls in comments are not read. A script passage is
314
+ * read for links only in its strings; a stylesheet passage (including a loaded `.css` file) is
315
+ * CSS and links to nothing. With a `target` (see `InspectOptions`), a passage that output leaves
316
+ * out links to nothing, except a script passage, which Twine 2 output runs.
272
317
  */
273
318
  links: Map<string, string[]>;
274
- /** Broken links: `{ from, to }` pairs where `to` doesn't exist as a passage. */
319
+ /**
320
+ * Broken links: `{ from, to }` pairs where `to` doesn't exist as a passage, or, with a `target`
321
+ * (see `InspectOptions`), where that output leaves the `to` passage out (`omission` says why).
322
+ */
275
323
  brokenLinks: BrokenLink[];
276
324
  /** Story passages with no outgoing links (potential dead ends). */
277
325
  deadEnds: string[];
@@ -283,6 +331,11 @@ interface StoryMap {
283
331
  interface BrokenLink {
284
332
  from: string;
285
333
  to: string;
334
+ /**
335
+ * Set when a passage named `to` exists, but the inspected output leaves it out of the story
336
+ * (only with a `target`): why it is left out. Absent when no passage has the name.
337
+ */
338
+ omission?: PassageOmission;
286
339
  }
287
340
  /**
288
341
  * Inspect a story and return its full structural map.
@@ -299,8 +352,15 @@ interface BrokenLink {
299
352
  * expect(map.brokenLinks).toEqual([]);
300
353
  * expect(map.deadEnds).not.toContain('Start');
301
354
  * ```
355
+ *
356
+ * By default, a link is broken only when no passage has its name. Pass a `target` to check links
357
+ * against what that output emits: `storyInspect(result.story, { target: 'twine2' })` also reports
358
+ * links to passages Twine 2 output leaves out, such as script, stylesheet and `Twine.private`
359
+ * passages. With a target, passages that output leaves out also give no links (script passages
360
+ * excepted, as Twine 2 output runs them), so they report no broken links and keep no passage from
361
+ * being an orphan.
302
362
  */
303
- export declare function storyInspect(story: ReadonlyStory): StoryMap;
363
+ export declare function storyInspect(story: ReadonlyStory, options?: InspectOptions): StoryMap;
304
364
  //#endregion
305
365
  //#region src/story.d.ts
306
366
  /**
@@ -327,8 +387,9 @@ interface DecompileResult {
327
387
  }
328
388
  /**
329
389
  * Parse a Twine 2 or Twine 1 compiled HTML file back into a Story model.
390
+ * Tweego always trims passage text; here `trim: false` keeps it exactly, as for Twee sources.
330
391
  */
331
- export declare function decompileHTML(html: string): DecompileResult;
392
+ export declare function decompileHTML(html: string, options?: DecompileOptions): DecompileResult;
332
393
  //#endregion
333
394
  //#region src/lint.d.ts
334
395
  interface LintResult {
@@ -348,7 +409,11 @@ interface LintResult {
348
409
  storyPassages: number;
349
410
  /** Info/special passage count. */
350
411
  infoPassages: number;
351
- /** Broken links: link targets that don't exist as passages. */
412
+ /**
413
+ * Broken links: link targets that don't exist as passages, or that Twine 2 output leaves out
414
+ * (script, stylesheet and `Twine.private` passages, StoryData, StoryTitle, an empty
415
+ * StorySettings); for those, `omission` says why.
416
+ */
352
417
  brokenLinks: BrokenLink[];
353
418
  /** Story passages with no outgoing links. */
354
419
  deadEnds: string[];
@@ -358,7 +423,10 @@ interface LintResult {
358
423
  /**
359
424
  * Lint a story: compile without output rendering, then inspect structure.
360
425
  * Uses JSON output mode internally to avoid format resolution, so it checks
361
- * the starting passage itself, against the Twine 2 passage rules.
426
+ * the starting passage itself, against the Twine 2 passage rules. Link
427
+ * destinations are checked against the same rules: a link to a passage that
428
+ * Twine 2 output leaves out is broken, and a passage it leaves out (other than
429
+ * a script passage) gives no links.
362
430
  */
363
431
  export declare function lint(options: Omit<CompileOptions, 'outputMode'>): Promise<LintResult>;
364
432
  /**
@@ -442,7 +510,10 @@ export declare function semverCompare(a: [number, number, number], b: [number, n
442
510
  //#region src/ifid.d.ts
443
511
  /** Generate a new IFID (UUID v4, uppercase). */
444
512
  export declare function generateIFID(): IFID;
445
- /** Validate and brand an IFID string. Throws on invalid input. */
513
+ /**
514
+ * Validate and brand an IFID string. Throws on invalid input.
515
+ * Returns the IFID in its stored form (see `normalizeIFID`).
516
+ */
446
517
  export declare function createIFID(value: string): IFID;
447
518
  /**
448
519
  * Validate an IFID string.
@@ -501,4 +572,4 @@ export declare function getCacheSize(): {
501
572
  count: number;
502
573
  };
503
574
  //#endregion
504
- export type { BrokenLink, CachedFormatEntry, CompileOptions, CompileResult, CompileStats, CompileToFileOptions, DecompileResult, Diagnostic, FileCacheEntry, IFID, InlineSource, LexerItem, LintResult, OutputMode, Passage, PassageMetadata, ReadonlyPassage, ReadonlyStory, SFAIndex, SFAIndexEntry, SourceInput, SourceLocation, Story, StoryFormatInfo, StoryMap, TweeTsConfig, WatchOptions, WordCountMethod };
575
+ export type { BrokenLink, CachedFormatEntry, CompileOptions, CompileResult, CompileStats, CompileToFileOptions, DecompileOptions, DecompileResult, Diagnostic, FileCacheEntry, IFID, InlineSource, InspectOptions, LexerItem, LintResult, OmittingTag, OutputMode, Passage, PassageMetadata, PassageOmission, PassageOutputTarget, ReadonlyPassage, ReadonlyStory, SFAIndex, SFAIndexEntry, SourceInput, SourceLocation, Story, StoryFormatInfo, StoryMap, TweeTsConfig, WatchOptions, WordCountMethod };
package/dist/index.d.ts CHANGED
@@ -55,9 +55,12 @@ interface CompileToFileOptions extends CompileOptions {
55
55
  outFile: string;
56
56
  }
57
57
  interface WatchOptions extends CompileToFileOptions {
58
- /** Called after each successful rebuild. */
58
+ /**
59
+ * Called after each build is written, including one whose diagnostics report errors. A build
60
+ * that changes made while it ran have superseded is neither written nor reported.
61
+ */
59
62
  onBuild?: (result: CompileResult) => void;
60
- /** Called on build errors. */
63
+ /** Called when a build fails with a fatal error (nothing is written). */
61
64
  onError?: (error: Error) => void;
62
65
  }
63
66
  type Diagnostic = {
@@ -142,6 +145,37 @@ type ReadonlyStory = Readonly<Omit<Story, 'passages' | 'twine1' | 'twine2'>> & {
142
145
  readonly tagColors: ReadonlyMap<string, string>;
143
146
  };
144
147
  };
148
+ type OmittingTag = 'Twine.private' | 'script' | 'stylesheet';
149
+ type PassageOmission = {
150
+ readonly kind: 'special-name';
151
+ readonly name: 'StoryData' | 'StoryTitle';
152
+ } | {
153
+ readonly kind: 'tag';
154
+ readonly tag: OmittingTag;
155
+ } | {
156
+ readonly kind: 'empty-story-settings';
157
+ };
158
+ /** The output whose rules decide which passages a story emits as passages. */
159
+ type PassageOutputTarget = 'twine1' | 'twine2';
160
+ interface DecompileOptions {
161
+ /**
162
+ * Trim whitespace at both ends of passage text (and of the Twine 2 story stylesheet and script),
163
+ * as the Twee lexer does. When false, the stored text is kept exactly. Default: true.
164
+ */
165
+ readonly trim?: boolean;
166
+ }
167
+ interface InspectOptions {
168
+ /**
169
+ * Check link destinations against this output's passage rules. A link to a passage that the
170
+ * output leaves out (in Twine 2: `script`, `stylesheet` and `Twine.private` passages,
171
+ * StoryData, StoryTitle and an empty StorySettings; in Twine 1: `Twine.private` passages) is
172
+ * then a broken link, and says why. The passages it leaves out also give no links, as their
173
+ * text never reaches the player, except script passages, which Twine 2 output runs. Without a
174
+ * target, every source passage gives links, and a link is broken only when no passage has its
175
+ * name.
176
+ */
177
+ readonly target?: PassageOutputTarget;
178
+ }
145
179
  interface StoryFormatInfo {
146
180
  id: string;
147
181
  filename: string;
@@ -242,10 +276,18 @@ export declare function compileToFile(options: CompileToFileOptions): Promise<Co
242
276
  /**
243
277
  * Compile with incremental caching support.
244
278
  * Plugins and advanced users can manage their own cache and changed-file tracking.
279
+ *
280
+ * Without `changedFiles`, a cached file is reused while its modification time is unchanged.
281
+ * With it, a file it names (by the path source discovery gives it, relative to the working
282
+ * directory) is always reparsed, whatever its modification time, and every other cached
283
+ * file is reused as it is.
245
284
  */
246
285
  export declare function compileIncremental(options: CompileOptions, cache: Map<string, FileCacheEntry>, changedFiles?: ReadonlySet<string>): Promise<CompileResult>;
247
286
  /**
248
- * Watch for file changes and recompile.
287
+ * Watch for file changes and recompile. Every build is written to `outFile`, including
288
+ * one whose diagnostics report errors. Builds run one at a time: changes made during a
289
+ * build go into one follow-up build after it, and the superseded build is neither
290
+ * written nor reported.
249
291
  */
250
292
  export declare function watch(options: WatchOptions): Promise<AbortController>;
251
293
  //#endregion
@@ -268,10 +310,16 @@ interface StoryMap {
268
310
  * Parses `[[target]]`, `[[display->target]]`, `[[target<-display]]`, `[[display|target]]`,
269
311
  * each with or without a setter (`[[display|target][$x to 1]]`), and SugarCube's
270
312
  * `<<goto "target">>` / `<<link "display" "target">>`, read as SugarCube 2 reads them
271
- * (see `sugarcube-macros.ts`). Links and calls in comments are not read.
313
+ * (see `sugarcube-macros.ts`). Links and calls in comments are not read. A script passage is
314
+ * read for links only in its strings; a stylesheet passage (including a loaded `.css` file) is
315
+ * CSS and links to nothing. With a `target` (see `InspectOptions`), a passage that output leaves
316
+ * out links to nothing, except a script passage, which Twine 2 output runs.
272
317
  */
273
318
  links: Map<string, string[]>;
274
- /** Broken links: `{ from, to }` pairs where `to` doesn't exist as a passage. */
319
+ /**
320
+ * Broken links: `{ from, to }` pairs where `to` doesn't exist as a passage, or, with a `target`
321
+ * (see `InspectOptions`), where that output leaves the `to` passage out (`omission` says why).
322
+ */
275
323
  brokenLinks: BrokenLink[];
276
324
  /** Story passages with no outgoing links (potential dead ends). */
277
325
  deadEnds: string[];
@@ -283,6 +331,11 @@ interface StoryMap {
283
331
  interface BrokenLink {
284
332
  from: string;
285
333
  to: string;
334
+ /**
335
+ * Set when a passage named `to` exists, but the inspected output leaves it out of the story
336
+ * (only with a `target`): why it is left out. Absent when no passage has the name.
337
+ */
338
+ omission?: PassageOmission;
286
339
  }
287
340
  /**
288
341
  * Inspect a story and return its full structural map.
@@ -299,8 +352,15 @@ interface BrokenLink {
299
352
  * expect(map.brokenLinks).toEqual([]);
300
353
  * expect(map.deadEnds).not.toContain('Start');
301
354
  * ```
355
+ *
356
+ * By default, a link is broken only when no passage has its name. Pass a `target` to check links
357
+ * against what that output emits: `storyInspect(result.story, { target: 'twine2' })` also reports
358
+ * links to passages Twine 2 output leaves out, such as script, stylesheet and `Twine.private`
359
+ * passages. With a target, passages that output leaves out also give no links (script passages
360
+ * excepted, as Twine 2 output runs them), so they report no broken links and keep no passage from
361
+ * being an orphan.
302
362
  */
303
- export declare function storyInspect(story: ReadonlyStory): StoryMap;
363
+ export declare function storyInspect(story: ReadonlyStory, options?: InspectOptions): StoryMap;
304
364
  //#endregion
305
365
  //#region src/story.d.ts
306
366
  /**
@@ -327,8 +387,9 @@ interface DecompileResult {
327
387
  }
328
388
  /**
329
389
  * Parse a Twine 2 or Twine 1 compiled HTML file back into a Story model.
390
+ * Tweego always trims passage text; here `trim: false` keeps it exactly, as for Twee sources.
330
391
  */
331
- export declare function decompileHTML(html: string): DecompileResult;
392
+ export declare function decompileHTML(html: string, options?: DecompileOptions): DecompileResult;
332
393
  //#endregion
333
394
  //#region src/lint.d.ts
334
395
  interface LintResult {
@@ -348,7 +409,11 @@ interface LintResult {
348
409
  storyPassages: number;
349
410
  /** Info/special passage count. */
350
411
  infoPassages: number;
351
- /** Broken links: link targets that don't exist as passages. */
412
+ /**
413
+ * Broken links: link targets that don't exist as passages, or that Twine 2 output leaves out
414
+ * (script, stylesheet and `Twine.private` passages, StoryData, StoryTitle, an empty
415
+ * StorySettings); for those, `omission` says why.
416
+ */
352
417
  brokenLinks: BrokenLink[];
353
418
  /** Story passages with no outgoing links. */
354
419
  deadEnds: string[];
@@ -358,7 +423,10 @@ interface LintResult {
358
423
  /**
359
424
  * Lint a story: compile without output rendering, then inspect structure.
360
425
  * Uses JSON output mode internally to avoid format resolution, so it checks
361
- * the starting passage itself, against the Twine 2 passage rules.
426
+ * the starting passage itself, against the Twine 2 passage rules. Link
427
+ * destinations are checked against the same rules: a link to a passage that
428
+ * Twine 2 output leaves out is broken, and a passage it leaves out (other than
429
+ * a script passage) gives no links.
362
430
  */
363
431
  export declare function lint(options: Omit<CompileOptions, 'outputMode'>): Promise<LintResult>;
364
432
  /**
@@ -442,7 +510,10 @@ export declare function semverCompare(a: [number, number, number], b: [number, n
442
510
  //#region src/ifid.d.ts
443
511
  /** Generate a new IFID (UUID v4, uppercase). */
444
512
  export declare function generateIFID(): IFID;
445
- /** Validate and brand an IFID string. Throws on invalid input. */
513
+ /**
514
+ * Validate and brand an IFID string. Throws on invalid input.
515
+ * Returns the IFID in its stored form (see `normalizeIFID`).
516
+ */
446
517
  export declare function createIFID(value: string): IFID;
447
518
  /**
448
519
  * Validate an IFID string.
@@ -501,4 +572,4 @@ export declare function getCacheSize(): {
501
572
  count: number;
502
573
  };
503
574
  //#endregion
504
- export type { BrokenLink, CachedFormatEntry, CompileOptions, CompileResult, CompileStats, CompileToFileOptions, DecompileResult, Diagnostic, FileCacheEntry, IFID, InlineSource, LexerItem, LintResult, OutputMode, Passage, PassageMetadata, ReadonlyPassage, ReadonlyStory, SFAIndex, SFAIndexEntry, SourceInput, SourceLocation, Story, StoryFormatInfo, StoryMap, TweeTsConfig, WatchOptions, WordCountMethod };
575
+ export type { BrokenLink, CachedFormatEntry, CompileOptions, CompileResult, CompileStats, CompileToFileOptions, DecompileOptions, DecompileResult, Diagnostic, FileCacheEntry, IFID, InlineSource, InspectOptions, LexerItem, LintResult, OmittingTag, OutputMode, Passage, PassageMetadata, PassageOmission, PassageOutputTarget, ReadonlyPassage, ReadonlyStory, SFAIndex, SFAIndexEntry, SourceInput, SourceLocation, Story, StoryFormatInfo, StoryMap, TweeTsConfig, WatchOptions, WordCountMethod };