@patterkit/model 0.1.2 → 0.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/dist/index.cjs CHANGED
@@ -26,6 +26,8 @@ __export(index_exports, {
26
26
  DEFAULT_RECORDING_STATUSES: () => DEFAULT_RECORDING_STATUSES,
27
27
  DEFAULT_WRITING_STATUSES: () => DEFAULT_WRITING_STATUSES,
28
28
  PROJECT_LOCALE_SCENE: () => PROJECT_LOCALE_SCENE,
29
+ RERECORD_STATUS: () => RERECORD_STATUS,
30
+ RERECORD_STATUS_DECL: () => RERECORD_STATUS_DECL,
29
31
  castStringKey: () => castStringKey,
30
32
  deriveRecordingFolders: () => deriveRecordingFolders,
31
33
  effectiveGameId: () => effectiveGameId,
@@ -81,6 +83,8 @@ var DEFAULT_RECORDING_STATUSES = [
81
83
  { name: "final", colour: 9 }
82
84
  // purple
83
85
  ];
86
+ var RERECORD_STATUS = "rerecord";
87
+ var RERECORD_STATUS_DECL = { name: RERECORD_STATUS, colour: 1 };
84
88
  function deriveRecordingFolders(audioRoot, statuses) {
85
89
  const root = audioRoot?.trim();
86
90
  return statuses.map((s, i) => {
@@ -110,6 +114,8 @@ var DEFAULT_CAPTION_CHARACTER = "SFX";
110
114
  DEFAULT_RECORDING_STATUSES,
111
115
  DEFAULT_WRITING_STATUSES,
112
116
  PROJECT_LOCALE_SCENE,
117
+ RERECORD_STATUS,
118
+ RERECORD_STATUS_DECL,
113
119
  castStringKey,
114
120
  deriveRecordingFolders,
115
121
  effectiveGameId,
package/dist/index.d.cts CHANGED
@@ -293,11 +293,18 @@ interface CoverageDriver {
293
293
  /** The pool the harness picks from (uniform). Empty = the driver is inert. */
294
294
  values: ScalarValue[];
295
295
  }
296
+ /** A character's grammatical gender, for localisation. Translators need it to inflect the speaker's own
297
+ * lines in gendered languages (adjectives, participles, pronouns), which the source text alone often
298
+ * cannot tell them. Absent means "not specified". Authoring-only: it never reaches the runtime bundle,
299
+ * but it IS carried into the localisation handoff formats as translator context (spec §14). */
300
+ type GrammaticalGender = "male" | "female" | "neuter";
296
301
  interface CastMember {
297
302
  /** Canonical speaker name (matched by a beat's `character`); language-neutral key. */
298
303
  name: string;
299
304
  /** Localised player-facing name - a localisation id (project-level strings). */
300
305
  displayName?: string;
306
+ /** Grammatical gender for translators (see `GrammaticalGender`); absent = not specified. */
307
+ gender?: GrammaticalGender;
301
308
  /** Free-text production notes about the character (casting, voice, intent) - authoring only. */
302
309
  notes?: string;
303
310
  /** The voice actor cast for this character, if known - surfaced in the VO script export (spec §16).
@@ -305,6 +312,12 @@ interface CastMember {
305
312
  actor?: string;
306
313
  gameData?: GameData;
307
314
  }
315
+ /** The cast as it reaches a compiled bundle: the player-facing fields only. `notes`, `actor` and
316
+ * `gender` are authoring / production / translation context, and the compiler drops them, so a shipped
317
+ * game never carries a real person's name or a writer's private notes. The compiler copies the shipping
318
+ * fields across explicitly (an allow-list), which is what actually keeps a new authoring field out of
319
+ * the bundle; this type states the resulting contract for anyone reading a bundle. */
320
+ type BundleCastMember = Omit<CastMember, "notes" | "actor" | "gender">;
308
321
  /** A node TYPE that can carry author-defined gameData fields (the gameData schema, project-level).
309
322
  * Beat kinds map straight through: dialogue = `line`, narration = `text`, game event = `gameEvent`. */
310
323
  type GameDataNodeKind = "scene" | "block" | "snippet" | "line" | "text" | "gameEvent";
@@ -357,6 +370,13 @@ interface RecordingStatusDecl {
357
370
  /** The default recording-status ladder (used when a project declares none). The FIRST rung is the
358
371
  * level-0 / absence status: a beat with no recorded status counts as `missing`. */
359
372
  declare const DEFAULT_RECORDING_STATUSES: RecordingStatusDecl[];
373
+ /** The reserved recording status a line takes when it is flagged **needs re-record** (#227): a recorded
374
+ * take exists but is unusable (bad quality, wrong take), so it must be redone. It is NOT a ladder rung -
375
+ * it is a regression flag that MASKS the derived / manual rung for the recording script, the production
376
+ * report, and status browse, so a line "recorded" on disk still shows up as work to do. Reserved so it
377
+ * can't collide with an author-declared rung; carries its own alert colour. */
378
+ declare const RERECORD_STATUS = "rerecord";
379
+ declare const RERECORD_STATUS_DECL: RecordingStatusDecl;
360
380
  /** One recording rung mapped to the folder its audio files live in (Audio Folders mode). */
361
381
  interface RecordingFolder {
362
382
  name: string;
@@ -663,6 +683,14 @@ interface AuthoringFile {
663
683
  * it as a separate "cut: N" figure so a removal is visible, not vanished.
664
684
  */
665
685
  cut?: Record<string, boolean>;
686
+ /**
687
+ * **Needs re-record** (#227): dialogue-line ids whose recorded take is unusable and must be redone
688
+ * (bad quality, wrong take, misread). Orthogonal to the recording ladder - a flagged line keeps its
689
+ * audio on disk, but its recording status is MASKED to the reserved `rerecord` status for the recording
690
+ * script / report / status browse (see `RERECORD_STATUS`), so a "recorded" line still reads as work.
691
+ * Authoring-only; never compiled into a bundle.
692
+ */
693
+ rerecord?: Record<string, boolean>;
666
694
  }
667
695
  /** A compiled expression envelope: canonical source + pre-derived tagged-tuple AST. */
668
696
  interface Expression {
@@ -748,7 +776,8 @@ interface Bundle {
748
776
  default: string;
749
777
  included: string[];
750
778
  };
751
- cast?: CastMember[];
779
+ /** Player-facing cast only: the compiler strips notes / actor / gender (see `BundleCastMember`). */
780
+ cast?: BundleCastMember[];
752
781
  properties?: PropertyDecl[];
753
782
  /** Host / world scope declarations, baked from the project so the runtime can self-back a declared
754
783
  * scope (`@world`, ...) when no host resolver claims its token. Absent = no host scopes. */
@@ -790,4 +819,4 @@ declare const DEFAULT_CAPTION_DELIMITERS: CaptionDelimiters;
790
819
  * captions are off). Applies even to a project that pins no `closedCaptions`. */
791
820
  declare const DEFAULT_CAPTION_CHARACTER = "SFX";
792
821
 
793
- export { type AuthoringFile, type Beat, type Block, type Bundle, type CaptionDelimiters, type CastMember, type Comment, type CommentMessage, type CommentRange, type CompiledBlock, type CompiledEffect, type CompiledGroup, type CompiledScene, type CompiledSnippet, type CoverageDriver, DEFAULT_CAPTION_CHARACTER, DEFAULT_CAPTION_DELIMITERS, DEFAULT_DOCUMENTATION_CLASSES, DEFAULT_RECORDING_STATUSES, DEFAULT_WRITING_STATUSES, type DocLine, type DocumentationClass, type EditRecord, type Effect, type EstimatingConfig, type Expression, type FlowFile, type FlowNode, type GameData, type GameDataField, type GameDataFieldType, type GameDataFields, type GameDataNodeKind, type GameEventBeat, type Group, type HostScopeDecl, type HostScopeRegistry, type HostScopeSpec, type Jump, type JumpTarget, type LineBeat, type LocaleFile, PROJECT_LOCALE_SCENE, type ProjectDictionary, type ProjectFile, type PromptBeat, type PropertyDecl, type PropertyType, type RecordingFolder, type RecordingStatusDecl, type ScalarValue, type Scene, type Selector, type SelectorExhaust, type SelectorOrder, type SequenceOptions, type Snippet, type Suggestion, type TextBeat, type VcsKind, type WritingStatusDecl, castStringKey, deriveRecordingFolders, effectiveGameId, gameIdify, isContentlessBeat, isValidGameId, walkNodes };
822
+ export { type AuthoringFile, type Beat, type Block, type Bundle, type BundleCastMember, type CaptionDelimiters, type CastMember, type Comment, type CommentMessage, type CommentRange, type CompiledBlock, type CompiledEffect, type CompiledGroup, type CompiledScene, type CompiledSnippet, type CoverageDriver, DEFAULT_CAPTION_CHARACTER, DEFAULT_CAPTION_DELIMITERS, DEFAULT_DOCUMENTATION_CLASSES, DEFAULT_RECORDING_STATUSES, DEFAULT_WRITING_STATUSES, type DocLine, type DocumentationClass, type EditRecord, type Effect, type EstimatingConfig, type Expression, type FlowFile, type FlowNode, type GameData, type GameDataField, type GameDataFieldType, type GameDataFields, type GameDataNodeKind, type GameEventBeat, type GrammaticalGender, type Group, type HostScopeDecl, type HostScopeRegistry, type HostScopeSpec, type Jump, type JumpTarget, type LineBeat, type LocaleFile, PROJECT_LOCALE_SCENE, type ProjectDictionary, type ProjectFile, type PromptBeat, type PropertyDecl, type PropertyType, RERECORD_STATUS, RERECORD_STATUS_DECL, type RecordingFolder, type RecordingStatusDecl, type ScalarValue, type Scene, type Selector, type SelectorExhaust, type SelectorOrder, type SequenceOptions, type Snippet, type Suggestion, type TextBeat, type VcsKind, type WritingStatusDecl, castStringKey, deriveRecordingFolders, effectiveGameId, gameIdify, isContentlessBeat, isValidGameId, walkNodes };
package/dist/index.d.ts CHANGED
@@ -293,11 +293,18 @@ interface CoverageDriver {
293
293
  /** The pool the harness picks from (uniform). Empty = the driver is inert. */
294
294
  values: ScalarValue[];
295
295
  }
296
+ /** A character's grammatical gender, for localisation. Translators need it to inflect the speaker's own
297
+ * lines in gendered languages (adjectives, participles, pronouns), which the source text alone often
298
+ * cannot tell them. Absent means "not specified". Authoring-only: it never reaches the runtime bundle,
299
+ * but it IS carried into the localisation handoff formats as translator context (spec §14). */
300
+ type GrammaticalGender = "male" | "female" | "neuter";
296
301
  interface CastMember {
297
302
  /** Canonical speaker name (matched by a beat's `character`); language-neutral key. */
298
303
  name: string;
299
304
  /** Localised player-facing name - a localisation id (project-level strings). */
300
305
  displayName?: string;
306
+ /** Grammatical gender for translators (see `GrammaticalGender`); absent = not specified. */
307
+ gender?: GrammaticalGender;
301
308
  /** Free-text production notes about the character (casting, voice, intent) - authoring only. */
302
309
  notes?: string;
303
310
  /** The voice actor cast for this character, if known - surfaced in the VO script export (spec §16).
@@ -305,6 +312,12 @@ interface CastMember {
305
312
  actor?: string;
306
313
  gameData?: GameData;
307
314
  }
315
+ /** The cast as it reaches a compiled bundle: the player-facing fields only. `notes`, `actor` and
316
+ * `gender` are authoring / production / translation context, and the compiler drops them, so a shipped
317
+ * game never carries a real person's name or a writer's private notes. The compiler copies the shipping
318
+ * fields across explicitly (an allow-list), which is what actually keeps a new authoring field out of
319
+ * the bundle; this type states the resulting contract for anyone reading a bundle. */
320
+ type BundleCastMember = Omit<CastMember, "notes" | "actor" | "gender">;
308
321
  /** A node TYPE that can carry author-defined gameData fields (the gameData schema, project-level).
309
322
  * Beat kinds map straight through: dialogue = `line`, narration = `text`, game event = `gameEvent`. */
310
323
  type GameDataNodeKind = "scene" | "block" | "snippet" | "line" | "text" | "gameEvent";
@@ -357,6 +370,13 @@ interface RecordingStatusDecl {
357
370
  /** The default recording-status ladder (used when a project declares none). The FIRST rung is the
358
371
  * level-0 / absence status: a beat with no recorded status counts as `missing`. */
359
372
  declare const DEFAULT_RECORDING_STATUSES: RecordingStatusDecl[];
373
+ /** The reserved recording status a line takes when it is flagged **needs re-record** (#227): a recorded
374
+ * take exists but is unusable (bad quality, wrong take), so it must be redone. It is NOT a ladder rung -
375
+ * it is a regression flag that MASKS the derived / manual rung for the recording script, the production
376
+ * report, and status browse, so a line "recorded" on disk still shows up as work to do. Reserved so it
377
+ * can't collide with an author-declared rung; carries its own alert colour. */
378
+ declare const RERECORD_STATUS = "rerecord";
379
+ declare const RERECORD_STATUS_DECL: RecordingStatusDecl;
360
380
  /** One recording rung mapped to the folder its audio files live in (Audio Folders mode). */
361
381
  interface RecordingFolder {
362
382
  name: string;
@@ -663,6 +683,14 @@ interface AuthoringFile {
663
683
  * it as a separate "cut: N" figure so a removal is visible, not vanished.
664
684
  */
665
685
  cut?: Record<string, boolean>;
686
+ /**
687
+ * **Needs re-record** (#227): dialogue-line ids whose recorded take is unusable and must be redone
688
+ * (bad quality, wrong take, misread). Orthogonal to the recording ladder - a flagged line keeps its
689
+ * audio on disk, but its recording status is MASKED to the reserved `rerecord` status for the recording
690
+ * script / report / status browse (see `RERECORD_STATUS`), so a "recorded" line still reads as work.
691
+ * Authoring-only; never compiled into a bundle.
692
+ */
693
+ rerecord?: Record<string, boolean>;
666
694
  }
667
695
  /** A compiled expression envelope: canonical source + pre-derived tagged-tuple AST. */
668
696
  interface Expression {
@@ -748,7 +776,8 @@ interface Bundle {
748
776
  default: string;
749
777
  included: string[];
750
778
  };
751
- cast?: CastMember[];
779
+ /** Player-facing cast only: the compiler strips notes / actor / gender (see `BundleCastMember`). */
780
+ cast?: BundleCastMember[];
752
781
  properties?: PropertyDecl[];
753
782
  /** Host / world scope declarations, baked from the project so the runtime can self-back a declared
754
783
  * scope (`@world`, ...) when no host resolver claims its token. Absent = no host scopes. */
@@ -790,4 +819,4 @@ declare const DEFAULT_CAPTION_DELIMITERS: CaptionDelimiters;
790
819
  * captions are off). Applies even to a project that pins no `closedCaptions`. */
791
820
  declare const DEFAULT_CAPTION_CHARACTER = "SFX";
792
821
 
793
- export { type AuthoringFile, type Beat, type Block, type Bundle, type CaptionDelimiters, type CastMember, type Comment, type CommentMessage, type CommentRange, type CompiledBlock, type CompiledEffect, type CompiledGroup, type CompiledScene, type CompiledSnippet, type CoverageDriver, DEFAULT_CAPTION_CHARACTER, DEFAULT_CAPTION_DELIMITERS, DEFAULT_DOCUMENTATION_CLASSES, DEFAULT_RECORDING_STATUSES, DEFAULT_WRITING_STATUSES, type DocLine, type DocumentationClass, type EditRecord, type Effect, type EstimatingConfig, type Expression, type FlowFile, type FlowNode, type GameData, type GameDataField, type GameDataFieldType, type GameDataFields, type GameDataNodeKind, type GameEventBeat, type Group, type HostScopeDecl, type HostScopeRegistry, type HostScopeSpec, type Jump, type JumpTarget, type LineBeat, type LocaleFile, PROJECT_LOCALE_SCENE, type ProjectDictionary, type ProjectFile, type PromptBeat, type PropertyDecl, type PropertyType, type RecordingFolder, type RecordingStatusDecl, type ScalarValue, type Scene, type Selector, type SelectorExhaust, type SelectorOrder, type SequenceOptions, type Snippet, type Suggestion, type TextBeat, type VcsKind, type WritingStatusDecl, castStringKey, deriveRecordingFolders, effectiveGameId, gameIdify, isContentlessBeat, isValidGameId, walkNodes };
822
+ export { type AuthoringFile, type Beat, type Block, type Bundle, type BundleCastMember, type CaptionDelimiters, type CastMember, type Comment, type CommentMessage, type CommentRange, type CompiledBlock, type CompiledEffect, type CompiledGroup, type CompiledScene, type CompiledSnippet, type CoverageDriver, DEFAULT_CAPTION_CHARACTER, DEFAULT_CAPTION_DELIMITERS, DEFAULT_DOCUMENTATION_CLASSES, DEFAULT_RECORDING_STATUSES, DEFAULT_WRITING_STATUSES, type DocLine, type DocumentationClass, type EditRecord, type Effect, type EstimatingConfig, type Expression, type FlowFile, type FlowNode, type GameData, type GameDataField, type GameDataFieldType, type GameDataFields, type GameDataNodeKind, type GameEventBeat, type GrammaticalGender, type Group, type HostScopeDecl, type HostScopeRegistry, type HostScopeSpec, type Jump, type JumpTarget, type LineBeat, type LocaleFile, PROJECT_LOCALE_SCENE, type ProjectDictionary, type ProjectFile, type PromptBeat, type PropertyDecl, type PropertyType, RERECORD_STATUS, RERECORD_STATUS_DECL, type RecordingFolder, type RecordingStatusDecl, type ScalarValue, type Scene, type Selector, type SelectorExhaust, type SelectorOrder, type SequenceOptions, type Snippet, type Suggestion, type TextBeat, type VcsKind, type WritingStatusDecl, castStringKey, deriveRecordingFolders, effectiveGameId, gameIdify, isContentlessBeat, isValidGameId, walkNodes };
package/dist/index.js CHANGED
@@ -45,6 +45,8 @@ var DEFAULT_RECORDING_STATUSES = [
45
45
  { name: "final", colour: 9 }
46
46
  // purple
47
47
  ];
48
+ var RERECORD_STATUS = "rerecord";
49
+ var RERECORD_STATUS_DECL = { name: RERECORD_STATUS, colour: 1 };
48
50
  function deriveRecordingFolders(audioRoot, statuses) {
49
51
  const root = audioRoot?.trim();
50
52
  return statuses.map((s, i) => {
@@ -73,6 +75,8 @@ export {
73
75
  DEFAULT_RECORDING_STATUSES,
74
76
  DEFAULT_WRITING_STATUSES,
75
77
  PROJECT_LOCALE_SCENE,
78
+ RERECORD_STATUS,
79
+ RERECORD_STATUS_DECL,
76
80
  castStringKey,
77
81
  deriveRecordingFolders,
78
82
  effectiveGameId,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@patterkit/model",
3
- "version": "0.1.2",
3
+ "version": "0.2.0",
4
4
  "description": "Patter data-model types: source (scene/block/group/snippet/beat/jump), project, locale, authoring. The shape source-of-truth.",
5
5
  "type": "module",
6
6
  "license": "MIT",