Skip to content

Commit 7b2d68b

Browse files
committed
refactor(workers): extract parseTableRow to shared markdown-utils
1 parent af861a7 commit 7b2d68b

3 files changed

Lines changed: 27 additions & 29 deletions

File tree

workers/src/index.ts

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -22,14 +22,15 @@ import { ZipBaselineFetcher } from "./zip-baseline-fetcher";
2222
import { RequestTracer } from "./tracing";
2323
import { parseConsumerLabel } from "./telemetry";
2424
import { renderNotFoundPage } from "./not-found-ui";
25+
import { parseTableRow } from "./markdown-utils";
2526
import pkg from "../package.json";
2627

2728
export type { Env };
2829

2930
const BUILD_VERSION = pkg.version;
3031

3132
// ──────────────────────────────────────────────────────────────────────────────
32-
// Canon-table parsing helper (local copy — mirrors orchestrate.ts parseTableRow).
33+
// Canon-table parsing helper.
3334
//
3435
// parseSelfReportHeadersTable extracts the self-report header contract from
3536
// canon/constraints/telemetry-governance.md. The table format is governed by
@@ -38,13 +39,6 @@ const BUILD_VERSION = pkg.version;
3839
// fall back to the minimal baseline without hiding the degradation.
3940
// ──────────────────────────────────────────────────────────────────────────────
4041

41-
function parseTableRow(row: string): string[] {
42-
const parts = row.split("|");
43-
if (parts.length > 0 && parts[0].trim() === "") parts.shift();
44-
if (parts.length > 0 && parts[parts.length - 1].trim() === "") parts.pop();
45-
return parts.map((c) => c.trim());
46-
}
47-
4842
function parseSelfReportHeadersTable(markdown: string): Record<string, string> | null {
4943
// Target section: "### Self-Report Fields" — grab the table that follows.
5044
// Stop at the next `###` or `##` heading, whichever comes first.

workers/src/markdown-utils.ts

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
/**
2+
* Shared markdown parsing helpers.
3+
*
4+
* Keep this module dependency-free so it can be imported from any code path
5+
* (orchestrate, index, future canon readers) without pulling in unrelated
6+
* state. Every helper here must be pure and stateless.
7+
*/
8+
9+
/**
10+
* Parse a single markdown table row into trimmed cell values, preserving
11+
* legitimately-empty middle cells. Only the leading and trailing empty strings
12+
* produced by splitting a `| a | b |`-style row are stripped — a prior
13+
* `.filter(c => c.length > 0)` approach also dropped empty interior cells,
14+
* which silently collapsed the column count and caused `cols.length >= N`
15+
* guards to misfire (e.g. a voice-dump row with an empty tiers cell).
16+
*/
17+
export function parseTableRow(row: string): string[] {
18+
const parts = row.split("|");
19+
// Strip the leading empty produced by a leading `|`, if present
20+
if (parts.length > 0 && parts[0].trim() === "") parts.shift();
21+
// Strip the trailing empty produced by a trailing `|`, if present
22+
if (parts.length > 0 && parts[parts.length - 1].trim() === "") parts.pop();
23+
return parts.map((c) => c.trim());
24+
}

workers/src/orchestrate.ts

Lines changed: 1 addition & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import {
1818
type SectionResult,
1919
} from "./zip-baseline-fetcher";
2020
import { buildBM25Index, searchBM25, type BM25Index } from "./bm25";
21+
import { parseTableRow } from "./markdown-utils";
2122
import type { RequestTracer } from "./tracing";
2223
import pkg from "../package.json";
2324

@@ -154,27 +155,6 @@ export interface OrchestrateOptions {
154155
canonUrl?: string;
155156
}
156157

157-
// ──────────────────────────────────────────────────────────────────────────────
158-
// Markdown table helpers
159-
// ──────────────────────────────────────────────────────────────────────────────
160-
161-
/**
162-
* Parse a single markdown table row into trimmed cell values, preserving
163-
* legitimately-empty middle cells. Only the leading and trailing empty strings
164-
* produced by splitting a `| a | b |`-style row are stripped — a prior
165-
* `.filter(c => c.length > 0)` approach also dropped empty interior cells,
166-
* which silently collapsed the column count and caused `cols.length >= N`
167-
* guards to misfire (e.g. a voice-dump row with an empty tiers cell).
168-
*/
169-
function parseTableRow(row: string): string[] {
170-
const parts = row.split("|");
171-
// Strip the leading empty produced by a leading `|`, if present
172-
if (parts.length > 0 && parts[0].trim() === "") parts.shift();
173-
// Strip the trailing empty produced by a trailing `|`, if present
174-
if (parts.length > 0 && parts[parts.length - 1].trim() === "") parts.pop();
175-
return parts.map((c) => c.trim());
176-
}
177-
178158
// ──────────────────────────────────────────────────────────────────────────────
179159
// BM25 Index Cache (per-request, lazy)
180160
// ──────────────────────────────────────────────────────────────────────────────

0 commit comments

Comments
 (0)