@cueloop/schema 0.1.0-alpha.5 → 0.1.0-alpha.50

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.
@@ -0,0 +1,61 @@
1
+ /**
2
+ * Working-copy block surgery: the only module that slices raw source text by
3
+ * Block line ranges. Cut removes a block's lines; restore re-inserts a base
4
+ * block's chunk and reports when the working copy round-trips back to the
5
+ * submitted revision (pristine). Callers never touch lineStart/lineEnd.
6
+ */
7
+
8
+ import { parseBlocks, type Block } from "./markdown";
9
+
10
+ /** Chunk of the base source a block occupies (for restore and display). */
11
+ export function sourceChunk(base: string, block: Block): string {
12
+ const lines = base.split("\n");
13
+ return lines.slice(block.lineStart, block.lineEnd + 1).join("\n");
14
+ }
15
+
16
+ /** Remove a work block's lines from the working source (Cut). */
17
+ export function cutBlock(working: string, block: Block): string {
18
+ const lines = working.split("\n");
19
+ const before = lines.slice(0, block.lineStart);
20
+ const after = lines.slice(block.lineEnd + 1);
21
+ while (before.length && before[before.length - 1]!.trim() === "") before.pop();
22
+ return [...before, ...after].join("\n");
23
+ }
24
+
25
+ /** The line a restored block re-enters at: the next surviving block's start. */
26
+ export function restoreLine(next: Block | undefined, workingLineCount: number): number {
27
+ return next ? next.lineStart : workingLineCount;
28
+ }
29
+
30
+ /**
31
+ * Block-structure signature: kind + text of every block, insensitive to
32
+ * blank-line layout between blocks. NUL separates blocks so no block text
33
+ * can fake a boundary.
34
+ */
35
+ function signature(text: string): string {
36
+ return parseBlocks(text)
37
+ .map((block) => block.kind + " " + block.text)
38
+ .join("\0");
39
+ }
40
+
41
+ /**
42
+ * Re-insert a cut base block into the working source before `beforeLine`.
43
+ * Returns undefined when the block structure round-trips to the base content
44
+ * (restore may differ in blank-line placement only) - the working copy is
45
+ * back to pristine and should be dropped.
46
+ */
47
+ export function restoreBlock(
48
+ base: string,
49
+ working: string,
50
+ block: Block,
51
+ beforeLine: number,
52
+ ): string | undefined {
53
+ const lines = working.split("\n");
54
+ const before = lines.slice(0, beforeLine);
55
+ const after = lines.slice(beforeLine);
56
+ const insertedLines = sourceChunk(base, block).split("\n");
57
+ if (before.length && before[before.length - 1]!.trim() !== "") insertedLines.unshift("");
58
+ if (after.length && after[0]!.trim() !== "") insertedLines.push("");
59
+ const restored = [...before, ...insertedLines, ...after].join("\n");
60
+ return signature(restored) === signature(base) ? undefined : restored;
61
+ }