Files
package-language-reader-run…/src/variants.ts
T

34 lines
1.6 KiB
TypeScript

import { textIndex, processingPolicy } from "./text-processing.js";
export type VariantSection = { start: number; end: number; text?: string };
export type TextVariant = {
source: string;
sourceRevision: string;
difficulty: string;
sections: VariantSection[];
};
/** Canonical ranges never change when an earlier section expands or contracts.
* Output offsets are appended in order, so annotations on ready text stay valid. */
export function createVariant(source: string, sourceRevision: string, difficulty: string): TextVariant {
const policy = processingPolicy({ chunkChars: 1400 });
return { source, sourceRevision, difficulty, sections: textIndex(source).chunks(policy.chunkChars) };
}
export function parseVariant(raw: string): TextVariant | null {
const value = JSON.parse(raw);
return typeof value.source === "string" && Array.isArray(value.sections) ? value : null;
}
export function nextSection(variant: TextVariant) {
return variant.sections.find((section) => section.text === undefined);
}
export function applySection(variant: TextVariant, start: number, end: number, text: string) {
const section = nextSection(variant);
if (!section || section.start !== start || section.end !== end) throw Error("Variant section changed");
if (!text.trim() || text.length > 12000) throw Error("Invalid variant text");
return { ...variant, sections: variant.sections.map((item) => (item === section ? { ...item, text } : item)) };
}
export function variantText(variant: TextVariant) {
return variant.sections
.filter((section) => section.text !== undefined)
.map((section) => section.text)
.join("\n\n");
}