diff --git a/src/lib/intelligence/briefingText.ts b/src/lib/intelligence/briefingText.ts new file mode 100644 index 0000000..06fc943 --- /dev/null +++ b/src/lib/intelligence/briefingText.ts @@ -0,0 +1,84 @@ +interface LexicalTextNode { + type: string; + text?: unknown; + children?: unknown[]; +} + +interface LexicalBlock { + type: string; + children?: unknown[]; +} + +export type SerializedLexicalState = { + root: { + type: "root"; + children: { + type: "paragraph"; + children: { type: "text"; text: string; version: number }[]; + direction: null; + format: ""; + indent: number; + version: number; + }[]; + direction: "ltr" | "rtl" | null; + format: "left" | "start" | "center" | "right" | "end" | "justify" | ""; + indent: number; + version: number; + }; +}; + +function collectText(node: unknown): string { + if (typeof node !== "object" || node === null) return ""; + const n = node as LexicalTextNode; + if (n.type === "linebreak") return "\n"; + if (typeof n.text === "string") return n.text; + if (!Array.isArray(n.children)) return ""; + return n.children.map(collectText).join(""); +} + +function collectBlockText(node: unknown): string { + if (typeof node !== "object" || node === null) return ""; + const n = node as LexicalBlock; + if (!Array.isArray(n.children)) return ""; + return n.children.map(collectText).join(""); +} + +export function lexicalToText(details: unknown): string { + if (typeof details !== "object" || details === null) return ""; + const root = (details as SerializedLexicalState).root; + if (!root || !Array.isArray(root.children)) return ""; + return root.children + .map(collectBlockText) + .filter((line, i, all) => line.trim() !== "" || (i > 0 && i < all.length - 1)) + .join("\n"); +} + +export function textToLexical(text: string): SerializedLexicalState { + const lines = text.split("\n"); + return { + root: { + type: "root", + children: (lines.length > 0 ? lines : [""]).map((line) => ({ + type: "paragraph", + children: + line === "" + ? [] + : [ + { + type: "text", + text: line, + version: 1, + }, + ], + direction: null, + format: "", + indent: 0, + version: 1, + })), + direction: "ltr", + format: "", + indent: 0, + version: 1, + }, + }; +}