Spaces:
Sleeping
Sleeping
Download backend/src/lib/tabularJsonStreamParser.ts from bardd/mike-backend: direct link, hf CLI and curl.
- Browser
- Download file 3.91 kB
-
https://huggingface.co/spaces/bardd/mike-backend/resolve/main/backend/src/lib/tabularJsonStreamParser.ts
- Command line
-
hf download hf://spaces/bardd/mike-backend/backend/src/lib/tabularJsonStreamParser.ts
-
curl -L -o tabularJsonStreamParser.ts https://huggingface.co/spaces/bardd/mike-backend/resolve/main/backend/src/lib/tabularJsonStreamParser.ts
3.91 kB
| export type TabularExtractionJsonObject = { | |
| column_index?: unknown; | |
| summary?: unknown; | |
| flag?: unknown; | |
| reasoning?: unknown; | |
| }; | |
| /** Escape literal newlines/tabs/CR inside JSON string literals so JSON.parse succeeds. */ | |
| export function escapeLiteralWhitespaceInJsonStrings(jsonStr: string): string { | |
| let cleaned = ""; | |
| let inStr = false; | |
| let isEsc = false; | |
| for (let i = 0; i < jsonStr.length; i++) { | |
| const c = jsonStr[i]; | |
| if (inStr) { | |
| if (isEsc) { | |
| cleaned += c; | |
| isEsc = false; | |
| } else if (c === "\\") { | |
| cleaned += c; | |
| isEsc = true; | |
| } else if (c === '"') { | |
| cleaned += c; | |
| inStr = false; | |
| } else if (c === "\n") { | |
| cleaned += "\\n"; | |
| } else if (c === "\r") { | |
| cleaned += "\\r"; | |
| } else if (c === "\t") { | |
| cleaned += "\\t"; | |
| } else { | |
| cleaned += c; | |
| } | |
| } else { | |
| if (c === '"') { | |
| inStr = true; | |
| } | |
| cleaned += c; | |
| } | |
| } | |
| return cleaned; | |
| } | |
| function findCompleteJsonObjectEnd(text: string, startIndex: number): number { | |
| let depth = 0; | |
| let inString = false; | |
| let escaped = false; | |
| for (let i = startIndex; i < text.length; i++) { | |
| const char = text[i]; | |
| if (inString) { | |
| if (escaped) escaped = false; | |
| else if (char === "\\") escaped = true; | |
| else if (char === '"') inString = false; | |
| } else { | |
| if (char === '"') inString = true; | |
| else if (char === "{") depth++; | |
| else if (char === "}") { | |
| depth--; | |
| if (depth === 0) return i; | |
| } | |
| } | |
| } | |
| return -1; | |
| } | |
| export function parseTabularExtractionObject( | |
| jsonStr: string, | |
| ): TabularExtractionJsonObject | null { | |
| try { | |
| const cleaned = escapeLiteralWhitespaceInJsonStrings(jsonStr); | |
| return JSON.parse(cleaned) as TabularExtractionJsonObject; | |
| } catch { | |
| return null; | |
| } | |
| } | |
| /** Extract complete top-level JSON objects from a text buffer. */ | |
| export function drainTabularJsonObjects(buffer: string): { | |
| objects: TabularExtractionJsonObject[]; | |
| remainder: string; | |
| parseFailures: number; | |
| } { | |
| const objects: TabularExtractionJsonObject[] = []; | |
| let remainder = buffer; | |
| let parseFailures = 0; | |
| let startIndex = remainder.indexOf("{"); | |
| while (startIndex !== -1) { | |
| const endIndex = findCompleteJsonObjectEnd(remainder, startIndex); | |
| if (endIndex === -1) break; | |
| const jsonStr = remainder.slice(startIndex, endIndex + 1); | |
| remainder = remainder.slice(endIndex + 1); | |
| const parsed = parseTabularExtractionObject(jsonStr); | |
| if (parsed) { | |
| objects.push(parsed); | |
| } else { | |
| parseFailures += 1; | |
| } | |
| startIndex = remainder.indexOf("{"); | |
| } | |
| return { objects, remainder, parseFailures }; | |
| } | |
| /** Incrementally parse streamed model output into tabular extraction objects. */ | |
| export class TabularJsonStreamParser { | |
| private buffer = ""; | |
| private totalParseFailures = 0; | |
| append(delta: string): TabularExtractionJsonObject[] { | |
| this.buffer += delta; | |
| return this.drain(); | |
| } | |
| flush(): TabularExtractionJsonObject[] { | |
| return this.drain(); | |
| } | |
| get remainder(): string { | |
| return this.buffer; | |
| } | |
| get parseFailureCount(): number { | |
| return this.totalParseFailures; | |
| } | |
| private drain(): TabularExtractionJsonObject[] { | |
| const { objects, remainder, parseFailures } = drainTabularJsonObjects( | |
| this.buffer, | |
| ); | |
| this.buffer = remainder; | |
| this.totalParseFailures += parseFailures; | |
| return objects; | |
| } | |
| } | |