@patterkit/runtime 0.24.0 → 0.25.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/CHANGELOG.md +13 -0
- package/LICENSE +21 -0
- package/dist/index.cjs +26 -2
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +10 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.js +27 -3
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.cts
CHANGED
|
@@ -22,6 +22,7 @@ type StepResult = {
|
|
|
22
22
|
direction?: string;
|
|
23
23
|
qualifier?: string;
|
|
24
24
|
qualifierName?: string;
|
|
25
|
+
speakerLabel?: string;
|
|
25
26
|
padAfter: number;
|
|
26
27
|
gameData?: GameData;
|
|
27
28
|
tags?: string[];
|
|
@@ -58,6 +59,8 @@ interface BeatInfo {
|
|
|
58
59
|
qualifier?: string;
|
|
59
60
|
/** The qualifier's shown name (source locale), e.g. `V.O.`. */
|
|
60
61
|
qualifierName?: string;
|
|
62
|
+
/** The speaker's label (source locale): `You (V.O.)`, a pair's own label, or with no qualifier the name. */
|
|
63
|
+
speakerLabel?: string;
|
|
61
64
|
/** The pause after this beat, in seconds, resolved from its own value and the defaults above it (line and
|
|
62
65
|
* text only; see line padding). What a delivered step carries. */
|
|
63
66
|
padAfter?: number;
|
|
@@ -133,6 +136,8 @@ interface ChoicePrompt {
|
|
|
133
136
|
/** The speaker qualifier's `gameId` (`vo`), and its resolved shown name (locale-aware). */
|
|
134
137
|
qualifier?: string;
|
|
135
138
|
qualifierName?: string;
|
|
139
|
+
/** The name to show for the speaker (locale-aware): see {@link speakerLabelOf}. */
|
|
140
|
+
speakerLabel?: string;
|
|
136
141
|
/** The prompt's resolved pause, in seconds: when it is spoken (by `replayPromptOnChoose`, or by a game that
|
|
137
142
|
* voices it), the wait before the reply, negative to cut in on the question (line padding). */
|
|
138
143
|
padAfter: number;
|
|
@@ -379,6 +384,11 @@ interface FlowHost {
|
|
|
379
384
|
castDisplay: Map<string, string>;
|
|
380
385
|
/** Speaker qualifier gameId -> authored name (the unlocalised fallback when no loc string exists). */
|
|
381
386
|
qualifierDisplay: Map<string, string>;
|
|
387
|
+
/** `<name>\0<gameId>` -> a character's own label with that qualifier, for the overridden pairs only (the
|
|
388
|
+
* unlocalised fallback). A pair not here follows the pattern, whatever a loc file holds for it. */
|
|
389
|
+
speakerLabels: Map<string, string>;
|
|
390
|
+
/** The project's speaker pattern (the unlocalised fallback for the `speaker:pattern` string). */
|
|
391
|
+
speakerPattern: string;
|
|
382
392
|
nodeIndex: Map<string, SelectableNode>;
|
|
383
393
|
blockIndex: Map<string, {
|
|
384
394
|
sceneId: string;
|
package/dist/index.d.ts
CHANGED
|
@@ -22,6 +22,7 @@ type StepResult = {
|
|
|
22
22
|
direction?: string;
|
|
23
23
|
qualifier?: string;
|
|
24
24
|
qualifierName?: string;
|
|
25
|
+
speakerLabel?: string;
|
|
25
26
|
padAfter: number;
|
|
26
27
|
gameData?: GameData;
|
|
27
28
|
tags?: string[];
|
|
@@ -58,6 +59,8 @@ interface BeatInfo {
|
|
|
58
59
|
qualifier?: string;
|
|
59
60
|
/** The qualifier's shown name (source locale), e.g. `V.O.`. */
|
|
60
61
|
qualifierName?: string;
|
|
62
|
+
/** The speaker's label (source locale): `You (V.O.)`, a pair's own label, or with no qualifier the name. */
|
|
63
|
+
speakerLabel?: string;
|
|
61
64
|
/** The pause after this beat, in seconds, resolved from its own value and the defaults above it (line and
|
|
62
65
|
* text only; see line padding). What a delivered step carries. */
|
|
63
66
|
padAfter?: number;
|
|
@@ -133,6 +136,8 @@ interface ChoicePrompt {
|
|
|
133
136
|
/** The speaker qualifier's `gameId` (`vo`), and its resolved shown name (locale-aware). */
|
|
134
137
|
qualifier?: string;
|
|
135
138
|
qualifierName?: string;
|
|
139
|
+
/** The name to show for the speaker (locale-aware): see {@link speakerLabelOf}. */
|
|
140
|
+
speakerLabel?: string;
|
|
136
141
|
/** The prompt's resolved pause, in seconds: when it is spoken (by `replayPromptOnChoose`, or by a game that
|
|
137
142
|
* voices it), the wait before the reply, negative to cut in on the question (line padding). */
|
|
138
143
|
padAfter: number;
|
|
@@ -379,6 +384,11 @@ interface FlowHost {
|
|
|
379
384
|
castDisplay: Map<string, string>;
|
|
380
385
|
/** Speaker qualifier gameId -> authored name (the unlocalised fallback when no loc string exists). */
|
|
381
386
|
qualifierDisplay: Map<string, string>;
|
|
387
|
+
/** `<name>\0<gameId>` -> a character's own label with that qualifier, for the overridden pairs only (the
|
|
388
|
+
* unlocalised fallback). A pair not here follows the pattern, whatever a loc file holds for it. */
|
|
389
|
+
speakerLabels: Map<string, string>;
|
|
390
|
+
/** The project's speaker pattern (the unlocalised fallback for the `speaker:pattern` string). */
|
|
391
|
+
speakerPattern: string;
|
|
382
392
|
nodeIndex: Map<string, SelectableNode>;
|
|
383
393
|
blockIndex: Map<string, {
|
|
384
394
|
sceneId: string;
|
package/dist/index.js
CHANGED
|
@@ -4,7 +4,7 @@ import { matchedSpecificity as scoreSpecificity } from "@wildwinter/expr-specifi
|
|
|
4
4
|
import { ScopeRegistry } from "@wildwinter/scoperegistry";
|
|
5
5
|
import { defaultFor, PropertyBag } from "@wildwinter/scoperegistry";
|
|
6
6
|
import { patterDialect, interpolate, splitRef, stripCaptions } from "@patterkit/dialect";
|
|
7
|
-
import { walkNodes, effectiveGameId, castStringKey, qualifierStringKey, DEFAULT_PAD_AFTER as DEFAULT_PAD_AFTER2, DEFAULT_CAPTION_DELIMITERS, DEFAULT_CAPTION_CHARACTER } from "@patterkit/model";
|
|
7
|
+
import { walkNodes, effectiveGameId, castStringKey, qualifierStringKey, speakerLabelKey, formatSpeakerLabel, SPEAKER_PATTERN_KEY, DEFAULT_SPEAKER_PATTERN, DEFAULT_PAD_AFTER as DEFAULT_PAD_AFTER2, DEFAULT_CAPTION_DELIMITERS, DEFAULT_CAPTION_CHARACTER } from "@patterkit/model";
|
|
8
8
|
|
|
9
9
|
// src/tags.ts
|
|
10
10
|
function dedupe(tags) {
|
|
@@ -168,6 +168,9 @@ var Engine = class _Engine {
|
|
|
168
168
|
for (const c of bundle.cast ?? []) if (c.displayName) castDisplay.set(c.name, c.displayName);
|
|
169
169
|
const qualifierDisplay = /* @__PURE__ */ new Map();
|
|
170
170
|
for (const q of bundle.qualifiers ?? []) if (q?.gameId) qualifierDisplay.set(q.gameId, q.name);
|
|
171
|
+
const speakerLabels = /* @__PURE__ */ new Map();
|
|
172
|
+
for (const c of bundle.cast ?? []) for (const [q, label] of Object.entries(c.qualifierLabels ?? {})) if (typeof label === "string") speakerLabels.set(`${c.name}\0${q}`, label);
|
|
173
|
+
const speakerPattern = bundle.speakerPattern ?? DEFAULT_SPEAKER_PATTERN;
|
|
171
174
|
this.defaultSeed = (options.seed ?? 2654435769) >>> 0;
|
|
172
175
|
const nodeIndex = /* @__PURE__ */ new Map();
|
|
173
176
|
const blockIndex = /* @__PURE__ */ new Map();
|
|
@@ -229,6 +232,8 @@ var Engine = class _Engine {
|
|
|
229
232
|
defaultStrings,
|
|
230
233
|
castDisplay,
|
|
231
234
|
qualifierDisplay,
|
|
235
|
+
speakerLabels,
|
|
236
|
+
speakerPattern,
|
|
232
237
|
nodeIndex,
|
|
233
238
|
blockIndex,
|
|
234
239
|
blockById,
|
|
@@ -639,6 +644,8 @@ var Engine = class _Engine {
|
|
|
639
644
|
const name = this.host.defaultStrings[qualifierStringKey(beat.qualifier)] ?? this.host.qualifierDisplay.get(beat.qualifier);
|
|
640
645
|
if (name !== void 0) info.qualifierName = name;
|
|
641
646
|
}
|
|
647
|
+
const label = speakerLabelOf(this.host, beat.character, beat.qualifier, true);
|
|
648
|
+
if (label !== void 0) info.speakerLabel = label;
|
|
642
649
|
}
|
|
643
650
|
if (beat.kind === "line" || beat.kind === "text") {
|
|
644
651
|
const pad = this.host.padIndex.get(beat.id);
|
|
@@ -1477,7 +1484,8 @@ var Flow = class {
|
|
|
1477
1484
|
if (!node) continue;
|
|
1478
1485
|
byId.set(o.id, node);
|
|
1479
1486
|
const { prompt: saved, ...rest } = o;
|
|
1480
|
-
|
|
1487
|
+
const label = saved?.kind === "line" && saved.speakerLabel === void 0 ? speakerLabelOf(this.host, saved.character, saved.qualifier) : void 0;
|
|
1488
|
+
options.push({ ...rest, ...saved ? { prompt: { ...saved, padAfter: saved.padAfter ?? this.promptPadOf(node), ...label !== void 0 ? { speakerLabel: label } : {} } } : {} });
|
|
1481
1489
|
}
|
|
1482
1490
|
if (options.length > 0) this.pendingChoice = { groupId: c.pendingChoice.groupId, options, byId };
|
|
1483
1491
|
}
|
|
@@ -1486,7 +1494,9 @@ var Flow = class {
|
|
|
1486
1494
|
if (this.pendingPromptOwnerId) {
|
|
1487
1495
|
const owner = this.host.nodeIndex.get(this.pendingPromptOwnerId);
|
|
1488
1496
|
const beat = owner ? this.authoredPromptOf(owner) : void 0;
|
|
1489
|
-
|
|
1497
|
+
const saved = c.pendingPrompt;
|
|
1498
|
+
const label = saved?.kind === "line" && saved.speakerLabel === void 0 ? speakerLabelOf(this.host, saved.character, saved.qualifier) : void 0;
|
|
1499
|
+
if (beat) this.pendingPrompt = { beat, ...saved ? { shown: { ...saved, padAfter: saved.padAfter ?? this.padOf(beat.id), ...label !== void 0 ? { speakerLabel: label } : {} } } : {} };
|
|
1490
1500
|
else this.pendingPromptOwnerId = null;
|
|
1491
1501
|
}
|
|
1492
1502
|
}
|
|
@@ -1872,6 +1882,7 @@ var Flow = class {
|
|
|
1872
1882
|
direction: silent ? void 0 : beat.direction,
|
|
1873
1883
|
qualifier: silent ? void 0 : beat.qualifier,
|
|
1874
1884
|
qualifierName: silent ? void 0 : this.resolveQualifierName(beat.qualifier),
|
|
1885
|
+
speakerLabel: silent ? void 0 : speakerLabelOf(this.host, beat.character, beat.qualifier),
|
|
1875
1886
|
padAfter: this.padOf(beat.id),
|
|
1876
1887
|
// a silent line still fires, so it still carries its pause
|
|
1877
1888
|
gameData: beat.gameData,
|
|
@@ -1921,6 +1932,7 @@ var Flow = class {
|
|
|
1921
1932
|
direction: beat.direction,
|
|
1922
1933
|
qualifier: beat.qualifier,
|
|
1923
1934
|
qualifierName: this.resolveQualifierName(beat.qualifier),
|
|
1935
|
+
speakerLabel: speakerLabelOf(this.host, beat.character, beat.qualifier),
|
|
1924
1936
|
padAfter
|
|
1925
1937
|
} : { kind: "text", text, padAfter };
|
|
1926
1938
|
}
|
|
@@ -1943,6 +1955,7 @@ var Flow = class {
|
|
|
1943
1955
|
direction: shown.direction,
|
|
1944
1956
|
qualifier: shown.qualifier,
|
|
1945
1957
|
qualifierName: shown.qualifierName,
|
|
1958
|
+
speakerLabel: shown.speakerLabel,
|
|
1946
1959
|
padAfter: this.padOf(beat.id),
|
|
1947
1960
|
gameData: beat.gameData,
|
|
1948
1961
|
...withTags
|
|
@@ -2088,6 +2101,16 @@ function collectCast(nodes, out) {
|
|
|
2088
2101
|
for (const beat of n.beats ?? []) if (beat.kind === "line" && beat.character) out.add(beat.character);
|
|
2089
2102
|
});
|
|
2090
2103
|
}
|
|
2104
|
+
function speakerLabelOf(host, character, qualifier, source = false) {
|
|
2105
|
+
if (!character || host.emitIds) return void 0;
|
|
2106
|
+
const lookup = (key) => (source ? void 0 : host.strings[key]) ?? host.defaultStrings[key];
|
|
2107
|
+
const name = lookup(castStringKey(character)) ?? host.castDisplay.get(character) ?? character;
|
|
2108
|
+
if (qualifier === void 0) return name;
|
|
2109
|
+
const own = host.speakerLabels.get(`${character}\0${qualifier}`);
|
|
2110
|
+
if (own !== void 0) return lookup(speakerLabelKey(character, qualifier)) ?? own;
|
|
2111
|
+
const shown = lookup(qualifierStringKey(qualifier)) ?? host.qualifierDisplay.get(qualifier) ?? qualifier;
|
|
2112
|
+
return formatSpeakerLabel(lookup(SPEAKER_PATTERN_KEY) ?? host.speakerPattern, name, shown);
|
|
2113
|
+
}
|
|
2091
2114
|
function gameDataField(gameData) {
|
|
2092
2115
|
return gameData && Object.keys(gameData).length ? { gameData } : {};
|
|
2093
2116
|
}
|
|
@@ -2098,6 +2121,7 @@ function savedPrompt(p) {
|
|
|
2098
2121
|
if (p.direction !== void 0) out.direction = p.direction;
|
|
2099
2122
|
if (p.qualifier !== void 0) out.qualifier = p.qualifier;
|
|
2100
2123
|
if (p.qualifierName !== void 0) out.qualifierName = p.qualifierName;
|
|
2124
|
+
if (p.speakerLabel !== void 0) out.speakerLabel = p.speakerLabel;
|
|
2101
2125
|
if (typeof p.padAfter === "number") out.padAfter = p.padAfter;
|
|
2102
2126
|
return out;
|
|
2103
2127
|
}
|