@patterkit/model 0.9.0 → 0.11.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 +54 -0
- package/dist/index.d.cts +72 -4
- package/dist/index.d.ts +72 -4
- package/dist/index.js +44 -0
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -20,19 +20,25 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
20
20
|
// src/index.ts
|
|
21
21
|
var index_exports = {};
|
|
22
22
|
__export(index_exports, {
|
|
23
|
+
AUTHORING_SCHEMA: () => AUTHORING_SCHEMA,
|
|
23
24
|
COMMON_GENDERS: () => COMMON_GENDERS,
|
|
24
25
|
DEFAULT_CAPTION_CHARACTER: () => DEFAULT_CAPTION_CHARACTER,
|
|
25
26
|
DEFAULT_CAPTION_DELIMITERS: () => DEFAULT_CAPTION_DELIMITERS,
|
|
26
27
|
DEFAULT_DOCUMENTATION_CLASSES: () => DEFAULT_DOCUMENTATION_CLASSES,
|
|
28
|
+
DEFAULT_LAYOUT: () => DEFAULT_LAYOUT,
|
|
29
|
+
DEFAULT_QUALIFIERS: () => DEFAULT_QUALIFIERS,
|
|
27
30
|
DEFAULT_RECORDING_STATUSES: () => DEFAULT_RECORDING_STATUSES,
|
|
28
31
|
DEFAULT_WRITING_STATUSES: () => DEFAULT_WRITING_STATUSES,
|
|
32
|
+
FLOW_SCHEMA: () => FLOW_SCHEMA,
|
|
29
33
|
HANDOFF_SCHEMA: () => HANDOFF_SCHEMA,
|
|
30
34
|
PROJECT_LOCALE_SCENE: () => PROJECT_LOCALE_SCENE,
|
|
35
|
+
PROJECT_SCHEMA: () => PROJECT_SCHEMA,
|
|
31
36
|
RERECORD_STATUS: () => RERECORD_STATUS,
|
|
32
37
|
RERECORD_STATUS_DECL: () => RERECORD_STATUS_DECL,
|
|
33
38
|
RESERVED_PROPERTY_NAMES: () => import_expr.RESERVED_PROPERTY_NAMES,
|
|
34
39
|
SAVE_SCHEMA: () => SAVE_SCHEMA,
|
|
35
40
|
SAVE_VERSION: () => SAVE_VERSION,
|
|
41
|
+
STRINGS_SCHEMA: () => STRINGS_SCHEMA,
|
|
36
42
|
castStringKey: () => castStringKey,
|
|
37
43
|
deriveRecordingFolders: () => deriveRecordingFolders,
|
|
38
44
|
effectiveGameId: () => effectiveGameId,
|
|
@@ -41,7 +47,11 @@ __export(index_exports, {
|
|
|
41
47
|
isContentlessBeat: () => isContentlessBeat,
|
|
42
48
|
isValidGameId: () => isValidGameId,
|
|
43
49
|
isValidPropertyName: () => import_expr.isValidPropertyName,
|
|
50
|
+
projectLayout: () => projectLayout,
|
|
51
|
+
projectQualifiers: () => projectQualifiers,
|
|
44
52
|
propertyNameify: () => import_expr.propertyNameify,
|
|
53
|
+
qualifierStringKey: () => qualifierStringKey,
|
|
54
|
+
usedQualifiers: () => usedQualifiers,
|
|
45
55
|
walkNodes: () => walkNodes
|
|
46
56
|
});
|
|
47
57
|
module.exports = __toCommonJS(index_exports);
|
|
@@ -71,6 +81,29 @@ function effectiveGameId(entity) {
|
|
|
71
81
|
return g ? g : gameIdify(entity.name);
|
|
72
82
|
}
|
|
73
83
|
var COMMON_GENDERS = ["male", "female", "neuter"];
|
|
84
|
+
var DEFAULT_QUALIFIERS = [
|
|
85
|
+
{ gameId: "vo", name: "V.O.", description: "Voice-over: the character isn't in the scene (a thought, narration, a voice in the ear)." },
|
|
86
|
+
{ gameId: "os", name: "O.S.", description: "Off-screen: the character is there, but not seen (the next room, behind a door)." },
|
|
87
|
+
{ gameId: "radio", name: "RADIO", description: "Heard through a radio, a phone, or a loudspeaker." }
|
|
88
|
+
];
|
|
89
|
+
function projectQualifiers(project) {
|
|
90
|
+
return project.qualifiers ?? DEFAULT_QUALIFIERS;
|
|
91
|
+
}
|
|
92
|
+
function usedQualifiers(project, scenes) {
|
|
93
|
+
const used = /* @__PURE__ */ new Set();
|
|
94
|
+
for (const scene of scenes) {
|
|
95
|
+
for (const block of scene.blocks) {
|
|
96
|
+
walkNodes(block.children, (node) => {
|
|
97
|
+
if (node.type === "group") {
|
|
98
|
+
if (node.prompt?.kind === "line" && node.prompt.qualifier) used.add(node.prompt.qualifier);
|
|
99
|
+
return;
|
|
100
|
+
}
|
|
101
|
+
for (const beat of node.beats ?? []) if (beat.kind === "line" && beat.qualifier) used.add(beat.qualifier);
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
return projectQualifiers(project).filter((q) => used.has(q.gameId));
|
|
106
|
+
}
|
|
74
107
|
var DEFAULT_WRITING_STATUSES = [
|
|
75
108
|
{ name: "stub", colour: 0 },
|
|
76
109
|
// red
|
|
@@ -116,26 +149,43 @@ var PROJECT_LOCALE_SCENE = "@project";
|
|
|
116
149
|
function castStringKey(name) {
|
|
117
150
|
return `cast:${name}`;
|
|
118
151
|
}
|
|
152
|
+
function qualifierStringKey(gameId) {
|
|
153
|
+
return `qualifier:${gameId}`;
|
|
154
|
+
}
|
|
119
155
|
var HANDOFF_SCHEMA = "patter/handoff@0";
|
|
120
156
|
var DEFAULT_CAPTION_DELIMITERS = { open: "[", close: "]" };
|
|
121
157
|
var DEFAULT_CAPTION_CHARACTER = "SFX";
|
|
122
158
|
var SAVE_SCHEMA = "patter/save@0";
|
|
123
159
|
var SAVE_VERSION = 3;
|
|
160
|
+
var DEFAULT_LAYOUT = { flow: "scenes/", strings: "loc/", authoring: "authoring/" };
|
|
161
|
+
function projectLayout(project) {
|
|
162
|
+
return { ...DEFAULT_LAYOUT, ...project.layout };
|
|
163
|
+
}
|
|
164
|
+
var FLOW_SCHEMA = "patter/flow@0";
|
|
165
|
+
var PROJECT_SCHEMA = "patter/project@0";
|
|
166
|
+
var STRINGS_SCHEMA = "patter/strings@0";
|
|
167
|
+
var AUTHORING_SCHEMA = "patter/authoring@0";
|
|
124
168
|
// Annotate the CommonJS export names for ESM import in node:
|
|
125
169
|
0 && (module.exports = {
|
|
170
|
+
AUTHORING_SCHEMA,
|
|
126
171
|
COMMON_GENDERS,
|
|
127
172
|
DEFAULT_CAPTION_CHARACTER,
|
|
128
173
|
DEFAULT_CAPTION_DELIMITERS,
|
|
129
174
|
DEFAULT_DOCUMENTATION_CLASSES,
|
|
175
|
+
DEFAULT_LAYOUT,
|
|
176
|
+
DEFAULT_QUALIFIERS,
|
|
130
177
|
DEFAULT_RECORDING_STATUSES,
|
|
131
178
|
DEFAULT_WRITING_STATUSES,
|
|
179
|
+
FLOW_SCHEMA,
|
|
132
180
|
HANDOFF_SCHEMA,
|
|
133
181
|
PROJECT_LOCALE_SCENE,
|
|
182
|
+
PROJECT_SCHEMA,
|
|
134
183
|
RERECORD_STATUS,
|
|
135
184
|
RERECORD_STATUS_DECL,
|
|
136
185
|
RESERVED_PROPERTY_NAMES,
|
|
137
186
|
SAVE_SCHEMA,
|
|
138
187
|
SAVE_VERSION,
|
|
188
|
+
STRINGS_SCHEMA,
|
|
139
189
|
castStringKey,
|
|
140
190
|
deriveRecordingFolders,
|
|
141
191
|
effectiveGameId,
|
|
@@ -144,6 +194,10 @@ var SAVE_VERSION = 3;
|
|
|
144
194
|
isContentlessBeat,
|
|
145
195
|
isValidGameId,
|
|
146
196
|
isValidPropertyName,
|
|
197
|
+
projectLayout,
|
|
198
|
+
projectQualifiers,
|
|
147
199
|
propertyNameify,
|
|
200
|
+
qualifierStringKey,
|
|
201
|
+
usedQualifiers,
|
|
148
202
|
walkNodes
|
|
149
203
|
});
|
package/dist/index.d.cts
CHANGED
|
@@ -23,6 +23,10 @@ interface LineBeat {
|
|
|
23
23
|
character?: string;
|
|
24
24
|
/** Performance direction, language-neutral (never localised). */
|
|
25
25
|
direction?: string;
|
|
26
|
+
/** Speaker qualifier: the `gameId` of one of the project's qualifiers (`vo`, `os`, `radio`), which says
|
|
27
|
+
* how the line is delivered (`TAM (O.S.)`), not who says it. Absent = none. The speaker is still
|
|
28
|
+
* `character` for every authoring and reporting purpose. See `SpeakerQualifier`. */
|
|
29
|
+
qualifier?: string;
|
|
26
30
|
gameData?: GameData;
|
|
27
31
|
/** Author-defined freeform tags (#215): a cross-cutting label layer that travels to the runtime.
|
|
28
32
|
* At runtime a beat's tags are the UNION of its own and every ancestor's (scene → block → group(s) →
|
|
@@ -328,6 +332,29 @@ interface CastMember {
|
|
|
328
332
|
actor?: string;
|
|
329
333
|
gameData?: GameData;
|
|
330
334
|
}
|
|
335
|
+
/** A speaker qualifier (a screenplay's character extension): `V.O.`, `O.S.`, `RADIO`, or the project's own.
|
|
336
|
+
* A line stores the `gameId`; the `name` is what the cue, Play, and the scripts show, and is localised as a
|
|
337
|
+
* cast display name is (`qualifierStringKey`). */
|
|
338
|
+
interface SpeakerQualifier {
|
|
339
|
+
/** What code switches on, and what a line stores. Unique in the project; hyphen-slug form (`gameIdify`). */
|
|
340
|
+
gameId: string;
|
|
341
|
+
/** What the script shows (`V.O.`). Free to change: lines hold the `gameId`. */
|
|
342
|
+
name: string;
|
|
343
|
+
/** What the qualifier means, for writers. Authoring only. */
|
|
344
|
+
description?: string;
|
|
345
|
+
}
|
|
346
|
+
/** The qualifiers a project starts with. Their `gameId`s are pinned (`gameIdify` would make `V.O.` into
|
|
347
|
+
* `v-o`); a qualifier a writer adds takes its `gameId` from `gameIdify(name)`. */
|
|
348
|
+
declare const DEFAULT_QUALIFIERS: SpeakerQualifier[];
|
|
349
|
+
/** The project's qualifiers: its own list, else the defaults. */
|
|
350
|
+
declare function projectQualifiers(project: Pick<ProjectFile, "qualifiers">): SpeakerQualifier[];
|
|
351
|
+
/** The project's qualifiers that some line (or line prompt) in these scenes uses, in the project's order. */
|
|
352
|
+
declare function usedQualifiers(project: Pick<ProjectFile, "qualifiers">, scenes: Scene[]): SpeakerQualifier[];
|
|
353
|
+
/** A qualifier as it reaches a compiled bundle: its `gameId` and authored name (the unlocalised fallback). */
|
|
354
|
+
interface BundleQualifier {
|
|
355
|
+
gameId: string;
|
|
356
|
+
name: string;
|
|
357
|
+
}
|
|
331
358
|
/** The cast as it reaches a compiled bundle: the player-facing fields only. `notes`, `actor` and
|
|
332
359
|
* `gender` are authoring / production / translation context, and the compiler drops them, so a shipped
|
|
333
360
|
* game never carries a real person's name or a writer's private notes. The compiler copies the shipping
|
|
@@ -533,7 +560,7 @@ interface ProjectFile {
|
|
|
533
560
|
authoring?: string;
|
|
534
561
|
};
|
|
535
562
|
/** `bundle`: the compiled `.patterc` output path (relative to the project root,
|
|
536
|
-
* or absolute); default
|
|
563
|
+
* or absolute); default `../patter-dist/<project-file-stem>.patterc`, beside the project (spec §11).
|
|
537
564
|
* `localisation`: how strings ship + are resolved (spec §11).
|
|
538
565
|
* - "embedded" (default): every locale's strings live INSIDE the `.patterc`; the runtime resolves
|
|
539
566
|
* them and can switch locale live (`setLocale`).
|
|
@@ -565,6 +592,9 @@ interface ProjectFile {
|
|
|
565
592
|
* externally-gated branches get exercised. Authoring-only (never reaches the runtime bundle). */
|
|
566
593
|
coverageDrivers?: CoverageDriver[];
|
|
567
594
|
cast?: CastMember[];
|
|
595
|
+
/** The speaker qualifiers a line can pick from, in display order; default `DEFAULT_QUALIFIERS`. An empty
|
|
596
|
+
* list means the project uses none. */
|
|
597
|
+
qualifiers?: SpeakerQualifier[];
|
|
568
598
|
gameDataFields?: GameDataFields;
|
|
569
599
|
/** Ordered writing-status ladder (not-done -> done); default `DEFAULT_WRITING_STATUSES`. */
|
|
570
600
|
writingStatuses?: WritingStatusDecl[];
|
|
@@ -605,12 +635,16 @@ interface LocaleFile {
|
|
|
605
635
|
strings: Record<string, string>;
|
|
606
636
|
}
|
|
607
637
|
/** The `scene` marker for a project-level loc shard (`loc/<locale>/_project.patterloc`): strings that
|
|
608
|
-
* aren't tied to a scene beat - currently cast display names
|
|
638
|
+
* aren't tied to a scene beat - currently cast display names and speaker qualifier names, later project
|
|
639
|
+
* title / UI strings. */
|
|
609
640
|
declare const PROJECT_LOCALE_SCENE = "@project";
|
|
610
641
|
/** The project-level loc-string key for a cast member's player-facing name, e.g. `cast:BARKEEP`.
|
|
611
642
|
* Namespaced so it can't collide with opaque beat ids. The default-locale value is seeded from the
|
|
612
643
|
* CastMember's `displayName`; the runtime resolves a character's shown name through this key. */
|
|
613
644
|
declare function castStringKey(name: string): string;
|
|
645
|
+
/** The project-level loc-string key for a speaker qualifier's shown name, e.g. `qualifier:vo`. Resolved as a
|
|
646
|
+
* cast display name is: the active locale, then the default locale, then the authored `name`. */
|
|
647
|
+
declare function qualifierStringKey(gameId: string): string;
|
|
614
648
|
/** Typed documentation annotation line (spec §18). */
|
|
615
649
|
interface DocLine {
|
|
616
650
|
/** The documentation CLASS (a `DocumentationClass.name`) - routes export
|
|
@@ -690,6 +724,10 @@ interface Suggestion {
|
|
|
690
724
|
/** A proposed new direction (the parenthetical), and the direction when suggested ("" for none). */
|
|
691
725
|
proposedDirection?: string;
|
|
692
726
|
baselineDirection?: string;
|
|
727
|
+
/** A proposed new speaker qualifier (a `gameId` from the project's list, "" for none), and the qualifier
|
|
728
|
+
* when suggested ("" for none). */
|
|
729
|
+
proposedQualifier?: string;
|
|
730
|
+
baselineQualifier?: string;
|
|
693
731
|
/** A proposal to cut the beat (an editor emptied its line). Accept marks it cut. */
|
|
694
732
|
proposedCut?: boolean;
|
|
695
733
|
/** Where the suggestion came from, when it arrived in an editable-script handoff: the handoff and the
|
|
@@ -795,8 +833,9 @@ interface HandoffLine {
|
|
|
795
833
|
/** The beat id (a line, a narration beat, or an option prompt). */
|
|
796
834
|
id: string;
|
|
797
835
|
kind: "line" | "narration" | "option";
|
|
798
|
-
/** The speaker and direction as sent (spoken lines only). */
|
|
836
|
+
/** The speaker, speaker qualifier (`gameId`), and direction as sent (spoken lines only). */
|
|
799
837
|
character?: string;
|
|
838
|
+
qualifier?: string;
|
|
800
839
|
direction?: string;
|
|
801
840
|
/** The text as sent: the baseline for every comparison on reimport. */
|
|
802
841
|
baseline: string;
|
|
@@ -910,6 +949,9 @@ interface Bundle {
|
|
|
910
949
|
};
|
|
911
950
|
/** Player-facing cast only: the compiler strips notes / actor / gender (see `BundleCastMember`). */
|
|
912
951
|
cast?: BundleCastMember[];
|
|
952
|
+
/** The speaker qualifiers the content uses, in the project's order. Absent when no line has one, so a
|
|
953
|
+
* bundle without qualifiers is exactly as before. */
|
|
954
|
+
qualifiers?: BundleQualifier[];
|
|
913
955
|
properties?: PropertyDecl[];
|
|
914
956
|
/** Host / world scope declarations, baked from the project so the runtime can self-back a declared
|
|
915
957
|
* scope (`@world`, ...) when no host resolver claims its token. Absent = no host scopes. */
|
|
@@ -991,6 +1033,8 @@ interface SavedChoicePrompt {
|
|
|
991
1033
|
character?: string;
|
|
992
1034
|
characterName?: string;
|
|
993
1035
|
direction?: string;
|
|
1036
|
+
qualifier?: string;
|
|
1037
|
+
qualifierName?: string;
|
|
994
1038
|
}
|
|
995
1039
|
/** One option of a pending choice, saved VERBATIM: re-deriving on load would re-evaluate conditions. */
|
|
996
1040
|
interface SavedChoiceOption {
|
|
@@ -1067,5 +1111,29 @@ interface SaveGameV2 {
|
|
|
1067
1111
|
stageBags: Record<string, Record<string, ScalarValue>>;
|
|
1068
1112
|
flows: Record<string, FlowSnapshotV2>;
|
|
1069
1113
|
}
|
|
1114
|
+
/** Where a project keeps its shards unless its `layout` says otherwise, relative to the project root. */
|
|
1115
|
+
declare const DEFAULT_LAYOUT: {
|
|
1116
|
+
readonly flow: "scenes/";
|
|
1117
|
+
readonly strings: "loc/";
|
|
1118
|
+
readonly authoring: "authoring/";
|
|
1119
|
+
};
|
|
1120
|
+
/** A project's layout with the defaults filled in: the one place they are written down (the loader,
|
|
1121
|
+
* validate, localisation, the scene scaffold, and Patterpad each had a copy). */
|
|
1122
|
+
declare function projectLayout(project: {
|
|
1123
|
+
layout?: {
|
|
1124
|
+
flow?: string;
|
|
1125
|
+
strings?: string;
|
|
1126
|
+
authoring?: string;
|
|
1127
|
+
};
|
|
1128
|
+
}): {
|
|
1129
|
+
flow: string;
|
|
1130
|
+
strings: string;
|
|
1131
|
+
authoring: string;
|
|
1132
|
+
};
|
|
1133
|
+
/** The source shards' schema tags (spec §10), written by every tool that makes one. */
|
|
1134
|
+
declare const FLOW_SCHEMA = "patter/flow@0";
|
|
1135
|
+
declare const PROJECT_SCHEMA = "patter/project@0";
|
|
1136
|
+
declare const STRINGS_SCHEMA = "patter/strings@0";
|
|
1137
|
+
declare const AUTHORING_SCHEMA = "patter/authoring@0";
|
|
1070
1138
|
|
|
1071
|
-
export { type AuthoringFile, type Beat, type Block, type Bundle, type BundleCastMember, COMMON_GENDERS, 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 EngineSave, type EstimatingConfig, type Expression, type FlowCursor, type FlowFile, type FlowNode, type FlowSnapshot, type FlowSnapshotV2, type GameData, type GameDataField, type GameDataFieldType, type GameDataFields, type GameDataNodeKind, type GameEventBeat, type GrammaticalGender, type Group, HANDOFF_SCHEMA, type HandoffFile, type HandoffImport, type HandoffLine, type HandoffRow, 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, SAVE_SCHEMA, SAVE_VERSION, type SaveEnvelope, type SaveGame, type SaveGameV2, type SavedChoice, type SavedChoiceOption, type SavedChoicePrompt, type ScalarValue, type Scene, type Selector, type SelectorExhaust, type SelectorOrder, type SelectorSnapshot, type SequenceOptions, type Snippet, type StackFrame, type Suggestion, type SuggestionSource, type TextBeat, type VcsKind, type WritingStatusDecl, castStringKey, deriveRecordingFolders, effectiveGameId, gameIdify, isContentlessBeat, isValidGameId, walkNodes };
|
|
1139
|
+
export { AUTHORING_SCHEMA, type AuthoringFile, type Beat, type Block, type Bundle, type BundleCastMember, type BundleQualifier, COMMON_GENDERS, 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_LAYOUT, DEFAULT_QUALIFIERS, DEFAULT_RECORDING_STATUSES, DEFAULT_WRITING_STATUSES, type DocLine, type DocumentationClass, type EditRecord, type Effect, type EngineSave, type EstimatingConfig, type Expression, FLOW_SCHEMA, type FlowCursor, type FlowFile, type FlowNode, type FlowSnapshot, type FlowSnapshotV2, type GameData, type GameDataField, type GameDataFieldType, type GameDataFields, type GameDataNodeKind, type GameEventBeat, type GrammaticalGender, type Group, HANDOFF_SCHEMA, type HandoffFile, type HandoffImport, type HandoffLine, type HandoffRow, type HostScopeDecl, type HostScopeRegistry, type HostScopeSpec, type Jump, type JumpTarget, type LineBeat, type LocaleFile, PROJECT_LOCALE_SCENE, PROJECT_SCHEMA, type ProjectDictionary, type ProjectFile, type PromptBeat, type PropertyDecl, type PropertyType, RERECORD_STATUS, RERECORD_STATUS_DECL, type RecordingFolder, type RecordingStatusDecl, SAVE_SCHEMA, SAVE_VERSION, STRINGS_SCHEMA, type SaveEnvelope, type SaveGame, type SaveGameV2, type SavedChoice, type SavedChoiceOption, type SavedChoicePrompt, type ScalarValue, type Scene, type Selector, type SelectorExhaust, type SelectorOrder, type SelectorSnapshot, type SequenceOptions, type Snippet, type SpeakerQualifier, type StackFrame, type Suggestion, type SuggestionSource, type TextBeat, type VcsKind, type WritingStatusDecl, castStringKey, deriveRecordingFolders, effectiveGameId, gameIdify, isContentlessBeat, isValidGameId, projectLayout, projectQualifiers, qualifierStringKey, usedQualifiers, walkNodes };
|
package/dist/index.d.ts
CHANGED
|
@@ -23,6 +23,10 @@ interface LineBeat {
|
|
|
23
23
|
character?: string;
|
|
24
24
|
/** Performance direction, language-neutral (never localised). */
|
|
25
25
|
direction?: string;
|
|
26
|
+
/** Speaker qualifier: the `gameId` of one of the project's qualifiers (`vo`, `os`, `radio`), which says
|
|
27
|
+
* how the line is delivered (`TAM (O.S.)`), not who says it. Absent = none. The speaker is still
|
|
28
|
+
* `character` for every authoring and reporting purpose. See `SpeakerQualifier`. */
|
|
29
|
+
qualifier?: string;
|
|
26
30
|
gameData?: GameData;
|
|
27
31
|
/** Author-defined freeform tags (#215): a cross-cutting label layer that travels to the runtime.
|
|
28
32
|
* At runtime a beat's tags are the UNION of its own and every ancestor's (scene → block → group(s) →
|
|
@@ -328,6 +332,29 @@ interface CastMember {
|
|
|
328
332
|
actor?: string;
|
|
329
333
|
gameData?: GameData;
|
|
330
334
|
}
|
|
335
|
+
/** A speaker qualifier (a screenplay's character extension): `V.O.`, `O.S.`, `RADIO`, or the project's own.
|
|
336
|
+
* A line stores the `gameId`; the `name` is what the cue, Play, and the scripts show, and is localised as a
|
|
337
|
+
* cast display name is (`qualifierStringKey`). */
|
|
338
|
+
interface SpeakerQualifier {
|
|
339
|
+
/** What code switches on, and what a line stores. Unique in the project; hyphen-slug form (`gameIdify`). */
|
|
340
|
+
gameId: string;
|
|
341
|
+
/** What the script shows (`V.O.`). Free to change: lines hold the `gameId`. */
|
|
342
|
+
name: string;
|
|
343
|
+
/** What the qualifier means, for writers. Authoring only. */
|
|
344
|
+
description?: string;
|
|
345
|
+
}
|
|
346
|
+
/** The qualifiers a project starts with. Their `gameId`s are pinned (`gameIdify` would make `V.O.` into
|
|
347
|
+
* `v-o`); a qualifier a writer adds takes its `gameId` from `gameIdify(name)`. */
|
|
348
|
+
declare const DEFAULT_QUALIFIERS: SpeakerQualifier[];
|
|
349
|
+
/** The project's qualifiers: its own list, else the defaults. */
|
|
350
|
+
declare function projectQualifiers(project: Pick<ProjectFile, "qualifiers">): SpeakerQualifier[];
|
|
351
|
+
/** The project's qualifiers that some line (or line prompt) in these scenes uses, in the project's order. */
|
|
352
|
+
declare function usedQualifiers(project: Pick<ProjectFile, "qualifiers">, scenes: Scene[]): SpeakerQualifier[];
|
|
353
|
+
/** A qualifier as it reaches a compiled bundle: its `gameId` and authored name (the unlocalised fallback). */
|
|
354
|
+
interface BundleQualifier {
|
|
355
|
+
gameId: string;
|
|
356
|
+
name: string;
|
|
357
|
+
}
|
|
331
358
|
/** The cast as it reaches a compiled bundle: the player-facing fields only. `notes`, `actor` and
|
|
332
359
|
* `gender` are authoring / production / translation context, and the compiler drops them, so a shipped
|
|
333
360
|
* game never carries a real person's name or a writer's private notes. The compiler copies the shipping
|
|
@@ -533,7 +560,7 @@ interface ProjectFile {
|
|
|
533
560
|
authoring?: string;
|
|
534
561
|
};
|
|
535
562
|
/** `bundle`: the compiled `.patterc` output path (relative to the project root,
|
|
536
|
-
* or absolute); default
|
|
563
|
+
* or absolute); default `../patter-dist/<project-file-stem>.patterc`, beside the project (spec §11).
|
|
537
564
|
* `localisation`: how strings ship + are resolved (spec §11).
|
|
538
565
|
* - "embedded" (default): every locale's strings live INSIDE the `.patterc`; the runtime resolves
|
|
539
566
|
* them and can switch locale live (`setLocale`).
|
|
@@ -565,6 +592,9 @@ interface ProjectFile {
|
|
|
565
592
|
* externally-gated branches get exercised. Authoring-only (never reaches the runtime bundle). */
|
|
566
593
|
coverageDrivers?: CoverageDriver[];
|
|
567
594
|
cast?: CastMember[];
|
|
595
|
+
/** The speaker qualifiers a line can pick from, in display order; default `DEFAULT_QUALIFIERS`. An empty
|
|
596
|
+
* list means the project uses none. */
|
|
597
|
+
qualifiers?: SpeakerQualifier[];
|
|
568
598
|
gameDataFields?: GameDataFields;
|
|
569
599
|
/** Ordered writing-status ladder (not-done -> done); default `DEFAULT_WRITING_STATUSES`. */
|
|
570
600
|
writingStatuses?: WritingStatusDecl[];
|
|
@@ -605,12 +635,16 @@ interface LocaleFile {
|
|
|
605
635
|
strings: Record<string, string>;
|
|
606
636
|
}
|
|
607
637
|
/** The `scene` marker for a project-level loc shard (`loc/<locale>/_project.patterloc`): strings that
|
|
608
|
-
* aren't tied to a scene beat - currently cast display names
|
|
638
|
+
* aren't tied to a scene beat - currently cast display names and speaker qualifier names, later project
|
|
639
|
+
* title / UI strings. */
|
|
609
640
|
declare const PROJECT_LOCALE_SCENE = "@project";
|
|
610
641
|
/** The project-level loc-string key for a cast member's player-facing name, e.g. `cast:BARKEEP`.
|
|
611
642
|
* Namespaced so it can't collide with opaque beat ids. The default-locale value is seeded from the
|
|
612
643
|
* CastMember's `displayName`; the runtime resolves a character's shown name through this key. */
|
|
613
644
|
declare function castStringKey(name: string): string;
|
|
645
|
+
/** The project-level loc-string key for a speaker qualifier's shown name, e.g. `qualifier:vo`. Resolved as a
|
|
646
|
+
* cast display name is: the active locale, then the default locale, then the authored `name`. */
|
|
647
|
+
declare function qualifierStringKey(gameId: string): string;
|
|
614
648
|
/** Typed documentation annotation line (spec §18). */
|
|
615
649
|
interface DocLine {
|
|
616
650
|
/** The documentation CLASS (a `DocumentationClass.name`) - routes export
|
|
@@ -690,6 +724,10 @@ interface Suggestion {
|
|
|
690
724
|
/** A proposed new direction (the parenthetical), and the direction when suggested ("" for none). */
|
|
691
725
|
proposedDirection?: string;
|
|
692
726
|
baselineDirection?: string;
|
|
727
|
+
/** A proposed new speaker qualifier (a `gameId` from the project's list, "" for none), and the qualifier
|
|
728
|
+
* when suggested ("" for none). */
|
|
729
|
+
proposedQualifier?: string;
|
|
730
|
+
baselineQualifier?: string;
|
|
693
731
|
/** A proposal to cut the beat (an editor emptied its line). Accept marks it cut. */
|
|
694
732
|
proposedCut?: boolean;
|
|
695
733
|
/** Where the suggestion came from, when it arrived in an editable-script handoff: the handoff and the
|
|
@@ -795,8 +833,9 @@ interface HandoffLine {
|
|
|
795
833
|
/** The beat id (a line, a narration beat, or an option prompt). */
|
|
796
834
|
id: string;
|
|
797
835
|
kind: "line" | "narration" | "option";
|
|
798
|
-
/** The speaker and direction as sent (spoken lines only). */
|
|
836
|
+
/** The speaker, speaker qualifier (`gameId`), and direction as sent (spoken lines only). */
|
|
799
837
|
character?: string;
|
|
838
|
+
qualifier?: string;
|
|
800
839
|
direction?: string;
|
|
801
840
|
/** The text as sent: the baseline for every comparison on reimport. */
|
|
802
841
|
baseline: string;
|
|
@@ -910,6 +949,9 @@ interface Bundle {
|
|
|
910
949
|
};
|
|
911
950
|
/** Player-facing cast only: the compiler strips notes / actor / gender (see `BundleCastMember`). */
|
|
912
951
|
cast?: BundleCastMember[];
|
|
952
|
+
/** The speaker qualifiers the content uses, in the project's order. Absent when no line has one, so a
|
|
953
|
+
* bundle without qualifiers is exactly as before. */
|
|
954
|
+
qualifiers?: BundleQualifier[];
|
|
913
955
|
properties?: PropertyDecl[];
|
|
914
956
|
/** Host / world scope declarations, baked from the project so the runtime can self-back a declared
|
|
915
957
|
* scope (`@world`, ...) when no host resolver claims its token. Absent = no host scopes. */
|
|
@@ -991,6 +1033,8 @@ interface SavedChoicePrompt {
|
|
|
991
1033
|
character?: string;
|
|
992
1034
|
characterName?: string;
|
|
993
1035
|
direction?: string;
|
|
1036
|
+
qualifier?: string;
|
|
1037
|
+
qualifierName?: string;
|
|
994
1038
|
}
|
|
995
1039
|
/** One option of a pending choice, saved VERBATIM: re-deriving on load would re-evaluate conditions. */
|
|
996
1040
|
interface SavedChoiceOption {
|
|
@@ -1067,5 +1111,29 @@ interface SaveGameV2 {
|
|
|
1067
1111
|
stageBags: Record<string, Record<string, ScalarValue>>;
|
|
1068
1112
|
flows: Record<string, FlowSnapshotV2>;
|
|
1069
1113
|
}
|
|
1114
|
+
/** Where a project keeps its shards unless its `layout` says otherwise, relative to the project root. */
|
|
1115
|
+
declare const DEFAULT_LAYOUT: {
|
|
1116
|
+
readonly flow: "scenes/";
|
|
1117
|
+
readonly strings: "loc/";
|
|
1118
|
+
readonly authoring: "authoring/";
|
|
1119
|
+
};
|
|
1120
|
+
/** A project's layout with the defaults filled in: the one place they are written down (the loader,
|
|
1121
|
+
* validate, localisation, the scene scaffold, and Patterpad each had a copy). */
|
|
1122
|
+
declare function projectLayout(project: {
|
|
1123
|
+
layout?: {
|
|
1124
|
+
flow?: string;
|
|
1125
|
+
strings?: string;
|
|
1126
|
+
authoring?: string;
|
|
1127
|
+
};
|
|
1128
|
+
}): {
|
|
1129
|
+
flow: string;
|
|
1130
|
+
strings: string;
|
|
1131
|
+
authoring: string;
|
|
1132
|
+
};
|
|
1133
|
+
/** The source shards' schema tags (spec §10), written by every tool that makes one. */
|
|
1134
|
+
declare const FLOW_SCHEMA = "patter/flow@0";
|
|
1135
|
+
declare const PROJECT_SCHEMA = "patter/project@0";
|
|
1136
|
+
declare const STRINGS_SCHEMA = "patter/strings@0";
|
|
1137
|
+
declare const AUTHORING_SCHEMA = "patter/authoring@0";
|
|
1070
1138
|
|
|
1071
|
-
export { type AuthoringFile, type Beat, type Block, type Bundle, type BundleCastMember, COMMON_GENDERS, 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 EngineSave, type EstimatingConfig, type Expression, type FlowCursor, type FlowFile, type FlowNode, type FlowSnapshot, type FlowSnapshotV2, type GameData, type GameDataField, type GameDataFieldType, type GameDataFields, type GameDataNodeKind, type GameEventBeat, type GrammaticalGender, type Group, HANDOFF_SCHEMA, type HandoffFile, type HandoffImport, type HandoffLine, type HandoffRow, 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, SAVE_SCHEMA, SAVE_VERSION, type SaveEnvelope, type SaveGame, type SaveGameV2, type SavedChoice, type SavedChoiceOption, type SavedChoicePrompt, type ScalarValue, type Scene, type Selector, type SelectorExhaust, type SelectorOrder, type SelectorSnapshot, type SequenceOptions, type Snippet, type StackFrame, type Suggestion, type SuggestionSource, type TextBeat, type VcsKind, type WritingStatusDecl, castStringKey, deriveRecordingFolders, effectiveGameId, gameIdify, isContentlessBeat, isValidGameId, walkNodes };
|
|
1139
|
+
export { AUTHORING_SCHEMA, type AuthoringFile, type Beat, type Block, type Bundle, type BundleCastMember, type BundleQualifier, COMMON_GENDERS, 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_LAYOUT, DEFAULT_QUALIFIERS, DEFAULT_RECORDING_STATUSES, DEFAULT_WRITING_STATUSES, type DocLine, type DocumentationClass, type EditRecord, type Effect, type EngineSave, type EstimatingConfig, type Expression, FLOW_SCHEMA, type FlowCursor, type FlowFile, type FlowNode, type FlowSnapshot, type FlowSnapshotV2, type GameData, type GameDataField, type GameDataFieldType, type GameDataFields, type GameDataNodeKind, type GameEventBeat, type GrammaticalGender, type Group, HANDOFF_SCHEMA, type HandoffFile, type HandoffImport, type HandoffLine, type HandoffRow, type HostScopeDecl, type HostScopeRegistry, type HostScopeSpec, type Jump, type JumpTarget, type LineBeat, type LocaleFile, PROJECT_LOCALE_SCENE, PROJECT_SCHEMA, type ProjectDictionary, type ProjectFile, type PromptBeat, type PropertyDecl, type PropertyType, RERECORD_STATUS, RERECORD_STATUS_DECL, type RecordingFolder, type RecordingStatusDecl, SAVE_SCHEMA, SAVE_VERSION, STRINGS_SCHEMA, type SaveEnvelope, type SaveGame, type SaveGameV2, type SavedChoice, type SavedChoiceOption, type SavedChoicePrompt, type ScalarValue, type Scene, type Selector, type SelectorExhaust, type SelectorOrder, type SelectorSnapshot, type SequenceOptions, type Snippet, type SpeakerQualifier, type StackFrame, type Suggestion, type SuggestionSource, type TextBeat, type VcsKind, type WritingStatusDecl, castStringKey, deriveRecordingFolders, effectiveGameId, gameIdify, isContentlessBeat, isValidGameId, projectLayout, projectQualifiers, qualifierStringKey, usedQualifiers, walkNodes };
|
package/dist/index.js
CHANGED
|
@@ -30,6 +30,29 @@ function effectiveGameId(entity) {
|
|
|
30
30
|
return g ? g : gameIdify(entity.name);
|
|
31
31
|
}
|
|
32
32
|
var COMMON_GENDERS = ["male", "female", "neuter"];
|
|
33
|
+
var DEFAULT_QUALIFIERS = [
|
|
34
|
+
{ gameId: "vo", name: "V.O.", description: "Voice-over: the character isn't in the scene (a thought, narration, a voice in the ear)." },
|
|
35
|
+
{ gameId: "os", name: "O.S.", description: "Off-screen: the character is there, but not seen (the next room, behind a door)." },
|
|
36
|
+
{ gameId: "radio", name: "RADIO", description: "Heard through a radio, a phone, or a loudspeaker." }
|
|
37
|
+
];
|
|
38
|
+
function projectQualifiers(project) {
|
|
39
|
+
return project.qualifiers ?? DEFAULT_QUALIFIERS;
|
|
40
|
+
}
|
|
41
|
+
function usedQualifiers(project, scenes) {
|
|
42
|
+
const used = /* @__PURE__ */ new Set();
|
|
43
|
+
for (const scene of scenes) {
|
|
44
|
+
for (const block of scene.blocks) {
|
|
45
|
+
walkNodes(block.children, (node) => {
|
|
46
|
+
if (node.type === "group") {
|
|
47
|
+
if (node.prompt?.kind === "line" && node.prompt.qualifier) used.add(node.prompt.qualifier);
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
for (const beat of node.beats ?? []) if (beat.kind === "line" && beat.qualifier) used.add(beat.qualifier);
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
return projectQualifiers(project).filter((q) => used.has(q.gameId));
|
|
55
|
+
}
|
|
33
56
|
var DEFAULT_WRITING_STATUSES = [
|
|
34
57
|
{ name: "stub", colour: 0 },
|
|
35
58
|
// red
|
|
@@ -75,25 +98,42 @@ var PROJECT_LOCALE_SCENE = "@project";
|
|
|
75
98
|
function castStringKey(name) {
|
|
76
99
|
return `cast:${name}`;
|
|
77
100
|
}
|
|
101
|
+
function qualifierStringKey(gameId) {
|
|
102
|
+
return `qualifier:${gameId}`;
|
|
103
|
+
}
|
|
78
104
|
var HANDOFF_SCHEMA = "patter/handoff@0";
|
|
79
105
|
var DEFAULT_CAPTION_DELIMITERS = { open: "[", close: "]" };
|
|
80
106
|
var DEFAULT_CAPTION_CHARACTER = "SFX";
|
|
81
107
|
var SAVE_SCHEMA = "patter/save@0";
|
|
82
108
|
var SAVE_VERSION = 3;
|
|
109
|
+
var DEFAULT_LAYOUT = { flow: "scenes/", strings: "loc/", authoring: "authoring/" };
|
|
110
|
+
function projectLayout(project) {
|
|
111
|
+
return { ...DEFAULT_LAYOUT, ...project.layout };
|
|
112
|
+
}
|
|
113
|
+
var FLOW_SCHEMA = "patter/flow@0";
|
|
114
|
+
var PROJECT_SCHEMA = "patter/project@0";
|
|
115
|
+
var STRINGS_SCHEMA = "patter/strings@0";
|
|
116
|
+
var AUTHORING_SCHEMA = "patter/authoring@0";
|
|
83
117
|
export {
|
|
118
|
+
AUTHORING_SCHEMA,
|
|
84
119
|
COMMON_GENDERS,
|
|
85
120
|
DEFAULT_CAPTION_CHARACTER,
|
|
86
121
|
DEFAULT_CAPTION_DELIMITERS,
|
|
87
122
|
DEFAULT_DOCUMENTATION_CLASSES,
|
|
123
|
+
DEFAULT_LAYOUT,
|
|
124
|
+
DEFAULT_QUALIFIERS,
|
|
88
125
|
DEFAULT_RECORDING_STATUSES,
|
|
89
126
|
DEFAULT_WRITING_STATUSES,
|
|
127
|
+
FLOW_SCHEMA,
|
|
90
128
|
HANDOFF_SCHEMA,
|
|
91
129
|
PROJECT_LOCALE_SCENE,
|
|
130
|
+
PROJECT_SCHEMA,
|
|
92
131
|
RERECORD_STATUS,
|
|
93
132
|
RERECORD_STATUS_DECL,
|
|
94
133
|
RESERVED_PROPERTY_NAMES,
|
|
95
134
|
SAVE_SCHEMA,
|
|
96
135
|
SAVE_VERSION,
|
|
136
|
+
STRINGS_SCHEMA,
|
|
97
137
|
castStringKey,
|
|
98
138
|
deriveRecordingFolders,
|
|
99
139
|
effectiveGameId,
|
|
@@ -102,6 +142,10 @@ export {
|
|
|
102
142
|
isContentlessBeat,
|
|
103
143
|
isValidGameId,
|
|
104
144
|
isValidPropertyName,
|
|
145
|
+
projectLayout,
|
|
146
|
+
projectQualifiers,
|
|
105
147
|
propertyNameify,
|
|
148
|
+
qualifierStringKey,
|
|
149
|
+
usedQualifiers,
|
|
106
150
|
walkNodes
|
|
107
151
|
};
|
package/package.json
CHANGED