Export template source from 11bc3ae35b0034c113daca4c35d1b341aa31ef70:examples/local-first/packages/language-reader-runtime
This commit is contained in:
@@ -0,0 +1,33 @@
|
||||
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");
|
||||
}
|
||||
Reference in New Issue
Block a user