Checkpoint current interactive fiction changes

This commit is contained in:
2026-06-03 12:59:43 +02:00
parent 61127c0a92
commit bccefd2a68
11 changed files with 342 additions and 895 deletions
+48 -3
View File
@@ -67,6 +67,9 @@ class SocketClientModule extends BaseModule {
'isTimedCueTag',
'isRenderMetadataTag',
'cueMarkersFromTags',
'collectGlossaryEntriesForTurn',
'applyTurnGlossaryEntries',
'mergeGlossaryEntries',
'dispatchChoices',
'dispatchInputMode',
'handleServerError',
@@ -302,9 +305,11 @@ class SocketClientModule extends BaseModule {
}
}
const turnGlossaryEntries = this.collectGlossaryEntriesForTurn(turnBlocks, globalTags);
this.applyTurnGlossaryEntries(turnBlocks, turnGlossaryEntries);
const choices = Array.isArray(data.choices) ? data.choices : [];
const inputMode = data.inputMode || (choices.length > 0 ? 'choice' : 'none');
this.dispatchChoices(choices);
this.dispatchChoices(choices, turnGlossaryEntries);
this.dispatchInputMode(inputMode);
await this.storeAndQueueBlocks(turnBlocks);
@@ -336,9 +341,49 @@ class SocketClientModule extends BaseModule {
});
}
dispatchChoices(choices) {
collectGlossaryEntriesForTurn(blocks = [], globalTags = []) {
const markupParser = this.getModule('markup-parser');
const fromGlobal = markupParser && typeof markupParser.extractGlossaryTags === 'function'
? markupParser.extractGlossaryTags(globalTags)
: [];
const entries = [
...fromGlobal,
...blocks.flatMap(block => Array.isArray(block?.glossaryEntries) ? block.glossaryEntries : [])
];
const seen = new Set();
return entries.filter((entry) => {
const key = `${entry?.term || ''}\u0000${entry?.definition || ''}`;
if (!entry?.term || !entry?.definition || seen.has(key)) return false;
seen.add(key);
return true;
});
}
applyTurnGlossaryEntries(blocks = [], entries = []) {
if (!Array.isArray(blocks) || !Array.isArray(entries) || entries.length === 0) return;
blocks
.filter(block => block?.type === 'paragraph' || block?.type === 'heading')
.forEach((block) => {
block.glossaryEntries = this.mergeGlossaryEntries(block.glossaryEntries, entries);
});
}
mergeGlossaryEntries(...entryLists) {
const seen = new Set();
return entryLists
.flatMap(list => Array.isArray(list) ? list : [])
.filter((entry) => {
const key = `${entry?.term || ''}\u0000${entry?.definition || ''}`;
if (!entry?.term || !entry?.definition || seen.has(key)) return false;
seen.add(key);
return true;
});
}
dispatchChoices(choices, glossaryEntries = []) {
document.dispatchEvent(new CustomEvent('story:choices', {
detail: choices
detail: { choices, glossaryEntries }
}));
}