goldenmatch 0.1.0

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.
Files changed (162) hide show
  1. package/README.md +140 -0
  2. package/dist/cli.cjs +6079 -0
  3. package/dist/cli.cjs.map +1 -0
  4. package/dist/cli.d.cts +1 -0
  5. package/dist/cli.d.ts +1 -0
  6. package/dist/cli.js +6076 -0
  7. package/dist/cli.js.map +1 -0
  8. package/dist/core/index.cjs +8449 -0
  9. package/dist/core/index.cjs.map +1 -0
  10. package/dist/core/index.d.cts +1972 -0
  11. package/dist/core/index.d.ts +1972 -0
  12. package/dist/core/index.js +8318 -0
  13. package/dist/core/index.js.map +1 -0
  14. package/dist/index.cjs +8449 -0
  15. package/dist/index.cjs.map +1 -0
  16. package/dist/index.d.cts +2 -0
  17. package/dist/index.d.ts +2 -0
  18. package/dist/index.js +8318 -0
  19. package/dist/index.js.map +1 -0
  20. package/dist/node/backends/score-worker.cjs +934 -0
  21. package/dist/node/backends/score-worker.cjs.map +1 -0
  22. package/dist/node/backends/score-worker.d.cts +14 -0
  23. package/dist/node/backends/score-worker.d.ts +14 -0
  24. package/dist/node/backends/score-worker.js +932 -0
  25. package/dist/node/backends/score-worker.js.map +1 -0
  26. package/dist/node/index.cjs +11430 -0
  27. package/dist/node/index.cjs.map +1 -0
  28. package/dist/node/index.d.cts +554 -0
  29. package/dist/node/index.d.ts +554 -0
  30. package/dist/node/index.js +11277 -0
  31. package/dist/node/index.js.map +1 -0
  32. package/dist/types-DhUdX5Rc.d.cts +304 -0
  33. package/dist/types-DhUdX5Rc.d.ts +304 -0
  34. package/examples/01-basic-dedupe.ts +60 -0
  35. package/examples/02-match-two-datasets.ts +48 -0
  36. package/examples/03-csv-file-pipeline.ts +62 -0
  37. package/examples/04-string-scoring.ts +63 -0
  38. package/examples/05-custom-config.ts +94 -0
  39. package/examples/06-probabilistic-fs.ts +72 -0
  40. package/examples/07-pprl-privacy.ts +76 -0
  41. package/examples/08-streaming.ts +79 -0
  42. package/examples/09-llm-scorer.ts +79 -0
  43. package/examples/10-explain.ts +60 -0
  44. package/examples/11-evaluate.ts +61 -0
  45. package/examples/README.md +53 -0
  46. package/package.json +66 -0
  47. package/src/cli.ts +372 -0
  48. package/src/core/ann-blocker.ts +593 -0
  49. package/src/core/api.ts +220 -0
  50. package/src/core/autoconfig.ts +363 -0
  51. package/src/core/autofix.ts +102 -0
  52. package/src/core/blocker.ts +655 -0
  53. package/src/core/cluster.ts +699 -0
  54. package/src/core/compare-clusters.ts +176 -0
  55. package/src/core/config/loader.ts +869 -0
  56. package/src/core/cross-encoder.ts +614 -0
  57. package/src/core/data.ts +430 -0
  58. package/src/core/domain.ts +277 -0
  59. package/src/core/embedder.ts +562 -0
  60. package/src/core/evaluate.ts +156 -0
  61. package/src/core/explain.ts +352 -0
  62. package/src/core/golden.ts +524 -0
  63. package/src/core/graph-er.ts +371 -0
  64. package/src/core/index.ts +314 -0
  65. package/src/core/ingest.ts +112 -0
  66. package/src/core/learned-blocking.ts +305 -0
  67. package/src/core/lineage.ts +221 -0
  68. package/src/core/llm/budget.ts +258 -0
  69. package/src/core/llm/cluster.ts +542 -0
  70. package/src/core/llm/scorer.ts +396 -0
  71. package/src/core/match-one.ts +95 -0
  72. package/src/core/matchkey.ts +97 -0
  73. package/src/core/memory/corrections.ts +179 -0
  74. package/src/core/memory/learner.ts +218 -0
  75. package/src/core/memory/store.ts +114 -0
  76. package/src/core/pipeline.ts +366 -0
  77. package/src/core/pprl/protocol.ts +216 -0
  78. package/src/core/probabilistic.ts +511 -0
  79. package/src/core/profiler.ts +212 -0
  80. package/src/core/quality.ts +197 -0
  81. package/src/core/review-queue.ts +177 -0
  82. package/src/core/scorer.ts +855 -0
  83. package/src/core/sensitivity.ts +196 -0
  84. package/src/core/standardize.ts +279 -0
  85. package/src/core/streaming.ts +128 -0
  86. package/src/core/transforms.ts +599 -0
  87. package/src/core/types.ts +570 -0
  88. package/src/core/validate.ts +243 -0
  89. package/src/index.ts +8 -0
  90. package/src/node/a2a/server.ts +470 -0
  91. package/src/node/api/server.ts +412 -0
  92. package/src/node/backends/duckdb.ts +130 -0
  93. package/src/node/backends/score-worker.ts +41 -0
  94. package/src/node/backends/workers.ts +212 -0
  95. package/src/node/config-file.ts +66 -0
  96. package/src/node/connectors/base.ts +57 -0
  97. package/src/node/connectors/bigquery.ts +61 -0
  98. package/src/node/connectors/databricks.ts +69 -0
  99. package/src/node/connectors/file.ts +350 -0
  100. package/src/node/connectors/hubspot.ts +62 -0
  101. package/src/node/connectors/index.ts +43 -0
  102. package/src/node/connectors/salesforce.ts +93 -0
  103. package/src/node/connectors/snowflake.ts +73 -0
  104. package/src/node/db/postgres.ts +173 -0
  105. package/src/node/db/sync.ts +103 -0
  106. package/src/node/dedupe-file.ts +156 -0
  107. package/src/node/index.ts +89 -0
  108. package/src/node/mcp/server.ts +940 -0
  109. package/src/node/tui/app.ts +756 -0
  110. package/src/node/tui/index.ts +6 -0
  111. package/src/node/tui/widgets.ts +128 -0
  112. package/tests/parity/scorer-ground-truth.test.ts +118 -0
  113. package/tests/smoke.test.ts +46 -0
  114. package/tests/unit/a2a-server.test.ts +175 -0
  115. package/tests/unit/ann-blocker.test.ts +117 -0
  116. package/tests/unit/api-server.test.ts +239 -0
  117. package/tests/unit/api.test.ts +77 -0
  118. package/tests/unit/autoconfig.test.ts +103 -0
  119. package/tests/unit/autofix.test.ts +71 -0
  120. package/tests/unit/blocker.test.ts +164 -0
  121. package/tests/unit/buildBlocksAsync.test.ts +63 -0
  122. package/tests/unit/cluster.test.ts +213 -0
  123. package/tests/unit/compare-clusters.test.ts +42 -0
  124. package/tests/unit/config-loader.test.ts +301 -0
  125. package/tests/unit/connectors-base.test.ts +48 -0
  126. package/tests/unit/cross-encoder-model.test.ts +198 -0
  127. package/tests/unit/cross-encoder.test.ts +173 -0
  128. package/tests/unit/db-connectors.test.ts +37 -0
  129. package/tests/unit/domain.test.ts +80 -0
  130. package/tests/unit/embedder.test.ts +151 -0
  131. package/tests/unit/evaluate.test.ts +85 -0
  132. package/tests/unit/explain.test.ts +73 -0
  133. package/tests/unit/golden.test.ts +97 -0
  134. package/tests/unit/graph-er.test.ts +173 -0
  135. package/tests/unit/hnsw-ann.test.ts +283 -0
  136. package/tests/unit/hubspot-connector.test.ts +118 -0
  137. package/tests/unit/ingest.test.ts +97 -0
  138. package/tests/unit/learned-blocking.test.ts +134 -0
  139. package/tests/unit/lineage.test.ts +135 -0
  140. package/tests/unit/match-one.test.ts +129 -0
  141. package/tests/unit/matchkey.test.ts +97 -0
  142. package/tests/unit/mcp-server.test.ts +183 -0
  143. package/tests/unit/memory.test.ts +119 -0
  144. package/tests/unit/pipeline.test.ts +118 -0
  145. package/tests/unit/pprl-protocol.test.ts +381 -0
  146. package/tests/unit/probabilistic.test.ts +494 -0
  147. package/tests/unit/profiler.test.ts +68 -0
  148. package/tests/unit/review-queue.test.ts +68 -0
  149. package/tests/unit/salesforce-connector.test.ts +148 -0
  150. package/tests/unit/scorer.test.ts +301 -0
  151. package/tests/unit/sensitivity.test.ts +154 -0
  152. package/tests/unit/standardize.test.ts +84 -0
  153. package/tests/unit/streaming.test.ts +82 -0
  154. package/tests/unit/transforms.test.ts +208 -0
  155. package/tests/unit/tui-widgets.test.ts +42 -0
  156. package/tests/unit/tui.test.ts +24 -0
  157. package/tests/unit/validate.test.ts +145 -0
  158. package/tests/unit/workers-parallel.test.ts +99 -0
  159. package/tests/unit/workers.test.ts +74 -0
  160. package/tsconfig.json +25 -0
  161. package/tsup.config.ts +37 -0
  162. package/vitest.config.ts +11 -0
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/node/connectors/file.ts","../src/core/types.ts","../src/core/transforms.ts","../src/core/matchkey.ts","../src/core/standardize.ts","../src/core/embedder.ts","../src/core/ann-blocker.ts","../src/core/blocker.ts","../src/core/cluster.ts","../src/core/scorer.ts","../src/core/golden.ts","../src/core/pipeline.ts","../src/core/api.ts","../src/core/config/loader.ts","../src/node/config-file.ts","../src/core/explain.ts","../src/core/profiler.ts","../src/core/evaluate.ts","../src/node/mcp/server.ts","../src/node/api/server.ts","../src/node/a2a/server.ts","../src/node/tui/widgets.ts","../src/node/tui/app.ts","../src/cli.ts"],"names":["parsed","out","results","winner","require","resolve","existsSync","readFileSync","server_exports","sanitizePath","isAbsolute","sep","init_server","readJsonBody","sendJson","createServer","createRequire","readFile","dedupe","extname","startMcpServer","startApiServer","startA2aServer","startTui"],"mappings":"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","file":"cli.js","sourcesContent":["/**\n * file.ts -- CSV/JSON/JSONL file I/O connector.\n *\n * Node-only: uses node:fs, node:path. NOT edge-safe.\n *\n * CSV parser rules (CRITICAL):\n * - Quoted fields preserve embedded commas and newlines\n * - Doubled quotes inside quoted fields unescape to a single quote\n * - Empty unquoted fields become null\n * - Leading-zero strings (zip codes \"01234\", SSNs, phones) are NEVER\n * coerced to numbers\n * - Booleans \"true\"/\"false\" (case-insensitive) coerce to boolean\n * - Numeric strings coerce to number only when fully numeric and not\n * leading-zero\n * - Supports both `\\n` and `\\r\\n` line endings\n */\n\nimport { readFileSync, writeFileSync, mkdirSync, existsSync } from \"node:fs\";\nimport { resolve, extname, dirname } from \"node:path\";\nimport type { Row } from \"../../core/types.js\";\n\n// ---------------------------------------------------------------------------\n// Value coercion\n// ---------------------------------------------------------------------------\n\n/**\n * Coerce a raw CSV field string to string | number | boolean.\n * Preserves leading-zero strings (zip codes, SSNs, phone numbers) as strings.\n */\nfunction coerceValue(raw: string): string | number | boolean {\n // Booleans (case insensitive)\n const lower = raw.toLowerCase();\n if (lower === \"true\") return true;\n if (lower === \"false\") return false;\n\n // Only try numeric coercion for strings that are already trimmed\n if (raw.length === 0 || raw !== raw.trim()) return raw;\n\n // NEVER coerce leading-zero strings to numbers, except \"0\" itself and\n // decimals like \"0.5\".\n if (raw.length > 1 && raw[0] === \"0\" && raw[1] !== \".\") return raw;\n\n // Also preserve negative leading-zero strings like \"-0123\" as strings\n if (raw.length > 2 && raw[0] === \"-\" && raw[1] === \"0\" && raw[2] !== \".\") {\n return raw;\n }\n\n const n = Number(raw);\n if (Number.isFinite(n)) return n;\n\n return raw;\n}\n\n// ---------------------------------------------------------------------------\n// CSV parsing\n// ---------------------------------------------------------------------------\n\n/**\n * Parse a full CSV document honoring quoted fields, doubled quotes,\n * embedded newlines/commas, and both CRLF/LF line endings.\n *\n * Returns an array of raw string rows. The caller is responsible for\n * interpreting the first row as a header.\n */\nfunction parseCsvDocument(content: string, delimiter: string): string[][] {\n const rows: string[][] = [];\n let current = \"\";\n let row: string[] = [];\n let inQuotes = false;\n let i = 0;\n const n = content.length;\n\n while (i < n) {\n const ch = content[i]!;\n\n if (inQuotes) {\n if (ch === '\"') {\n if (i + 1 < n && content[i + 1] === '\"') {\n current += '\"';\n i += 2;\n continue;\n }\n inQuotes = false;\n i++;\n continue;\n }\n current += ch;\n i++;\n continue;\n }\n\n // Not in quotes\n if (ch === '\"') {\n inQuotes = true;\n i++;\n continue;\n }\n if (ch === delimiter) {\n row.push(current);\n current = \"\";\n i++;\n continue;\n }\n if (ch === \"\\r\") {\n // Swallow \\r, then handle \\n on next iteration\n i++;\n continue;\n }\n if (ch === \"\\n\") {\n row.push(current);\n current = \"\";\n rows.push(row);\n row = [];\n i++;\n continue;\n }\n current += ch;\n i++;\n }\n\n // Flush trailing field/row if any\n if (current.length > 0 || row.length > 0) {\n row.push(current);\n rows.push(row);\n }\n\n return rows;\n}\n\n// ---------------------------------------------------------------------------\n// Public API\n// ---------------------------------------------------------------------------\n\nexport interface ReadCsvOptions {\n readonly delimiter?: string;\n readonly hasHeader?: boolean;\n readonly encoding?: BufferEncoding;\n}\n\n/**\n * Read a CSV (or TSV, via `delimiter: \"\\t\"`) file from disk.\n *\n * Returns an array of `Row` objects (header -> coerced value). If\n * `hasHeader` is false, synthetic headers `col_0`, `col_1`, ... are used.\n */\nexport function readCsv(path: string, options?: ReadCsvOptions): Row[] {\n const resolved = resolve(path);\n if (!existsSync(resolved)) {\n throw new Error(`File not found: ${resolved}`);\n }\n\n const delimiter = options?.delimiter ?? \",\";\n const hasHeader = options?.hasHeader ?? true;\n const encoding = options?.encoding ?? \"utf8\";\n\n const content = readFileSync(resolved, encoding);\n // Strip UTF-8 BOM if present (Excel-exported CSVs often include it)\n const cleaned = content.charCodeAt(0) === 0xfeff ? content.slice(1) : content;\n\n const rawRows = parseCsvDocument(cleaned, delimiter);\n if (rawRows.length === 0) return [];\n\n // Skip completely empty rows (trailing newlines, blank lines between records)\n const nonEmpty = rawRows.filter(\n (r) => !(r.length === 1 && r[0] === \"\"),\n );\n if (nonEmpty.length === 0) return [];\n\n let headers: string[];\n let dataRows: string[][];\n if (hasHeader) {\n headers = nonEmpty[0]!.map((h) => h.trim());\n dataRows = nonEmpty.slice(1);\n } else {\n const width = nonEmpty[0]!.length;\n headers = Array.from({ length: width }, (_, i) => `col_${i}`);\n dataRows = nonEmpty;\n }\n\n const rows: Row[] = [];\n for (const raw of dataRows) {\n const record: Record<string, unknown> = {};\n for (let j = 0; j < headers.length; j++) {\n const field = raw[j] ?? \"\";\n record[headers[j]!] = field === \"\" ? null : coerceValue(field);\n }\n rows.push(record);\n }\n return rows;\n}\n\n/**\n * Read a JSON or JSONL file.\n *\n * - `.json`: expects an array of objects at the top level.\n * - `.jsonl` / `.ndjson`: one JSON object per line.\n *\n * Auto-detected based on whether the first non-whitespace character is `[`.\n */\nexport function readJson(path: string): Row[] {\n const resolved = resolve(path);\n if (!existsSync(resolved)) {\n throw new Error(`File not found: ${resolved}`);\n }\n const content = readFileSync(resolved, \"utf8\");\n const trimmed = content.trimStart();\n\n // JSONL: one object per line, detected by lack of opening `[`\n const ext = extname(resolved).toLowerCase();\n const isJsonl =\n ext === \".jsonl\" ||\n ext === \".ndjson\" ||\n (trimmed.length > 0 && trimmed[0] !== \"[\");\n\n if (isJsonl) {\n const rows: Row[] = [];\n const lines = content.split(/\\r?\\n/);\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i]!.trim();\n if (line === \"\") continue;\n try {\n const parsed = JSON.parse(line);\n if (parsed !== null && typeof parsed === \"object\" && !Array.isArray(parsed)) {\n rows.push(parsed as Row);\n } else {\n throw new Error(\n `JSONL line ${i + 1}: expected an object, got ${Array.isArray(parsed) ? \"array\" : typeof parsed}`,\n );\n }\n } catch (err) {\n if (err instanceof SyntaxError) {\n throw new Error(`JSONL parse error at line ${i + 1}: ${err.message}`);\n }\n throw err;\n }\n }\n return rows;\n }\n\n // Standard JSON array\n let parsed: unknown;\n try {\n parsed = JSON.parse(content);\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n throw new Error(`JSON parse error in ${resolved}: ${msg}`);\n }\n if (!Array.isArray(parsed)) {\n throw new Error(\n `JSON file ${resolved}: expected an array of objects at the root`,\n );\n }\n return parsed as Row[];\n}\n\n/**\n * Dispatch to readCsv / readJson based on file extension.\n *\n * Supported: `.csv`, `.tsv`, `.json`, `.jsonl`, `.ndjson`.\n */\nexport function readFile(path: string): Row[] {\n const ext = extname(path).toLowerCase();\n if (ext === \".csv\") return readCsv(path, { delimiter: \",\" });\n if (ext === \".tsv\") return readCsv(path, { delimiter: \"\\t\" });\n if (ext === \".json\" || ext === \".jsonl\" || ext === \".ndjson\") {\n return readJson(path);\n }\n throw new Error(\n `Unsupported file format: ${ext}. Supported: .csv, .tsv, .json, .jsonl, .ndjson`,\n );\n}\n\n// ---------------------------------------------------------------------------\n// Serialization\n// ---------------------------------------------------------------------------\n\n/** Escape a CSV field: quote if it contains delimiter, quote, or newline. */\nfunction escapeCsvField(value: unknown, delimiter: string): string {\n if (value === null || value === undefined) return \"\";\n const s = String(value);\n const needsQuoting =\n s.includes(delimiter) ||\n s.includes('\"') ||\n s.includes(\"\\n\") ||\n s.includes(\"\\r\");\n if (!needsQuoting) return s;\n return `\"${s.replace(/\"/g, '\"\"')}\"`;\n}\n\nexport interface WriteCsvOptions {\n readonly columns?: readonly string[];\n readonly delimiter?: string;\n}\n\n/**\n * Write rows to a CSV file. Creates parent directories as needed.\n *\n * If `columns` is not supplied, the union of keys from all rows is used,\n * ordered by first appearance.\n */\nexport function writeCsv(\n path: string,\n rows: readonly Row[],\n options?: WriteCsvOptions,\n): void {\n const resolved = resolve(path);\n const dir = dirname(resolved);\n if (dir && dir !== \".\" && !existsSync(dir)) {\n mkdirSync(dir, { recursive: true });\n }\n\n const delimiter = options?.delimiter ?? \",\";\n\n let columns: string[];\n if (options?.columns && options.columns.length > 0) {\n columns = [...options.columns];\n } else if (rows.length === 0) {\n writeFileSync(resolved, \"\", \"utf8\");\n return;\n } else {\n const seen = new Set<string>();\n columns = [];\n for (const row of rows) {\n for (const key of Object.keys(row)) {\n if (!seen.has(key)) {\n seen.add(key);\n columns.push(key);\n }\n }\n }\n }\n\n const lines: string[] = [];\n lines.push(columns.map((c) => escapeCsvField(c, delimiter)).join(delimiter));\n for (const row of rows) {\n const fields = columns.map((c) => escapeCsvField(row[c], delimiter));\n lines.push(fields.join(delimiter));\n }\n writeFileSync(resolved, lines.join(\"\\n\") + \"\\n\", \"utf8\");\n}\n\n/** Write rows to a JSON file as a pretty-printed array. */\nexport function writeJson(path: string, rows: readonly Row[]): void {\n const resolved = resolve(path);\n const dir = dirname(resolved);\n if (dir && dir !== \".\" && !existsSync(dir)) {\n mkdirSync(dir, { recursive: true });\n }\n writeFileSync(resolved, JSON.stringify(rows, null, 2), \"utf8\");\n}\n","/**\n * types.ts — GoldenMatch config interfaces and result types.\n * Edge-safe: no Node.js imports, no `process`.\n */\n\n// ---------------------------------------------------------------------------\n// Primitive types\n// ---------------------------------------------------------------------------\n\nexport type ColumnValue = string | number | boolean | null;\nexport type Row = Readonly<Record<string, unknown>>;\n\n/** A canonical pair key in the form \"minId:maxId\". Only produced by pairKey(). */\nexport type PairKey = string & { readonly __brand: \"PairKey\" };\n\n// ---------------------------------------------------------------------------\n// Matchkey field config\n// ---------------------------------------------------------------------------\n\nexport interface MatchkeyField {\n readonly field: string;\n readonly transforms: readonly string[];\n readonly scorer: string;\n readonly weight: number;\n readonly model?: string;\n readonly columns?: readonly string[];\n readonly columnWeights?: Readonly<Record<string, number>>;\n readonly levels?: number;\n readonly partialThreshold?: number;\n}\n\nexport interface ExactMatchkey {\n readonly name: string;\n readonly type: \"exact\";\n readonly fields: readonly MatchkeyField[];\n}\n\nexport interface WeightedMatchkey {\n readonly name: string;\n readonly type: \"weighted\";\n readonly fields: readonly MatchkeyField[];\n readonly threshold: number;\n readonly autoThreshold?: boolean;\n readonly rerank?: boolean;\n readonly rerankModel?: string;\n readonly rerankBand?: number;\n}\n\nexport interface ProbabilisticMatchkey {\n readonly name: string;\n readonly type: \"probabilistic\";\n readonly fields: readonly MatchkeyField[];\n readonly threshold?: number;\n readonly emIterations?: number;\n readonly convergenceThreshold?: number;\n readonly linkThreshold?: number;\n readonly reviewThreshold?: number;\n}\n\nexport type MatchkeyConfig =\n | ExactMatchkey\n | WeightedMatchkey\n | ProbabilisticMatchkey;\n\n// ---------------------------------------------------------------------------\n// Blocking config\n// ---------------------------------------------------------------------------\n\nexport interface BlockingKeyConfig {\n readonly fields: readonly string[];\n readonly transforms: readonly string[];\n}\n\nexport interface SortKeyField {\n readonly column: string;\n readonly transforms: readonly string[];\n}\n\nexport interface CanopyConfig {\n readonly fields: readonly string[];\n readonly looseThreshold: number;\n readonly tightThreshold: number;\n readonly maxCanopySize: number;\n}\n\nexport interface BlockingConfig {\n readonly strategy:\n | \"static\"\n | \"adaptive\"\n | \"sorted_neighborhood\"\n | \"multi_pass\"\n | \"ann\"\n | \"canopy\"\n | \"ann_pairs\"\n | \"learned\";\n readonly keys: readonly BlockingKeyConfig[];\n readonly maxBlockSize: number;\n readonly skipOversized: boolean;\n readonly autoSuggest?: boolean;\n readonly autoSelect?: boolean;\n readonly subBlockKeys?: readonly BlockingKeyConfig[];\n readonly windowSize?: number;\n readonly sortKey?: readonly SortKeyField[];\n readonly passes?: readonly BlockingKeyConfig[];\n readonly unionMode?: boolean;\n readonly maxTotalComparisons?: number;\n readonly annColumn?: string;\n readonly annModel?: string;\n readonly annTopK?: number;\n readonly canopy?: CanopyConfig;\n readonly learnedSampleSize?: number;\n readonly learnedMinRecall?: number;\n readonly learnedMinReduction?: number;\n readonly learnedPredicateDepth?: number;\n readonly learnedCachePath?: string;\n}\n\n// ---------------------------------------------------------------------------\n// Golden rules config\n// ---------------------------------------------------------------------------\n\nexport interface GoldenFieldRule {\n readonly strategy:\n | \"most_complete\"\n | \"majority_vote\"\n | \"source_priority\"\n | \"most_recent\"\n | \"first_non_null\";\n readonly dateColumn?: string;\n readonly sourcePriority?: readonly string[];\n}\n\nexport interface GoldenRulesConfig {\n readonly defaultStrategy: string;\n readonly fieldRules: Readonly<Record<string, GoldenFieldRule>>;\n readonly maxClusterSize: number;\n readonly autoSplit: boolean;\n readonly qualityWeighting: boolean;\n readonly weakClusterThreshold: number;\n}\n\n// ---------------------------------------------------------------------------\n// Standardization, validation, quality, transform\n// ---------------------------------------------------------------------------\n\nexport interface StandardizationConfig {\n readonly rules: Readonly<Record<string, readonly string[]>>;\n}\n\nexport interface ValidationRuleConfig {\n readonly column: string;\n readonly ruleType:\n | \"regex\"\n | \"min_length\"\n | \"max_length\"\n | \"not_null\"\n | \"in_set\"\n | \"format\";\n readonly params: Readonly<Record<string, unknown>>;\n readonly action: \"null\" | \"quarantine\" | \"flag\";\n}\n\nexport interface ValidationConfig {\n readonly rules: readonly ValidationRuleConfig[];\n readonly autoFix: boolean;\n}\n\nexport interface QualityConfig {\n readonly enabled: boolean;\n readonly mode: \"silent\" | \"announced\" | \"disabled\";\n readonly fixMode: \"safe\" | \"moderate\" | \"none\";\n readonly domain?: string;\n}\n\nexport interface TransformConfig {\n readonly enabled: boolean;\n readonly mode: \"silent\" | \"announced\" | \"disabled\";\n}\n\n// ---------------------------------------------------------------------------\n// LLM scorer & budget\n// ---------------------------------------------------------------------------\n\nexport interface BudgetConfig {\n readonly maxCostUsd?: number;\n readonly maxCalls?: number;\n readonly escalationModel?: string;\n readonly escalationBand?: readonly number[];\n readonly escalationBudgetPct?: number;\n readonly warnAtPct?: number;\n}\n\nexport interface LLMScorerConfig {\n readonly enabled: boolean;\n readonly provider?: string;\n readonly model?: string;\n readonly autoThreshold: number;\n readonly candidateLo: number;\n readonly candidateHi: number;\n readonly batchSize: number;\n readonly maxWorkers: number;\n readonly budget?: BudgetConfig;\n readonly mode: \"pairwise\" | \"cluster\";\n readonly clusterMaxSize?: number;\n readonly clusterMinSize?: number;\n}\n\n// ---------------------------------------------------------------------------\n// Domain config\n// ---------------------------------------------------------------------------\n\nexport interface DomainConfig {\n readonly enabled: boolean;\n readonly mode?: string;\n readonly confidenceThreshold: number;\n readonly llmValidation: boolean;\n readonly budget?: BudgetConfig;\n}\n\n// ---------------------------------------------------------------------------\n// Memory & learning\n// ---------------------------------------------------------------------------\n\nexport interface LearningConfig {\n readonly thresholdMinCorrections: number;\n readonly weightsMinCorrections: number;\n}\n\nexport interface MemoryConfig {\n readonly enabled: boolean;\n readonly backend: \"sqlite\" | \"postgres\";\n readonly path?: string;\n readonly trust: number;\n readonly learning: LearningConfig;\n}\n\n// ---------------------------------------------------------------------------\n// Input & output config\n// ---------------------------------------------------------------------------\n\nexport interface InputFileConfig {\n readonly path: string;\n readonly idColumn?: string;\n readonly sourceLabel?: string;\n readonly sourceName?: string;\n readonly columnMap?: Readonly<Record<string, string>>;\n readonly delimiter?: string;\n readonly encoding?: string;\n readonly sheet?: string;\n readonly parseMode?: string;\n readonly headerRow?: number;\n readonly hasHeader?: boolean;\n readonly skipRows?: readonly number[];\n}\n\nexport interface InputConfig {\n readonly files: readonly InputFileConfig[];\n readonly fileA?: InputFileConfig;\n readonly fileB?: InputFileConfig;\n}\n\nexport interface OutputConfig {\n readonly path?: string;\n readonly format?: string;\n readonly directory?: string;\n readonly runName?: string;\n}\n\n// ---------------------------------------------------------------------------\n// Top-level config\n// ---------------------------------------------------------------------------\n\nexport interface GoldenMatchConfig {\n readonly matchkeys?: readonly MatchkeyConfig[];\n readonly matchSettings?: readonly MatchkeyConfig[];\n readonly blocking?: BlockingConfig;\n readonly threshold?: number;\n readonly goldenRules?: GoldenRulesConfig;\n readonly standardization?: StandardizationConfig;\n readonly validation?: ValidationConfig;\n readonly quality?: QualityConfig;\n readonly transform?: TransformConfig;\n readonly llmScorer?: LLMScorerConfig;\n readonly domain?: DomainConfig;\n readonly memory?: MemoryConfig;\n readonly input?: InputConfig;\n readonly output?: OutputConfig;\n readonly backend?: string;\n readonly llmAuto?: boolean;\n readonly llmBoost?: boolean;\n}\n\n// ---------------------------------------------------------------------------\n// Result types\n// ---------------------------------------------------------------------------\n\nexport interface ScoredPair {\n readonly idA: number;\n readonly idB: number;\n readonly score: number;\n}\n\nexport interface ClusterInfo {\n readonly members: readonly number[];\n readonly size: number;\n readonly oversized: boolean;\n readonly pairScores: ReadonlyMap<PairKey, number>;\n readonly confidence: number;\n readonly bottleneckPair: readonly [number, number] | null;\n readonly clusterQuality: \"strong\" | \"weak\" | \"split\";\n}\n\nexport interface DedupeStats {\n readonly totalRecords: number;\n readonly totalClusters: number;\n readonly matchRate: number;\n readonly matchedRecords: number;\n readonly uniqueRecords: number;\n}\n\nexport interface DedupeResult {\n readonly goldenRecords: readonly Row[];\n readonly clusters: ReadonlyMap<number, ClusterInfo>;\n readonly dupes: readonly Row[];\n readonly unique: readonly Row[];\n readonly stats: DedupeStats;\n readonly scoredPairs: readonly ScoredPair[];\n readonly config: GoldenMatchConfig;\n}\n\nexport interface MatchResult {\n readonly matched: readonly Row[];\n readonly unmatched: readonly Row[];\n readonly stats: Readonly<Record<string, unknown>>;\n}\n\nexport interface FieldProvenance {\n readonly value: unknown;\n readonly sourceRowId: number;\n readonly strategy: string;\n readonly confidence: number;\n readonly candidates: readonly Readonly<Record<string, unknown>>[];\n}\n\nexport interface ClusterProvenance {\n readonly clusterId: number;\n readonly clusterQuality: string;\n readonly clusterConfidence: number;\n readonly fields: Readonly<Record<string, FieldProvenance>>;\n}\n\nexport interface BlockResult {\n readonly blockKey: string;\n readonly rows: readonly Row[];\n readonly strategy: string;\n readonly depth: number;\n readonly parentKey?: string;\n readonly preScoredPairs?: readonly ScoredPair[];\n}\n\n// ---------------------------------------------------------------------------\n// Valid enum sets\n// ---------------------------------------------------------------------------\n\nexport const VALID_SCORERS = new Set([\n \"exact\",\n \"jaro_winkler\",\n \"levenshtein\",\n \"token_sort\",\n \"soundex_match\",\n \"embedding\",\n \"record_embedding\",\n \"ensemble\",\n \"dice\",\n \"jaccard\",\n] as const);\n\nexport const VALID_TRANSFORMS = new Set([\n \"lowercase\",\n \"uppercase\",\n \"strip\",\n \"strip_all\",\n \"soundex\",\n \"metaphone\",\n \"digits_only\",\n \"alpha_only\",\n \"normalize_whitespace\",\n \"token_sort\",\n \"first_token\",\n \"last_token\",\n] as const);\n\nexport const VALID_STRATEGIES = new Set([\n \"most_recent\",\n \"source_priority\",\n \"most_complete\",\n \"majority_vote\",\n \"first_non_null\",\n] as const);\n\nexport const VALID_STANDARDIZERS = new Set([\n \"email\",\n \"name_proper\",\n \"name_upper\",\n \"name_lower\",\n \"phone\",\n \"zip5\",\n \"address\",\n \"state\",\n \"strip\",\n \"trim_whitespace\",\n] as const);\n\n// ---------------------------------------------------------------------------\n// Factory functions\n// ---------------------------------------------------------------------------\n\n/**\n * Create a ScoredPair guaranteeing idA <= idB (canonical order).\n * Always use this instead of constructing `{ idA, idB, score }` directly.\n */\nexport function makeScoredPair(\n a: number,\n b: number,\n score: number,\n): ScoredPair {\n const lo = a < b ? a : b;\n const hi = a < b ? b : a;\n return { idA: lo, idB: hi, score };\n}\n\n/** Create a MatchkeyField with sensible defaults. */\nexport function makeMatchkeyField(\n partial: Partial<MatchkeyField> & Pick<MatchkeyField, \"field\">,\n): MatchkeyField {\n return {\n transforms: [],\n scorer: \"jaro_winkler\",\n weight: 1.0,\n ...partial,\n };\n}\n\n/**\n * Shape accepted by `makeMatchkeyConfig`. All variant-specific fields are\n * optional; the factory picks the right variant based on `type`.\n */\nexport interface MakeMatchkeyConfigInput {\n readonly name: string;\n readonly type?: \"exact\" | \"weighted\" | \"probabilistic\";\n readonly fields?: readonly MatchkeyField[];\n readonly threshold?: number;\n readonly autoThreshold?: boolean;\n readonly rerank?: boolean;\n readonly rerankModel?: string;\n readonly rerankBand?: number;\n readonly emIterations?: number;\n readonly convergenceThreshold?: number;\n readonly linkThreshold?: number;\n readonly reviewThreshold?: number;\n}\n\n/** Create a MatchkeyConfig with sensible defaults. Produces the correct variant. */\nexport function makeMatchkeyConfig(\n partial: MakeMatchkeyConfigInput,\n): MatchkeyConfig {\n const type = partial.type ?? \"weighted\";\n const fields = partial.fields ?? [];\n if (type === \"exact\") {\n return { name: partial.name, type: \"exact\", fields };\n }\n if (type === \"probabilistic\") {\n const out: ProbabilisticMatchkey = {\n name: partial.name,\n type: \"probabilistic\",\n fields,\n ...(partial.threshold !== undefined\n ? { threshold: partial.threshold }\n : {}),\n ...(partial.emIterations !== undefined\n ? { emIterations: partial.emIterations }\n : {}),\n ...(partial.convergenceThreshold !== undefined\n ? { convergenceThreshold: partial.convergenceThreshold }\n : {}),\n ...(partial.linkThreshold !== undefined\n ? { linkThreshold: partial.linkThreshold }\n : {}),\n ...(partial.reviewThreshold !== undefined\n ? { reviewThreshold: partial.reviewThreshold }\n : {}),\n };\n return out;\n }\n // weighted (default)\n const out: WeightedMatchkey = {\n name: partial.name,\n type: \"weighted\",\n fields,\n threshold: partial.threshold ?? 0.85,\n ...(partial.autoThreshold !== undefined\n ? { autoThreshold: partial.autoThreshold }\n : {}),\n ...(partial.rerank !== undefined ? { rerank: partial.rerank } : {}),\n ...(partial.rerankModel !== undefined\n ? { rerankModel: partial.rerankModel }\n : {}),\n ...(partial.rerankBand !== undefined\n ? { rerankBand: partial.rerankBand }\n : {}),\n };\n return out;\n}\n\n/** Create a BlockingConfig with sensible defaults. */\nexport function makeBlockingConfig(\n partial?: Partial<BlockingConfig>,\n): BlockingConfig {\n return {\n strategy: \"static\",\n keys: [],\n maxBlockSize: 5000,\n skipOversized: false,\n ...partial,\n };\n}\n\n/** Create a GoldenRulesConfig with sensible defaults. */\nexport function makeGoldenRulesConfig(\n partial?: Partial<GoldenRulesConfig>,\n): GoldenRulesConfig {\n return {\n defaultStrategy: \"most_complete\",\n fieldRules: {},\n maxClusterSize: 10,\n autoSplit: true,\n qualityWeighting: true,\n weakClusterThreshold: 0.3,\n ...partial,\n };\n}\n\n/** Create a full GoldenMatchConfig with sensible defaults. */\nexport function makeConfig(\n partial?: Partial<GoldenMatchConfig>,\n): GoldenMatchConfig {\n return {\n threshold: 0.85,\n blocking: makeBlockingConfig(partial?.blocking),\n goldenRules: makeGoldenRulesConfig(partial?.goldenRules),\n ...partial,\n // Re-apply blocking/goldenRules after spread so partial overrides win\n ...(partial?.blocking !== undefined\n ? { blocking: makeBlockingConfig(partial.blocking) }\n : {}),\n ...(partial?.goldenRules !== undefined\n ? { goldenRules: makeGoldenRulesConfig(partial.goldenRules) }\n : {}),\n };\n}\n\n/**\n * Return matchkeys from config, checking both `matchkeys` and `matchSettings`.\n * Mirrors Python's `GoldenMatchConfig.get_matchkeys()`.\n */\nexport function getMatchkeys(\n config: GoldenMatchConfig,\n): readonly MatchkeyConfig[] {\n return config.matchkeys ?? config.matchSettings ?? [];\n}\n","/**\n * transforms.ts — Pure field transform utilities.\n * Edge-safe: no Node.js imports, no `process`.\n *\n * Ports goldenmatch/utils/transforms.py.\n */\n\n// ---------------------------------------------------------------------------\n// Public API\n// ---------------------------------------------------------------------------\n\n/** Apply a single named transform to a value. Returns null if input is null. */\nexport function applyTransform(\n value: string | null,\n transform: string,\n): string | null {\n if (value === null) return null;\n\n // Handle parameterized transforms (substring:start:end, qgram:n, bloom_filter:...)\n if (transform.startsWith(\"substring:\")) return applySubstring(value, transform);\n if (transform.startsWith(\"qgram:\")) return applyQgram(value, transform);\n if (transform.startsWith(\"bloom_filter\")) return applyBloomFilter(value, transform);\n\n switch (transform) {\n case \"lowercase\":\n return value.toLowerCase();\n case \"uppercase\":\n return value.toUpperCase();\n case \"strip\":\n return value.trim();\n case \"strip_all\":\n return value.replace(/\\s+/g, \"\");\n case \"digits_only\":\n return value.replace(/\\D/g, \"\");\n case \"alpha_only\":\n return value.replace(/[^a-zA-Z]/g, \"\");\n case \"normalize_whitespace\":\n return value.trim().replace(/\\s+/g, \" \");\n case \"token_sort\":\n return value\n .trim()\n .split(/\\s+/)\n .sort()\n .join(\" \");\n case \"first_token\":\n return value.trim().split(/\\s+/)[0] ?? \"\";\n case \"last_token\": {\n const tokens = value.trim().split(/\\s+/);\n return tokens[tokens.length - 1] ?? \"\";\n }\n case \"soundex\":\n return soundex(value);\n case \"metaphone\":\n return metaphone(value);\n default:\n return value;\n }\n}\n\n/** Apply a chain of transforms in order. */\nexport function applyTransforms(\n value: string | null,\n transforms: readonly string[],\n): string | null {\n let result = value;\n for (const t of transforms) {\n result = applyTransform(result, t);\n if (result === null) return null;\n }\n return result;\n}\n\n// ---------------------------------------------------------------------------\n// Parameterized transforms\n// ---------------------------------------------------------------------------\n\n/** substring:start:end */\nfunction applySubstring(value: string, transform: string): string {\n const parts = transform.split(\":\");\n const start = parseInt(parts[1] ?? \"0\", 10);\n const end = parts[2] !== undefined ? parseInt(parts[2], 10) : undefined;\n return value.slice(start, end);\n}\n\n/** qgram:n — split into character n-grams, sorted and space-separated. */\nfunction applyQgram(value: string, transform: string): string {\n const parts = transform.split(\":\");\n const n = parseInt(parts[1] ?? \"2\", 10);\n if (n <= 0 || value.length < n) return value;\n const grams: string[] = [];\n for (let i = 0; i <= value.length - n; i++) {\n grams.push(value.slice(i, i + n));\n }\n return grams.sort().join(\" \");\n}\n\n// ---------------------------------------------------------------------------\n// Soundex — Robert Russell's algorithm\n// ---------------------------------------------------------------------------\n\nconst SOUNDEX_MAP: Record<string, string> = {\n B: \"1\", F: \"1\", P: \"1\", V: \"1\",\n C: \"2\", G: \"2\", J: \"2\", K: \"2\", Q: \"2\", S: \"2\", X: \"2\", Z: \"2\",\n D: \"3\", T: \"3\",\n L: \"4\",\n M: \"5\", N: \"5\",\n R: \"6\",\n};\n\n/**\n * American Soundex (Robert Russell, 1918).\n * 1. Keep first letter\n * 2. Map consonants to digits (B/F/P/V->1, C/G/J/K/Q/S/X/Z->2, D/T->3, L->4, M/N->5, R->6)\n * 3. Remove adjacent duplicates, vowels/H/W\n * 4. Pad/truncate to 4 chars\n *\n * H and W are transparent — they do NOT reset the duplicate suppression.\n * Vowels (A/E/I/O/U/Y) DO reset, so \"Pfister\" and \"Jackson\" work correctly.\n */\nexport function soundex(value: string): string {\n const clean = value.toUpperCase().replace(/[^A-Z]/g, \"\");\n if (clean.length === 0) return \"0000\";\n\n const firstLetter = clean[0]!;\n let code = firstLetter;\n let lastDigit = SOUNDEX_MAP[firstLetter] ?? \"0\";\n\n for (let i = 1; i < clean.length && code.length < 4; i++) {\n const ch = clean[i]!;\n const digit = SOUNDEX_MAP[ch];\n if (digit && digit !== lastDigit) {\n code += digit;\n lastDigit = digit;\n } else if (!digit) {\n // Vowel / H / W / Y — only H and W are transparent (do NOT reset)\n if (ch !== \"H\" && ch !== \"W\") {\n lastDigit = \"0\";\n }\n }\n }\n\n return (code + \"0000\").slice(0, 4);\n}\n\n// ---------------------------------------------------------------------------\n// Simplified Metaphone (Lawrence Philips, 1990)\n// ---------------------------------------------------------------------------\n\n/**\n * Simplified Metaphone.\n * Returns a phonetic code of up to 4 characters.\n */\nexport function metaphone(value: string): string {\n let word = value.toUpperCase().replace(/[^A-Z]/g, \"\");\n if (word.length === 0) return \"\";\n\n // Drop initial silent letter pairs\n const dropPrefixes = [\"AE\", \"GN\", \"KN\", \"PN\", \"WR\"];\n for (const prefix of dropPrefixes) {\n if (word.startsWith(prefix)) {\n word = word.slice(1);\n break;\n }\n }\n\n // Drop trailing MB (silent B)\n if (word.endsWith(\"MB\")) {\n word = word.slice(0, -1);\n }\n\n let code = \"\";\n let i = 0;\n\n while (i < word.length && code.length < 4) {\n const ch = word[i]!;\n const next = word[i + 1] ?? \"\";\n const prev = i > 0 ? word[i - 1]! : \"\";\n\n // Skip duplicate adjacent letters (except C)\n if (ch === prev && ch !== \"C\") {\n i++;\n continue;\n }\n\n switch (ch) {\n case \"A\":\n case \"E\":\n case \"I\":\n case \"O\":\n case \"U\":\n // Vowels only kept at the beginning\n if (i === 0) code += ch;\n break;\n\n case \"B\":\n code += \"B\";\n break;\n\n case \"C\":\n if (next === \"I\" || next === \"E\" || next === \"Y\") {\n code += \"S\";\n } else {\n code += \"K\";\n }\n break;\n\n case \"D\":\n if (next === \"G\" && \"IEY\".includes(word[i + 2] ?? \"\")) {\n code += \"J\";\n } else {\n code += \"T\";\n }\n break;\n\n case \"F\":\n code += \"F\";\n break;\n\n case \"G\":\n if (next === \"H\" && i + 2 < word.length && !\"AEIOU\".includes(word[i + 2] ?? \"\")) {\n // GH before non-vowel is silent\n i += 2;\n continue;\n } else if (i > 0 && (next === \"N\" || (next === \"N\" && word[i + 2] === \"E\" && i + 2 === word.length - 1))) {\n // GN at end is silent — skip\n } else if (prev === \"G\") {\n // Already handled double G\n } else if (next === \"I\" || next === \"E\" || next === \"Y\") {\n code += \"J\";\n } else {\n code += \"K\";\n }\n break;\n\n case \"H\":\n if (\"AEIOU\".includes(next) && !\"AEIOU\".includes(prev)) {\n code += \"H\";\n }\n break;\n\n case \"J\":\n code += \"J\";\n break;\n\n case \"K\":\n if (prev !== \"C\") code += \"K\";\n break;\n\n case \"L\":\n code += \"L\";\n break;\n\n case \"M\":\n code += \"M\";\n break;\n\n case \"N\":\n code += \"N\";\n break;\n\n case \"P\":\n if (next === \"H\") {\n code += \"F\";\n i++;\n } else {\n code += \"P\";\n }\n break;\n\n case \"Q\":\n code += \"K\";\n break;\n\n case \"R\":\n code += \"R\";\n break;\n\n case \"S\":\n if (next === \"H\" || (next === \"I\" && (word[i + 2] === \"O\" || word[i + 2] === \"A\"))) {\n code += \"X\";\n i++;\n } else if (next === \"C\" && word[i + 2] === \"H\") {\n code += \"SK\";\n i += 2;\n } else {\n code += \"S\";\n }\n break;\n\n case \"T\":\n if (next === \"H\") {\n code += \"0\"; // theta\n i++;\n } else if (next === \"I\" && (word[i + 2] === \"O\" || word[i + 2] === \"A\")) {\n code += \"X\";\n } else {\n code += \"T\";\n }\n break;\n\n case \"V\":\n code += \"F\";\n break;\n\n case \"W\":\n case \"Y\":\n if (\"AEIOU\".includes(next)) {\n code += ch;\n }\n break;\n\n case \"X\":\n code += \"KS\";\n break;\n\n case \"Z\":\n code += \"S\";\n break;\n\n default:\n break;\n }\n i++;\n }\n\n return code.slice(0, 4);\n}\n\n// ---------------------------------------------------------------------------\n// Bloom filter transform (pure TS, for PPRL) — SHA-256 parity with Python\n// ---------------------------------------------------------------------------\n\n/**\n * Security level presets for bloom filter parameters (match Python exactly).\n *\n * standard: 512-bit, 20 hash functions, 2-grams\n * high: 1024-bit, 30 hash functions, 2-grams, HMAC-SHA256 salting\n * paranoid: 2048-bit, 40 hash functions, 3-grams, HMAC-SHA256 + balanced padding\n *\n * See goldenmatch/utils/transforms.py::_bloom_filter_transform for the\n * reference algorithm we match.\n */\ninterface BloomPreset {\n readonly size: number;\n readonly k: number;\n readonly ngram: number;\n readonly hmac: boolean;\n readonly balanced: boolean;\n}\n\nconst BLOOM_PRESETS: Record<string, BloomPreset> = {\n standard: { size: 512, k: 20, ngram: 2, hmac: false, balanced: false },\n high: { size: 1024, k: 30, ngram: 2, hmac: true, balanced: false },\n paranoid: { size: 2048, k: 40, ngram: 3, hmac: true, balanced: true },\n};\n\n/** Default parameters when called as plain \"bloom_filter\" (matches Python). */\nconst BLOOM_DEFAULTS = { size: 1024, k: 20, ngram: 2 };\n\n/** Default HMAC key used by the high/paranoid presets (matches Python). */\nconst BLOOM_DEFAULT_HMAC_KEY = \"default_field_key\";\n\n/**\n * Build a CLK (Cryptographic Longterm Key) bloom filter hex string.\n *\n * Forms accepted:\n * - \"bloom_filter\" -> defaults (1024/20/2, no hmac)\n * - \"bloom_filter:standard\" -> preset\n * - \"bloom_filter:high[:customKey]\" -> preset, optional HMAC key override\n * - \"bloom_filter:paranoid[:customKey]\" -> preset, optional HMAC key override\n * - \"bloom_filter:<ngram>:<k>:<size>[:hmac_key]\" -> fully parametric\n */\nfunction applyBloomFilter(value: string, transform: string): string {\n let ngramSize = BLOOM_DEFAULTS.ngram;\n let numHashes = BLOOM_DEFAULTS.k;\n let filterSize = BLOOM_DEFAULTS.size;\n let hmacKey: string | null = null;\n let balanced = false;\n\n if (transform === \"bloom_filter\") {\n // defaults\n } else {\n const parts = transform.split(\":\");\n const maybeLevel = parts[1];\n if (maybeLevel && (maybeLevel in BLOOM_PRESETS)) {\n const preset = BLOOM_PRESETS[maybeLevel]!;\n ngramSize = preset.ngram;\n numHashes = preset.k;\n filterSize = preset.size;\n balanced = preset.balanced;\n if (preset.hmac) {\n // Allow per-field HMAC key override via bloom_filter:<level>:<key>\n hmacKey = parts[2] && parts[2].length > 0 ? parts[2] : BLOOM_DEFAULT_HMAC_KEY;\n }\n } else {\n // Parametric form: bloom_filter:<ngram>:<k>:<size>[:hmac_key]\n ngramSize = parseInt(parts[1] ?? String(BLOOM_DEFAULTS.ngram), 10);\n numHashes = parseInt(parts[2] ?? String(BLOOM_DEFAULTS.k), 10);\n filterSize = parseInt(parts[3] ?? String(BLOOM_DEFAULTS.size), 10);\n if (parts.length > 4 && parts[4]!.length > 0) {\n hmacKey = parts[4]!;\n }\n }\n }\n\n const filterBytes = Math.floor(filterSize / 8);\n const bits = new Uint8Array(filterBytes);\n\n // Match Python: value.lower().strip(), left-pad with '_' up to ngramSize.\n let padded = value.toLowerCase().trim();\n if (padded.length < ngramSize) {\n padded = padded.padEnd(ngramSize, \"_\");\n }\n\n // Balanced padding: deterministic salt append to normalize filter density.\n if (balanced && padded.length < 8) {\n const salt = sha256Hex(padded).slice(0, 8);\n padded = padded + salt;\n }\n\n // Generate character n-grams.\n const ngrams: string[] = [];\n for (let i = 0; i <= padded.length - ngramSize; i++) {\n ngrams.push(padded.slice(i, i + ngramSize));\n }\n\n // Hash each n-gram k times.\n for (const ngram of ngrams) {\n for (let k = 0; k < numHashes; k++) {\n const hex = hmacKey\n ? hmacSha256Hex(`${hmacKey}:${k}`, ngram)\n : sha256Hex(`${k}:${ngram}`);\n // bit_pos = int(h, 16) % filter_size\n const bitPos = Number(modHexBigInt(hex, filterSize));\n bits[bitPos >> 3]! |= 1 << (bitPos & 7);\n }\n }\n\n return hexEncode(bits);\n}\n\n/** Compute (BigInt hex) mod (Number) and return a non-negative Number result. */\nfunction modHexBigInt(hex: string, modulus: number): number {\n // filterSize fits comfortably in a Number; use BigInt only for the big hex.\n const big = BigInt(\"0x\" + hex);\n const mod = BigInt(modulus);\n const rem = big % mod;\n return Number(rem);\n}\n\n/** Hex-encode a Uint8Array. */\nfunction hexEncode(bytes: Uint8Array): string {\n const hex: string[] = [];\n for (let i = 0; i < bytes.length; i++) {\n hex.push(bytes[i]!.toString(16).padStart(2, \"0\"));\n }\n return hex.join(\"\");\n}\n\n// ---------------------------------------------------------------------------\n// SHA-256 — pure TS, edge-safe (no node: imports)\n// ---------------------------------------------------------------------------\n\n// FIPS 180-4 round constants.\nconst K256 = new Uint32Array([\n 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,\n 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,\n 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,\n 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,\n 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,\n 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,\n 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,\n 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2,\n]);\n\nfunction rotr32(x: number, n: number): number {\n return ((x >>> n) | (x << (32 - n))) >>> 0;\n}\n\n/** UTF-8 encode a string to bytes (edge-safe — uses TextEncoder). */\nfunction utf8Encode(input: string): Uint8Array {\n return new TextEncoder().encode(input);\n}\n\n/** SHA-256 core: digest a byte array, return 32-byte digest. */\nfunction sha256Bytes(msg: Uint8Array): Uint8Array {\n // Initial hash values (FIPS 180-4).\n const H = new Uint32Array([\n 0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a,\n 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19,\n ]);\n\n // Pre-processing: append 1 bit, k zero bits, 64-bit length (big-endian).\n const msgLen = msg.length;\n const bitLen = msgLen * 8;\n const withPadLen = ((msgLen + 9 + 63) >> 6) << 6; // round up to 64-byte block\n const padded = new Uint8Array(withPadLen);\n padded.set(msg);\n padded[msgLen] = 0x80;\n // Length in bits as 64-bit big-endian at the end.\n // High 32 bits are ~0 for any realistic input in JS; write bitLen in low 32.\n const hi = Math.floor(bitLen / 0x100000000);\n const lo = bitLen >>> 0;\n const dv = new DataView(padded.buffer);\n dv.setUint32(withPadLen - 8, hi, false);\n dv.setUint32(withPadLen - 4, lo, false);\n\n const W = new Uint32Array(64);\n\n for (let offset = 0; offset < withPadLen; offset += 64) {\n // Schedule\n for (let t = 0; t < 16; t++) {\n W[t] = dv.getUint32(offset + t * 4, false);\n }\n for (let t = 16; t < 64; t++) {\n const w15 = W[t - 15]!;\n const w2 = W[t - 2]!;\n const s0 = rotr32(w15, 7) ^ rotr32(w15, 18) ^ (w15 >>> 3);\n const s1 = rotr32(w2, 17) ^ rotr32(w2, 19) ^ (w2 >>> 10);\n W[t] = (W[t - 16]! + s0 + W[t - 7]! + s1) >>> 0;\n }\n\n let a = H[0]!, b = H[1]!, c = H[2]!, d = H[3]!;\n let e = H[4]!, f = H[5]!, g = H[6]!, h = H[7]!;\n\n for (let t = 0; t < 64; t++) {\n const S1 = rotr32(e, 6) ^ rotr32(e, 11) ^ rotr32(e, 25);\n const ch = (e & f) ^ (~e & g);\n const T1 = (h + S1 + ch + K256[t]! + W[t]!) >>> 0;\n const S0 = rotr32(a, 2) ^ rotr32(a, 13) ^ rotr32(a, 22);\n const mj = (a & b) ^ (a & c) ^ (b & c);\n const T2 = (S0 + mj) >>> 0;\n h = g;\n g = f;\n f = e;\n e = (d + T1) >>> 0;\n d = c;\n c = b;\n b = a;\n a = (T1 + T2) >>> 0;\n }\n\n H[0] = (H[0]! + a) >>> 0;\n H[1] = (H[1]! + b) >>> 0;\n H[2] = (H[2]! + c) >>> 0;\n H[3] = (H[3]! + d) >>> 0;\n H[4] = (H[4]! + e) >>> 0;\n H[5] = (H[5]! + f) >>> 0;\n H[6] = (H[6]! + g) >>> 0;\n H[7] = (H[7]! + h) >>> 0;\n }\n\n const out = new Uint8Array(32);\n const outDv = new DataView(out.buffer);\n for (let i = 0; i < 8; i++) outDv.setUint32(i * 4, H[i]!, false);\n return out;\n}\n\n/**\n * SHA-256 digest of a UTF-8 string, returned as lowercase 64-char hex.\n *\n * Matches Python `hashlib.sha256(s.encode()).hexdigest()` bit-for-bit.\n */\nexport function sha256Hex(input: string): string {\n return hexEncode(sha256Bytes(utf8Encode(input)));\n}\n\n/**\n * HMAC-SHA256(key, msg) as lowercase 64-char hex.\n *\n * Matches Python `hmac.new(key.encode(), msg.encode(), hashlib.sha256).hexdigest()`.\n */\nexport function hmacSha256Hex(key: string, msg: string): string {\n const blockSize = 64;\n let keyBytes = utf8Encode(key);\n if (keyBytes.length > blockSize) {\n keyBytes = sha256Bytes(keyBytes);\n }\n const kPad = new Uint8Array(blockSize);\n kPad.set(keyBytes);\n\n const oKeyPad = new Uint8Array(blockSize);\n const iKeyPad = new Uint8Array(blockSize);\n for (let i = 0; i < blockSize; i++) {\n oKeyPad[i] = kPad[i]! ^ 0x5c;\n iKeyPad[i] = kPad[i]! ^ 0x36;\n }\n\n const msgBytes = utf8Encode(msg);\n const inner = new Uint8Array(blockSize + msgBytes.length);\n inner.set(iKeyPad);\n inner.set(msgBytes, blockSize);\n const innerHash = sha256Bytes(inner);\n\n const outer = new Uint8Array(blockSize + innerHash.length);\n outer.set(oKeyPad);\n outer.set(innerHash, blockSize);\n return hexEncode(sha256Bytes(outer));\n}\n","/**\n * matchkey.ts — Matchkey builder for GoldenMatch-JS.\n * Edge-safe: no `node:` imports, pure TypeScript only.\n *\n * Ports matchkey building from goldenmatch/core/matchkey.py.\n * In Python this uses Polars expressions; here we work with Row arrays.\n */\n\nimport type { Row, MatchkeyConfig } from \"./types.js\";\nimport { applyTransforms } from \"./transforms.js\";\n\n// ---------------------------------------------------------------------------\n// computeMatchkeyValue — build a matchkey value for a single row\n// ---------------------------------------------------------------------------\n\n/**\n * Build a composite matchkey value for a single row.\n *\n * For each field in the matchkey config:\n * 1. Read the raw value from the row\n * 2. Apply the field's transform chain\n * 3. Concatenate all parts with \"||\" separator\n *\n * Returns `null` if any field value is null/undefined or transforms to null.\n */\nexport function computeMatchkeyValue(\n row: Row,\n mk: MatchkeyConfig,\n): string | null {\n const parts: string[] = [];\n for (const f of mk.fields) {\n const raw = row[f.field];\n if (raw === null || raw === undefined) return null;\n const val = applyTransforms(String(raw), f.transforms);\n if (val === null) return null;\n parts.push(val);\n }\n return parts.join(\"||\");\n}\n\n// ---------------------------------------------------------------------------\n// computeMatchkeys — add matchkey columns to all rows\n// ---------------------------------------------------------------------------\n\n/**\n * Add matchkey columns to rows. For each matchkey `mk`, adds a column\n * `__mk_{mk.name}__` with the computed matchkey value.\n *\n * Returns new row objects (does not mutate originals).\n */\nexport function computeMatchkeys(\n rows: readonly Row[],\n matchkeys: readonly MatchkeyConfig[],\n): Row[] {\n return rows.map((row) => {\n const extra: Record<string, unknown> = {};\n for (const mk of matchkeys) {\n extra[`__mk_${mk.name}__`] = computeMatchkeyValue(row, mk);\n }\n return { ...row, ...extra };\n });\n}\n\n// ---------------------------------------------------------------------------\n// addRowIds — add sequential __row_id__ column\n// ---------------------------------------------------------------------------\n\n/**\n * Add `__row_id__` column as sequential integers starting from `offset`.\n *\n * Returns new row objects (does not mutate originals).\n */\nexport function addRowIds(rows: readonly Row[], offset: number = 0): Row[] {\n return rows.map((row, i) => ({\n ...row,\n __row_id__: offset + i,\n }));\n}\n\n// ---------------------------------------------------------------------------\n// addSourceColumn — add __source__ column\n// ---------------------------------------------------------------------------\n\n/**\n * Add `__source__` column with the given source name to every row.\n *\n * Returns new row objects (does not mutate originals).\n */\nexport function addSourceColumn(\n rows: readonly Row[],\n sourceName: string,\n): Row[] {\n return rows.map((row) => ({\n ...row,\n __source__: sourceName,\n }));\n}\n","/**\n * standardize.ts — Data standardization for GoldenMatch-JS.\n * Edge-safe: no `node:` imports, pure TypeScript only.\n *\n * Ports standardization from goldenmatch/core/standardize.py.\n * These are data cleaning transforms applied to columns before matching.\n */\n\nimport type { Row } from \"./types.js\";\n\n// ---------------------------------------------------------------------------\n// Address abbreviations (USPS standard)\n// ---------------------------------------------------------------------------\n\n/** Map of full word (lowercase) to USPS abbreviation. */\nconst ADDRESS_ABBREVIATIONS: Readonly<Record<string, string>> = {\n street: \"St\",\n avenue: \"Ave\",\n boulevard: \"Blvd\",\n drive: \"Dr\",\n lane: \"Ln\",\n road: \"Rd\",\n court: \"Ct\",\n place: \"Pl\",\n circle: \"Cir\",\n terrace: \"Ter\",\n highway: \"Hwy\",\n parkway: \"Pkwy\",\n expressway: \"Expy\",\n freeway: \"Fwy\",\n trail: \"Trl\",\n way: \"Way\",\n north: \"N\",\n south: \"S\",\n east: \"E\",\n west: \"W\",\n northeast: \"NE\",\n northwest: \"NW\",\n southeast: \"SE\",\n southwest: \"SW\",\n apartment: \"Apt\",\n suite: \"Ste\",\n building: \"Bldg\",\n floor: \"Fl\",\n room: \"Rm\",\n unit: \"Unit\",\n department: \"Dept\",\n \"post office box\": \"PO Box\",\n \"p.o. box\": \"PO Box\",\n \"po box\": \"PO Box\",\n};\n\n// ---------------------------------------------------------------------------\n// Individual standardizer functions\n// ---------------------------------------------------------------------------\n\n/**\n * Standardize email: lowercase, strip, validate basic structure.\n * Returns null for invalid emails.\n */\nfunction stdEmail(value: string): string | null {\n const v = value.trim().toLowerCase();\n if (!v || !v.includes(\"@\")) return null;\n const domain = v.split(\"@\").pop();\n if (!domain || !domain.includes(\".\")) return null;\n return v;\n}\n\n/**\n * Standardize name to proper case (Title Case).\n * Handles hyphenated names: mary-jane -> Mary-Jane.\n */\nfunction stdNameProper(value: string): string | null {\n const v = value.trim();\n if (!v) return null;\n // Collapse whitespace\n const collapsed = v.replace(/\\s+/g, \" \");\n // Title-case each whitespace-separated word; within a word handle hyphens\n const titleWord = (word: string): string => {\n if (!word) return \"\";\n const hyphenParts = word.split(\"-\");\n return hyphenParts\n .map((p) => {\n if (!p) return \"\";\n return p.charAt(0).toUpperCase() + p.slice(1).toLowerCase();\n })\n .join(\"-\");\n };\n return collapsed.split(\" \").map(titleWord).join(\" \");\n}\n\n/**\n * Standardize name to UPPER CASE.\n */\nfunction stdNameUpper(value: string): string | null {\n const v = value.trim().replace(/\\s+/g, \" \").toUpperCase();\n return v || null;\n}\n\n/**\n * Standardize name to lower case.\n */\nfunction stdNameLower(value: string): string | null {\n const v = value.trim().replace(/\\s+/g, \" \");\n return v ? v.toLowerCase() : null;\n}\n\n/**\n * Standardize phone: digits only, strip US country code if 11 digits starting with 1.\n * Returns null if fewer than 7 digits.\n */\nfunction stdPhone(value: string): string | null {\n let digits = value.replace(/\\D/g, \"\");\n if (!digits) return null;\n // Strip US country code\n if (digits.length === 11 && digits.startsWith(\"1\")) {\n digits = digits.slice(1);\n }\n // Must be at least 7 digits\n if (digits.length < 7) return null;\n return digits;\n}\n\n/**\n * Standardize ZIP code to first 5 digits, zero-padded.\n */\nfunction stdZip5(value: string): string | null {\n // Take part before hyphen or space\n const first = value.split(\"-\")[0]!.split(\" \")[0]!;\n const digits = first.replace(/\\D/g, \"\");\n if (!digits) return null;\n return digits.slice(0, 5).padStart(5, \"0\");\n}\n\n/**\n * Title-case a single word.\n */\nfunction titleCase(word: string): string {\n if (!word) return word;\n return word.charAt(0).toUpperCase() + word.slice(1).toLowerCase();\n}\n\n/**\n * Standardize address: title case, USPS abbreviations, normalize whitespace.\n */\nfunction stdAddress(value: string): string | null {\n let v = value.trim();\n if (!v) return null;\n // Normalize whitespace\n v = v.replace(/\\s+/g, \" \");\n const words = v.split(\" \");\n const result: string[] = [];\n let i = 0;\n while (i < words.length) {\n // Check two-word phrases first (e.g. \"post office\")\n if (i + 1 < words.length) {\n const twoWord = `${words[i]} ${words[i + 1]}`.toLowerCase();\n if (twoWord in ADDRESS_ABBREVIATIONS) {\n result.push(ADDRESS_ABBREVIATIONS[twoWord]!);\n i += 2;\n continue;\n }\n }\n // Strip trailing punctuation for lookup\n const wordLower = words[i]!.toLowerCase().replace(/[.,]+$/, \"\");\n if (wordLower in ADDRESS_ABBREVIATIONS) {\n result.push(ADDRESS_ABBREVIATIONS[wordLower]!);\n } else {\n result.push(titleCase(words[i]!));\n }\n i += 1;\n }\n return result.join(\" \");\n}\n\n/**\n * Standardize state to uppercase, strip.\n */\nfunction stdState(value: string): string | null {\n const v = value.trim().toUpperCase();\n return v || null;\n}\n\n/**\n * Strip whitespace, normalize to null if empty.\n */\nfunction stdStrip(value: string): string | null {\n const v = value.trim();\n return v || null;\n}\n\n/**\n * Collapse multiple spaces to one, strip.\n */\nfunction stdTrimWhitespace(value: string): string | null {\n const v = value.replace(/\\s+/g, \" \").trim();\n return v || null;\n}\n\n// ---------------------------------------------------------------------------\n// Standardizer registry\n// ---------------------------------------------------------------------------\n\n/** Map of standardizer name to function. */\nconst STANDARDIZERS: Readonly<Record<string, (value: string) => string | null>> = {\n email: stdEmail,\n name_proper: stdNameProper,\n name_upper: stdNameUpper,\n name_lower: stdNameLower,\n phone: stdPhone,\n zip5: stdZip5,\n address: stdAddress,\n state: stdState,\n strip: stdStrip,\n trim_whitespace: stdTrimWhitespace,\n};\n\n// ---------------------------------------------------------------------------\n// applyStandardizer — dispatch to the correct standardizer\n// ---------------------------------------------------------------------------\n\n/**\n * Apply a named standardizer to a string value.\n *\n * @throws Error if the standardizer name is not recognized.\n */\nexport function applyStandardizer(value: string, name: string): string {\n const fn = STANDARDIZERS[name];\n if (!fn) {\n const available = Object.keys(STANDARDIZERS).sort().join(\", \");\n throw new Error(\n `Unknown standardizer: \"${name}\". Available: ${available}`,\n );\n }\n const result = fn(value);\n // Standardizers may return null for invalid data; treat as empty string\n // so downstream pipeline can decide how to handle it.\n return result ?? \"\";\n}\n\n// ---------------------------------------------------------------------------\n// applyStandardization — apply rules to all rows\n// ---------------------------------------------------------------------------\n\n/**\n * Apply standardization rules to rows.\n *\n * `rules` maps column names to arrays of standardizer names that are\n * applied in sequence. For example:\n *\n * ```ts\n * applyStandardization(rows, {\n * email: [\"email\"],\n * first_name: [\"strip\", \"name_proper\"],\n * phone: [\"phone\"],\n * });\n * ```\n *\n * Returns new row objects (does not mutate originals).\n * Null/undefined column values are skipped (left as-is).\n */\nexport function applyStandardization(\n rows: readonly Row[],\n rules: Readonly<Record<string, readonly string[]>>,\n): Row[] {\n return rows.map((row) => {\n const newRow: Record<string, unknown> = { ...row };\n for (const [column, standardizers] of Object.entries(rules)) {\n const val = row[column];\n if (val === null || val === undefined) continue;\n let str = String(val);\n for (const stdName of standardizers) {\n str = applyStandardizer(str, stdName);\n }\n newRow[column] = str;\n }\n return newRow as Row;\n });\n}\n","/**\n * embedder.ts — Embedding API client (OpenAI / Vertex AI / Voyage).\n *\n * Edge-safe: uses global `fetch()` only. No `node:` imports.\n *\n * Ports `goldenmatch/core/embedder.py` and `goldenmatch/core/vertex_embedder.py`,\n * but replaces sentence-transformers / google-cloud-aiplatform with HTTP calls\n * so the module runs in Edge / Workers / browser-like runtimes.\n */\n\n// ---------------------------------------------------------------------------\n// Public types\n// ---------------------------------------------------------------------------\n\nexport type EmbedderProvider = \"openai\" | \"vertex\" | \"voyage\";\n\nexport interface EmbedderOptions {\n readonly provider?: EmbedderProvider;\n readonly model?: string;\n readonly apiKey?: string;\n /** Override the default endpoint URL. */\n readonly endpoint?: string;\n /** Batch size for API calls (default 64 for OpenAI, 50 for Vertex). */\n readonly batchSize?: number;\n /** Cache embeddings by text hash within an Embedder instance. */\n readonly cache?: boolean;\n /**\n * For OpenAI text-embedding-3+ this requests a smaller embedding\n * dimension (e.g. 512 instead of 1536).\n */\n readonly dimensions?: number;\n /** GCP project ID (required for Vertex). */\n readonly project?: string;\n /** GCP region (Vertex). Default: us-central1. */\n readonly location?: string;\n /** Pre-fetched OAuth bearer token for Vertex. */\n readonly bearerToken?: string;\n /** Maximum HTTP retries for transient failures (default 3). */\n readonly maxRetries?: number;\n}\n\nexport interface EmbeddingResult {\n readonly embeddings: readonly Float32Array[];\n readonly model: string;\n readonly tokensUsed: number;\n}\n\n// ---------------------------------------------------------------------------\n// Errors\n// ---------------------------------------------------------------------------\n\nexport class EmbedderError extends Error {\n constructor(\n message: string,\n public readonly status?: number,\n public readonly body?: string,\n ) {\n super(message);\n this.name = \"EmbedderError\";\n }\n}\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\nfunction readEnv(key: string): string | undefined {\n // Optional, soft-read env without hard `process` reference.\n const proc = (globalThis as { process?: { env?: Record<string, string | undefined> } }).process;\n return proc?.env?.[key];\n}\n\nasync function sleep(ms: number): Promise<void> {\n await new Promise<void>((resolve) => {\n setTimeout(resolve, ms);\n });\n}\n\n/** Cheap stable hash for cache keys. */\nfunction hashText(text: string): string {\n // FNV-1a 32-bit. Stable, no collisions matter much for cache use.\n let h = 0x811c9dc5;\n for (let i = 0; i < text.length; i++) {\n h ^= text.charCodeAt(i);\n h = Math.imul(h, 0x01000193);\n }\n return (h >>> 0).toString(36);\n}\n\n/** L2-normalize an embedding in place. */\nfunction l2Normalize(vec: Float32Array): Float32Array {\n let s = 0;\n for (let i = 0; i < vec.length; i++) s += vec[i]! * vec[i]!;\n const norm = Math.sqrt(s);\n if (norm === 0) return vec;\n for (let i = 0; i < vec.length; i++) vec[i] = vec[i]! / norm;\n return vec;\n}\n\nfunction toFloat32(arr: readonly number[]): Float32Array {\n const out = new Float32Array(arr.length);\n for (let i = 0; i < arr.length; i++) out[i] = arr[i] ?? 0;\n return out;\n}\n\n// ---------------------------------------------------------------------------\n// Provider defaults\n// ---------------------------------------------------------------------------\n\nfunction defaultModelFor(provider: EmbedderProvider): string {\n switch (provider) {\n case \"openai\":\n return \"text-embedding-3-small\";\n case \"vertex\":\n return \"text-embedding-004\";\n case \"voyage\":\n return \"voyage-3\";\n }\n}\n\nfunction defaultBatchSizeFor(provider: EmbedderProvider): number {\n switch (provider) {\n case \"openai\":\n return 64;\n case \"vertex\":\n return 50;\n case \"voyage\":\n return 64;\n }\n}\n\n// ---------------------------------------------------------------------------\n// Retry wrapper\n// ---------------------------------------------------------------------------\n\nasync function fetchWithRetry(\n url: string,\n init: RequestInit,\n maxRetries: number,\n): Promise<Response> {\n let lastErr: unknown = null;\n for (let attempt = 0; attempt <= maxRetries; attempt++) {\n try {\n const resp = await fetch(url, init);\n if (resp.status === 429 || (resp.status >= 500 && resp.status < 600)) {\n if (attempt < maxRetries) {\n // Exponential backoff: 0.5s, 1s, 2s ...\n await sleep(500 * Math.pow(2, attempt));\n continue;\n }\n }\n return resp;\n } catch (err) {\n lastErr = err;\n if (attempt < maxRetries) {\n await sleep(500 * Math.pow(2, attempt));\n continue;\n }\n }\n }\n throw new EmbedderError(\n `Network error after ${maxRetries + 1} attempts: ${String(lastErr)}`,\n );\n}\n\n// ---------------------------------------------------------------------------\n// Embedder\n// ---------------------------------------------------------------------------\n\nexport class Embedder {\n private readonly cacheMap = new Map<string, Float32Array>();\n private readonly provider: EmbedderProvider;\n private readonly model: string;\n private readonly batchSize: number;\n private readonly maxRetries: number;\n private readonly cacheEnabled: boolean;\n\n constructor(private readonly options: EmbedderOptions = {}) {\n this.provider = options.provider ?? \"openai\";\n this.model = options.model ?? defaultModelFor(this.provider);\n this.batchSize = options.batchSize ?? defaultBatchSizeFor(this.provider);\n this.maxRetries = options.maxRetries ?? 3;\n this.cacheEnabled = options.cache ?? true;\n }\n\n // ──────────────────────────────────────────────────────────\n // Public API\n // ──────────────────────────────────────────────────────────\n\n /** Embed a batch of texts in one or more API calls. */\n async embedBatch(texts: readonly string[]): Promise<EmbeddingResult> {\n if (texts.length === 0) {\n return { embeddings: [], model: this.model, tokensUsed: 0 };\n }\n\n // Deduplicate while preserving original order mapping.\n const uniqueOrder: string[] = [];\n const uniqueIndex = new Map<string, number>();\n const indexFor: number[] = new Array(texts.length).fill(0);\n for (let i = 0; i < texts.length; i++) {\n const t = texts[i] ?? \"\";\n let idx = uniqueIndex.get(t);\n if (idx === undefined) {\n idx = uniqueOrder.length;\n uniqueOrder.push(t);\n uniqueIndex.set(t, idx);\n }\n indexFor[i] = idx;\n }\n\n // Resolve from cache where possible.\n const uniqueEmbeddings: (Float32Array | null)[] = new Array(uniqueOrder.length).fill(null);\n const toFetchIdx: number[] = [];\n const toFetchText: string[] = [];\n for (let i = 0; i < uniqueOrder.length; i++) {\n const text = uniqueOrder[i]!;\n if (this.cacheEnabled) {\n const hit = this.cacheMap.get(hashText(text));\n if (hit) {\n uniqueEmbeddings[i] = hit;\n continue;\n }\n }\n toFetchIdx.push(i);\n toFetchText.push(text);\n }\n\n let tokensUsed = 0;\n\n if (toFetchText.length > 0) {\n // Batch the API calls.\n for (let start = 0; start < toFetchText.length; start += this.batchSize) {\n const end = Math.min(start + this.batchSize, toFetchText.length);\n const slice = toFetchText.slice(start, end);\n const result = await this.callProvider(slice);\n tokensUsed += result.tokensUsed;\n for (let j = 0; j < result.embeddings.length; j++) {\n const targetIdx = toFetchIdx[start + j]!;\n const emb = result.embeddings[j]!;\n uniqueEmbeddings[targetIdx] = emb;\n if (this.cacheEnabled) {\n this.cacheMap.set(hashText(uniqueOrder[targetIdx]!), emb);\n }\n }\n }\n }\n\n // Re-expand back to original order.\n const embeddings: Float32Array[] = new Array(texts.length);\n for (let i = 0; i < texts.length; i++) {\n const u = uniqueEmbeddings[indexFor[i]!];\n if (!u) {\n // Should not happen; fall back to zero vector of last-known dim.\n const dim = this.firstDim(uniqueEmbeddings) ?? 0;\n embeddings[i] = new Float32Array(dim);\n } else {\n embeddings[i] = u;\n }\n }\n\n return { embeddings, model: this.model, tokensUsed };\n }\n\n /** Embed a single text. */\n async embedOne(text: string): Promise<Float32Array> {\n const r = await this.embedBatch([text]);\n return r.embeddings[0] ?? new Float32Array(0);\n }\n\n /**\n * Embed a column of (possibly null) values. Null/empty get a zero vector.\n * Identical text values are de-duplicated automatically.\n */\n async embedColumn(\n values: readonly (string | null | undefined)[],\n _cacheKey?: string,\n ): Promise<readonly Float32Array[]> {\n if (values.length === 0) return [];\n\n // Substitute null/empty with a sentinel; we replace with zero vectors after.\n const ZERO_SENTINEL = \"\\u0000__GM_NULL__\\u0000\";\n const inputs: string[] = values.map((v) => {\n if (v === null || v === undefined) return ZERO_SENTINEL;\n const s = String(v).trim();\n return s === \"\" ? ZERO_SENTINEL : s;\n });\n\n // Embed only the non-null subset.\n const nonNullTexts: string[] = [];\n const positions: number[] = [];\n for (let i = 0; i < inputs.length; i++) {\n if (inputs[i] !== ZERO_SENTINEL) {\n nonNullTexts.push(inputs[i]!);\n positions.push(i);\n }\n }\n\n let dim = 0;\n let realEmbeddings: readonly Float32Array[] = [];\n if (nonNullTexts.length > 0) {\n const r = await this.embedBatch(nonNullTexts);\n realEmbeddings = r.embeddings;\n dim = realEmbeddings[0]?.length ?? 0;\n }\n\n const out: Float32Array[] = new Array(values.length);\n for (let i = 0; i < values.length; i++) out[i] = new Float32Array(dim);\n for (let k = 0; k < positions.length; k++) {\n out[positions[k]!] = realEmbeddings[k] ?? new Float32Array(dim);\n }\n return out;\n }\n\n // ──────────────────────────────────────────────────────────\n // Similarity helpers\n // ──────────────────────────────────────────────────────────\n\n cosineSimilarity(a: Float32Array, b: Float32Array): number {\n let dot = 0;\n let na = 0;\n let nb = 0;\n const n = Math.min(a.length, b.length);\n for (let i = 0; i < n; i++) {\n const av = a[i]!;\n const bv = b[i]!;\n dot += av * bv;\n na += av * av;\n nb += bv * bv;\n }\n const denom = Math.sqrt(na) * Math.sqrt(nb);\n return denom === 0 ? 0 : dot / denom;\n }\n\n cosineSimilarityMatrix(embeddings: readonly Float32Array[]): number[][] {\n const n = embeddings.length;\n const out: number[][] = new Array(n);\n for (let i = 0; i < n; i++) out[i] = new Array(n).fill(0);\n for (let i = 0; i < n; i++) {\n out[i]![i] = 1;\n for (let j = i + 1; j < n; j++) {\n const s = this.cosineSimilarity(embeddings[i]!, embeddings[j]!);\n out[i]![j] = s;\n out[j]![i] = s;\n }\n }\n return out;\n }\n\n // ──────────────────────────────────────────────────────────\n // Internals\n // ──────────────────────────────────────────────────────────\n\n private firstDim(arr: readonly (Float32Array | null)[]): number | null {\n for (const v of arr) if (v) return v.length;\n return null;\n }\n\n private async callProvider(\n texts: readonly string[],\n ): Promise<EmbeddingResult> {\n switch (this.provider) {\n case \"openai\":\n return this.callOpenAI(texts);\n case \"vertex\":\n return this.callVertex(texts);\n case \"voyage\":\n return this.callVoyage(texts);\n }\n }\n\n // ── OpenAI ────────────────────────────────────────────────\n private async callOpenAI(texts: readonly string[]): Promise<EmbeddingResult> {\n const apiKey = this.options.apiKey ?? readEnv(\"OPENAI_API_KEY\");\n if (!apiKey) {\n throw new EmbedderError(\n \"OpenAI API key required. Pass options.apiKey or set OPENAI_API_KEY.\",\n );\n }\n const url = this.options.endpoint ?? \"https://api.openai.com/v1/embeddings\";\n const body: Record<string, unknown> = {\n model: this.model,\n input: texts,\n };\n if (this.options.dimensions !== undefined) {\n body.dimensions = this.options.dimensions;\n }\n const resp = await fetchWithRetry(\n url,\n {\n method: \"POST\",\n headers: {\n Authorization: `Bearer ${apiKey}`,\n \"Content-Type\": \"application/json\",\n },\n body: JSON.stringify(body),\n },\n this.maxRetries,\n );\n if (!resp.ok) {\n const text = await resp.text().catch(() => \"\");\n throw new EmbedderError(\n `OpenAI embeddings ${resp.status}`,\n resp.status,\n text.slice(0, 500),\n );\n }\n const data = (await resp.json()) as {\n data?: Array<{ embedding?: number[] }>;\n usage?: { total_tokens?: number };\n };\n const arr = data.data ?? [];\n const embeddings: Float32Array[] = arr.map((d) => {\n const v = d.embedding ?? [];\n return l2Normalize(toFloat32(v));\n });\n return {\n embeddings,\n model: this.model,\n tokensUsed: data.usage?.total_tokens ?? 0,\n };\n }\n\n // ── Vertex AI ─────────────────────────────────────────────\n private async callVertex(texts: readonly string[]): Promise<EmbeddingResult> {\n const project = this.options.project ?? readEnv(\"GOOGLE_CLOUD_PROJECT\");\n if (!project) {\n throw new EmbedderError(\n \"Vertex requires options.project or GOOGLE_CLOUD_PROJECT.\",\n );\n }\n const location =\n this.options.location ??\n readEnv(\"GOOGLE_CLOUD_LOCATION\") ??\n \"us-central1\";\n const token =\n this.options.bearerToken ??\n this.options.apiKey ??\n readEnv(\"GOOGLE_OAUTH_TOKEN\");\n if (!token) {\n throw new EmbedderError(\n \"Vertex requires options.bearerToken (OAuth access token). \" +\n \"Service-account JWT signing is unavailable in edge runtime — \" +\n \"fetch a token out-of-band and pass it in.\",\n );\n }\n const url =\n this.options.endpoint ??\n `https://${location}-aiplatform.googleapis.com/v1/projects/${project}/locations/${location}/publishers/google/models/${this.model}:predict`;\n\n const body = JSON.stringify({\n instances: texts.map((t) => ({ content: t })),\n });\n const resp = await fetchWithRetry(\n url,\n {\n method: \"POST\",\n headers: {\n Authorization: `Bearer ${token}`,\n \"Content-Type\": \"application/json\",\n },\n body,\n },\n this.maxRetries,\n );\n if (!resp.ok) {\n const text = await resp.text().catch(() => \"\");\n throw new EmbedderError(\n `Vertex embeddings ${resp.status}`,\n resp.status,\n text.slice(0, 500),\n );\n }\n const data = (await resp.json()) as {\n predictions?: Array<{\n embeddings?: { values?: number[]; statistics?: { token_count?: number } };\n }>;\n };\n let tokens = 0;\n const embeddings: Float32Array[] = (data.predictions ?? []).map((p) => {\n const v = p.embeddings?.values ?? [];\n tokens += p.embeddings?.statistics?.token_count ?? 0;\n return l2Normalize(toFloat32(v));\n });\n return { embeddings, model: this.model, tokensUsed: tokens };\n }\n\n // ── Voyage AI ─────────────────────────────────────────────\n private async callVoyage(texts: readonly string[]): Promise<EmbeddingResult> {\n const apiKey = this.options.apiKey ?? readEnv(\"VOYAGE_API_KEY\");\n if (!apiKey) {\n throw new EmbedderError(\n \"Voyage API key required. Pass options.apiKey or set VOYAGE_API_KEY.\",\n );\n }\n const url = this.options.endpoint ?? \"https://api.voyageai.com/v1/embeddings\";\n const resp = await fetchWithRetry(\n url,\n {\n method: \"POST\",\n headers: {\n Authorization: `Bearer ${apiKey}`,\n \"Content-Type\": \"application/json\",\n },\n body: JSON.stringify({ model: this.model, input: texts }),\n },\n this.maxRetries,\n );\n if (!resp.ok) {\n const text = await resp.text().catch(() => \"\");\n throw new EmbedderError(\n `Voyage embeddings ${resp.status}`,\n resp.status,\n text.slice(0, 500),\n );\n }\n const data = (await resp.json()) as {\n data?: Array<{ embedding?: number[] }>;\n usage?: { total_tokens?: number };\n };\n const arr = data.data ?? [];\n const embeddings: Float32Array[] = arr.map((d) => {\n const v = d.embedding ?? [];\n return l2Normalize(toFloat32(v));\n });\n return {\n embeddings,\n model: this.model,\n tokensUsed: data.usage?.total_tokens ?? 0,\n };\n }\n}\n\n// ---------------------------------------------------------------------------\n// Singleton factory\n// ---------------------------------------------------------------------------\n\nconst embedderCache = new Map<string, Embedder>();\n\n/**\n * Return a cached Embedder instance keyed by provider+model.\n * Pass a string to use a model name with default provider, or full options.\n */\nexport function getEmbedder(modelOrOptions?: string | EmbedderOptions): Embedder {\n const opts: EmbedderOptions =\n typeof modelOrOptions === \"string\"\n ? { model: modelOrOptions }\n : (modelOrOptions ?? {});\n const provider = opts.provider ?? \"openai\";\n const model = opts.model ?? defaultModelFor(provider);\n const key = `${provider}::${model}`;\n let e = embedderCache.get(key);\n if (!e) {\n e = new Embedder(opts);\n embedderCache.set(key, e);\n }\n return e;\n}\n\n/** Test-only: clear the embedder cache. */\nexport function _clearEmbedderCache(): void {\n embedderCache.clear();\n}\n","/**\n * ann-blocker.ts — Approximate nearest neighbour blocking.\n *\n * Edge-safe: no `node:` imports, no FAISS. Implements a brute-force kNN\n * (O(n^2)) which is appropriate for <= ~10K records. Embeddings are\n * fetched via `getEmbedder()` which uses HTTP `fetch()`.\n *\n * Ports `goldenmatch/core/ann_blocker.py`.\n */\n\nimport type { BlockResult, Row, ScoredPair } from \"./types.js\";\nimport { makeScoredPair } from \"./types.js\";\nimport { getEmbedder, type EmbedderOptions } from \"./embedder.js\";\n\n// ---------------------------------------------------------------------------\n// Public option types\n// ---------------------------------------------------------------------------\n\nexport interface ANNBlockerOptions {\n readonly topK?: number;\n readonly metric?: \"cosine\" | \"euclidean\";\n}\n\nexport interface BuildANNOptions {\n readonly topK?: number;\n readonly model?: string;\n readonly apiKey?: string;\n readonly provider?: EmbedderOptions[\"provider\"];\n /** Row identifier column (default `__row_id__`). */\n readonly idColumn?: string;\n /** Maximum block size produced by Union-Find grouping. */\n readonly maxBlockSize?: number;\n /** Use hnswlib-node fast-path when available (falls back to brute-force). */\n readonly useHNSW?: boolean;\n}\n\n/**\n * Minimal shape of the `hnswlib-node` module that we rely on. The caller\n * passes in the loaded module; we deliberately keep the surface tiny so we\n * don't hard-depend on its types.\n */\nexport interface HNSWModule {\n readonly HierarchicalNSW: new (\n metric: string,\n dim: number,\n ) => HNSWIndexLike;\n}\n\nexport interface HNSWIndexLike {\n initIndex(\n maxElements: number,\n M?: number,\n efConstruction?: number,\n randomSeed?: number,\n ): void;\n setEf(ef: number): void;\n addPoint(vector: number[] | Float32Array, labelId: number): void;\n searchKnn(\n query: number[] | Float32Array,\n k: number,\n ): { distances: number[]; neighbors: number[] };\n}\n\nexport interface HNSWOptions {\n readonly hnswModule: HNSWModule;\n readonly topK?: number;\n readonly metric?: \"cosine\" | \"euclidean\";\n readonly maxElements?: number;\n readonly M?: number;\n readonly efConstruction?: number;\n readonly efSearch?: number;\n}\n\n/** Shared interface so `ANNBlocker` and `HNSWANNBlocker` are interchangeable. */\nexport interface ANNBlockerBase {\n buildIndex(embeddings: readonly Float32Array[]): void;\n addToIndex(embedding: Float32Array): number;\n query(queryEmbeddings: readonly Float32Array[]): Array<[number, number]>;\n queryWithScores(\n queryEmbeddings: readonly Float32Array[],\n ): Array<[number, number, number]>;\n queryOne(queryEmbedding: Float32Array): Array<[number, number]>;\n readonly indexSize: number;\n}\n\n// ---------------------------------------------------------------------------\n// Distance helpers\n// ---------------------------------------------------------------------------\n\nexport function cosineSim(a: Float32Array, b: Float32Array): number {\n let dot = 0;\n let na = 0;\n let nb = 0;\n const n = Math.min(a.length, b.length);\n for (let i = 0; i < n; i++) {\n const av = a[i]!;\n const bv = b[i]!;\n dot += av * bv;\n na += av * av;\n nb += bv * bv;\n }\n const denom = Math.sqrt(na) * Math.sqrt(nb);\n return denom === 0 ? 0 : dot / denom;\n}\n\nexport function euclideanDist(a: Float32Array, b: Float32Array): number {\n let s = 0;\n const n = Math.min(a.length, b.length);\n for (let i = 0; i < n; i++) {\n const d = a[i]! - b[i]!;\n s += d * d;\n }\n return Math.sqrt(s);\n}\n\n// ---------------------------------------------------------------------------\n// ANNBlocker\n// ---------------------------------------------------------------------------\n\nexport class ANNBlocker implements ANNBlockerBase {\n private embeddings: Float32Array[] = [];\n private readonly topK: number;\n private readonly metric: \"cosine\" | \"euclidean\";\n\n constructor(options: ANNBlockerOptions = {}) {\n this.topK = options.topK ?? 20;\n this.metric = options.metric ?? \"cosine\";\n }\n\n /** Replace the index with a fresh set of embeddings. */\n buildIndex(embeddings: readonly Float32Array[]): void {\n this.embeddings = embeddings.map((e) => e);\n }\n\n /** Number of vectors currently in the index. */\n get indexSize(): number {\n return this.embeddings.length;\n }\n\n /** Append a single embedding; returns its position. */\n addToIndex(embedding: Float32Array): number {\n this.embeddings.push(embedding);\n return this.embeddings.length - 1;\n }\n\n // ──────────────────────────────────────────────────────────\n // Querying\n // ──────────────────────────────────────────────────────────\n\n /**\n * For each query embedding, return up to topK (queryIdx, indexIdx) pairs.\n * Self-matches (same index when queries == embeddings) are excluded only\n * when the underlying object identity matches; otherwise the caller is\n * responsible for filtering self-pairs.\n *\n * Pairs are canonicalised so the lower index is always first when querying\n * against the same index population (queryIdx === indexIdx case removed).\n */\n query(queryEmbeddings: readonly Float32Array[]): Array<[number, number]> {\n const seen = new Set<number>();\n const out: Array<[number, number]> = [];\n const sameIndex = queryEmbeddings === (this.embeddings as readonly Float32Array[]);\n for (let i = 0; i < queryEmbeddings.length; i++) {\n const top = this.topKFor(queryEmbeddings[i]!);\n for (const [neighbour] of top) {\n if (sameIndex && neighbour === i) continue;\n if (neighbour < 0) continue;\n const a = Math.min(i, neighbour);\n const b = Math.max(i, neighbour);\n const key = a * 100000003 + b; // rough Cantor-like dedup key\n if (seen.has(key)) continue;\n seen.add(key);\n out.push([a, b]);\n }\n }\n return out;\n }\n\n /** Same as `query` but also returns the similarity score for each pair. */\n queryWithScores(\n queryEmbeddings: readonly Float32Array[],\n ): Array<[number, number, number]> {\n const best = new Map<number, [number, number, number]>();\n const sameIndex = queryEmbeddings === (this.embeddings as readonly Float32Array[]);\n for (let i = 0; i < queryEmbeddings.length; i++) {\n const top = this.topKFor(queryEmbeddings[i]!);\n for (const [neighbour, score] of top) {\n if (sameIndex && neighbour === i) continue;\n if (neighbour < 0) continue;\n const a = Math.min(i, neighbour);\n const b = Math.max(i, neighbour);\n const key = a * 100000003 + b;\n const prev = best.get(key);\n if (!prev || score > prev[2]) {\n best.set(key, [a, b, score]);\n }\n }\n }\n return [...best.values()];\n }\n\n /** Top-K matches for a single query. Returns (neighborIdx, score). */\n queryOne(queryEmbedding: Float32Array): Array<[number, number]> {\n return this.topKFor(queryEmbedding);\n }\n\n // ──────────────────────────────────────────────────────────\n // Internals\n // ──────────────────────────────────────────────────────────\n\n private topKFor(query: Float32Array): Array<[number, number]> {\n const n = this.embeddings.length;\n if (n === 0) return [];\n // Score every vector. For 10k×10k that's 100M ops — acceptable for an\n // edge-safe brute-force fallback, but callers should pre-filter for very\n // large datasets.\n const scores = new Array<{ idx: number; score: number }>(n);\n for (let i = 0; i < n; i++) {\n const s =\n this.metric === \"cosine\"\n ? cosineSim(query, this.embeddings[i]!)\n : -euclideanDist(query, this.embeddings[i]!);\n scores[i] = { idx: i, score: s };\n }\n // Partial sort: top-K only.\n const k = Math.min(this.topK, n);\n scores.sort((a, b) => b.score - a.score);\n const out: Array<[number, number]> = new Array(k);\n for (let i = 0; i < k; i++) out[i] = [scores[i]!.idx, scores[i]!.score];\n return out;\n }\n}\n\n// ---------------------------------------------------------------------------\n// HNSWANNBlocker — optional fast-path backed by `hnswlib-node`.\n//\n// The caller provides the loaded `hnswlib-node` module via `opts.hnswModule`,\n// keeping this file edge-safe (we never import the native module here).\n// ---------------------------------------------------------------------------\n\nexport class HNSWANNBlocker implements ANNBlockerBase {\n private index: HNSWIndexLike | null = null;\n private count = 0;\n private readonly opts: HNSWOptions;\n private readonly topK: number;\n private readonly metric: \"cosine\" | \"euclidean\";\n\n constructor(opts: HNSWOptions) {\n this.opts = opts;\n this.topK = opts.topK ?? 20;\n this.metric = opts.metric ?? \"cosine\";\n }\n\n get indexSize(): number {\n return this.count;\n }\n\n buildIndex(embeddings: readonly Float32Array[]): void {\n if (embeddings.length === 0) {\n this.index = null;\n this.count = 0;\n return;\n }\n const dim = embeddings[0]!.length;\n const metricStr = this.metric === \"euclidean\" ? \"l2\" : \"cosine\";\n const HierarchicalNSW = this.opts.hnswModule.HierarchicalNSW;\n const index = new HierarchicalNSW(metricStr, dim);\n const maxElements = this.opts.maxElements ?? Math.max(embeddings.length * 2, 16);\n const M = this.opts.M ?? 16;\n const efConstruction = this.opts.efConstruction ?? 200;\n index.initIndex(maxElements, M, efConstruction, 100);\n const efSearch = this.opts.efSearch ?? Math.max(this.topK, 50);\n index.setEf(efSearch);\n for (let i = 0; i < embeddings.length; i++) {\n index.addPoint(Array.from(embeddings[i]!), i);\n }\n this.index = index;\n this.count = embeddings.length;\n }\n\n addToIndex(embedding: Float32Array): number {\n if (!this.index) {\n throw new Error(\"HNSWANNBlocker.addToIndex called before buildIndex\");\n }\n const id = this.count;\n this.index.addPoint(Array.from(embedding), id);\n this.count++;\n return id;\n }\n\n query(queryEmbeddings: readonly Float32Array[]): Array<[number, number]> {\n const pairs: Array<[number, number]> = [];\n if (!this.index || this.count === 0) return pairs;\n const k = Math.min(this.topK, this.count);\n const seen = new Set<number>();\n for (let i = 0; i < queryEmbeddings.length; i++) {\n const q = Array.from(queryEmbeddings[i]!);\n const result = this.index.searchKnn(q, k);\n for (const neighbour of result.neighbors) {\n if (neighbour === i) continue;\n if (neighbour < 0) continue;\n const a = Math.min(i, neighbour);\n const b = Math.max(i, neighbour);\n const key = a * 100000003 + b;\n if (seen.has(key)) continue;\n seen.add(key);\n pairs.push([a, b]);\n }\n }\n return pairs;\n }\n\n queryWithScores(\n queryEmbeddings: readonly Float32Array[],\n ): Array<[number, number, number]> {\n const best = new Map<number, [number, number, number]>();\n if (!this.index || this.count === 0) return [];\n const k = Math.min(this.topK, this.count);\n for (let i = 0; i < queryEmbeddings.length; i++) {\n const q = Array.from(queryEmbeddings[i]!);\n const result = this.index.searchKnn(q, k);\n for (let idx = 0; idx < result.neighbors.length; idx++) {\n const neighbour = result.neighbors[idx]!;\n const d = result.distances[idx]!;\n if (neighbour === i) continue;\n if (neighbour < 0) continue;\n // For \"cosine\" metric hnswlib returns (1 - cos_sim); for \"l2\" it\n // returns squared Euclidean distance. Convert to a similarity score\n // bounded in (roughly) [0, 1].\n const score = this.metric === \"euclidean\" ? 1 / (1 + d) : 1 - d;\n const a = Math.min(i, neighbour);\n const b = Math.max(i, neighbour);\n const key = a * 100000003 + b;\n const prev = best.get(key);\n if (!prev || score > prev[2]) {\n best.set(key, [a, b, score]);\n }\n }\n }\n return [...best.values()];\n }\n\n queryOne(queryEmbedding: Float32Array): Array<[number, number]> {\n if (!this.index || this.count === 0) return [];\n const k = Math.min(this.topK, this.count);\n const result = this.index.searchKnn(Array.from(queryEmbedding), k);\n const out: Array<[number, number]> = [];\n for (let idx = 0; idx < result.neighbors.length; idx++) {\n const neighbour = result.neighbors[idx]!;\n const d = result.distances[idx]!;\n const score = this.metric === \"euclidean\" ? 1 / (1 + d) : 1 - d;\n out.push([neighbour, score]);\n }\n return out;\n }\n}\n\n// ---------------------------------------------------------------------------\n// Factory — auto-loads `hnswlib-node` when requested, falls back to brute-force.\n// ---------------------------------------------------------------------------\n\nexport interface CreateANNBlockerOptions extends ANNBlockerOptions {\n /** Attempt to use the hnswlib-node fast-path. */\n readonly useHNSW?: boolean;\n /** Pre-loaded hnswlib-node module (skips dynamic import). */\n readonly hnswModule?: HNSWModule;\n /** Additional HNSW tuning knobs. Ignored when falling back to brute-force. */\n readonly maxElements?: number;\n readonly M?: number;\n readonly efConstruction?: number;\n readonly efSearch?: number;\n /**\n * Override the warning sink when the fast-path is unavailable. Defaults to\n * `console.warn`. Tests pass a spy here.\n */\n readonly onFallbackWarning?: (message: string) => void;\n}\n\n/**\n * Build an ANN blocker, preferring the `hnswlib-node` fast-path when\n * `useHNSW` is `true` and the module can be loaded. Falls back to the\n * brute-force `ANNBlocker` when the module is missing (e.g. edge runtime,\n * peer dep not installed) and emits a single warning.\n */\nexport async function createANNBlocker(\n options: CreateANNBlockerOptions = {},\n): Promise<ANNBlockerBase> {\n const bruteOptions: ANNBlockerOptions = {\n ...(options.topK !== undefined ? { topK: options.topK } : {}),\n ...(options.metric !== undefined ? { metric: options.metric } : {}),\n };\n\n if (!options.useHNSW) {\n return new ANNBlocker(bruteOptions);\n }\n\n let hnsw: HNSWModule | null = options.hnswModule ?? null;\n if (!hnsw) {\n try {\n // `as string` prevents tsup / bundlers from trying to resolve this\n // optional native module at build time; it stays a runtime dynamic\n // import that we catch below if it fails.\n const mod = (await import(\"hnswlib-node\" as string)) as unknown as {\n HierarchicalNSW: HNSWModule[\"HierarchicalNSW\"];\n default?: { HierarchicalNSW: HNSWModule[\"HierarchicalNSW\"] };\n };\n const ctor =\n mod.HierarchicalNSW ?? mod.default?.HierarchicalNSW ?? null;\n if (ctor) {\n hnsw = { HierarchicalNSW: ctor };\n }\n } catch {\n hnsw = null;\n }\n }\n\n if (!hnsw) {\n const warn = options.onFallbackWarning ?? ((m: string) => console.warn(m));\n warn(\"hnswlib-node not installed; falling back to brute-force ANN\");\n return new ANNBlocker(bruteOptions);\n }\n\n return new HNSWANNBlocker({\n hnswModule: hnsw,\n ...(options.topK !== undefined ? { topK: options.topK } : {}),\n ...(options.metric !== undefined ? { metric: options.metric } : {}),\n ...(options.maxElements !== undefined\n ? { maxElements: options.maxElements }\n : {}),\n ...(options.M !== undefined ? { M: options.M } : {}),\n ...(options.efConstruction !== undefined\n ? { efConstruction: options.efConstruction }\n : {}),\n ...(options.efSearch !== undefined ? { efSearch: options.efSearch } : {}),\n });\n}\n\n// ---------------------------------------------------------------------------\n// Block builders\n// ---------------------------------------------------------------------------\n\n/** Pull an ANN-relevant text from a row. Coerces non-strings, drops null. */\nfunction getText(row: Row, col: string): string | null {\n const v = row[col];\n if (v === null || v === undefined) return null;\n const s = String(v).trim();\n return s === \"\" ? null : s;\n}\n\n/** Trivial Union-Find. */\nclass UnionFind {\n private parent: number[];\n constructor(n: number) {\n this.parent = new Array(n);\n for (let i = 0; i < n; i++) this.parent[i] = i;\n }\n find(x: number): number {\n let r = x;\n while (this.parent[r]! !== r) r = this.parent[r]!;\n // Path compression.\n let cur = x;\n while (this.parent[cur]! !== r) {\n const next = this.parent[cur]!;\n this.parent[cur] = r;\n cur = next;\n }\n return r;\n }\n union(a: number, b: number): void {\n const ra = this.find(a);\n const rb = this.find(b);\n if (ra !== rb) this.parent[ra] = rb;\n }\n}\n\n/**\n * Embed one column, query top-K neighbours, and group connected pairs\n * into micro-blocks via Union-Find.\n */\nexport async function buildANNBlocks(\n rows: readonly Row[],\n annColumn: string,\n options: BuildANNOptions = {},\n): Promise<BlockResult[]> {\n if (rows.length < 2) return [];\n\n const topK = options.topK ?? 20;\n const maxBlockSize = options.maxBlockSize ?? 1000;\n\n const embedder = getEmbedder({\n ...(options.model !== undefined ? { model: options.model } : {}),\n ...(options.apiKey !== undefined ? { apiKey: options.apiKey } : {}),\n ...(options.provider !== undefined ? { provider: options.provider } : {}),\n });\n\n // Extract texts.\n const texts: (string | null)[] = rows.map((r) => getText(r, annColumn));\n const embeddings = await embedder.embedColumn(texts);\n\n // Build index across all rows.\n const blocker = await createANNBlocker({\n topK,\n ...(options.useHNSW !== undefined ? { useHNSW: options.useHNSW } : {}),\n });\n blocker.buildIndex(embeddings);\n const pairs = blocker.query(embeddings);\n if (pairs.length === 0) return [];\n\n // Union-Find on the connected pairs.\n const uf = new UnionFind(rows.length);\n for (const [a, b] of pairs) uf.union(a, b);\n\n // Group by root.\n const groups = new Map<number, number[]>();\n for (let i = 0; i < rows.length; i++) {\n // Only include rows that participated in at least one pair (avoid singletons).\n // To detect that, we just include any row whose root has more than itself.\n const root = uf.find(i);\n let arr = groups.get(root);\n if (!arr) {\n arr = [];\n groups.set(root, arr);\n }\n arr.push(i);\n }\n\n const results: BlockResult[] = [];\n let blockNum = 0;\n for (const [, members] of groups) {\n if (members.length < 2) continue;\n if (members.length > maxBlockSize) continue; // skip oversized\n results.push({\n blockKey: `ann_${blockNum++}`,\n rows: members.map((idx) => rows[idx]!),\n strategy: \"ann\",\n depth: 0,\n });\n }\n return results;\n}\n\n/**\n * Variant that returns one BlockResult containing every row plus\n * pre-scored pairs derived from ANN cosine similarity. Useful when the\n * scorer should reuse the embedding-based scores instead of recomputing.\n */\nexport async function buildANNPairBlocks(\n rows: readonly Row[],\n annColumn: string,\n options: BuildANNOptions = {},\n): Promise<BlockResult[]> {\n if (rows.length < 2) return [];\n\n const topK = options.topK ?? 20;\n const idColumn = options.idColumn ?? \"__row_id__\";\n\n const embedder = getEmbedder({\n ...(options.model !== undefined ? { model: options.model } : {}),\n ...(options.apiKey !== undefined ? { apiKey: options.apiKey } : {}),\n ...(options.provider !== undefined ? { provider: options.provider } : {}),\n });\n\n const texts: (string | null)[] = rows.map((r) => getText(r, annColumn));\n const embeddings = await embedder.embedColumn(texts);\n\n const blocker = await createANNBlocker({\n topK,\n ...(options.useHNSW !== undefined ? { useHNSW: options.useHNSW } : {}),\n });\n blocker.buildIndex(embeddings);\n const scored = blocker.queryWithScores(embeddings);\n if (scored.length === 0) return [];\n\n // Map index positions -> __row_id__ values (fall back to index).\n const rowIdAt = (idx: number): number => {\n const v = rows[idx]?.[idColumn];\n return typeof v === \"number\" ? v : idx;\n };\n\n const preScoredPairs: ScoredPair[] = scored.map(([a, b, score]) =>\n makeScoredPair(rowIdAt(a), rowIdAt(b), score),\n );\n\n return [\n {\n blockKey: \"ann_pairs_0\",\n rows: rows.slice(),\n strategy: \"ann_pairs\",\n depth: 0,\n preScoredPairs,\n },\n ];\n}\n","/**\n * blocker.ts — Groups records into blocks for pairwise comparison.\n *\n * Edge-safe: no Node.js imports. Pure TypeScript only.\n *\n * Ports `goldenmatch/core/blocker.py`.\n */\n\nimport type {\n BlockingConfig,\n BlockingKeyConfig,\n BlockResult,\n Row,\n SortKeyField,\n} from \"./types.js\";\nimport { applyTransforms } from \"./transforms.js\";\nimport { buildANNBlocks, buildANNPairBlocks } from \"./ann-blocker.js\";\n\n// ---------------------------------------------------------------------------\n// Internal helpers\n// ---------------------------------------------------------------------------\n\n/**\n * Build a composite block key string for a single row.\n *\n * For each field in `keyConfig.fields`, extracts the value, applies\n * transforms, and concatenates with \"||\". Returns `null` if any field\n * value is null/undefined or any transform returns null.\n */\nfunction buildBlockKey(\n row: Row,\n keyConfig: BlockingKeyConfig,\n): string | null {\n const parts: string[] = [];\n for (const field of keyConfig.fields) {\n const raw = row[field];\n if (raw === null || raw === undefined) return null;\n const str = String(raw);\n if (keyConfig.transforms.length > 0) {\n const val = applyTransforms(str, keyConfig.transforms);\n if (val === null || val === undefined) return null;\n parts.push(val);\n } else {\n parts.push(str);\n }\n }\n return parts.join(\"||\");\n}\n\n/**\n * Build a sort key string for a row using SortKeyField config.\n * Returns `null` if any field value is null/undefined.\n */\nfunction buildSortKey(\n row: Row,\n sortKeyFields: readonly SortKeyField[],\n): string | null {\n const parts: string[] = [];\n for (const skf of sortKeyFields) {\n const raw = row[skf.column];\n if (raw === null || raw === undefined) return null;\n const str = String(raw);\n if (skf.transforms.length > 0) {\n const val = applyTransforms(str, skf.transforms);\n if (val === null || val === undefined) return null;\n parts.push(val);\n } else {\n parts.push(str);\n }\n }\n return parts.join(\"||\");\n}\n\n// ---------------------------------------------------------------------------\n// Static blocking\n// ---------------------------------------------------------------------------\n\n/**\n * Group rows by blocking key. Skip blocks with fewer than 2 rows.\n * Handle oversized blocks per `config.skipOversized`.\n */\nexport function buildStaticBlocks(\n rows: readonly Row[],\n config: BlockingConfig,\n): BlockResult[] {\n if (rows.length < 2) return [];\n\n const results: BlockResult[] = [];\n\n for (const keyConfig of config.keys) {\n const groups = new Map<string, Row[]>();\n\n for (const row of rows) {\n const key = buildBlockKey(row, keyConfig);\n if (key === null) continue;\n let group = groups.get(key);\n if (!group) {\n group = [];\n groups.set(key, group);\n }\n group.push(row);\n }\n\n for (const [key, group] of groups) {\n if (group.length < 2) continue;\n\n if (group.length > config.maxBlockSize) {\n if (config.skipOversized) {\n // Skip oversized blocks\n continue;\n }\n // Process anyway (caller is warned via the oversized size)\n }\n\n results.push({\n blockKey: key,\n rows: group,\n strategy: \"static\",\n depth: 0,\n });\n }\n }\n\n return results;\n}\n\n// ---------------------------------------------------------------------------\n// Multi-pass blocking\n// ---------------------------------------------------------------------------\n\n/**\n * Run multiple blocking passes using `config.passes`.\n *\n * Each pass uses a different `BlockingKeyConfig`. Blocks are deduplicated\n * by block key so each unique key appears only once.\n */\nexport function buildMultiPassBlocks(\n rows: readonly Row[],\n config: BlockingConfig,\n): BlockResult[] {\n if (rows.length < 2) return [];\n\n const passes = config.passes ?? [];\n if (passes.length === 0) return [];\n\n const allBlocks: BlockResult[] = [];\n const seenKeys = new Set<string>();\n\n for (const passConfig of passes) {\n // Build a temporary config with just this pass's key\n const tempConfig: BlockingConfig = {\n ...config,\n strategy: \"static\",\n keys: [passConfig],\n };\n\n const blocks = buildStaticBlocks(rows, tempConfig);\n\n for (const block of blocks) {\n if (!seenKeys.has(block.blockKey)) {\n seenKeys.add(block.blockKey);\n allBlocks.push({\n ...block,\n strategy: \"multi_pass\",\n });\n }\n }\n }\n\n return allBlocks;\n}\n\n// ---------------------------------------------------------------------------\n// Sorted neighborhood blocking\n// ---------------------------------------------------------------------------\n\n/**\n * Sort rows by a composite sort key, then slide a window of\n * `config.windowSize` through the sorted data.\n *\n * Each window position produces one block. Requires `config.sortKey`\n * to be configured.\n */\nexport function buildSortedNeighborhoodBlocks(\n rows: readonly Row[],\n config: BlockingConfig,\n): BlockResult[] {\n if (rows.length < 2) return [];\n\n const sortKeyFields = config.sortKey;\n if (!sortKeyFields || sortKeyFields.length === 0) {\n throw new Error(\n \"sorted_neighborhood strategy requires sortKey configuration.\",\n );\n }\n\n const windowSize = config.windowSize ?? 10;\n\n // Build (sortKey, row) pairs, filter nulls, and sort\n const keyed: Array<{ key: string; row: Row }> = [];\n for (const row of rows) {\n const key = buildSortKey(row, sortKeyFields);\n if (key !== null) {\n keyed.push({ key, row });\n }\n }\n\n keyed.sort((a, b) => {\n if (a.key < b.key) return -1;\n if (a.key > b.key) return 1;\n return 0;\n });\n\n const n = keyed.length;\n if (n < 2) return [];\n\n const results: BlockResult[] = [];\n\n if (n <= windowSize) {\n // Dataset smaller than window -- single block\n results.push({\n blockKey: \"sorted_window_0\",\n rows: keyed.map((k) => k.row),\n strategy: \"sorted_neighborhood\",\n depth: 0,\n });\n return results;\n }\n\n // Slide window through sorted data\n for (let i = 0; i <= n - windowSize; i++) {\n const windowRows = keyed.slice(i, i + windowSize).map((k) => k.row);\n results.push({\n blockKey: `sorted_window_${i}`,\n rows: windowRows,\n strategy: \"sorted_neighborhood\",\n depth: 0,\n });\n }\n\n return results;\n}\n\n// ---------------------------------------------------------------------------\n// Auto-split oversized block\n// ---------------------------------------------------------------------------\n\n/**\n * Split an oversized block by the column with the most unique values\n * that produces useful groups (>= 2 rows each).\n *\n * This is a zero-config fallback when no `subBlockKeys` are configured\n * for adaptive blocking.\n */\nexport function autoSplitBlock(\n blockRows: readonly Row[],\n maxBlockSize: number,\n parentKey: string,\n): BlockResult[] {\n if (blockRows.length < 2) return [];\n\n // Find non-internal columns (not prefixed with __)\n const sampleRow = blockRows[0];\n if (!sampleRow) return [];\n\n const candidates = Object.keys(sampleRow).filter(\n (c) => !c.startsWith(\"__\"),\n );\n\n if (candidates.length === 0) {\n // No non-internal columns -- return as-is\n return [\n {\n blockKey: parentKey,\n rows: blockRows,\n strategy: \"adaptive\",\n depth: 1,\n parentKey,\n },\n ];\n }\n\n // Pick column whose cardinality best splits blocks.\n // Score = number of groups with >= 2 rows (useful groups).\n let bestCol = candidates[0]!;\n let bestUsefulGroups = 0;\n let bestNunique = 0;\n\n for (const col of candidates) {\n const groups = new Map<string, number>();\n for (const row of blockRows) {\n const val = row[col];\n const key = val === null || val === undefined ? \"__null__\" : String(val);\n groups.set(key, (groups.get(key) ?? 0) + 1);\n }\n\n const nunique = groups.size;\n let usefulGroups = 0;\n for (const count of groups.values()) {\n if (count >= 2) usefulGroups++;\n }\n\n const avgGroup = nunique > 0 ? blockRows.length / nunique : blockRows.length;\n\n if (\n usefulGroups > bestUsefulGroups ||\n (usefulGroups === bestUsefulGroups &&\n avgGroup <= maxBlockSize &&\n nunique > bestNunique)\n ) {\n bestUsefulGroups = usefulGroups;\n bestNunique = nunique;\n bestCol = col;\n }\n }\n\n // Split by the chosen column\n const splitGroups = new Map<string, Row[]>();\n for (const row of blockRows) {\n const val = row[bestCol];\n const key = val === null || val === undefined ? \"__null__\" : String(val);\n let group = splitGroups.get(key);\n if (!group) {\n group = [];\n splitGroups.set(key, group);\n }\n group.push(row);\n }\n\n const results: BlockResult[] = [];\n for (const [key, group] of splitGroups) {\n if (key === \"__null__\") continue; // skip null groups\n if (group.length < 2) continue;\n results.push({\n blockKey: `${parentKey}||${key}`,\n rows: group,\n strategy: \"adaptive\",\n depth: 1,\n parentKey,\n });\n }\n\n // If no useful splits, return the block as-is\n if (results.length === 0) {\n return [\n {\n blockKey: parentKey,\n rows: blockRows,\n strategy: \"adaptive\",\n depth: 1,\n parentKey,\n },\n ];\n }\n\n return results;\n}\n\n// ---------------------------------------------------------------------------\n// Adaptive blocking (static + auto-split for oversized)\n// ---------------------------------------------------------------------------\n\n/**\n * Build static blocks first, then auto-split any oversized blocks\n * using the highest-cardinality column.\n *\n * If `config.subBlockKeys` is configured, uses recursive sub-blocking\n * instead of auto-split.\n */\nexport function buildAdaptiveBlocks(\n rows: readonly Row[],\n config: BlockingConfig,\n): BlockResult[] {\n if (rows.length < 2) return [];\n\n const primaryBlocks = buildStaticBlocks(rows, config);\n const subBlockKeys = config.subBlockKeys ?? [];\n\n const results: BlockResult[] = [];\n\n for (const block of primaryBlocks) {\n const size = block.rows.length;\n\n if (size > config.maxBlockSize && subBlockKeys.length > 0) {\n // Recursive sub-blocking with configured keys\n const subResults = subBlock(\n block.rows,\n subBlockKeys,\n config.maxBlockSize,\n 1,\n block.blockKey,\n );\n results.push(...subResults);\n } else if (size > config.maxBlockSize && !config.skipOversized) {\n // Auto-split by highest-cardinality column\n const autoResults = autoSplitBlock(\n block.rows,\n config.maxBlockSize,\n block.blockKey,\n );\n results.push(...autoResults);\n } else {\n results.push(block);\n }\n }\n\n return results;\n}\n\n/**\n * Recursively sub-block an oversized block using configured sub-block keys.\n *\n * Max recursion depth is 3. If all keys are exhausted or depth exceeds 3,\n * the block is returned as-is.\n */\nfunction subBlock(\n blockRows: readonly Row[],\n subBlockKeys: readonly BlockingKeyConfig[],\n maxBlockSize: number,\n depth: number,\n parentKey: string,\n): BlockResult[] {\n if (depth > 3 || subBlockKeys.length === 0) {\n // Max depth or no more keys -- return as-is\n return [\n {\n blockKey: parentKey,\n rows: blockRows,\n strategy: \"adaptive\",\n depth,\n parentKey,\n },\n ];\n }\n\n const currentKey = subBlockKeys[0]!;\n const remainingKeys = subBlockKeys.slice(1);\n\n const groups = new Map<string, Row[]>();\n for (const row of blockRows) {\n const key = buildBlockKey(row, currentKey);\n if (key === null) continue;\n let group = groups.get(key);\n if (!group) {\n group = [];\n groups.set(key, group);\n }\n group.push(row);\n }\n\n const results: BlockResult[] = [];\n for (const [key, group] of groups) {\n if (group.length < 2) continue;\n\n if (group.length > maxBlockSize && remainingKeys.length > 0 && depth < 3) {\n // Recurse with next sub-block key\n const subResults = subBlock(\n group,\n remainingKeys,\n maxBlockSize,\n depth + 1,\n parentKey,\n );\n results.push(...subResults);\n } else {\n results.push({\n blockKey: key,\n rows: group,\n strategy: \"adaptive\",\n depth,\n parentKey,\n });\n }\n }\n\n return results;\n}\n\n// ---------------------------------------------------------------------------\n// Best blocking key selection\n// ---------------------------------------------------------------------------\n\n/**\n * Evaluate candidate blocking keys and select the one with the smallest\n * max group size while maintaining >= 50% coverage.\n *\n * Coverage = fraction of rows that produce a non-null block key.\n * If only one key is provided, returns it directly.\n */\nexport function selectBestBlockingKey(\n rows: readonly Row[],\n keys: readonly BlockingKeyConfig[],\n maxBlockSize: number = 5000,\n): BlockingKeyConfig {\n if (keys.length === 0) {\n throw new Error(\"selectBestBlockingKey requires at least one key.\");\n }\n if (keys.length === 1) return keys[0]!;\n\n const total = rows.length;\n if (total === 0) return keys[0]!;\n\n let bestKey: BlockingKeyConfig = keys[0]!;\n let bestMaxSize = Infinity;\n\n for (const keyConfig of keys) {\n const groupSizes = new Map<string, number>();\n let nonNull = 0;\n\n for (const row of rows) {\n const key = buildBlockKey(row, keyConfig);\n if (key !== null) {\n nonNull++;\n groupSizes.set(key, (groupSizes.get(key) ?? 0) + 1);\n }\n }\n\n const coverage = nonNull / total;\n if (coverage < 0.5) continue; // Skip low-coverage keys\n\n // Find max group size\n let maxSize = 0;\n for (const size of groupSizes.values()) {\n if (size > maxSize) maxSize = size;\n }\n\n if (\n maxSize < bestMaxSize ||\n (maxSize === bestMaxSize && groupSizes.size > 0)\n ) {\n bestMaxSize = maxSize;\n bestKey = keyConfig;\n }\n }\n\n return bestKey;\n}\n\n// ---------------------------------------------------------------------------\n// Main entry point\n// ---------------------------------------------------------------------------\n\n/**\n * Build blocks from rows based on blocking configuration.\n *\n * Routes by `config.strategy`:\n * - `\"static\"` -- hash-based grouping on blocking keys\n * - `\"multi_pass\"` -- multiple passes with deduplication\n * - `\"sorted_neighborhood\"` -- sliding window over sorted data\n * - `\"adaptive\"` -- static + auto-split for oversized blocks\n * - `\"ann\"`, `\"ann_pairs\"`, `\"canopy\"`, `\"learned\"` -- not yet implemented\n *\n * If `config.autoSelect` is true and multiple keys are configured,\n * automatically selects the best key before blocking.\n */\nexport function buildBlocks(\n rows: readonly Row[],\n config: BlockingConfig,\n): BlockResult[] {\n if (rows.length < 2) return [];\n\n // Auto-select best key if enabled\n let effectiveConfig = config;\n if (config.autoSelect && config.keys.length > 1) {\n const bestKey = selectBestBlockingKey(\n rows,\n config.keys,\n config.maxBlockSize,\n );\n effectiveConfig = {\n ...config,\n keys: [bestKey],\n autoSelect: false,\n };\n }\n\n switch (effectiveConfig.strategy) {\n case \"static\":\n return buildStaticBlocks(rows, effectiveConfig);\n\n case \"multi_pass\":\n return buildMultiPassBlocks(rows, effectiveConfig);\n\n case \"sorted_neighborhood\":\n return buildSortedNeighborhoodBlocks(rows, effectiveConfig);\n\n case \"adaptive\":\n return buildAdaptiveBlocks(rows, effectiveConfig);\n\n case \"ann\":\n case \"ann_pairs\":\n throw new Error(\n `ANN blocking strategy \"${effectiveConfig.strategy}\" is not yet implemented in the TypeScript port. ` +\n \"It requires FAISS or a similar approximate nearest neighbor library.\",\n );\n\n case \"canopy\":\n throw new Error(\n 'Canopy blocking strategy is not yet implemented in the TypeScript port. ' +\n \"It requires TF-IDF vectorization.\",\n );\n\n case \"learned\":\n throw new Error(\n 'Learned blocking strategy is not yet implemented in the TypeScript port. ' +\n \"It requires predicate learning from training pairs.\",\n );\n\n default: {\n // Exhaustive check -- if a new strategy is added to the union type\n // but not handled here, this will cause a compile-time error.\n const _exhaustive: never = effectiveConfig.strategy;\n throw new Error(`Unknown blocking strategy: ${String(_exhaustive)}`);\n }\n }\n}\n\n// ---------------------------------------------------------------------------\n// Async entry point — required for ANN strategies that fetch embeddings.\n// ---------------------------------------------------------------------------\n\n/**\n * Async variant of `buildBlocks`. Required for `\"ann\"` and `\"ann_pairs\"`\n * strategies which need to fetch embeddings via HTTP. All other strategies\n * delegate to the synchronous `buildBlocks` path.\n */\nexport async function buildBlocksAsync(\n rows: readonly Row[],\n config: BlockingConfig,\n): Promise<BlockResult[]> {\n if (rows.length < 2) return [];\n\n if (config.strategy === \"ann\") {\n if (!config.annColumn) {\n throw new Error('\"ann\" strategy requires `annColumn` in BlockingConfig.');\n }\n return await buildANNBlocks(rows, config.annColumn, {\n ...(config.annTopK !== undefined ? { topK: config.annTopK } : {}),\n ...(config.annModel !== undefined ? { model: config.annModel } : {}),\n ...(config.maxBlockSize !== undefined ? { maxBlockSize: config.maxBlockSize } : {}),\n });\n }\n\n if (config.strategy === \"ann_pairs\") {\n if (!config.annColumn) {\n throw new Error('\"ann_pairs\" strategy requires `annColumn` in BlockingConfig.');\n }\n return await buildANNPairBlocks(rows, config.annColumn, {\n ...(config.annTopK !== undefined ? { topK: config.annTopK } : {}),\n ...(config.annModel !== undefined ? { model: config.annModel } : {}),\n });\n }\n\n return buildBlocks(rows, config);\n}\n","/**\n * cluster.ts — Union-Find clustering with MST splitting.\n * Edge-safe: no Node.js imports, pure TypeScript only.\n */\n\nimport type { ClusterInfo, PairKey } from \"./types.js\";\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\n/** Canonicalize a pair key: always min:max. Sole producer of branded PairKey. */\nexport function pairKey(a: number, b: number): PairKey {\n const lo = a < b ? a : b;\n const hi = a < b ? b : a;\n return `${lo}:${hi}` as PairKey;\n}\n\n/** Parse a pair key back into [idA, idB]. */\nexport function parsePairKey(key: PairKey): readonly [number, number] {\n const idx = key.indexOf(\":\");\n return [Number(key.slice(0, idx)), Number(key.slice(idx + 1))];\n}\n\n// ---------------------------------------------------------------------------\n// UnionFind\n// ---------------------------------------------------------------------------\n\nexport class UnionFind {\n private parent = new Map<number, number>();\n private rank = new Map<number, number>();\n\n /** Add element as its own root. */\n add(x: number): void {\n if (!this.parent.has(x)) {\n this.parent.set(x, x);\n this.rank.set(x, 0);\n }\n }\n\n /** Batch add multiple elements. */\n addMany(ids: readonly number[]): void {\n for (const x of ids) {\n if (!this.parent.has(x)) {\n this.parent.set(x, x);\n this.rank.set(x, 0);\n }\n }\n }\n\n /** Find root with iterative path compression. */\n find(x: number): number {\n let root = x;\n while (this.parent.get(root) !== root) {\n root = this.parent.get(root)!;\n }\n // Path compression\n let current = x;\n while (this.parent.get(current) !== root) {\n const next = this.parent.get(current)!;\n this.parent.set(current, root);\n current = next;\n }\n return root;\n }\n\n /** Union by rank. */\n union(a: number, b: number): void {\n let ra = this.find(a);\n let rb = this.find(b);\n if (ra === rb) return;\n const rankA = this.rank.get(ra)!;\n const rankB = this.rank.get(rb)!;\n if (rankA < rankB) {\n [ra, rb] = [rb, ra];\n }\n this.parent.set(rb, ra);\n if (rankA === rankB) {\n this.rank.set(ra, rankA + 1);\n }\n }\n\n /** Return all clusters as arrays of sets. */\n getClusters(): Set<number>[] {\n const groups = new Map<number, Set<number>>();\n for (const x of this.parent.keys()) {\n const root = this.find(x);\n let group = groups.get(root);\n if (!group) {\n group = new Set<number>();\n groups.set(root, group);\n }\n group.add(x);\n }\n return Array.from(groups.values());\n }\n}\n\n// ---------------------------------------------------------------------------\n// MST (max-weight spanning tree via Kruskal)\n// ---------------------------------------------------------------------------\n\n/**\n * Build a max-weight spanning tree using Kruskal's algorithm.\n * Returns edges as [idA, idB, score] sorted by descending weight.\n */\nexport function buildMst(\n members: readonly number[],\n pairScores: ReadonlyMap<PairKey, number>,\n): [number, number, number][] {\n // Collect and sort edges by score descending\n const edges: [number, number, number][] = [];\n for (const [key, score] of pairScores) {\n const [a, b] = parsePairKey(key);\n edges.push([a, b, score]);\n }\n edges.sort((x, y) => y[2] - x[2]);\n\n const uf = new UnionFind();\n uf.addMany(members);\n\n const mst: [number, number, number][] = [];\n const target = members.length - 1;\n for (const [a, b, s] of edges) {\n if (uf.find(a) !== uf.find(b)) {\n uf.union(a, b);\n mst.push([a, b, s]);\n if (mst.length === target) break;\n }\n }\n return mst;\n}\n\n// ---------------------------------------------------------------------------\n// Cluster confidence\n// ---------------------------------------------------------------------------\n\nexport interface ClusterConfidence {\n readonly minEdge: number | null;\n readonly avgEdge: number | null;\n readonly connectivity: number;\n readonly bottleneckPair: readonly [number, number] | null;\n readonly confidence: number;\n}\n\n/**\n * Compute confidence metrics for a cluster.\n * confidence = 0.4 * minEdge + 0.3 * avgEdge + 0.3 * connectivity\n */\nexport function computeClusterConfidence(\n pairScores: ReadonlyMap<PairKey, number>,\n size: number,\n): ClusterConfidence {\n if (size <= 1 || pairScores.size === 0) {\n return {\n minEdge: null,\n avgEdge: null,\n connectivity: size <= 1 ? 1.0 : 0.0,\n bottleneckPair: null,\n confidence: size <= 1 ? 1.0 : 0.0,\n };\n }\n\n let minEdge = Infinity;\n let sum = 0;\n let bottleneckKey: PairKey | null = null;\n\n for (const [key, score] of pairScores) {\n sum += score;\n if (score < minEdge) {\n minEdge = score;\n bottleneckKey = key;\n }\n }\n\n const avgEdge = sum / pairScores.size;\n const maxPossibleEdges = (size * (size - 1)) / 2;\n const connectivity =\n maxPossibleEdges > 0 ? pairScores.size / maxPossibleEdges : 0.0;\n\n const bottleneckPair: readonly [number, number] | null = bottleneckKey\n ? parsePairKey(bottleneckKey)\n : null;\n\n const confidence = 0.4 * minEdge + 0.3 * avgEdge + 0.3 * connectivity;\n\n return { minEdge, avgEdge, connectivity, bottleneckPair, confidence };\n}\n\n// ---------------------------------------------------------------------------\n// Split oversized cluster\n// ---------------------------------------------------------------------------\n\n/** Internal mutable cluster info used during building. */\ninterface MutableClusterInfo {\n members: number[];\n size: number;\n oversized: boolean;\n pairScores: Map<PairKey, number>;\n confidence: number;\n bottleneckPair: readonly [number, number] | null;\n clusterQuality: \"strong\" | \"weak\" | \"split\";\n _wasSplit?: boolean;\n}\n\n/**\n * Split a cluster by removing the weakest MST edge.\n * Returns sub-cluster infos.\n */\nexport function splitOversizedCluster(\n members: readonly number[],\n pairScores: ReadonlyMap<PairKey, number>,\n): MutableClusterInfo[] {\n if (members.length <= 1 || pairScores.size === 0) {\n return [\n {\n members: [...members].sort((a, b) => a - b),\n size: members.length,\n oversized: false,\n pairScores: new Map(pairScores),\n confidence: 1.0,\n bottleneckPair: null,\n clusterQuality: \"strong\",\n },\n ];\n }\n\n const mst = buildMst(members, pairScores);\n if (mst.length === 0) {\n return [\n {\n members: [...members].sort((a, b) => a - b),\n size: members.length,\n oversized: false,\n pairScores: new Map(pairScores),\n confidence: 1.0,\n bottleneckPair: null,\n clusterQuality: \"strong\",\n },\n ];\n }\n\n // Find weakest edge\n let weakestIdx = 0;\n let weakestScore = mst[0]![2];\n for (let i = 1; i < mst.length; i++) {\n if (mst[i]![2] < weakestScore) {\n weakestScore = mst[i]![2];\n weakestIdx = i;\n }\n }\n\n // Rebuild without weakest edge\n const uf = new UnionFind();\n uf.addMany(members as number[]);\n for (let i = 0; i < mst.length; i++) {\n if (i !== weakestIdx) {\n uf.union(mst[i]![0], mst[i]![1]);\n }\n }\n\n const result: MutableClusterInfo[] = [];\n for (const subMembers of uf.getClusters()) {\n const subList = [...subMembers].sort((a, b) => a - b);\n const subPairs = new Map<PairKey, number>();\n for (const [key, score] of pairScores) {\n const [a, b] = parsePairKey(key);\n if (subMembers.has(a) && subMembers.has(b)) {\n subPairs.set(key, score);\n }\n }\n const conf = computeClusterConfidence(subPairs, subList.length);\n result.push({\n members: subList,\n size: subList.length,\n oversized: false,\n pairScores: subPairs,\n confidence: conf.confidence,\n bottleneckPair: conf.bottleneckPair,\n clusterQuality: \"strong\",\n });\n }\n return result;\n}\n\n// ---------------------------------------------------------------------------\n// buildClusters options\n// ---------------------------------------------------------------------------\n\nexport interface BuildClustersOptions {\n readonly maxClusterSize?: number;\n readonly weakClusterThreshold?: number;\n readonly autoSplit?: boolean;\n}\n\n// ---------------------------------------------------------------------------\n// buildClusters\n// ---------------------------------------------------------------------------\n\n/**\n * Build clusters from scored pairs using Union-Find.\n *\n * Auto-splits oversized clusters via MST (iterative, not recursive).\n * Assigns cluster_quality: \"strong\", \"weak\" (avg-min > weakThreshold), or \"split\".\n * Downgrades confidence by 0.7 for weak clusters.\n */\nexport function buildClusters(\n pairs: readonly (readonly [number, number, number])[],\n allIds: readonly number[],\n options?: BuildClustersOptions,\n): Map<number, ClusterInfo> {\n const maxClusterSize = options?.maxClusterSize ?? 100;\n const weakClusterThreshold = options?.weakClusterThreshold ?? 0.3;\n const autoSplit = options?.autoSplit ?? true;\n\n // Build Union-Find from pairs\n const uf = new UnionFind();\n uf.addMany(allIds);\n for (const [idA, idB] of pairs) {\n uf.union(idA, idB);\n }\n\n const clusters = uf.getClusters();\n\n // Sort clusters by minimum member for deterministic IDs.\n // Use for-loop min — Math.min(...set) crashes on Sets with >65K elements.\n const minOf = (s: Set<number>): number => {\n let m = Infinity;\n for (const v of s) if (v < m) m = v;\n return m;\n };\n clusters.sort((a, b) => minOf(a) - minOf(b));\n\n // Map members to cluster IDs\n const memberToCid = new Map<number, number>();\n for (let i = 0; i < clusters.length; i++) {\n const cid = i + 1;\n for (const m of clusters[i]!) {\n memberToCid.set(m, cid);\n }\n }\n\n // Build mutable result\n const result = new Map<number, MutableClusterInfo>();\n for (let i = 0; i < clusters.length; i++) {\n const cid = i + 1;\n const memberArr = [...clusters[i]!].sort((a, b) => a - b);\n result.set(cid, {\n members: memberArr,\n size: memberArr.length,\n oversized: memberArr.length > maxClusterSize,\n pairScores: new Map(),\n confidence: 0,\n bottleneckPair: null,\n clusterQuality: \"strong\",\n });\n }\n\n // Assign pair scores to clusters (canonicalized keys)\n for (const [idA, idB, score] of pairs) {\n const cid = memberToCid.get(idA)!;\n const info = result.get(cid)!;\n info.pairScores.set(pairKey(idA, idB), score);\n }\n\n // Compute initial confidence\n for (const [, cinfo] of result) {\n const conf = computeClusterConfidence(cinfo.pairScores, cinfo.size);\n cinfo.confidence = conf.confidence;\n cinfo.bottleneckPair = conf.bottleneckPair;\n }\n\n // Auto-split oversized clusters (iterative)\n if (autoSplit) {\n const toSplit: number[] = [];\n for (const [cid, c] of result) {\n if (c.oversized) toSplit.push(cid);\n }\n\n while (toSplit.length > 0) {\n const cid = toSplit.pop()!;\n const cinfo = result.get(cid)!;\n result.delete(cid);\n\n const subClusters = splitOversizedCluster(\n cinfo.members,\n cinfo.pairScores,\n );\n let nextCid = 0;\n for (const [k] of result) {\n if (k > nextCid) nextCid = k;\n }\n nextCid += 1;\n\n for (const sc of subClusters) {\n sc.oversized = sc.size > maxClusterSize;\n sc._wasSplit = true;\n result.set(nextCid, sc);\n if (sc.oversized) {\n toSplit.push(nextCid);\n }\n nextCid++;\n }\n }\n }\n\n // Assign cluster_quality and apply confidence downgrade\n for (const [, cinfo] of result) {\n if (cinfo._wasSplit) {\n cinfo.clusterQuality = \"split\";\n } else if (cinfo.size > 1 && cinfo.pairScores.size > 0) {\n const scores = [...cinfo.pairScores.values()];\n let minE = Infinity;\n let sumE = 0;\n for (const s of scores) {\n if (s < minE) minE = s;\n sumE += s;\n }\n const avgE = sumE / scores.length;\n if (avgE - minE > weakClusterThreshold) {\n cinfo.clusterQuality = \"weak\";\n cinfo.confidence *= 0.7;\n } else {\n cinfo.clusterQuality = \"strong\";\n }\n } else {\n cinfo.clusterQuality = \"strong\";\n }\n delete cinfo._wasSplit;\n }\n\n // Freeze into ClusterInfo\n const frozen = new Map<number, ClusterInfo>();\n for (const [cid, c] of result) {\n frozen.set(cid, {\n members: c.members,\n size: c.size,\n oversized: c.oversized,\n pairScores: c.pairScores,\n confidence: c.confidence,\n bottleneckPair: c.bottleneckPair,\n clusterQuality: c.clusterQuality,\n });\n }\n return frozen;\n}\n\n// ---------------------------------------------------------------------------\n// addToCluster\n// ---------------------------------------------------------------------------\n\n/**\n * Add a new record to existing clusters based on matches.\n *\n * - No matches: new singleton cluster\n * - Single cluster match: join that cluster\n * - Multiple cluster match: merge all matched clusters\n *\n * Flags oversized but does NOT auto-split. Caller should call\n * splitOversizedCluster() if desired.\n */\nexport function addToCluster(\n recordId: number,\n matches: readonly (readonly [number, number])[],\n clusters: Map<number, ClusterInfo>,\n maxClusterSize = 100,\n): Map<number, ClusterInfo> {\n const makeSingleton = (): ClusterInfo => ({\n members: [recordId],\n size: 1,\n oversized: false,\n pairScores: new Map(),\n confidence: 1.0,\n bottleneckPair: null,\n clusterQuality: \"strong\",\n });\n\n if (matches.length === 0) {\n const nextCid = _nextCid(clusters);\n clusters.set(nextCid, makeSingleton());\n return clusters;\n }\n\n // Map members to cluster IDs\n const memberToCid = new Map<number, number>();\n for (const [cid, cinfo] of clusters) {\n for (const m of cinfo.members) {\n memberToCid.set(m, cid);\n }\n }\n\n const matchedCids = new Set<number>();\n for (const [matchedId] of matches) {\n const cid = memberToCid.get(matchedId);\n if (cid !== undefined) matchedCids.add(cid);\n }\n\n if (matchedCids.size === 0) {\n const nextCid = _nextCid(clusters);\n clusters.set(nextCid, makeSingleton());\n return clusters;\n }\n\n if (matchedCids.size === 1) {\n const cid = matchedCids.values().next().value!;\n const old = clusters.get(cid)!;\n const newPairs = new Map(old.pairScores);\n\n for (const [matchedId, score] of matches) {\n if (memberToCid.get(matchedId) === cid) {\n newPairs.set(pairKey(recordId, matchedId), score);\n }\n }\n\n const newMembers = [...old.members, recordId].sort((a, b) => a - b);\n const newSize = newMembers.length;\n const conf = computeClusterConfidence(newPairs, newSize);\n\n clusters.set(cid, {\n members: newMembers,\n size: newSize,\n oversized: newSize > maxClusterSize,\n pairScores: newPairs,\n confidence: conf.confidence,\n bottleneckPair: conf.bottleneckPair,\n clusterQuality: old.clusterQuality,\n });\n return clusters;\n }\n\n // Multiple clusters: merge all\n const mergedMembers: number[] = [recordId];\n const mergedPairs = new Map<PairKey, number>();\n\n for (const cid of matchedCids) {\n const cinfo = clusters.get(cid)!;\n mergedMembers.push(...cinfo.members);\n for (const [k, v] of cinfo.pairScores) {\n mergedPairs.set(k, v);\n }\n clusters.delete(cid);\n }\n\n for (const [matchedId, score] of matches) {\n mergedPairs.set(pairKey(recordId, matchedId), score);\n }\n\n const sortedMembers = mergedMembers.sort((a, b) => a - b);\n const size = sortedMembers.length;\n const conf = computeClusterConfidence(mergedPairs, size);\n const nextCid = _nextCid(clusters);\n\n clusters.set(nextCid, {\n members: sortedMembers,\n size,\n oversized: size > maxClusterSize,\n pairScores: mergedPairs,\n confidence: conf.confidence,\n bottleneckPair: conf.bottleneckPair,\n clusterQuality: \"strong\",\n });\n\n return clusters;\n}\n\n// ---------------------------------------------------------------------------\n// unmergeRecord\n// ---------------------------------------------------------------------------\n\n/**\n * Remove a record from its cluster and re-cluster remaining members.\n * The removed record becomes a singleton.\n */\nexport function unmergeRecord(\n recordId: number,\n clusters: Map<number, ClusterInfo>,\n threshold = 0.0,\n): Map<number, ClusterInfo> {\n // Find which cluster contains this record\n let sourceCid: number | null = null;\n for (const [cid, cinfo] of clusters) {\n if (cinfo.members.includes(recordId)) {\n sourceCid = cid;\n break;\n }\n }\n\n if (sourceCid === null) return clusters; // Not found\n const cinfo = clusters.get(sourceCid)!;\n if (cinfo.size <= 1) return clusters; // Already singleton\n\n // Extract pairs excluding the removed record, applying threshold\n const remainingMembers = cinfo.members.filter((m) => m !== recordId);\n const remainingPairs: [number, number, number][] = [];\n for (const [key, score] of cinfo.pairScores) {\n const [a, b] = parsePairKey(key);\n if (a !== recordId && b !== recordId && score >= threshold) {\n remainingPairs.push([a, b, score]);\n }\n }\n\n // Re-cluster remaining members\n const subClusters = buildClusters(remainingPairs, remainingMembers);\n\n // Remove the original cluster\n clusters.delete(sourceCid);\n\n // Assign new cluster IDs\n let nextCid = _nextCid(clusters);\n\n // Add the removed record as a singleton\n clusters.set(nextCid, {\n members: [recordId],\n size: 1,\n oversized: false,\n pairScores: new Map(),\n confidence: 1.0,\n bottleneckPair: null,\n clusterQuality: \"strong\",\n });\n nextCid++;\n\n // Add re-clustered groups\n for (const [, subInfo] of subClusters) {\n clusters.set(nextCid, subInfo);\n nextCid++;\n }\n\n return clusters;\n}\n\n// ---------------------------------------------------------------------------\n// unmergeCluster\n// ---------------------------------------------------------------------------\n\n/**\n * Shatter a cluster into individual singletons.\n * All members become their own cluster. Pair scores are discarded.\n */\nexport function unmergeCluster(\n clusterId: number,\n clusters: Map<number, ClusterInfo>,\n): Map<number, ClusterInfo> {\n const cinfo = clusters.get(clusterId);\n if (!cinfo) return clusters;\n\n const members = cinfo.members;\n clusters.delete(clusterId);\n\n let nextCid = _nextCid(clusters);\n for (const memberId of members) {\n clusters.set(nextCid, {\n members: [memberId],\n size: 1,\n oversized: false,\n pairScores: new Map(),\n confidence: 1.0,\n bottleneckPair: null,\n clusterQuality: \"strong\",\n });\n nextCid++;\n }\n\n return clusters;\n}\n\n// ---------------------------------------------------------------------------\n// getClusterPairScores\n// ---------------------------------------------------------------------------\n\n/**\n * Get pair scores for a specific set of cluster members from all pairs.\n * Call on-demand, not in hot path.\n */\nexport function getClusterPairScores(\n members: readonly number[],\n allPairs: readonly (readonly [number, number, number])[],\n): Map<PairKey, number> {\n const memberSet = new Set(members);\n const result = new Map<PairKey, number>();\n for (const [a, b, s] of allPairs) {\n if (memberSet.has(a) && memberSet.has(b)) {\n result.set(pairKey(a, b), s);\n }\n }\n return result;\n}\n\n// ---------------------------------------------------------------------------\n// Internal helpers\n// ---------------------------------------------------------------------------\n\nfunction _nextCid(clusters: ReadonlyMap<number, unknown>): number {\n let max = 0;\n for (const k of clusters.keys()) {\n if (k > max) max = k;\n }\n return max + 1;\n}\n","/**\n * scorer.ts — Fuzzy scoring module for GoldenMatch.\n * Edge-safe: no Node.js imports, pure TypeScript only.\n *\n * Ports goldenmatch/core/scorer.py. The Python version uses `rapidfuzz`\n * for vectorized NxN scoring. Here we implement all algorithms in pure TS.\n */\n\nimport type {\n Row,\n MatchkeyField,\n MatchkeyConfig,\n PairKey,\n ScoredPair,\n BlockResult,\n} from \"./types.js\";\nimport { makeScoredPair } from \"./types.js\";\nimport { pairKey } from \"./cluster.js\";\nimport { applyTransforms, soundex } from \"./transforms.js\";\n\n// ---------------------------------------------------------------------------\n// Helper: coerce unknown to string | null\n// ---------------------------------------------------------------------------\n\n/** Convert unknown value to string or null. */\nexport function asString(v: unknown): string | null {\n if (v === null || v === undefined) return null;\n if (typeof v === \"string\") return v;\n return String(v);\n}\n\n// ---------------------------------------------------------------------------\n// Scoring algorithms — pure TS\n// ---------------------------------------------------------------------------\n\n/**\n * Jaro similarity between two strings.\n *\n * matchWindow = floor(max(lenA, lenB) / 2) - 1\n * Count matches (chars within window) and transpositions.\n * jaro = (m/lenA + m/lenB + (m - t/2) / m) / 3\n */\nexport function jaro(a: string, b: string): number {\n if (a === b) return 1.0;\n const lenA = a.length;\n const lenB = b.length;\n if (lenA === 0 || lenB === 0) return 0.0;\n\n const matchWindow = Math.max(Math.floor(Math.max(lenA, lenB) / 2) - 1, 0);\n\n const aMatched = new Uint8Array(lenA); // 0 = unmatched\n const bMatched = new Uint8Array(lenB);\n let matches = 0;\n\n // Find matching characters\n for (let i = 0; i < lenA; i++) {\n const lo = Math.max(0, i - matchWindow);\n const hi = Math.min(lenB - 1, i + matchWindow);\n for (let j = lo; j <= hi; j++) {\n if (bMatched[j] !== 0 || a[i] !== b[j]) continue;\n aMatched[i] = 1;\n bMatched[j] = 1;\n matches++;\n break;\n }\n }\n\n if (matches === 0) return 0.0;\n\n // Count transpositions\n let transpositions = 0;\n let k = 0;\n for (let i = 0; i < lenA; i++) {\n if (aMatched[i] === 0) continue;\n while (bMatched[k] === 0) k++;\n if (a[i] !== b[k]) transpositions++;\n k++;\n }\n\n return (\n (matches / lenA + matches / lenB + (matches - transpositions / 2) / matches) / 3\n );\n}\n\n/**\n * Jaro-Winkler similarity.\n * Adds a bonus for a common prefix of up to 4 characters, scaling factor 0.1.\n */\nexport function jaroWinkler(a: string, b: string): number {\n const jaroSim = jaro(a, b);\n if (jaroSim === 0.0) return 0.0;\n\n // Common prefix up to 4 chars\n const maxPrefix = Math.min(4, Math.min(a.length, b.length));\n let prefix = 0;\n for (let i = 0; i < maxPrefix; i++) {\n if (a[i] === b[i]) prefix++;\n else break;\n }\n\n return jaroSim + prefix * 0.1 * (1 - jaroSim);\n}\n\n/**\n * Levenshtein edit distance (classic DP, 2-row optimization).\n */\nexport function levenshteinDistance(a: string, b: string): number {\n const lenA = a.length;\n const lenB = b.length;\n if (lenA === 0) return lenB;\n if (lenB === 0) return lenA;\n\n // Two-row DP\n let prev = new Uint32Array(lenB + 1);\n let curr = new Uint32Array(lenB + 1);\n\n for (let j = 0; j <= lenB; j++) prev[j] = j;\n\n for (let i = 1; i <= lenA; i++) {\n curr[0] = i;\n for (let j = 1; j <= lenB; j++) {\n const cost = a[i - 1] === b[j - 1] ? 0 : 1;\n curr[j] = Math.min(\n prev[j]! + 1, // deletion\n curr[j - 1]! + 1, // insertion\n prev[j - 1]! + cost, // substitution\n );\n }\n // Swap rows\n [prev, curr] = [curr, prev];\n }\n\n return prev[lenB]!;\n}\n\n/**\n * Normalized Levenshtein similarity: 1 - distance / max(lenA, lenB).\n */\nexport function levenshteinSimilarity(a: string, b: string): number {\n if (a === b) return 1.0;\n const maxLen = Math.max(a.length, b.length);\n if (maxLen === 0) return 1.0;\n return 1 - levenshteinDistance(a, b) / maxLen;\n}\n\n/**\n * Indel (insertion+deletion) edit distance.\n *\n * Like Levenshtein but without substitutions — a substitution costs 2\n * (one delete + one insert) instead of 1. This matches the distance\n * metric used by rapidfuzz's Indel ratio, which underlies\n * `rapidfuzz.fuzz.token_sort_ratio` in Python.\n */\nexport function indelDistance(a: string, b: string): number {\n if (a === b) return 0;\n if (a.length === 0) return b.length;\n if (b.length === 0) return a.length;\n const m = a.length;\n const n = b.length;\n let prev = new Uint32Array(n + 1);\n let curr = new Uint32Array(n + 1);\n for (let j = 0; j <= n; j++) prev[j] = j;\n for (let i = 1; i <= m; i++) {\n curr[0] = i;\n for (let j = 1; j <= n; j++) {\n if (a.charCodeAt(i - 1) === b.charCodeAt(j - 1)) {\n curr[j] = prev[j - 1]!;\n } else {\n // Only insert or delete allowed — cost 1 each. No substitution.\n curr[j] = Math.min(prev[j]! + 1, curr[j - 1]! + 1);\n }\n }\n [prev, curr] = [curr, prev];\n }\n return prev[n]!;\n}\n\n/**\n * Indel normalized similarity: `1 - d_indel / (len_a + len_b)`.\n * Matches rapidfuzz's `Indel.normalized_similarity`.\n */\nexport function indelSimilarity(a: string, b: string): number {\n const total = a.length + b.length;\n if (total === 0) return 1.0;\n return 1 - indelDistance(a, b) / total;\n}\n\n/**\n * Token sort ratio, rapidfuzz-compatible.\n *\n * Matches `rapidfuzz.fuzz.token_sort_ratio`:\n * 1. Lowercase both strings.\n * 2. Strip non-alphanumeric characters (replace with whitespace).\n * 3. Split on whitespace, drop empties, sort tokens, rejoin with single space.\n * 4. Compare via Indel normalized similarity (NOT Levenshtein).\n *\n * Python reference: for (\"John Smith\", \"Smith Johnson\") returns ~0.8571.\n */\nexport function tokenSortRatio(a: string, b: string): number {\n const normalize = (s: string): string =>\n s\n .toLowerCase()\n .replace(/[^a-z0-9\\s]/g, \" \")\n .trim()\n .split(/\\s+/)\n .filter(Boolean)\n .sort()\n .join(\" \");\n return indelSimilarity(normalize(a), normalize(b));\n}\n\n/**\n * Soundex match: 1.0 if soundex codes equal, else 0.0.\n */\nexport function soundexMatch(a: string, b: string): number {\n return soundex(a) === soundex(b) ? 1.0 : 0.0;\n}\n\n// ---------------------------------------------------------------------------\n// Bloom filter / PPRL scorers\n// ---------------------------------------------------------------------------\n\n/** Convert a hex string to a Uint8Array of bytes. */\nfunction hexToBytes(hex: string): Uint8Array {\n const len = hex.length >>> 1;\n const bytes = new Uint8Array(len);\n for (let i = 0; i < len; i++) {\n bytes[i] = parseInt(hex.slice(i * 2, i * 2 + 2), 16);\n }\n return bytes;\n}\n\n/** Count the number of set bits (popcount) in a byte array. */\nfunction popcount(bytes: Uint8Array): number {\n let count = 0;\n for (let i = 0; i < bytes.length; i++) {\n let b = bytes[i]!;\n // Brian Kernighan's algorithm\n while (b !== 0) {\n b &= b - 1;\n count++;\n }\n }\n return count;\n}\n\n/** Count set bits in bitwise AND of two byte arrays. */\nfunction popcountAnd(a: Uint8Array, b: Uint8Array): number {\n const len = Math.min(a.length, b.length);\n let count = 0;\n for (let i = 0; i < len; i++) {\n let v = (a[i]! & b[i]!);\n while (v !== 0) {\n v &= v - 1;\n count++;\n }\n }\n return count;\n}\n\n/** Count set bits in bitwise OR of two byte arrays. */\nfunction popcountOr(a: Uint8Array, b: Uint8Array): number {\n const maxLen = Math.max(a.length, b.length);\n let count = 0;\n for (let i = 0; i < maxLen; i++) {\n let v = ((a[i] ?? 0) | (b[i] ?? 0));\n while (v !== 0) {\n v &= v - 1;\n count++;\n }\n }\n return count;\n}\n\n/**\n * Dice coefficient on two hex-encoded bloom filters.\n * 2 * intersection / (popcount_a + popcount_b)\n */\nexport function diceCoefficient(a: string, b: string): number {\n const bytesA = hexToBytes(a);\n const bytesB = hexToBytes(b);\n const pcA = popcount(bytesA);\n const pcB = popcount(bytesB);\n const total = pcA + pcB;\n if (total === 0) return 0.0;\n const intersection = popcountAnd(bytesA, bytesB);\n return (2 * intersection) / total;\n}\n\n/**\n * Jaccard similarity on two hex-encoded bloom filters.\n * intersection / union of bits\n */\nexport function jaccardSimilarity(a: string, b: string): number {\n const bytesA = hexToBytes(a);\n const bytesB = hexToBytes(b);\n const intersection = popcountAnd(bytesA, bytesB);\n const union = popcountOr(bytesA, bytesB);\n if (union === 0) return 0.0;\n return intersection / union;\n}\n\n// ---------------------------------------------------------------------------\n// Ensemble scorer\n// ---------------------------------------------------------------------------\n\n/**\n * Ensemble scorer: combines jaro_winkler, token_sort, and soundex_match * 0.8.\n * Takes element-wise max of all three.\n */\nexport function ensembleScore(a: string, b: string): number {\n const jw = jaroWinkler(a, b);\n const ts = tokenSortRatio(a, b);\n const sx = soundexMatch(a, b) * 0.8;\n return Math.max(jw, ts, sx);\n}\n\n// ---------------------------------------------------------------------------\n// Public: scoreField\n// ---------------------------------------------------------------------------\n\n/**\n * Score two field values using the specified scorer.\n * Returns null if either value is null.\n */\nexport function scoreField(\n valA: string | null,\n valB: string | null,\n scorer: string,\n): number | null {\n if (valA === null || valB === null) return null;\n\n switch (scorer) {\n case \"exact\":\n return valA === valB ? 1.0 : 0.0;\n case \"jaro_winkler\":\n return jaroWinkler(valA, valB);\n case \"levenshtein\":\n return levenshteinSimilarity(valA, valB);\n case \"token_sort\":\n return tokenSortRatio(valA, valB);\n case \"soundex_match\":\n return soundexMatch(valA, valB);\n case \"dice\":\n return diceCoefficient(valA, valB);\n case \"jaccard\":\n return jaccardSimilarity(valA, valB);\n case \"ensemble\":\n return ensembleScore(valA, valB);\n default:\n throw new Error(`Unknown scorer: ${JSON.stringify(scorer)}`);\n }\n}\n\n// ---------------------------------------------------------------------------\n// Public: scorePair\n// ---------------------------------------------------------------------------\n\n/**\n * Score a pair of rows across all fields using weighted aggregation.\n * Fields that produce null scores are excluded. If all null -> 0.0.\n */\nexport function scorePair(\n rowA: Row,\n rowB: Row,\n fields: readonly MatchkeyField[],\n): number {\n let weightedSum = 0;\n let weightSum = 0;\n for (const f of fields) {\n const valA = applyTransforms(asString(rowA[f.field]), f.transforms);\n const valB = applyTransforms(asString(rowB[f.field]), f.transforms);\n const fieldScore = scoreField(valA, valB, f.scorer);\n if (fieldScore !== null) {\n weightedSum += fieldScore * f.weight;\n weightSum += f.weight;\n }\n }\n return weightSum === 0 ? 0 : weightedSum / weightSum;\n}\n\n// ---------------------------------------------------------------------------\n// NxN score matrix\n// ---------------------------------------------------------------------------\n\n/**\n * Build an NxN score matrix for a list of values using a scorer.\n * Symmetric: matrix[i][j] === matrix[j][i]. Diagonal is 0.\n */\nexport function scoreMatrix(\n values: (string | null)[],\n scorerName: string,\n): number[][] {\n const n = values.length;\n const matrix: number[][] = Array.from({ length: n }, () => new Array<number>(n).fill(0));\n for (let i = 0; i < n; i++) {\n for (let j = i + 1; j < n; j++) {\n const s = scoreField(values[i]!, values[j]!, scorerName) ?? 0;\n matrix[i]![j] = s;\n matrix[j]![i] = s;\n }\n }\n return matrix;\n}\n\n// ---------------------------------------------------------------------------\n// Exact score matrix (hash-based grouping, O(n))\n// ---------------------------------------------------------------------------\n\nfunction exactScoreMatrix(values: (string | null)[]): number[][] {\n const n = values.length;\n const matrix: number[][] = Array.from({ length: n }, () => new Array<number>(n).fill(0));\n // Group indices by value\n const groups = new Map<string, number[]>();\n for (let i = 0; i < n; i++) {\n const v = values[i];\n if (v != null) {\n const existing = groups.get(v);\n if (existing !== undefined) {\n existing.push(i);\n } else {\n groups.set(v, [i]);\n }\n }\n }\n groups.forEach((indices) => {\n if (indices.length > 1) {\n for (let a = 0; a < indices.length; a++) {\n for (let b = a + 1; b < indices.length; b++) {\n matrix[indices[a]!]![indices[b]!] = 1.0;\n matrix[indices[b]!]![indices[a]!] = 1.0;\n }\n }\n }\n });\n return matrix;\n}\n\n/** Soundex score matrix: group by soundex code, 1.0 for same code. */\nfunction soundexScoreMatrix(values: (string | null)[]): number[][] {\n const codes = values.map((v) => (v !== null ? soundex(v) : null));\n return exactScoreMatrix(codes);\n}\n\n/** Ensemble score matrix: max of jaro_winkler, token_sort, soundex*0.8 */\nfunction ensembleScoreMatrix(values: (string | null)[]): number[][] {\n const n = values.length;\n const clean = values.map((v) => v ?? \"\");\n const jw: number[][] = Array.from({ length: n }, () => new Array<number>(n).fill(0));\n const ts: number[][] = Array.from({ length: n }, () => new Array<number>(n).fill(0));\n const sx = soundexScoreMatrix(values);\n const result: number[][] = Array.from({ length: n }, () => new Array<number>(n).fill(0));\n\n for (let i = 0; i < n; i++) {\n for (let j = i + 1; j < n; j++) {\n if (values[i] === null || values[j] === null) continue;\n jw[i]![j] = jaroWinkler(clean[i]!, clean[j]!);\n jw[j]![i] = jw[i]![j]!;\n ts[i]![j] = tokenSortRatio(clean[i]!, clean[j]!);\n ts[j]![i] = ts[i]![j]!;\n }\n }\n\n for (let i = 0; i < n; i++) {\n for (let j = i + 1; j < n; j++) {\n const val = Math.max(jw[i]![j]!, ts[i]![j]!, sx[i]![j]! * 0.8);\n result[i]![j] = val;\n result[j]![i] = val;\n }\n }\n return result;\n}\n\n/**\n * Build an NxN null mask: true where either value is null.\n */\nfunction buildNullMask(values: (string | null)[]): boolean[][] {\n const n = values.length;\n const mask: boolean[][] = Array.from({ length: n }, () => new Array<boolean>(n).fill(false));\n for (let i = 0; i < n; i++) {\n if (values[i] === null) {\n for (let j = 0; j < n; j++) {\n mask[i]![j] = true;\n mask[j]![i] = true;\n }\n }\n }\n return mask;\n}\n\n/**\n * Build the appropriate score matrix for a scorer name.\n */\nfunction buildScoreMatrix(values: (string | null)[], scorerName: string): number[][] {\n switch (scorerName) {\n case \"exact\":\n return exactScoreMatrix(values);\n case \"soundex_match\":\n return soundexScoreMatrix(values);\n case \"ensemble\":\n return ensembleScoreMatrix(values);\n default:\n return scoreMatrix(values, scorerName);\n }\n}\n\n// ---------------------------------------------------------------------------\n// Get transformed values for a field from block rows\n// ---------------------------------------------------------------------------\n\nfunction getTransformedValues(\n rows: readonly Row[],\n field: MatchkeyField,\n): (string | null)[] {\n return rows.map((row) => {\n const raw = asString(row[field.field]);\n return applyTransforms(raw, field.transforms);\n });\n}\n\n// ---------------------------------------------------------------------------\n// Public: findExactMatches\n// ---------------------------------------------------------------------------\n\n/**\n * Find exact matches by grouping rows on matchkey columns.\n * Builds a composite key from all matchkey fields (with transforms applied),\n * groups rows sharing the same key, and returns all pairs with score 1.0.\n *\n * Rows must have a `__row_id__` field.\n */\nexport function findExactMatches(\n rows: readonly Row[],\n mk: MatchkeyConfig,\n): ScoredPair[] {\n if (rows.length < 2) return [];\n\n // Build composite matchkey for each row\n const groups = new Map<string, number[]>();\n for (let i = 0; i < rows.length; i++) {\n const row = rows[i]!;\n const rowId = row[\"__row_id__\"] as number;\n // Build key from all fields\n let keyParts: (string | null)[] = [];\n let hasNull = false;\n for (const f of mk.fields) {\n const raw = asString(row[f.field]);\n const transformed = applyTransforms(raw, f.transforms);\n if (transformed === null) {\n hasNull = true;\n break;\n }\n keyParts.push(transformed);\n }\n // Skip rows with any null field (nulls don't match)\n if (hasNull) continue;\n\n const key = keyParts.join(\"\\x00\"); // null byte separator\n const existing = groups.get(key);\n if (existing !== undefined) {\n existing.push(rowId);\n } else {\n groups.set(key, [rowId]);\n }\n }\n\n // Extract pairs from groups\n const pairs: ScoredPair[] = [];\n groups.forEach((members) => {\n if (members.length < 2) return;\n for (let i = 0; i < members.length; i++) {\n for (let j = i + 1; j < members.length; j++) {\n pairs.push(makeScoredPair(members[i]!, members[j]!, 1.0));\n }\n }\n });\n return pairs;\n}\n\n// ---------------------------------------------------------------------------\n// Public: findFuzzyMatches\n// ---------------------------------------------------------------------------\n\n/**\n * Find fuzzy matches within a block of rows (NxN scoring).\n *\n * Implements early termination:\n * - Score cheap fields (exact/soundex) first\n * - Check if max possible score can reach threshold\n * - Score expensive fuzzy fields only for promising pairs\n *\n * Rows must have a `__row_id__` field.\n */\nexport function findFuzzyMatches(\n rows: readonly Row[],\n mk: MatchkeyConfig,\n excludePairs?: ReadonlySet<PairKey>,\n preScoredPairs?: readonly ScoredPair[],\n): ScoredPair[] {\n // findFuzzyMatches only runs for weighted/probabilistic matchkeys\n // (exact is handled via findExactMatches). Exact has no threshold.\n const threshold = mk.type === \"exact\" ? 1.0 : (mk.threshold ?? 0.85);\n\n // Fast path: pre-scored pairs (from ANN blocking)\n if (preScoredPairs !== undefined) {\n const results: ScoredPair[] = [];\n for (const p of preScoredPairs) {\n if (p.score < threshold) continue;\n const idA = Math.min(p.idA, p.idB);\n const idB = Math.max(p.idA, p.idB);\n const key = pairKey(idA, idB);\n if (excludePairs !== undefined && excludePairs.has(key)) continue;\n results.push(makeScoredPair(idA, idB, p.score));\n }\n return results;\n }\n\n const n = rows.length;\n if (n < 2) return [];\n\n const rowIds = rows.map((r) => r[\"__row_id__\"] as number);\n\n // Separate cheap (exact + soundex) from expensive (fuzzy) fields\n const cheapFields = mk.fields.filter(\n (f) => f.scorer === \"exact\" || f.scorer === \"soundex_match\",\n );\n const fuzzyFields = mk.fields.filter(\n (f) => f.scorer !== \"exact\" && f.scorer !== \"soundex_match\" && f.scorer !== \"record_embedding\",\n );\n\n const totalWeight = mk.fields.reduce((sum, f) => sum + f.weight, 0);\n if (totalWeight === 0) return [];\n\n // Phase 1: Score cheap fields and build null masks\n // cheapNumerator[i][j] = sum(fieldScore * weight) for cheap fields\n // cheapDenominator[i][j] = sum(weight) for non-null cheap fields\n const cheapNumerator: number[][] = Array.from({ length: n }, () => new Array<number>(n).fill(0));\n const cheapDenominator: number[][] = Array.from({ length: n }, () => new Array<number>(n).fill(0));\n\n for (const f of cheapFields) {\n const values = getTransformedValues(rows, f);\n const nullMask = buildNullMask(values);\n const scores =\n f.scorer === \"exact\"\n ? exactScoreMatrix(values)\n : soundexScoreMatrix(values);\n\n for (let i = 0; i < n; i++) {\n for (let j = i + 1; j < n; j++) {\n if (!nullMask[i]![j]!) {\n cheapNumerator[i]![j]! += scores[i]![j]! * f.weight;\n cheapNumerator[j]![i]! = cheapNumerator[i]![j]!;\n cheapDenominator[i]![j]! += f.weight;\n cheapDenominator[j]![i]! = cheapDenominator[i]![j]!;\n }\n }\n }\n }\n\n // Phase 2: Early termination check\n const fuzzyTotalWeight = fuzzyFields.reduce((sum, f) => sum + f.weight, 0);\n\n // Track which pairs are impossible (can't reach threshold)\n const impossible: boolean[][] = Array.from({ length: n }, () => new Array<boolean>(n).fill(false));\n\n let combined: number[][];\n\n if (fuzzyFields.length === 0) {\n // No fuzzy fields — just use cheap scores\n combined = Array.from({ length: n }, () => new Array<number>(n).fill(0));\n for (let i = 0; i < n; i++) {\n for (let j = i + 1; j < n; j++) {\n combined[i]![j] =\n cheapDenominator[i]![j]! > 0\n ? cheapNumerator[i]![j]! / cheapDenominator[i]![j]!\n : 0;\n combined[j]![i] = combined[i]![j]!;\n }\n }\n } else {\n // Check which pairs can possibly reach threshold\n for (let i = 0; i < n; i++) {\n for (let j = i + 1; j < n; j++) {\n const maxNum = cheapNumerator[i]![j]! + fuzzyTotalWeight;\n const maxDen = cheapDenominator[i]![j]! + fuzzyTotalWeight;\n const maxPossible = maxDen > 0 ? maxNum / maxDen : 0;\n if (maxPossible < threshold) {\n impossible[i]![j] = true;\n impossible[j]![i] = true;\n }\n }\n }\n\n // Phase 3: Score fuzzy fields with intra-field early termination\n const fuzzyNumerator: number[][] = Array.from({ length: n }, () => new Array<number>(n).fill(0));\n const fuzzyDenominator: number[][] = Array.from({ length: n }, () => new Array<number>(n).fill(0));\n\n for (let fIdx = 0; fIdx < fuzzyFields.length; fIdx++) {\n const f = fuzzyFields[fIdx]!;\n const values = getTransformedValues(rows, f);\n const nullMask = buildNullMask(values);\n const scores = buildScoreMatrix(values, f.scorer);\n\n for (let i = 0; i < n; i++) {\n for (let j = i + 1; j < n; j++) {\n if (!nullMask[i]![j]!) {\n fuzzyNumerator[i]![j]! += scores[i]![j]! * f.weight;\n fuzzyNumerator[j]![i] = fuzzyNumerator[i]![j]!;\n fuzzyDenominator[i]![j]! += f.weight;\n fuzzyDenominator[j]![i] = fuzzyDenominator[i]![j]!;\n }\n }\n }\n\n // Intra-field early termination: check if any pair can still reach threshold\n const remainingWeight = fuzzyFields\n .slice(fIdx + 1)\n .reduce((sum, ff) => sum + ff.weight, 0);\n\n if (remainingWeight > 0) {\n let anyCanReach = false;\n for (let i = 0; i < n && !anyCanReach; i++) {\n for (let j = i + 1; j < n && !anyCanReach; j++) {\n if (impossible[i]![j]!) continue;\n const totalNum =\n cheapNumerator[i]![j]! + fuzzyNumerator[i]![j]! + remainingWeight;\n const totalDen =\n cheapDenominator[i]![j]! + fuzzyDenominator[i]![j]! + remainingWeight;\n const bestPossible = totalDen > 0 ? totalNum / totalDen : 0;\n if (bestPossible >= threshold) {\n anyCanReach = true;\n }\n }\n }\n if (!anyCanReach) break; // No pair can reach threshold — skip remaining fields\n }\n }\n\n // Combine cheap + fuzzy\n combined = Array.from({ length: n }, () => new Array<number>(n).fill(0));\n for (let i = 0; i < n; i++) {\n for (let j = i + 1; j < n; j++) {\n if (impossible[i]![j]!) {\n combined[i]![j] = 0;\n } else {\n const totalNum = cheapNumerator[i]![j]! + fuzzyNumerator[i]![j]!;\n const totalDen = cheapDenominator[i]![j]! + fuzzyDenominator[i]![j]!;\n combined[i]![j] = totalDen > 0 ? totalNum / totalDen : 0;\n }\n combined[j]![i] = combined[i]![j]!;\n }\n }\n }\n\n // Extract upper triangle pairs above threshold\n const results: ScoredPair[] = [];\n for (let i = 0; i < n; i++) {\n for (let j = i + 1; j < n; j++) {\n const score = combined[i]![j]!;\n if (score < threshold) continue;\n const idA = Math.min(rowIds[i]!, rowIds[j]!);\n const idB = Math.max(rowIds[i]!, rowIds[j]!);\n const key = pairKey(idA, idB);\n if (excludePairs !== undefined && excludePairs.has(key)) continue;\n results.push(makeScoredPair(idA, idB, score));\n }\n }\n return results;\n}\n\n// ---------------------------------------------------------------------------\n// Public: scoreBlocksSequential\n// ---------------------------------------------------------------------------\n\nexport interface ScoreBlocksOptions {\n /** Filter to cross-source pairs only. */\n readonly acrossFilesOnly?: boolean;\n /** Row ID -> source name mapping (for acrossFilesOnly). */\n readonly sourceLookup?: ReadonlyMap<number, string>;\n /** Target IDs for match mode — filter to target/ref cross pairs. */\n readonly targetIds?: ReadonlySet<number>;\n}\n\n/**\n * Score all blocks sequentially.\n *\n * In JS there is no GIL, so we use sequential scoring as the default.\n * For web workers or similar concurrency, the caller can partition blocks.\n */\nexport function scoreBlocksSequential(\n blocks: readonly BlockResult[],\n mk: MatchkeyConfig,\n matchedPairs: Set<PairKey>,\n options?: ScoreBlocksOptions,\n): ScoredPair[] {\n if (blocks.length === 0) return [];\n\n const acrossFilesOnly = options?.acrossFilesOnly ?? false;\n const sourceLookup = options?.sourceLookup;\n const targetIds = options?.targetIds;\n\n const allPairs: ScoredPair[] = [];\n\n for (const block of blocks) {\n // For cross-file mode, check that block has records from multiple sources\n if (acrossFilesOnly && sourceLookup !== undefined) {\n const sourcesInBlock = new Set<string>();\n for (const row of block.rows) {\n const src = sourceLookup.get(row[\"__row_id__\"] as number);\n if (src !== undefined) sourcesInBlock.add(src);\n }\n if (sourcesInBlock.size < 2) continue;\n }\n\n // Use a frozen copy of matchedPairs for consistency\n const excludeSnapshot: ReadonlySet<PairKey> = new Set(matchedPairs);\n\n let pairs = findFuzzyMatches(\n block.rows,\n mk,\n excludeSnapshot,\n block.preScoredPairs,\n );\n\n // Cross-file filter\n if (acrossFilesOnly && sourceLookup !== undefined) {\n pairs = pairs.filter((p) => {\n const srcA = sourceLookup.get(p.idA);\n const srcB = sourceLookup.get(p.idB);\n return srcA !== srcB;\n });\n }\n\n // Target/ref cross filter for match mode\n if (targetIds !== undefined) {\n pairs = pairs.filter(\n (p) => targetIds.has(p.idA) !== targetIds.has(p.idB),\n );\n }\n\n for (const p of pairs) {\n allPairs.push(p);\n matchedPairs.add(pairKey(p.idA, p.idB));\n }\n }\n\n return allPairs;\n}\n\n// ---------------------------------------------------------------------------\n// Utility: canonicalize pair key\n// ---------------------------------------------------------------------------\n\n// Re-export pairKey from cluster.ts — single canonical source of truth.\nexport { pairKey };\n","/**\n * golden.ts — Golden record builder with per-field merge strategies.\n * Edge-safe: no Node.js imports, pure TypeScript only.\n */\n\nimport type {\n ClusterInfo,\n ClusterProvenance,\n FieldProvenance,\n GoldenFieldRule,\n GoldenRulesConfig,\n Row,\n} from \"./types.js\";\n\n// ---------------------------------------------------------------------------\n// Constants\n// ---------------------------------------------------------------------------\n\nconst INTERNAL_PREFIXES = [\n \"__row_id__\",\n \"__source__\",\n \"__block_key__\",\n \"__mk_\",\n \"__cluster_id__\",\n \"__golden_confidence__\",\n];\n\nfunction isInternal(col: string): boolean {\n return (\n col === \"__mk_\" ||\n INTERNAL_PREFIXES.some((prefix) => col.startsWith(prefix))\n );\n}\n\n// ---------------------------------------------------------------------------\n// MergeField result\n// ---------------------------------------------------------------------------\n\nexport interface MergeFieldResult {\n readonly value: unknown;\n readonly confidence: number;\n readonly sourceIndex: number | null;\n}\n\n// ---------------------------------------------------------------------------\n// MergeField options\n// ---------------------------------------------------------------------------\n\nexport interface MergeFieldOptions {\n readonly sources?: readonly string[];\n readonly dates?: readonly unknown[];\n readonly qualityWeights?: readonly number[];\n}\n\n// ---------------------------------------------------------------------------\n// mergeField\n// ---------------------------------------------------------------------------\n\n/**\n * Merge a list of values using the given strategy.\n *\n * Strategies:\n * - most_complete: pick longest string value; tie-break by quality weight\n * - majority_vote: pick most frequent value; weighted by quality if available\n * - source_priority: pick first non-null from priority list\n * - most_recent: pick value with most recent date\n * - first_non_null: pick first non-null; prefer highest quality weight\n */\nexport function mergeField(\n values: readonly unknown[],\n rule: GoldenFieldRule,\n options?: MergeFieldOptions,\n): MergeFieldResult {\n const nonNull: [number, unknown][] = [];\n for (let i = 0; i < values.length; i++) {\n if (values[i] != null) {\n nonNull.push([i, values[i]]);\n }\n }\n\n if (nonNull.length === 0) {\n return { value: null, confidence: 0.0, sourceIndex: null };\n }\n\n // All non-null values identical -> confidence 1.0 shortcut\n const uniqueVals = new Set(nonNull.map(([, v]) => v));\n if (uniqueVals.size === 1) {\n return { value: nonNull[0]![1], confidence: 1.0, sourceIndex: nonNull[0]![0] };\n }\n\n const strategy = rule.strategy;\n\n switch (strategy) {\n case \"most_complete\":\n return _mostComplete(nonNull, options?.qualityWeights);\n case \"majority_vote\":\n return _majorityVote(nonNull, options?.qualityWeights);\n case \"source_priority\":\n return _sourcePriority(values, rule, options?.sources);\n case \"most_recent\":\n return _mostRecent(values, options?.dates);\n case \"first_non_null\":\n return _firstNonNull(nonNull, options?.qualityWeights);\n default:\n throw new Error(`Unknown strategy: ${strategy}`);\n }\n}\n\n// ---------------------------------------------------------------------------\n// Strategy implementations\n// ---------------------------------------------------------------------------\n\nfunction _mostComplete(\n nonNull: [number, unknown][],\n qualityWeights?: readonly number[],\n): MergeFieldResult {\n const strVals = nonNull.map(\n ([i, v]) => [i, String(v), v] as [number, string, unknown],\n );\n // For-loop max — Math.max(...arr) crashes on arrays with >65K elements.\n let maxLen = 0;\n for (const [, s] of strVals) if (s.length > maxLen) maxLen = s.length;\n const longest = strVals.filter(([, s]) => s.length === maxLen);\n\n if (longest.length === 1) {\n return { value: longest[0]![2], confidence: 1.0, sourceIndex: longest[0]![0] };\n }\n\n // Tie-break by quality weight\n if (qualityWeights) {\n const best = longest.reduce((a, b) => {\n const wa =\n a[0] < qualityWeights.length ? qualityWeights[a[0]]! : 1.0;\n const wb =\n b[0] < qualityWeights.length ? qualityWeights[b[0]]! : 1.0;\n return wa >= wb ? a : b;\n });\n const w =\n best[0] < qualityWeights.length ? qualityWeights[best[0]]! : 1.0;\n const conf = Math.min(1.0, 0.7 * w);\n return { value: best[2], confidence: conf, sourceIndex: best[0] };\n }\n\n return { value: longest[0]![2], confidence: 0.7, sourceIndex: longest[0]![0] };\n}\n\nfunction _majorityVote(\n nonNull: [number, unknown][],\n qualityWeights?: readonly number[],\n): MergeFieldResult {\n if (qualityWeights) {\n // Weighted vote: sum quality weights per value\n const valueWeights = new Map<unknown, number>();\n const valueIdx = new Map<unknown, number>();\n\n for (const [i, v] of nonNull) {\n const w = i < qualityWeights.length ? qualityWeights[i]! : 1.0;\n valueWeights.set(v, (valueWeights.get(v) ?? 0) + w);\n if (!valueIdx.has(v)) valueIdx.set(v, i);\n }\n\n let winner: unknown = null;\n let bestWeight = -Infinity;\n for (const [v, w] of valueWeights) {\n if (w > bestWeight) {\n bestWeight = w;\n winner = v;\n }\n }\n\n let totalWeight = 0;\n for (const w of valueWeights.values()) totalWeight += w;\n const conf = totalWeight > 0 ? bestWeight / totalWeight : 0.0;\n return { value: winner, confidence: conf, sourceIndex: valueIdx.get(winner)! };\n }\n\n // Unweighted: count occurrences\n const counts = new Map<unknown, number>();\n for (const [, v] of nonNull) {\n counts.set(v, (counts.get(v) ?? 0) + 1);\n }\n\n let winner: unknown = null;\n let bestCount = -1;\n for (const [v, c] of counts) {\n if (c > bestCount) {\n bestCount = c;\n winner = v;\n }\n }\n\n const winnerIdx = nonNull.find(([, v]) => v === winner)![0];\n return {\n value: winner,\n confidence: bestCount / nonNull.length,\n sourceIndex: winnerIdx,\n };\n}\n\nfunction _sourcePriority(\n values: readonly unknown[],\n rule: GoldenFieldRule,\n sources?: readonly string[],\n): MergeFieldResult {\n if (!sources) {\n throw new Error(\"source_priority strategy requires sources list\");\n }\n\n const sourceVal = new Map<string, unknown>();\n const sourceIdx = new Map<string, number>();\n\n for (let i = 0; i < sources.length; i++) {\n const src = sources[i]!;\n if (!sourceVal.has(src)) {\n sourceVal.set(src, values[i]);\n sourceIdx.set(src, i);\n }\n }\n\n const priority = rule.sourcePriority ?? [];\n for (let idx = 0; idx < priority.length; idx++) {\n const src = priority[idx]!;\n const val = sourceVal.get(src);\n if (val != null) {\n const conf = Math.max(0.1, 1.0 - idx * 0.1);\n return { value: val, confidence: conf, sourceIndex: sourceIdx.get(src)! };\n }\n }\n\n // Fallback: no match in priority list\n return { value: null, confidence: 0.0, sourceIndex: null };\n}\n\nfunction _mostRecent(\n values: readonly unknown[],\n dates?: readonly unknown[],\n): MergeFieldResult {\n if (!dates) {\n throw new Error(\"most_recent strategy requires dates list\");\n }\n\n const indexed: [number, unknown, unknown][] = [];\n for (let i = 0; i < values.length; i++) {\n if (values[i] != null && dates[i] != null) {\n indexed.push([i, dates[i], values[i]]);\n }\n }\n\n if (indexed.length === 0) {\n return { value: null, confidence: 0.0, sourceIndex: null };\n }\n\n // Sort by date descending (works for ISO strings and numbers)\n indexed.sort((a, b) => {\n if (a[1]! > b[1]!) return -1;\n if (a[1]! < b[1]!) return 1;\n return 0;\n });\n\n const topDate = indexed[0]![1];\n const tied = indexed.filter(([, d]) => d === topDate);\n const conf = tied.length === 1 ? 1.0 : 0.5;\n\n return { value: indexed[0]![2], confidence: conf, sourceIndex: indexed[0]![0] };\n}\n\nfunction _firstNonNull(\n nonNull: [number, unknown][],\n qualityWeights?: readonly number[],\n): MergeFieldResult {\n if (qualityWeights) {\n // Pick the non-null value with the highest quality weight\n let bestIdx = nonNull[0]![0];\n let bestVal = nonNull[0]![1];\n let bestWeight =\n nonNull[0]![0] < qualityWeights.length\n ? qualityWeights[nonNull[0]![0]]!\n : 1.0;\n\n for (let i = 1; i < nonNull.length; i++) {\n const [idx, val] = nonNull[i]!;\n const w = idx < qualityWeights.length ? qualityWeights[idx]! : 1.0;\n if (w > bestWeight) {\n bestWeight = w;\n bestIdx = idx;\n bestVal = val;\n }\n }\n\n return { value: bestVal, confidence: 0.6, sourceIndex: bestIdx };\n }\n\n return { value: nonNull[0]![1], confidence: 0.6, sourceIndex: nonNull[0]![0] };\n}\n\n// ---------------------------------------------------------------------------\n// GoldenRecord\n// ---------------------------------------------------------------------------\n\nexport interface GoldenRecord {\n readonly fields: Readonly<Record<string, { value: unknown; confidence: number }>>;\n readonly goldenConfidence: number;\n}\n\n// ---------------------------------------------------------------------------\n// buildGoldenRecord\n// ---------------------------------------------------------------------------\n\n/**\n * Build a golden record from cluster rows.\n *\n * @param clusterRows - Array of row objects belonging to one cluster.\n * @param rules - Golden rules config with default strategy and field rules.\n * @param qualityScores - Optional map of `\"rowId:column\"` -> quality score.\n */\nexport function buildGoldenRecord(\n clusterRows: readonly Row[],\n rules: GoldenRulesConfig,\n qualityScores?: ReadonlyMap<string, number>,\n): GoldenRecord {\n if (clusterRows.length === 0) {\n return { fields: {}, goldenConfidence: 0.0 };\n }\n\n // Collect all column names\n const columns = new Set<string>();\n for (const row of clusterRows) {\n for (const col of Object.keys(row)) {\n columns.add(col);\n }\n }\n\n const rowIds: number[] = clusterRows.map(\n (r) => (r.__row_id__ as number) ?? 0,\n );\n\n const fields: Record<string, { value: unknown; confidence: number }> = {};\n const confidences: number[] = [];\n\n for (const col of columns) {\n if (isInternal(col)) continue;\n\n const values = clusterRows.map((r) => r[col] ?? null);\n\n // Look up field rule or use default\n const fieldRule: GoldenFieldRule =\n rules.fieldRules[col] ?? { strategy: rules.defaultStrategy as GoldenFieldRule[\"strategy\"] };\n\n // Gather optional lists\n let sources: string[] | undefined;\n let dates: unknown[] | undefined;\n let weights: number[] | undefined;\n\n if (fieldRule.strategy === \"source_priority\") {\n sources = clusterRows.map((r) => String(r.__source__ ?? \"\"));\n }\n if (fieldRule.strategy === \"most_recent\" && fieldRule.dateColumn) {\n dates = clusterRows.map((r) => r[fieldRule.dateColumn!] ?? null);\n }\n if (qualityScores) {\n weights = rowIds.map((rid) => qualityScores.get(`${rid}:${col}`) ?? 1.0);\n }\n\n const mergeOpts: MergeFieldOptions = {\n ...(sources !== undefined && { sources }),\n ...(dates !== undefined && { dates }),\n ...(weights !== undefined && { qualityWeights: weights }),\n };\n const result = mergeField(values, fieldRule, mergeOpts);\n fields[col] = { value: result.value, confidence: result.confidence };\n confidences.push(result.confidence);\n }\n\n const goldenConfidence =\n confidences.length > 0\n ? confidences.reduce((a, b) => a + b, 0) / confidences.length\n : 0.0;\n\n return { fields, goldenConfidence };\n}\n\n// ---------------------------------------------------------------------------\n// buildGoldenRecordWithProvenance\n// ---------------------------------------------------------------------------\n\nexport interface GoldenRecordWithProvenanceResult {\n readonly goldenRecords: readonly (Row & {\n __cluster_id__: number;\n __golden_confidence__: number;\n })[];\n readonly provenance: readonly ClusterProvenance[];\n}\n\n/**\n * Build golden records with full field-level provenance tracking.\n *\n * @param allRows - All rows with `__cluster_id__` and `__row_id__` columns.\n * @param rules - Golden rules config.\n * @param clusters - Cluster map from buildClusters.\n * @param qualityScores - Optional `\"rowId:column\"` -> quality score map.\n */\nexport function buildGoldenRecordWithProvenance(\n allRows: readonly Row[],\n rules: GoldenRulesConfig,\n clusters: ReadonlyMap<number, ClusterInfo>,\n qualityScores?: ReadonlyMap<string, number>,\n): GoldenRecordWithProvenanceResult {\n // Group rows by cluster ID\n const clusterDfs = new Map<number, Row[]>();\n for (const row of allRows) {\n const cid = (row.__cluster_id__ as number) ?? 1;\n let arr = clusterDfs.get(cid);\n if (!arr) {\n arr = [];\n clusterDfs.set(cid, arr);\n }\n arr.push(row);\n }\n\n const clusterIds = [...clusterDfs.keys()].sort((a, b) => a - b);\n const goldenRecords: (Row & {\n __cluster_id__: number;\n __golden_confidence__: number;\n })[] = [];\n const provenanceList: ClusterProvenance[] = [];\n\n for (const cid of clusterIds) {\n const clusterRows = clusterDfs.get(cid)!;\n const cinfo = clusters.get(cid);\n const rowIds = clusterRows.map(\n (r) => (r.__row_id__ as number) ?? 0,\n );\n\n // Collect columns\n const columns = new Set<string>();\n for (const row of clusterRows) {\n for (const col of Object.keys(row)) {\n columns.add(col);\n }\n }\n\n const fieldProvenance: Record<string, FieldProvenance> = {};\n const goldenRow: Record<string, unknown> = { __cluster_id__: cid };\n const confidences: number[] = [];\n\n for (const col of columns) {\n if (isInternal(col)) continue;\n\n const values = clusterRows.map((r) => r[col] ?? null);\n\n const fieldRule: GoldenFieldRule =\n rules.fieldRules[col] ?? { strategy: rules.defaultStrategy as GoldenFieldRule[\"strategy\"] };\n\n let sources: string[] | undefined;\n let dates: unknown[] | undefined;\n let weights: number[] | undefined;\n\n if (fieldRule.strategy === \"source_priority\") {\n sources = clusterRows.map((r) => String(r.__source__ ?? \"\"));\n }\n if (fieldRule.strategy === \"most_recent\" && fieldRule.dateColumn) {\n dates = clusterRows.map((r) => r[fieldRule.dateColumn!] ?? null);\n }\n if (qualityScores) {\n weights = rowIds.map(\n (rid) => qualityScores.get(`${rid}:${col}`) ?? 1.0,\n );\n }\n\n const mergeOpts: MergeFieldOptions = {\n ...(sources !== undefined && { sources }),\n ...(dates !== undefined && { dates }),\n ...(weights !== undefined && { qualityWeights: weights }),\n };\n const result = mergeField(values, fieldRule, mergeOpts);\n confidences.push(result.confidence);\n\n const sourceRowId =\n result.sourceIndex != null && result.sourceIndex < rowIds.length\n ? rowIds[result.sourceIndex]!\n : rowIds[0]!;\n\n const candidates = rowIds.map((rid, idx) => {\n const q = qualityScores\n ? (qualityScores.get(`${rid}:${col}`) ?? 1.0)\n : 1.0;\n return { row_id: rid, value: values[idx], quality: q };\n });\n\n fieldProvenance[col] = {\n value: result.value,\n sourceRowId,\n strategy: fieldRule.strategy,\n confidence: result.confidence,\n candidates,\n };\n\n goldenRow[col] = result.value;\n }\n\n const goldenConfidence =\n confidences.length > 0\n ? confidences.reduce((a, b) => a + b, 0) / confidences.length\n : 0.0;\n\n goldenRow.__golden_confidence__ = goldenConfidence;\n\n goldenRecords.push(\n goldenRow as Row & {\n __cluster_id__: number;\n __golden_confidence__: number;\n },\n );\n\n provenanceList.push({\n clusterId: cid,\n clusterQuality: cinfo?.clusterQuality ?? \"strong\",\n clusterConfidence: cinfo?.confidence ?? 0.0,\n fields: fieldProvenance,\n });\n }\n\n return { goldenRecords, provenance: provenanceList };\n}\n","/**\n * pipeline.ts — Core pipeline orchestrator for GoldenMatch-JS.\n * Edge-safe: no `node:` imports, pure TypeScript only.\n *\n * Ports goldenmatch/core/pipeline.py.\n * Chains: standardize -> matchkeys -> block -> score -> cluster -> golden.\n */\n\nimport type {\n Row,\n GoldenMatchConfig,\n MatchkeyConfig,\n DedupeResult,\n DedupeStats,\n PairKey,\n ScoredPair,\n MatchResult,\n GoldenRulesConfig,\n ClusterInfo,\n} from \"./types.js\";\nimport { makeGoldenRulesConfig, getMatchkeys, makeBlockingConfig } from \"./types.js\";\nimport { computeMatchkeys, addRowIds, addSourceColumn } from \"./matchkey.js\";\nimport { applyStandardization } from \"./standardize.js\";\nimport { buildBlocks } from \"./blocker.js\";\nimport {\n findExactMatches,\n scoreBlocksSequential,\n} from \"./scorer.js\";\nimport { buildClusters, pairKey } from \"./cluster.js\";\nimport { buildGoldenRecord } from \"./golden.js\";\n\n// ---------------------------------------------------------------------------\n// Options\n// ---------------------------------------------------------------------------\n\nexport interface DedupeOptions {\n readonly outputGolden?: boolean;\n readonly outputReport?: boolean;\n readonly acrossFilesOnly?: boolean;\n}\n\n// ---------------------------------------------------------------------------\n// Internal helpers\n// ---------------------------------------------------------------------------\n\n/** Build a source lookup map from rows (rowId -> source name). */\nfunction buildSourceLookup(rows: readonly Row[]): Map<number, string> {\n const lookup = new Map<number, string>();\n for (const row of rows) {\n const id = row.__row_id__ as number;\n const src = row.__source__ as string | undefined;\n if (id !== undefined && src !== undefined) {\n lookup.set(id, src);\n }\n }\n return lookup;\n}\n\n/** Collect all row IDs from rows. */\nfunction collectRowIds(rows: readonly Row[]): number[] {\n return rows.map((r) => r.__row_id__ as number);\n}\n\n/** Assign __cluster_id__ to rows based on cluster membership. */\nfunction assignClusterIds(\n rows: readonly Row[],\n clusters: ReadonlyMap<number, ClusterInfo>,\n): Row[] {\n // Build rowId -> clusterId lookup\n const rowToCluster = new Map<number, number>();\n for (const [cid, cinfo] of clusters) {\n for (const memberId of cinfo.members) {\n rowToCluster.set(memberId, cid);\n }\n }\n\n return rows.map((row) => {\n const rowId = row.__row_id__ as number;\n const cid = rowToCluster.get(rowId);\n return cid !== undefined ? { ...row, __cluster_id__: cid } : row;\n });\n}\n\n// ---------------------------------------------------------------------------\n// runDedupePipeline\n// ---------------------------------------------------------------------------\n\n/**\n * Run the full deduplication pipeline.\n *\n * Steps:\n * 1. Add __row_id__ and __source__ if not present\n * 2. Apply standardization\n * 3. Compute matchkeys\n * 4. Phase 1: Exact matchkeys (hash-based grouping)\n * 5. Phase 2: Fuzzy matchkeys (block + score)\n * 6. Phase 3: Cluster (Union-Find with MST splitting)\n * 7. Phase 4: Build golden records for multi-member clusters\n * 8. Classify dupes vs unique\n * 9. Compute stats\n * 10. Return DedupeResult\n */\nexport function runDedupePipeline(\n rows: readonly Row[],\n config: GoldenMatchConfig,\n options?: DedupeOptions,\n): DedupeResult {\n if (rows.length === 0) {\n return _emptyDedupeResult(config);\n }\n\n const matchkeys = getMatchkeys(config);\n const goldenRules = config.goldenRules ?? makeGoldenRulesConfig();\n const blockingConfig = config.blocking ?? makeBlockingConfig();\n const acrossFilesOnly = options?.acrossFilesOnly ?? false;\n\n // ---- Step 1: Add __row_id__ and __source__ ----\n let processed: Row[] = rows.map((r, i) => {\n const extra: Record<string, unknown> = {};\n if (r.__row_id__ === undefined) extra.__row_id__ = i;\n if (r.__source__ === undefined) extra.__source__ = \"default\";\n return Object.keys(extra).length > 0 ? { ...r, ...extra } : (r as Row);\n });\n\n // ---- Step 2: Apply standardization ----\n if (config.standardization) {\n processed = applyStandardization(processed, config.standardization.rules);\n }\n\n // ---- Step 3: Compute matchkeys ----\n processed = computeMatchkeys(processed, matchkeys);\n\n // ---- Step 4 & 5: Score exact + fuzzy matchkeys ----\n const allPairs: ScoredPair[] = [];\n const matchedPairKeys = new Set<PairKey>();\n const sourceLookup = buildSourceLookup(processed);\n\n for (const mk of matchkeys) {\n if (mk.type === \"exact\") {\n // Phase 1: Exact matching via hash grouping\n let pairs = findExactMatches(processed, mk);\n\n // Cross-file filter\n if (acrossFilesOnly) {\n pairs = pairs.filter((p) => {\n const srcA = sourceLookup.get(p.idA);\n const srcB = sourceLookup.get(p.idB);\n return srcA !== srcB;\n });\n }\n\n for (const p of pairs) {\n const key = pairKey(p.idA, p.idB);\n if (!matchedPairKeys.has(key)) {\n matchedPairKeys.add(key);\n allPairs.push(p);\n }\n }\n } else {\n // Phase 2: Fuzzy (weighted/probabilistic) — block then score\n const blocks = buildBlocks(processed, blockingConfig);\n\n const pairs = scoreBlocksSequential(blocks, mk, matchedPairKeys, {\n acrossFilesOnly,\n sourceLookup,\n });\n\n for (const p of pairs) {\n allPairs.push(p);\n }\n }\n }\n\n // ---- Step 6: Cluster ----\n const allIds = collectRowIds(processed);\n const pairTuples: [number, number, number][] = allPairs.map((p) => [\n p.idA,\n p.idB,\n p.score,\n ]);\n\n const clusters = buildClusters(pairTuples, allIds, {\n maxClusterSize: goldenRules.maxClusterSize,\n weakClusterThreshold: goldenRules.weakClusterThreshold,\n autoSplit: goldenRules.autoSplit,\n });\n\n // ---- Step 7: Build golden records ----\n const rowsWithClusters = assignClusterIds(processed, clusters);\n const goldenRecords: Row[] = [];\n\n if (options?.outputGolden !== false) {\n for (const [cid, cinfo] of clusters) {\n if (cinfo.size < 2) continue; // Only build golden for multi-member clusters\n\n const clusterRows = rowsWithClusters.filter(\n (r) => (r.__cluster_id__ as number) === cid,\n );\n const golden = buildGoldenRecord(clusterRows, goldenRules);\n\n const goldenRow: Record<string, unknown> = {\n __cluster_id__: cid,\n __golden_confidence__: golden.goldenConfidence,\n };\n for (const [col, info] of Object.entries(golden.fields)) {\n goldenRow[col] = info.value;\n }\n goldenRecords.push(goldenRow as Row);\n }\n }\n\n // ---- Step 8: Classify dupes vs unique ----\n const multiMemberClusterIds = new Set<number>();\n for (const [cid, cinfo] of clusters) {\n if (cinfo.size >= 2) multiMemberClusterIds.add(cid);\n }\n\n const dupeRowIds = new Set<number>();\n for (const [, cinfo] of clusters) {\n if (cinfo.size >= 2) {\n for (const m of cinfo.members) {\n dupeRowIds.add(m);\n }\n }\n }\n\n const dupes: Row[] = [];\n const unique: Row[] = [];\n for (const row of rowsWithClusters) {\n const rowId = row.__row_id__ as number;\n if (dupeRowIds.has(rowId)) {\n dupes.push(row);\n } else {\n unique.push(row);\n }\n }\n\n // ---- Step 9: Compute stats ----\n const totalRecords = processed.length;\n const totalClusters = clusters.size;\n const matchedRecords = dupes.length;\n const uniqueRecords = unique.length;\n const matchRate = totalRecords > 0 ? matchedRecords / totalRecords : 0;\n\n const stats: DedupeStats = {\n totalRecords,\n totalClusters,\n matchRate,\n matchedRecords,\n uniqueRecords,\n };\n\n // ---- Step 10: Return result ----\n return {\n goldenRecords,\n clusters,\n dupes,\n unique,\n stats,\n scoredPairs: allPairs,\n config,\n };\n}\n\n// ---------------------------------------------------------------------------\n// runMatchPipeline\n// ---------------------------------------------------------------------------\n\n/**\n * Run the match pipeline: match target rows against reference rows.\n *\n * - Assigns __row_id__ with offset for reference rows\n * - Assigns __source__ (\"target\" / \"reference\")\n * - Runs same pipeline but filters to cross-source pairs only\n */\nexport function runMatchPipeline(\n targetRows: readonly Row[],\n referenceRows: readonly Row[],\n config: GoldenMatchConfig,\n): MatchResult {\n if (targetRows.length === 0 || referenceRows.length === 0) {\n return {\n matched: [],\n unmatched: [...targetRows],\n stats: {\n totalTarget: targetRows.length,\n totalReference: referenceRows.length,\n matchedCount: 0,\n unmatchedCount: targetRows.length,\n matchRate: 0,\n },\n };\n }\n\n // Add row IDs and source labels\n const target = addSourceColumn(addRowIds(targetRows, 0), \"target\");\n const reference = addSourceColumn(\n addRowIds(referenceRows, targetRows.length),\n \"reference\",\n );\n\n // Combine and run dedupe pipeline with cross-file filter\n const combined = [...target, ...reference];\n const result = runDedupePipeline(combined, config, {\n acrossFilesOnly: true,\n outputGolden: false,\n });\n\n // Track which target row IDs got matched\n const targetIds = new Set<number>(\n target.map((r) => r.__row_id__ as number),\n );\n const matchedTargetIds = new Set<number>();\n\n for (const pair of result.scoredPairs) {\n if (targetIds.has(pair.idA)) matchedTargetIds.add(pair.idA);\n if (targetIds.has(pair.idB)) matchedTargetIds.add(pair.idB);\n }\n\n // Build matched/unmatched from original target rows\n const matched: Row[] = [];\n const unmatched: Row[] = [];\n for (const row of target) {\n const rowId = row.__row_id__ as number;\n if (matchedTargetIds.has(rowId)) {\n matched.push(row);\n } else {\n unmatched.push(row);\n }\n }\n\n return {\n matched,\n unmatched,\n stats: {\n totalTarget: targetRows.length,\n totalReference: referenceRows.length,\n matchedCount: matched.length,\n unmatchedCount: unmatched.length,\n matchRate:\n targetRows.length > 0 ? matched.length / targetRows.length : 0,\n },\n };\n}\n\n// ---------------------------------------------------------------------------\n// Internal: empty result\n// ---------------------------------------------------------------------------\n\nfunction _emptyDedupeResult(config: GoldenMatchConfig): DedupeResult {\n return {\n goldenRecords: [],\n clusters: new Map(),\n dupes: [],\n unique: [],\n stats: {\n totalRecords: 0,\n totalClusters: 0,\n matchRate: 0,\n matchedRecords: 0,\n uniqueRecords: 0,\n },\n scoredPairs: [],\n config,\n };\n}\n","/**\n * api.ts — High-level API functions wrapping the pipeline.\n * Edge-safe: no `node:` imports, pure TypeScript only.\n *\n * Ports goldenmatch/_api.py convenience functions.\n */\n\nimport type {\n Row,\n GoldenMatchConfig,\n DedupeResult,\n MatchResult,\n MatchkeyConfig,\n MatchkeyField,\n BlockingKeyConfig,\n} from \"./types.js\";\nimport {\n makeConfig,\n makeMatchkeyConfig,\n makeMatchkeyField,\n makeBlockingConfig,\n} from \"./types.js\";\nimport { runDedupePipeline, runMatchPipeline } from \"./pipeline.js\";\nimport { scoreField, scorePair, asString } from \"./scorer.js\";\nimport { applyTransforms } from \"./transforms.js\";\n\n// ---------------------------------------------------------------------------\n// Options\n// ---------------------------------------------------------------------------\n\nexport interface DedupeOptions {\n /** Full config object -- takes precedence over shorthand options. */\n readonly config?: GoldenMatchConfig;\n /** Columns for exact matching (creates one exact matchkey per column). */\n readonly exact?: readonly string[];\n /** Columns for fuzzy matching with per-field thresholds. */\n readonly fuzzy?: Readonly<Record<string, number>>;\n /** Blocking key columns (lowercase transform applied). */\n readonly blocking?: readonly string[];\n /** Overall fuzzy threshold (default 0.85). */\n readonly threshold?: number;\n /** Enable LLM scorer for borderline pairs. Requires OPENAI_API_KEY or ANTHROPIC_API_KEY in env. */\n readonly llmScorer?: boolean;\n}\n\n// ---------------------------------------------------------------------------\n// Build config from shorthand options\n// ---------------------------------------------------------------------------\n\nfunction buildConfigFromOptions(options?: DedupeOptions): GoldenMatchConfig {\n if (options?.config) return options.config;\n\n const matchkeys: MatchkeyConfig[] = [];\n const threshold = options?.threshold ?? 0.85;\n\n // Exact matchkeys: one per column\n if (options?.exact) {\n for (const col of options.exact) {\n matchkeys.push(\n makeMatchkeyConfig({\n name: `exact_${col}`,\n type: \"exact\",\n fields: [\n makeMatchkeyField({\n field: col,\n transforms: [\"lowercase\", \"strip\"],\n scorer: \"exact\",\n }),\n ],\n }),\n );\n }\n }\n\n // Fuzzy matchkey: all fuzzy columns combined into one weighted matchkey\n if (options?.fuzzy) {\n const fuzzyEntries = Object.entries(options.fuzzy);\n if (fuzzyEntries.length > 0) {\n const fields: MatchkeyField[] = fuzzyEntries.map(([col, weight]) =>\n makeMatchkeyField({\n field: col,\n transforms: [\"lowercase\", \"strip\"],\n scorer: \"jaro_winkler\",\n weight,\n }),\n );\n matchkeys.push(\n makeMatchkeyConfig({\n name: \"fuzzy_combined\",\n type: \"weighted\",\n fields,\n threshold,\n }),\n );\n }\n }\n\n // Blocking config\n let blocking = makeBlockingConfig();\n if (options?.blocking && options.blocking.length > 0) {\n const keys: BlockingKeyConfig[] = options.blocking.map((col) => ({\n fields: [col],\n transforms: [\"lowercase\", \"strip\"],\n }));\n blocking = makeBlockingConfig({ keys });\n }\n\n const partial: Partial<GoldenMatchConfig> = {\n blocking,\n threshold,\n };\n if (matchkeys.length > 0) {\n (partial as Record<string, unknown>).matchkeys = matchkeys;\n }\n if (options?.llmScorer) {\n (partial as Record<string, unknown>).llmScorer = {\n enabled: true,\n autoThreshold: 0.9,\n candidateLo: 0.6,\n candidateHi: 0.9,\n batchSize: 10,\n maxWorkers: 4,\n mode: \"pairwise\",\n };\n }\n return makeConfig(partial);\n}\n\n// ---------------------------------------------------------------------------\n// Public API: dedupe\n// ---------------------------------------------------------------------------\n\n/**\n * Deduplicate an array of row objects.\n *\n * Shorthand usage:\n * ```ts\n * const result = dedupe(rows, {\n * exact: [\"email\"],\n * fuzzy: { name: 0.85, address: 0.7 },\n * blocking: [\"zip\"],\n * threshold: 0.85,\n * });\n * ```\n *\n * Or provide a full config:\n * ```ts\n * const result = dedupe(rows, { config: myConfig });\n * ```\n */\nexport function dedupe(\n rows: readonly Row[],\n options?: DedupeOptions,\n): DedupeResult {\n const config = buildConfigFromOptions(options);\n return runDedupePipeline(rows, config);\n}\n\n// ---------------------------------------------------------------------------\n// Public API: match\n// ---------------------------------------------------------------------------\n\n/**\n * Match target rows against reference rows.\n *\n * Same options as `dedupe()`. Returns matched/unmatched target rows.\n */\nexport function match(\n target: readonly Row[],\n reference: readonly Row[],\n options?: DedupeOptions,\n): MatchResult {\n const config = buildConfigFromOptions(options);\n return runMatchPipeline(target, reference, config);\n}\n\n// ---------------------------------------------------------------------------\n// Public API: scoreStrings\n// ---------------------------------------------------------------------------\n\n/**\n * Score two strings using the specified scorer algorithm.\n *\n * @param a - First string.\n * @param b - Second string.\n * @param scorer - Scorer name (default: \"jaro_winkler\").\n * Valid scorers: exact, jaro_winkler, levenshtein, token_sort,\n * soundex_match, dice, jaccard, ensemble.\n * @returns Similarity score between 0.0 and 1.0.\n */\nexport function scoreStrings(\n a: string,\n b: string,\n scorer: string = \"jaro_winkler\",\n): number {\n const result = scoreField(a, b, scorer);\n return result ?? 0.0;\n}\n\n// ---------------------------------------------------------------------------\n// Public API: scorePairRecord\n// ---------------------------------------------------------------------------\n\n/**\n * Score a pair of row objects across specified fields using weighted\n * aggregation.\n *\n * @param rowA - First row.\n * @param rowB - Second row.\n * @param fields - Field configs specifying which fields to compare,\n * transforms to apply, scorer to use, and weight.\n * @returns Weighted similarity score between 0.0 and 1.0.\n */\nexport function scorePairRecord(\n rowA: Row,\n rowB: Row,\n fields: readonly MatchkeyField[],\n): number {\n return scorePair(rowA, rowB, fields);\n}\n","/**\n * config/loader.ts — Config loader that parses raw objects (from YAML/JSON)\n * into typed GoldenMatchConfig.\n *\n * Edge-safe: no `node:` imports, no `require()`.\n */\n\nimport type {\n GoldenMatchConfig,\n MatchkeyConfig,\n MatchkeyField,\n BlockingConfig,\n BlockingKeyConfig,\n GoldenRulesConfig,\n GoldenFieldRule,\n StandardizationConfig,\n LLMScorerConfig,\n BudgetConfig,\n ValidationConfig,\n ValidationRuleConfig,\n DomainConfig,\n QualityConfig,\n TransformConfig,\n MemoryConfig,\n LearningConfig,\n InputConfig,\n InputFileConfig,\n OutputConfig,\n SortKeyField,\n CanopyConfig,\n} from \"../types.js\";\nimport {\n VALID_SCORERS,\n VALID_TRANSFORMS,\n VALID_STRATEGIES,\n VALID_STANDARDIZERS,\n} from \"../types.js\";\n\n// ---------------------------------------------------------------------------\n// String-union validation\n// ---------------------------------------------------------------------------\n\nconst VALID_MATCHKEY_TYPES = new Set([\n \"exact\",\n \"weighted\",\n \"probabilistic\",\n] as const);\n\nconst VALID_BLOCKING_STRATEGIES = new Set([\n \"static\",\n \"adaptive\",\n \"sorted_neighborhood\",\n \"multi_pass\",\n \"ann\",\n \"canopy\",\n \"ann_pairs\",\n \"learned\",\n] as const);\n\nconst VALID_MEMORY_BACKENDS = new Set([\"sqlite\", \"postgres\"] as const);\n\nconst VALID_QUALITY_MODES = new Set([\n \"silent\",\n \"announced\",\n \"disabled\",\n] as const);\n\nconst VALID_QUALITY_FIX_MODES = new Set([\"safe\", \"moderate\", \"none\"] as const);\n\nconst VALID_LLM_MODES = new Set([\"pairwise\", \"cluster\"] as const);\n\nconst VALID_VALIDATION_RULE_TYPES = new Set([\n \"regex\",\n \"min_length\",\n \"max_length\",\n \"not_null\",\n \"in_set\",\n \"format\",\n] as const);\n\nconst VALID_VALIDATION_ACTIONS = new Set([\n \"null\",\n \"quarantine\",\n \"flag\",\n] as const);\n\n/**\n * Validate that `value` is one of `allowed`. If `defaultValue` is provided,\n * return it when `value` is null/undefined. Throws a clear error otherwise.\n */\nfunction requireIn<T extends string>(\n value: unknown,\n allowed: ReadonlySet<T>,\n fieldName: string,\n defaultValue?: T,\n): T {\n if (value === undefined || value === null) {\n if (defaultValue !== undefined) return defaultValue;\n throw new Error(`Required field '${fieldName}' is missing`);\n }\n if (typeof value !== \"string\" || !(allowed as ReadonlySet<string>).has(value)) {\n const valid = [...allowed].sort().join(\", \");\n throw new Error(\n `Invalid value '${String(value)}' for '${fieldName}'. Valid options: ${valid}`,\n );\n }\n return value as T;\n}\n\n/**\n * Accept known transforms plus parametric forms:\n * - substring:<n>:<n>\n * - qgram:<n>\n * - bloom_filter, bloom_filter:<...>\n */\nfunction isValidTransform(t: string): boolean {\n if ((VALID_TRANSFORMS as ReadonlySet<string>).has(t)) return true;\n if (/^substring:\\d+:\\d+$/.test(t)) return true;\n if (/^qgram:\\d+$/.test(t)) return true;\n if (t === \"bloom_filter\" || /^bloom_filter:/.test(t)) return true;\n return false;\n}\n\n// ---------------------------------------------------------------------------\n// Snake_case to camelCase conversion\n// ---------------------------------------------------------------------------\n\n/** Convert a snake_case key to camelCase. */\nfunction snakeToCamel(s: string): string {\n return s.replace(/_([a-z])/g, (_, c: string) => c.toUpperCase());\n}\n\n/** Recursively convert all keys of a plain object from snake_case to camelCase. */\nfunction camelizeKeys(obj: unknown): unknown {\n if (obj === null || obj === undefined) return obj;\n if (Array.isArray(obj)) return obj.map(camelizeKeys);\n if (typeof obj === \"object\") {\n const result: Record<string, unknown> = {};\n for (const [key, val] of Object.entries(obj as Record<string, unknown>)) {\n result[snakeToCamel(key)] = camelizeKeys(val);\n }\n return result;\n }\n return obj;\n}\n\n/** Recursively convert all keys from camelCase to snake_case. */\nfunction camelToSnake(s: string): string {\n return s.replace(/[A-Z]/g, (c) => `_${c.toLowerCase()}`);\n}\n\nfunction snakeifyKeys(obj: unknown): unknown {\n if (obj === null || obj === undefined) return obj;\n if (Array.isArray(obj)) return obj.map(snakeifyKeys);\n if (typeof obj === \"object\") {\n const result: Record<string, unknown> = {};\n for (const [key, val] of Object.entries(obj as Record<string, unknown>)) {\n result[camelToSnake(key)] = snakeifyKeys(val);\n }\n return result;\n }\n return obj;\n}\n\n// ---------------------------------------------------------------------------\n// Helpers: strip undefined values for exactOptionalPropertyTypes\n// ---------------------------------------------------------------------------\n\n/**\n * Remove keys whose value is `undefined` from a plain object.\n * Required because TypeScript's `exactOptionalPropertyTypes` disallows\n * assigning `undefined` to optional properties.\n */\nfunction stripUndefined<T extends Record<string, unknown>>(obj: T): T {\n const result = {} as Record<string, unknown>;\n for (const [k, v] of Object.entries(obj)) {\n if (v !== undefined) result[k] = v;\n }\n return result as T;\n}\n\n// ---------------------------------------------------------------------------\n// Helpers: safe getters\n// ---------------------------------------------------------------------------\n\ntype RawObj = Record<string, unknown>;\n\nfunction asObj(v: unknown, ctx: string): RawObj {\n if (typeof v !== \"object\" || v === null || Array.isArray(v)) {\n throw new Error(`${ctx}: expected object, got ${typeof v}`);\n }\n return v as RawObj;\n}\n\nfunction asArr(v: unknown, ctx: string): unknown[] {\n if (!Array.isArray(v)) {\n throw new Error(`${ctx}: expected array, got ${typeof v}`);\n }\n return v;\n}\n\nfunction asStr(v: unknown, ctx: string): string {\n if (typeof v !== \"string\") {\n throw new Error(`${ctx}: expected string, got ${typeof v}`);\n }\n return v;\n}\n\nfunction asNum(v: unknown, ctx: string): number {\n if (typeof v !== \"number\") {\n throw new Error(`${ctx}: expected number, got ${typeof v}`);\n }\n return v;\n}\n\nfunction asBool(v: unknown, ctx: string): boolean {\n if (typeof v !== \"boolean\") {\n throw new Error(`${ctx}: expected boolean, got ${typeof v}`);\n }\n return v;\n}\n\nfunction optStr(v: unknown): string | undefined {\n return typeof v === \"string\" ? v : undefined;\n}\n\nfunction optNum(v: unknown): number | undefined {\n return typeof v === \"number\" ? v : undefined;\n}\n\nfunction optBool(v: unknown): boolean | undefined {\n return typeof v === \"boolean\" ? v : undefined;\n}\n\n// ---------------------------------------------------------------------------\n// Parsers for nested config objects\n// ---------------------------------------------------------------------------\n\nfunction parseMatchkeyField(raw: unknown, ctx: string): MatchkeyField {\n const obj = asObj(raw, ctx);\n const fieldName = typeof obj.field === \"string\" ? obj.field : \"<unknown>\";\n\n // Validate transforms. Allow parametric forms like \"substring:0:3\", \"qgram:3\",\n // \"bloom_filter:high\".\n const transforms: string[] = Array.isArray(obj.transforms)\n ? (obj.transforms as unknown[]).map((t, i) => {\n if (typeof t !== \"string\") {\n throw new Error(\n `${ctx}.transforms[${i}]: expected string, got ${typeof t}`,\n );\n }\n return t;\n })\n : [];\n for (const t of transforms) {\n if (!isValidTransform(t)) {\n const valid = [...VALID_TRANSFORMS].sort().join(\", \");\n throw new Error(\n `Invalid transform '${t}' on field '${fieldName}'. ` +\n `Valid: ${valid}, or 'substring:<n>:<n>', 'qgram:<n>', 'bloom_filter[:...]'.`,\n );\n }\n }\n\n // Scorer is optional for exact matchkeys. Allow plugin scorers — warn only\n // if the name is unknown (plugin registration may fill it in later).\n if (obj.scorer !== undefined && obj.scorer !== null) {\n if (\n typeof obj.scorer !== \"string\" ||\n !(VALID_SCORERS as ReadonlySet<string>).has(obj.scorer)\n ) {\n // eslint-disable-next-line no-console\n console.warn(\n `Unknown scorer '${String(obj.scorer)}' on field '${fieldName}' ` +\n `(will be rejected at score-time if no plugin is registered).`,\n );\n }\n }\n\n return stripUndefined({\n field: asStr(obj.field, `${ctx}.field`),\n transforms,\n scorer: typeof obj.scorer === \"string\" ? obj.scorer : \"jaro_winkler\",\n weight: typeof obj.weight === \"number\" ? obj.weight : 1.0,\n model: optStr(obj.model),\n columns: Array.isArray(obj.columns)\n ? (obj.columns as string[])\n : undefined,\n columnWeights:\n typeof obj.columnWeights === \"object\" && obj.columnWeights !== null\n ? (obj.columnWeights as Record<string, number>)\n : undefined,\n levels: optNum(obj.levels),\n partialThreshold: optNum(obj.partialThreshold),\n }) as MatchkeyField;\n}\n\nfunction parseMatchkeyConfig(raw: unknown, ctx: string): MatchkeyConfig {\n const obj = asObj(raw, ctx);\n const fields = Array.isArray(obj.fields)\n ? obj.fields.map((f: unknown, i: number) =>\n parseMatchkeyField(f, `${ctx}.fields[${i}]`),\n )\n : [];\n\n const name = asStr(obj.name, `${ctx}.name`);\n const type = requireIn(\n obj.type,\n VALID_MATCHKEY_TYPES,\n `${ctx}.type`,\n \"weighted\",\n ) as \"exact\" | \"weighted\" | \"probabilistic\";\n\n if (type === \"exact\") {\n return { name, type: \"exact\", fields };\n }\n if (type === \"probabilistic\") {\n return stripUndefined({\n name,\n type: \"probabilistic\" as const,\n fields,\n threshold: optNum(obj.threshold),\n emIterations: optNum(obj.emIterations),\n convergenceThreshold: optNum(obj.convergenceThreshold),\n linkThreshold: optNum(obj.linkThreshold),\n reviewThreshold: optNum(obj.reviewThreshold),\n }) as MatchkeyConfig;\n }\n // weighted\n return stripUndefined({\n name,\n type: \"weighted\" as const,\n fields,\n threshold: optNum(obj.threshold) ?? 0.85,\n autoThreshold: optBool(obj.autoThreshold),\n rerank: optBool(obj.rerank),\n rerankModel: optStr(obj.rerankModel),\n rerankBand: optNum(obj.rerankBand),\n }) as MatchkeyConfig;\n}\n\nfunction parseBlockingKeyConfig(\n raw: unknown,\n ctx: string,\n): BlockingKeyConfig {\n const obj = asObj(raw, ctx);\n return {\n fields: Array.isArray(obj.fields) ? (obj.fields as string[]) : [],\n transforms: Array.isArray(obj.transforms)\n ? (obj.transforms as string[])\n : [],\n };\n}\n\nfunction parseSortKeyField(raw: unknown, ctx: string): SortKeyField {\n const obj = asObj(raw, ctx);\n return {\n column: asStr(obj.column, `${ctx}.column`),\n transforms: Array.isArray(obj.transforms)\n ? (obj.transforms as string[])\n : [],\n };\n}\n\nfunction parseCanopyConfig(raw: unknown, ctx: string): CanopyConfig {\n const obj = asObj(raw, ctx);\n return {\n fields: Array.isArray(obj.fields) ? (obj.fields as string[]) : [],\n looseThreshold: typeof obj.looseThreshold === \"number\" ? obj.looseThreshold : 0.7,\n tightThreshold: typeof obj.tightThreshold === \"number\" ? obj.tightThreshold : 0.9,\n maxCanopySize: typeof obj.maxCanopySize === \"number\" ? obj.maxCanopySize : 1000,\n };\n}\n\nfunction parseBlockingConfig(raw: unknown, ctx: string): BlockingConfig {\n const obj = asObj(raw, ctx);\n const keys = Array.isArray(obj.keys)\n ? obj.keys.map((k: unknown, i: number) =>\n parseBlockingKeyConfig(k, `${ctx}.keys[${i}]`),\n )\n : [];\n const passes = Array.isArray(obj.passes)\n ? obj.passes.map((p: unknown, i: number) =>\n parseBlockingKeyConfig(p, `${ctx}.passes[${i}]`),\n )\n : undefined;\n const subBlockKeys = Array.isArray(obj.subBlockKeys)\n ? obj.subBlockKeys.map((k: unknown, i: number) =>\n parseBlockingKeyConfig(k, `${ctx}.subBlockKeys[${i}]`),\n )\n : undefined;\n const sortKey = Array.isArray(obj.sortKey)\n ? obj.sortKey.map((s: unknown, i: number) =>\n parseSortKeyField(s, `${ctx}.sortKey[${i}]`),\n )\n : undefined;\n const canopy =\n typeof obj.canopy === \"object\" && obj.canopy !== null\n ? parseCanopyConfig(obj.canopy, `${ctx}.canopy`)\n : undefined;\n\n return stripUndefined({\n strategy: requireIn(\n obj.strategy,\n VALID_BLOCKING_STRATEGIES,\n `${ctx}.strategy`,\n \"static\",\n ),\n keys,\n maxBlockSize:\n typeof obj.maxBlockSize === \"number\" ? obj.maxBlockSize : 5000,\n skipOversized:\n typeof obj.skipOversized === \"boolean\" ? obj.skipOversized : false,\n autoSuggest: optBool(obj.autoSuggest),\n autoSelect: optBool(obj.autoSelect),\n subBlockKeys,\n windowSize: optNum(obj.windowSize),\n sortKey,\n passes,\n unionMode: optBool(obj.unionMode),\n maxTotalComparisons: optNum(obj.maxTotalComparisons),\n annColumn: optStr(obj.annColumn),\n annModel: optStr(obj.annModel),\n annTopK: optNum(obj.annTopK),\n canopy,\n learnedSampleSize: optNum(obj.learnedSampleSize),\n learnedMinRecall: optNum(obj.learnedMinRecall),\n learnedMinReduction: optNum(obj.learnedMinReduction),\n learnedPredicateDepth: optNum(obj.learnedPredicateDepth),\n learnedCachePath: optStr(obj.learnedCachePath),\n }) as BlockingConfig;\n}\n\nfunction parseGoldenFieldRule(raw: unknown, ctx: string): GoldenFieldRule {\n const obj = asObj(raw, ctx);\n return stripUndefined({\n strategy: requireIn(\n obj.strategy,\n VALID_STRATEGIES,\n `${ctx}.strategy`,\n ) as GoldenFieldRule[\"strategy\"],\n dateColumn: optStr(obj.dateColumn),\n sourcePriority: Array.isArray(obj.sourcePriority)\n ? (obj.sourcePriority as string[])\n : undefined,\n }) as GoldenFieldRule;\n}\n\nfunction parseGoldenRulesConfig(\n raw: unknown,\n ctx: string,\n): GoldenRulesConfig {\n const obj = asObj(raw, ctx);\n\n // Normalize: YAML uses `default`, TS interface uses `defaultStrategy`\n const defaultStrategy =\n typeof obj.defaultStrategy === \"string\"\n ? obj.defaultStrategy\n : typeof obj.default === \"string\"\n ? obj.default\n : \"most_complete\";\n\n const fieldRules: Record<string, GoldenFieldRule> = {};\n if (\n typeof obj.fieldRules === \"object\" &&\n obj.fieldRules !== null &&\n !Array.isArray(obj.fieldRules)\n ) {\n for (const [key, val] of Object.entries(\n obj.fieldRules as Record<string, unknown>,\n )) {\n fieldRules[key] = parseGoldenFieldRule(val, `${ctx}.fieldRules.${key}`);\n }\n }\n\n return {\n defaultStrategy,\n fieldRules,\n maxClusterSize:\n typeof obj.maxClusterSize === \"number\" ? obj.maxClusterSize : 10,\n autoSplit:\n typeof obj.autoSplit === \"boolean\" ? obj.autoSplit : true,\n qualityWeighting:\n typeof obj.qualityWeighting === \"boolean\"\n ? obj.qualityWeighting\n : true,\n weakClusterThreshold:\n typeof obj.weakClusterThreshold === \"number\"\n ? obj.weakClusterThreshold\n : 0.3,\n };\n}\n\nfunction parseStandardizationConfig(\n raw: unknown,\n ctx: string,\n): StandardizationConfig {\n const obj = asObj(raw, ctx);\n\n // Normalize: in YAML the rules may be at top level or nested under `rules`\n let rulesObj: Record<string, unknown>;\n if (\n typeof obj.rules === \"object\" &&\n obj.rules !== null &&\n !Array.isArray(obj.rules)\n ) {\n rulesObj = obj.rules as Record<string, unknown>;\n } else {\n // Flat form: each key is a column name mapping to standardizers\n rulesObj = obj;\n }\n\n const rules: Record<string, readonly string[]> = {};\n for (const [key, val] of Object.entries(rulesObj)) {\n if (Array.isArray(val)) {\n const arr = val as unknown[];\n for (const rule of arr) {\n if (typeof rule !== \"string\") {\n throw new Error(\n `${ctx}.${key}: expected array of strings, got ${typeof rule}`,\n );\n }\n if (!(VALID_STANDARDIZERS as ReadonlySet<string>).has(rule)) {\n const valid = [...VALID_STANDARDIZERS].sort().join(\", \");\n throw new Error(\n `Invalid standardizer '${rule}' on column '${key}'. Valid: ${valid}`,\n );\n }\n }\n rules[key] = arr as string[];\n }\n }\n\n return { rules };\n}\n\nfunction parseBudgetConfig(raw: unknown, ctx: string): BudgetConfig {\n const obj = asObj(raw, ctx);\n return stripUndefined({\n maxCostUsd: optNum(obj.maxCostUsd),\n maxCalls: optNum(obj.maxCalls),\n escalationModel: optStr(obj.escalationModel),\n escalationBand: Array.isArray(obj.escalationBand)\n ? (obj.escalationBand as number[])\n : undefined,\n escalationBudgetPct: optNum(obj.escalationBudgetPct),\n warnAtPct: optNum(obj.warnAtPct),\n }) as BudgetConfig;\n}\n\nfunction parseLLMScorerConfig(\n raw: unknown,\n ctx: string,\n): LLMScorerConfig {\n const obj = asObj(raw, ctx);\n return stripUndefined({\n enabled: typeof obj.enabled === \"boolean\" ? obj.enabled : false,\n provider: optStr(obj.provider),\n model: optStr(obj.model),\n autoThreshold:\n typeof obj.autoThreshold === \"number\" ? obj.autoThreshold : 0.9,\n candidateLo:\n typeof obj.candidateLo === \"number\" ? obj.candidateLo : 0.6,\n candidateHi:\n typeof obj.candidateHi === \"number\" ? obj.candidateHi : 0.9,\n batchSize:\n typeof obj.batchSize === \"number\" ? obj.batchSize : 10,\n maxWorkers:\n typeof obj.maxWorkers === \"number\" ? obj.maxWorkers : 4,\n budget:\n typeof obj.budget === \"object\" && obj.budget !== null\n ? parseBudgetConfig(obj.budget, `${ctx}.budget`)\n : undefined,\n mode: requireIn(obj.mode, VALID_LLM_MODES, `${ctx}.mode`, \"pairwise\"),\n clusterMaxSize: optNum(obj.clusterMaxSize),\n clusterMinSize: optNum(obj.clusterMinSize),\n }) as LLMScorerConfig;\n}\n\nfunction parseValidationRuleConfig(\n raw: unknown,\n ctx: string,\n): ValidationRuleConfig {\n const obj = asObj(raw, ctx);\n return {\n column: asStr(obj.column, `${ctx}.column`),\n ruleType: requireIn(\n obj.ruleType,\n VALID_VALIDATION_RULE_TYPES,\n `${ctx}.ruleType`,\n ),\n params:\n typeof obj.params === \"object\" && obj.params !== null\n ? (obj.params as Record<string, unknown>)\n : {},\n action: requireIn(\n obj.action,\n VALID_VALIDATION_ACTIONS,\n `${ctx}.action`,\n \"flag\",\n ),\n };\n}\n\nfunction parseValidationConfig(\n raw: unknown,\n ctx: string,\n): ValidationConfig {\n const obj = asObj(raw, ctx);\n return {\n rules: Array.isArray(obj.rules)\n ? obj.rules.map((r: unknown, i: number) =>\n parseValidationRuleConfig(r, `${ctx}.rules[${i}]`),\n )\n : [],\n autoFix: typeof obj.autoFix === \"boolean\" ? obj.autoFix : false,\n };\n}\n\nfunction parseDomainConfig(raw: unknown, ctx: string): DomainConfig {\n const obj = asObj(raw, ctx);\n return stripUndefined({\n enabled: typeof obj.enabled === \"boolean\" ? obj.enabled : false,\n mode: optStr(obj.mode),\n confidenceThreshold:\n typeof obj.confidenceThreshold === \"number\"\n ? obj.confidenceThreshold\n : 0.8,\n llmValidation:\n typeof obj.llmValidation === \"boolean\" ? obj.llmValidation : false,\n budget:\n typeof obj.budget === \"object\" && obj.budget !== null\n ? parseBudgetConfig(obj.budget, `${ctx}.budget`)\n : undefined,\n }) as DomainConfig;\n}\n\nfunction parseQualityConfig(raw: unknown, ctx: string): QualityConfig {\n const obj = asObj(raw, ctx);\n return stripUndefined({\n enabled: typeof obj.enabled === \"boolean\" ? obj.enabled : true,\n mode: requireIn(obj.mode, VALID_QUALITY_MODES, `${ctx}.mode`, \"silent\"),\n fixMode: requireIn(\n obj.fixMode,\n VALID_QUALITY_FIX_MODES,\n `${ctx}.fixMode`,\n \"safe\",\n ),\n domain: optStr(obj.domain),\n }) as QualityConfig;\n}\n\nfunction parseTransformConfig(raw: unknown, ctx: string): TransformConfig {\n const obj = asObj(raw, ctx);\n return {\n enabled: typeof obj.enabled === \"boolean\" ? obj.enabled : true,\n mode: requireIn(obj.mode, VALID_QUALITY_MODES, `${ctx}.mode`, \"silent\"),\n };\n}\n\nfunction parseLearningConfig(raw: unknown, ctx: string): LearningConfig {\n const obj = asObj(raw, ctx);\n return {\n thresholdMinCorrections:\n typeof obj.thresholdMinCorrections === \"number\"\n ? obj.thresholdMinCorrections\n : 10,\n weightsMinCorrections:\n typeof obj.weightsMinCorrections === \"number\"\n ? obj.weightsMinCorrections\n : 50,\n };\n}\n\nfunction parseMemoryConfig(raw: unknown, ctx: string): MemoryConfig {\n const obj = asObj(raw, ctx);\n return stripUndefined({\n enabled: typeof obj.enabled === \"boolean\" ? obj.enabled : false,\n backend: requireIn(\n obj.backend,\n VALID_MEMORY_BACKENDS,\n `${ctx}.backend`,\n \"sqlite\",\n ),\n path: optStr(obj.path),\n trust: typeof obj.trust === \"number\" ? obj.trust : 0.9,\n learning:\n typeof obj.learning === \"object\" && obj.learning !== null\n ? parseLearningConfig(obj.learning, `${ctx}.learning`)\n : { thresholdMinCorrections: 10, weightsMinCorrections: 50 },\n }) as MemoryConfig;\n}\n\nfunction parseInputFileConfig(\n raw: unknown,\n ctx: string,\n): InputFileConfig {\n const obj = asObj(raw, ctx);\n return stripUndefined({\n path: asStr(obj.path, `${ctx}.path`),\n idColumn: optStr(obj.idColumn),\n sourceLabel: optStr(obj.sourceLabel),\n sourceName: optStr(obj.sourceName),\n columnMap:\n typeof obj.columnMap === \"object\" && obj.columnMap !== null\n ? (obj.columnMap as Record<string, string>)\n : undefined,\n delimiter: optStr(obj.delimiter),\n encoding: optStr(obj.encoding),\n sheet: optStr(obj.sheet),\n parseMode: optStr(obj.parseMode),\n headerRow: optNum(obj.headerRow),\n hasHeader: optBool(obj.hasHeader),\n skipRows: Array.isArray(obj.skipRows)\n ? (obj.skipRows as number[])\n : undefined,\n }) as InputFileConfig;\n}\n\nfunction parseInputConfig(raw: unknown, ctx: string): InputConfig {\n const obj = asObj(raw, ctx);\n return stripUndefined({\n files: Array.isArray(obj.files)\n ? obj.files.map((f: unknown, i: number) =>\n parseInputFileConfig(f, `${ctx}.files[${i}]`),\n )\n : [],\n fileA:\n typeof obj.fileA === \"object\" && obj.fileA !== null\n ? parseInputFileConfig(obj.fileA, `${ctx}.fileA`)\n : undefined,\n fileB:\n typeof obj.fileB === \"object\" && obj.fileB !== null\n ? parseInputFileConfig(obj.fileB, `${ctx}.fileB`)\n : undefined,\n }) as InputConfig;\n}\n\nfunction parseOutputConfig(raw: unknown, ctx: string): OutputConfig {\n const obj = asObj(raw, ctx);\n return stripUndefined({\n path: optStr(obj.path),\n format: optStr(obj.format),\n directory: optStr(obj.directory),\n runName: optStr(obj.runName),\n }) as OutputConfig;\n}\n\n// ---------------------------------------------------------------------------\n// Public API\n// ---------------------------------------------------------------------------\n\n/**\n * Parse a raw JS object (already deserialized from YAML or JSON) into a\n * validated GoldenMatchConfig.\n *\n * Handles:\n * - Snake_case to camelCase key conversion\n * - Normalization of `matchkeys` / `match_settings`\n * - Parsing of all nested config objects\n * - `default` -> `defaultStrategy` normalization in golden_rules\n */\nexport function parseConfig(raw: unknown): GoldenMatchConfig {\n if (typeof raw !== \"object\" || raw === null) {\n throw new Error(\"Invalid config: expected a non-null object\");\n }\n\n // Camelize all keys recursively\n const obj = camelizeKeys(raw) as RawObj;\n\n // Normalize matchkeys: accept either `matchkeys` or `matchSettings`\n const rawMatchkeys = obj.matchkeys ?? obj.matchSettings;\n const matchkeys = Array.isArray(rawMatchkeys)\n ? rawMatchkeys.map((mk: unknown, i: number) =>\n parseMatchkeyConfig(mk, `matchkeys[${i}]`),\n )\n : undefined;\n\n const config = stripUndefined({\n matchkeys,\n blocking:\n typeof obj.blocking === \"object\" && obj.blocking !== null\n ? parseBlockingConfig(obj.blocking, \"blocking\")\n : undefined,\n threshold: optNum(obj.threshold),\n goldenRules:\n typeof obj.goldenRules === \"object\" && obj.goldenRules !== null\n ? parseGoldenRulesConfig(obj.goldenRules, \"goldenRules\")\n : undefined,\n standardization:\n typeof obj.standardization === \"object\" && obj.standardization !== null\n ? parseStandardizationConfig(obj.standardization, \"standardization\")\n : undefined,\n validation:\n typeof obj.validation === \"object\" && obj.validation !== null\n ? parseValidationConfig(obj.validation, \"validation\")\n : undefined,\n quality:\n typeof obj.quality === \"object\" && obj.quality !== null\n ? parseQualityConfig(obj.quality, \"quality\")\n : undefined,\n transform:\n typeof obj.transform === \"object\" && obj.transform !== null\n ? parseTransformConfig(obj.transform, \"transform\")\n : undefined,\n llmScorer:\n typeof obj.llmScorer === \"object\" && obj.llmScorer !== null\n ? parseLLMScorerConfig(obj.llmScorer, \"llmScorer\")\n : undefined,\n domain:\n typeof obj.domain === \"object\" && obj.domain !== null\n ? parseDomainConfig(obj.domain, \"domain\")\n : undefined,\n memory:\n typeof obj.memory === \"object\" && obj.memory !== null\n ? parseMemoryConfig(obj.memory, \"memory\")\n : undefined,\n input:\n typeof obj.input === \"object\" && obj.input !== null\n ? parseInputConfig(obj.input, \"input\")\n : undefined,\n output:\n typeof obj.output === \"object\" && obj.output !== null\n ? parseOutputConfig(obj.output, \"output\")\n : undefined,\n backend: optStr(obj.backend),\n llmAuto: optBool(obj.llmAuto),\n llmBoost: optBool(obj.llmBoost),\n }) as GoldenMatchConfig;\n\n return config;\n}\n\n/**\n * Parse a YAML string into a GoldenMatchConfig.\n *\n * Requires the caller to provide a YAML parse function (e.g. from the `yaml`\n * npm package) to keep this module edge-safe with no dynamic imports.\n *\n * @param yamlStr - The YAML configuration string.\n * @param yamlParseFn - A function that parses a YAML string into a JS object.\n */\nexport function parseConfigYaml(\n yamlStr: string,\n yamlParseFn: (s: string) => unknown,\n): GoldenMatchConfig {\n const raw = yamlParseFn(yamlStr);\n if (typeof raw !== \"object\" || raw === null) {\n throw new Error(\"Invalid YAML config: expected a non-null object at root\");\n }\n return parseConfig(raw);\n}\n\n/**\n * Convert a GoldenMatchConfig back to a plain JS object suitable for\n * YAML or JSON serialization (snake_case keys).\n *\n * @param config - The typed config object.\n * @param yamlStringifyFn - A function that serializes a JS object to YAML.\n */\nexport function configToYaml(\n config: GoldenMatchConfig,\n yamlStringifyFn: (obj: unknown) => string,\n): string {\n // Strip undefined values then convert keys to snake_case\n const plain = JSON.parse(JSON.stringify(config));\n const snaked = snakeifyKeys(plain);\n return yamlStringifyFn(snaked);\n}\n","/**\n * config-file.ts -- YAML config loading/saving from disk.\n *\n * Node-only. Uses `createRequire` so the optional `yaml` peer dependency\n * is resolved lazily without breaking edge-safe ESM builds.\n */\n\nimport { readFileSync, writeFileSync, mkdirSync, existsSync } from \"node:fs\";\nimport { resolve, dirname } from \"node:path\";\nimport { createRequire } from \"node:module\";\nimport { parseConfigYaml, configToYaml } from \"../core/config/loader.js\";\nimport type { GoldenMatchConfig } from \"../core/types.js\";\n\nconst require = createRequire(import.meta.url);\n\ninterface YamlModule {\n parse: (s: string) => unknown;\n stringify: (v: unknown) => string;\n}\n\nfunction loadYamlModule(): YamlModule {\n try {\n // eslint-disable-next-line @typescript-eslint/no-var-requires\n const mod = require(\"yaml\") as YamlModule;\n if (typeof mod.parse !== \"function\" || typeof mod.stringify !== \"function\") {\n throw new Error(\"'yaml' module missing parse/stringify exports\");\n }\n return mod;\n } catch (err) {\n const detail = err instanceof Error ? err.message : String(err);\n throw new Error(\n `'yaml' package is required for config file I/O. Install: npm install yaml (${detail})`,\n );\n }\n}\n\n/**\n * Load and parse a YAML config file into a typed GoldenMatchConfig.\n *\n * @throws if the file cannot be read, `yaml` is not installed, or the\n * document does not describe a valid config.\n */\nexport function loadConfigFile(path: string): GoldenMatchConfig {\n const resolved = resolve(path);\n if (!existsSync(resolved)) {\n throw new Error(`Config file not found: ${resolved}`);\n }\n const content = readFileSync(resolved, \"utf8\");\n const yamlMod = loadYamlModule();\n return parseConfigYaml(content, yamlMod.parse);\n}\n\n/**\n * Serialize a GoldenMatchConfig to YAML and write it to disk.\n * Creates parent directories as needed.\n */\nexport function writeConfigFile(path: string, config: GoldenMatchConfig): void {\n const resolved = resolve(path);\n const dir = dirname(resolved);\n if (dir && dir !== \".\" && !existsSync(dir)) {\n mkdirSync(dir, { recursive: true });\n }\n const yamlMod = loadYamlModule();\n const yamlStr = configToYaml(config, yamlMod.stringify);\n writeFileSync(resolved, yamlStr, \"utf8\");\n}\n","/**\n * explain.ts — Natural language explanations for match decisions.\n * Ports `goldenmatch/core/explain.py` (+ parts of `explainer.py`).\n *\n * Template-based, zero LLM cost. Produces human-readable summaries of why\n * two records matched, plus cluster-level summaries.\n *\n * Edge-safe: no `node:` imports.\n */\n\nimport type {\n Row,\n MatchkeyConfig,\n MatchkeyField,\n ClusterInfo,\n} from \"./types.js\";\nimport { scoreField, asString } from \"./scorer.js\";\nimport { pairKey } from \"./cluster.js\";\nimport { applyTransforms } from \"./transforms.js\";\n\n// ---------------------------------------------------------------------------\n// Score descriptors\n// ---------------------------------------------------------------------------\n\nconst SCORE_DESCRIPTORS: ReadonlyArray<readonly [number, string]> = [\n [0.95, \"identical\"],\n [0.85, \"very similar\"],\n [0.7, \"similar\"],\n [0.5, \"somewhat similar\"],\n [0.3, \"weakly similar\"],\n [0.0, \"different\"],\n];\n\nconst SCORER_NAMES: Readonly<Record<string, string>> = {\n jaro_winkler: \"string similarity\",\n levenshtein: \"edit distance\",\n token_sort: \"token similarity\",\n soundex_match: \"phonetic match\",\n exact: \"exact match\",\n ensemble: \"best-of-multiple\",\n dice: \"Dice coefficient\",\n jaccard: \"Jaccard similarity\",\n embedding: \"semantic similarity\",\n record_embedding: \"record similarity\",\n};\n\nfunction describeScore(score: number): string {\n for (const [threshold, desc] of SCORE_DESCRIPTORS) {\n if (score >= threshold) return desc;\n }\n return \"different\";\n}\n\nfunction describeScorer(name: string): string {\n return SCORER_NAMES[name] ?? name;\n}\n\n// ---------------------------------------------------------------------------\n// Public types\n// ---------------------------------------------------------------------------\n\nexport interface FieldScoreDetail {\n readonly field: string;\n readonly scorer: string;\n readonly valueA: string | null;\n readonly valueB: string | null;\n readonly score: number | null;\n readonly weight: number;\n readonly diffType: \"identical\" | \"similar\" | \"different\" | \"missing\" | \"unknown\";\n}\n\nexport interface PairExplanation {\n readonly score: number;\n readonly fieldScores: Readonly<Record<string, number | null>>;\n readonly explanation: string;\n readonly confidence: \"high\" | \"medium\" | \"low\";\n readonly reasoning: readonly string[];\n readonly details: readonly FieldScoreDetail[];\n}\n\nexport interface ClusterExplanation {\n readonly clusterId: number;\n readonly size: number;\n readonly confidence: number;\n readonly quality: string;\n readonly summary: string;\n readonly strongestField: string | null;\n readonly weakestLink: readonly [number, number] | null;\n}\n\n// ---------------------------------------------------------------------------\n// Formatting helpers\n// ---------------------------------------------------------------------------\n\nfunction fmtVal(v: string | null): string {\n if (v === null || v === undefined) return \"[null]\";\n const s = String(v).trim();\n if (s.length > 40) return s.slice(0, 37) + \"...\";\n return s;\n}\n\nfunction classifyDiff(\n score: number | null,\n): \"identical\" | \"similar\" | \"different\" | \"missing\" {\n if (score === null) return \"missing\";\n if (score >= 0.99) return \"identical\";\n if (score >= 0.7) return \"similar\";\n return \"different\";\n}\n\nfunction confidenceBand(score: number): \"high\" | \"medium\" | \"low\" {\n if (score >= 0.9) return \"high\";\n if (score >= 0.75) return \"medium\";\n return \"low\";\n}\n\n// ---------------------------------------------------------------------------\n// Per-field scoring (used by both pair and cluster explanation)\n// ---------------------------------------------------------------------------\n\nfunction scoreFieldDetail(\n rowA: Row,\n rowB: Row,\n field: MatchkeyField,\n): FieldScoreDetail {\n const rawA = asString(rowA[field.field]);\n const rawB = asString(rowB[field.field]);\n const valA = applyTransforms(rawA, field.transforms);\n const valB = applyTransforms(rawB, field.transforms);\n const score = scoreField(valA, valB, field.scorer);\n return {\n field: field.field,\n scorer: field.scorer,\n valueA: valA,\n valueB: valB,\n score,\n weight: field.weight,\n diffType: classifyDiff(score),\n };\n}\n\nfunction aggregateScore(details: readonly FieldScoreDetail[]): number {\n let weightedSum = 0;\n let weightSum = 0;\n for (const d of details) {\n if (d.score === null) continue;\n weightedSum += d.score * d.weight;\n weightSum += d.weight;\n }\n return weightSum === 0 ? 0 : weightedSum / weightSum;\n}\n\n// ---------------------------------------------------------------------------\n// Public: explainPair\n// ---------------------------------------------------------------------------\n\n/**\n * Produce an NL explanation for why two rows match (or don't), using the\n * scorers and weights defined by the matchkey config.\n */\nexport function explainPair(\n rowA: Row,\n rowB: Row,\n mk: MatchkeyConfig,\n): PairExplanation {\n const details = mk.fields.map((f) => scoreFieldDetail(rowA, rowB, f));\n const overall = aggregateScore(details);\n\n // Sort by contribution (score * weight) descending.\n const sorted = [...details].sort((a, b) => {\n const aw = (a.score ?? 0) * a.weight;\n const bw = (b.score ?? 0) * b.weight;\n return bw - aw;\n });\n\n // Build per-field phrases.\n const reasoning: string[] = [];\n let weakest: FieldScoreDetail | null = null;\n let weakestScore = 1.0;\n\n for (const d of sorted) {\n if (d.score !== null && d.score < weakestScore) {\n weakestScore = d.score;\n weakest = d;\n }\n\n const scorerDesc = describeScorer(d.scorer);\n if (d.diffType === \"missing\") {\n reasoning.push(`${d.field} missing on one side`);\n } else if (d.diffType === \"identical\" || (d.score ?? 0) >= 0.99) {\n reasoning.push(`${d.field} match exactly (${fmtVal(d.valueA)})`);\n } else if ((d.score ?? 0) >= 0.8) {\n reasoning.push(\n `${d.field} are ${describeScore(d.score!)} ` +\n `(${fmtVal(d.valueA)} ~ ${fmtVal(d.valueB)}, ` +\n `${scorerDesc} ${d.score!.toFixed(2)})`,\n );\n } else if ((d.score ?? 0) > 0) {\n reasoning.push(\n `${d.field} differ ` +\n `(${fmtVal(d.valueA)} vs ${fmtVal(d.valueB)}, ` +\n `${scorerDesc} ${d.score!.toFixed(2)})`,\n );\n } else {\n reasoning.push(\n `${d.field} do not match ` +\n `(${fmtVal(d.valueA)} vs ${fmtVal(d.valueB)})`,\n );\n }\n }\n\n // Build top-line explanation.\n const overallDesc = describeScore(overall);\n const header = `Match (${overallDesc}, score ${overall.toFixed(2)}):`;\n const body = reasoning.join(\"; \");\n const weakestNote =\n weakest && weakestScore < 0.8 ? ` Weakest signal: ${weakest.field}.` : \"\";\n const explanation = `${header} ${body}.${weakestNote}`.replace(/\\s+/g, \" \").trim();\n\n // Field scores map.\n const fieldScores: Record<string, number | null> = {};\n for (const d of details) fieldScores[d.field] = d.score;\n\n return {\n score: overall,\n fieldScores,\n explanation,\n confidence: confidenceBand(overall),\n reasoning,\n details,\n };\n}\n\n// ---------------------------------------------------------------------------\n// Public: explainCluster\n// ---------------------------------------------------------------------------\n\n/**\n * Produce a template summary for a cluster: size, confidence, weakest link.\n * Mirrors `explain_cluster_nl` in Python.\n */\nexport function explainCluster(\n clusterId: number,\n cluster: ClusterInfo,\n rows: readonly Row[],\n mk: MatchkeyConfig,\n): ClusterExplanation {\n const size = cluster.size;\n const confidence = cluster.confidence;\n const pairScores = cluster.pairScores;\n\n if (size <= 1) {\n return {\n clusterId,\n size,\n confidence,\n quality: cluster.clusterQuality,\n summary: \"Singleton cluster with 1 record.\",\n strongestField: null,\n weakestLink: null,\n };\n }\n\n // Score statistics.\n const scores: number[] = [];\n pairScores.forEach((s) => scores.push(s));\n const minScore = scores.length > 0 ? Math.min(...scores) : 0;\n const maxScore = scores.length > 0 ? Math.max(...scores) : 0;\n const avgScore =\n scores.length > 0 ? scores.reduce((a, b) => a + b, 0) / scores.length : 0;\n\n const parts: string[] = [];\n parts.push(\n `Cluster of ${size} records ` +\n `(confidence ${confidence.toFixed(2)}, ` +\n `scores ${minScore.toFixed(2)}-${maxScore.toFixed(2)}, ` +\n `avg ${avgScore.toFixed(2)}).`,\n );\n\n if (cluster.bottleneckPair !== null) {\n const [a, b] = cluster.bottleneckPair;\n const bpScore = pairScores.get(pairKey(a, b)) ?? 0;\n parts.push(\n `Weakest link: records ${a} and ${b} (score ${bpScore.toFixed(2)}).`,\n );\n }\n\n if (cluster.oversized) {\n parts.push(\"WARNING: cluster exceeds max size limit.\");\n }\n\n // Identify the strongest field by averaging per-field scores across member pairs.\n const strongestField = computeStrongestField(cluster, rows, mk);\n\n return {\n clusterId,\n size,\n confidence,\n quality: cluster.clusterQuality,\n summary: parts.join(\" \"),\n strongestField,\n weakestLink: cluster.bottleneckPair,\n };\n}\n\nfunction computeStrongestField(\n cluster: ClusterInfo,\n rows: readonly Row[],\n mk: MatchkeyConfig,\n): string | null {\n if (mk.fields.length === 0) return null;\n\n const rowById = new Map<number, Row>();\n for (const r of rows) {\n const id = r[\"__row_id__\"];\n if (typeof id === \"number\") rowById.set(id, r);\n }\n\n const fieldSums: Record<string, { sum: number; count: number }> = {};\n for (const f of mk.fields) {\n fieldSums[f.field] = { sum: 0, count: 0 };\n }\n\n // Sample every pair in the cluster.\n const members = cluster.members;\n for (let i = 0; i < members.length; i++) {\n for (let j = i + 1; j < members.length; j++) {\n const rowA = rowById.get(members[i]!);\n const rowB = rowById.get(members[j]!);\n if (!rowA || !rowB) continue;\n for (const f of mk.fields) {\n const d = scoreFieldDetail(rowA, rowB, f);\n if (d.score === null) continue;\n const entry = fieldSums[f.field]!;\n entry.sum += d.score;\n entry.count += 1;\n }\n }\n }\n\n let best: string | null = null;\n let bestAvg = -1;\n for (const [name, { sum, count }] of Object.entries(fieldSums)) {\n if (count === 0) continue;\n const avg = sum / count;\n if (avg > bestAvg) {\n bestAvg = avg;\n best = name;\n }\n }\n return best;\n}\n","/**\n * profiler.ts — Lightweight per-column data profiler.\n * Edge-safe: no `node:` imports.\n *\n * Ports parts of goldenmatch/core/profiler.py that autoconfig relies on.\n */\n\nimport type { Row } from \"./types.js\";\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\nexport type ColumnType =\n | \"email\"\n | \"phone\"\n | \"zip\"\n | \"date\"\n | \"name\"\n | \"geo\"\n | \"id\"\n | \"numeric\"\n | \"text\";\n\nexport interface ColumnProfile {\n readonly name: string;\n readonly nullRate: number;\n readonly nullCount: number;\n readonly totalCount: number;\n readonly distinctCount: number;\n readonly cardinalityRatio: number;\n readonly inferredType: ColumnType;\n readonly avgLength: number;\n readonly maxLength: number;\n readonly sampleValues: readonly string[];\n}\n\nexport interface DatasetProfile {\n readonly rowCount: number;\n readonly columns: readonly ColumnProfile[];\n readonly byName: Readonly<Record<string, ColumnProfile>>;\n}\n\n// ---------------------------------------------------------------------------\n// Regex heuristics\n// ---------------------------------------------------------------------------\n\nconst EMAIL_VALUE_RE = /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/;\nconst PHONE_STRIP_RE = /[()\\-+.\\s]/g;\nconst DATE_VALUE_RES: readonly RegExp[] = [\n /^\\d{1,2}[/\\-]\\d{1,2}[/\\-]\\d{2,4}$/,\n /^\\d{4}[/\\-]\\d{1,2}[/\\-]\\d{1,2}$/,\n /^\\d{1,2}\\s[A-Za-z]+\\s\\d{2,4}$/,\n];\nconst ZIP_VALUE_RE = /^\\d{5}(-?\\d{4})?$/;\nconst NAME_VALUE_RE = /^[A-Za-z][A-Za-z \\-']{0,28}[A-Za-z]$|^[A-Za-z]{2,3}$/;\n\n// ---------------------------------------------------------------------------\n// Per-column profiling\n// ---------------------------------------------------------------------------\n\nfunction toStringOrNull(value: unknown): string | null {\n if (value === null || value === undefined) return null;\n if (typeof value === \"string\") {\n const t = value.trim();\n return t.length === 0 ? null : t;\n }\n return String(value);\n}\n\nfunction guessType(values: readonly string[], columnName: string): ColumnType {\n if (values.length === 0) return \"text\";\n const n = values.length;\n const lname = columnName.toLowerCase();\n\n // Email: >60% look like addresses\n const emailCount = values.reduce(\n (acc, v) => acc + (EMAIL_VALUE_RE.test(v) ? 1 : 0),\n 0,\n );\n if (emailCount / n > 0.6) return \"email\";\n\n // Phone\n let phoneCount = 0;\n for (const v of values) {\n const stripped = v.replace(PHONE_STRIP_RE, \"\");\n if (/^\\d+$/.test(stripped) && stripped.length >= 7 && stripped.length <= 15) {\n phoneCount++;\n }\n }\n if (phoneCount / n > 0.6) return \"phone\";\n\n // Zip: 5 or 9 digits (with optional dash)\n const zipCount = values.reduce(\n (acc, v) => acc + (ZIP_VALUE_RE.test(v) ? 1 : 0),\n 0,\n );\n if (zipCount / n > 0.6) return \"zip\";\n\n // Date\n let dateCount = 0;\n for (const v of values) {\n if (DATE_VALUE_RES.some((re) => re.test(v))) dateCount++;\n }\n if (dateCount / n > 0.6) return \"date\";\n\n // Geographic columns by name + short text values\n if (/^(city|state|county|country|region|province)/i.test(lname)) return \"geo\";\n if (/city_desc|state_cd|country_code|state_code/i.test(lname)) return \"geo\";\n\n // Identifier columns by name\n if (/^id$|_id$|uuid|guid/i.test(lname)) return \"id\";\n\n // Name: >60% match alpha-name pattern\n const nameCount = values.reduce(\n (acc, v) => acc + (NAME_VALUE_RE.test(v) ? 1 : 0),\n 0,\n );\n if (nameCount / n > 0.6) return \"name\";\n\n // Numeric\n let numericCount = 0;\n for (const v of values) {\n if (/^-?\\d+(\\.\\d+)?$/.test(v)) numericCount++;\n }\n if (numericCount / n > 0.8) return \"numeric\";\n\n return \"text\";\n}\n\nfunction profileColumn(name: string, rawValues: readonly unknown[]): ColumnProfile {\n const totalCount = rawValues.length;\n let nullCount = 0;\n const nonNull: string[] = [];\n for (const v of rawValues) {\n const s = toStringOrNull(v);\n if (s === null) nullCount++;\n else nonNull.push(s);\n }\n\n const distinct = new Set(nonNull);\n const distinctCount = distinct.size;\n const cardinalityRatio = totalCount > 0 ? distinctCount / totalCount : 0;\n\n let totalLen = 0;\n let maxLen = 0;\n for (const v of nonNull) {\n totalLen += v.length;\n if (v.length > maxLen) maxLen = v.length;\n }\n const avgLength = nonNull.length > 0 ? totalLen / nonNull.length : 0;\n const nullRate = totalCount > 0 ? nullCount / totalCount : 0;\n\n // Sample values (first 5 unique)\n const sampleValues: string[] = [];\n for (const v of distinct) {\n sampleValues.push(v);\n if (sampleValues.length >= 5) break;\n }\n\n // Subsample for type guessing for performance\n const sampleForType = nonNull.length > 500 ? nonNull.slice(0, 500) : nonNull;\n const inferredType = guessType(sampleForType, name);\n\n return {\n name,\n nullRate,\n nullCount,\n totalCount,\n distinctCount,\n cardinalityRatio,\n inferredType,\n avgLength,\n maxLength: maxLen,\n sampleValues,\n };\n}\n\n// ---------------------------------------------------------------------------\n// Public API\n// ---------------------------------------------------------------------------\n\n/** Profile all columns of a row array. */\nexport function profileRows(rows: readonly Row[]): DatasetProfile {\n if (rows.length === 0) {\n return { rowCount: 0, columns: [], byName: {} };\n }\n\n // Collect column names from all rows (not just first)\n const colSet = new Set<string>();\n for (const r of rows) {\n for (const k of Object.keys(r)) {\n if (!k.startsWith(\"__\")) colSet.add(k);\n }\n }\n const columns = [...colSet];\n\n const profiles: ColumnProfile[] = [];\n const byName: Record<string, ColumnProfile> = {};\n for (const col of columns) {\n const values = rows.map((r) => r[col]);\n const profile = profileColumn(col, values);\n profiles.push(profile);\n byName[col] = profile;\n }\n\n return {\n rowCount: rows.length,\n columns: profiles,\n byName,\n };\n}\n","/**\n * evaluate.ts — Precision/recall/F1 evaluation against ground truth.\n * Edge-safe: no Node.js imports, pure TypeScript only.\n *\n * Ports goldenmatch/core/evaluate.py.\n */\n\nimport type { Row, ScoredPair, ClusterInfo } from \"./types.js\";\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\nexport interface EvalResult {\n readonly precision: number;\n readonly recall: number;\n readonly f1: number;\n readonly truePositives: number;\n readonly falsePositives: number;\n readonly falseNegatives: number;\n}\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\nfunction canonicalPair(a: number, b: number): string {\n return a < b ? `${a}:${b}` : `${b}:${a}`;\n}\n\nfunction toPairSet(\n pairs: readonly (readonly [number, number])[],\n): Set<string> {\n const out = new Set<string>();\n for (const [a, b] of pairs) {\n if (a === b) continue;\n out.add(canonicalPair(a, b));\n }\n return out;\n}\n\nfunction computeMetrics(\n tp: number,\n fp: number,\n fn: number,\n): EvalResult {\n const precision = tp + fp > 0 ? tp / (tp + fp) : 0;\n const recall = tp + fn > 0 ? tp / (tp + fn) : 0;\n const f1 =\n precision + recall > 0 ? (2 * precision * recall) / (precision + recall) : 0;\n return {\n precision,\n recall,\n f1,\n truePositives: tp,\n falsePositives: fp,\n falseNegatives: fn,\n };\n}\n\n// ---------------------------------------------------------------------------\n// Public API\n// ---------------------------------------------------------------------------\n\n/**\n * Evaluate predicted pairs against ground-truth pairs.\n *\n * Pairs are treated as unordered (canonicalized to min:max).\n */\nexport function evaluatePairs(\n predictedPairs: readonly ScoredPair[],\n groundTruthPairs: readonly (readonly [number, number])[],\n): EvalResult {\n const truth = toPairSet(groundTruthPairs);\n const predicted = new Set<string>();\n for (const p of predictedPairs) {\n if (p.idA === p.idB) continue;\n predicted.add(canonicalPair(p.idA, p.idB));\n }\n\n let tp = 0;\n let fp = 0;\n for (const key of predicted) {\n if (truth.has(key)) tp++;\n else fp++;\n }\n let fn = 0;\n for (const key of truth) {\n if (!predicted.has(key)) fn++;\n }\n\n return computeMetrics(tp, fp, fn);\n}\n\n/**\n * Evaluate clusters against ground-truth pairs.\n *\n * Expands each cluster's members into the full set of intra-cluster pairs and\n * compares that set to the ground truth.\n */\nexport function evaluateClusters(\n clusters: ReadonlyMap<number, ClusterInfo>,\n groundTruthPairs: readonly (readonly [number, number])[],\n _allIds: readonly number[],\n): EvalResult {\n const predicted = new Set<string>();\n for (const info of clusters.values()) {\n const members = info.members;\n if (members.length < 2) continue;\n for (let i = 0; i < members.length; i++) {\n for (let j = i + 1; j < members.length; j++) {\n predicted.add(canonicalPair(members[i]!, members[j]!));\n }\n }\n }\n\n const truth = toPairSet(groundTruthPairs);\n\n let tp = 0;\n let fp = 0;\n for (const key of predicted) {\n if (truth.has(key)) tp++;\n else fp++;\n }\n let fn = 0;\n for (const key of truth) {\n if (!predicted.has(key)) fn++;\n }\n\n return computeMetrics(tp, fp, fn);\n}\n\n/**\n * Extract ground truth pairs from a list of rows containing two id columns.\n *\n * Numeric strings are parsed to integers. Rows with missing/unparseable ids\n * are skipped.\n */\nexport function loadGroundTruthPairs(\n rows: readonly Row[],\n idColA: string,\n idColB: string,\n): (readonly [number, number])[] {\n const out: [number, number][] = [];\n for (const row of rows) {\n const rawA = row[idColA];\n const rawB = row[idColB];\n if (rawA === null || rawA === undefined) continue;\n if (rawB === null || rawB === undefined) continue;\n const a = typeof rawA === \"number\" ? rawA : Number(rawA);\n const b = typeof rawB === \"number\" ? rawB : Number(rawB);\n if (!Number.isFinite(a) || !Number.isFinite(b)) continue;\n out.push([a, b]);\n }\n return out;\n}\n","/**\n * mcp/server.ts -- GoldenMatch MCP server (stdio transport, JSON-RPC).\n *\n * Node-only: uses node:fs, node:path, node:readline. NOT edge-safe.\n *\n * Exposes ~20 tools covering dedupe, match, scoring, explanation,\n * profiling, auto-config (shorthand), evaluation, and listings.\n *\n * Every tool dispatch is wrapped in try/catch so a single failure never\n * crashes the JSON-RPC loop; errors come back as `{ error: \"<msg>\" }`.\n *\n * Ports ideas from goldenmatch/mcp/server.py.\n */\n\nimport { readFileSync } from \"node:fs\";\nimport { resolve, isAbsolute, sep } from \"node:path\";\nimport { createInterface } from \"node:readline\";\n\nimport { dedupe, match, scoreStrings } from \"../../core/api.js\";\nimport { readFile, writeCsv, writeJson } from \"../connectors/file.js\";\nimport { loadConfigFile } from \"../config-file.js\";\nimport type { Row, MatchkeyField } from \"../../core/types.js\";\nimport {\n makeMatchkeyConfig,\n makeMatchkeyField,\n VALID_SCORERS,\n VALID_TRANSFORMS,\n VALID_STRATEGIES,\n} from \"../../core/types.js\";\nimport {\n scoreField,\n findExactMatches,\n findFuzzyMatches,\n scorePair,\n} from \"../../core/scorer.js\";\nimport { addRowIds } from \"../../core/matchkey.js\";\nimport { buildClusters } from \"../../core/cluster.js\";\nimport { explainPair, explainCluster } from \"../../core/explain.js\";\nimport { profileRows } from \"../../core/profiler.js\";\nimport { evaluatePairs, loadGroundTruthPairs } from \"../../core/evaluate.js\";\n\n// ---------------------------------------------------------------------------\n// Tool definitions\n// ---------------------------------------------------------------------------\n\ninterface Tool {\n readonly name: string;\n readonly description: string;\n readonly inputSchema: Readonly<Record<string, unknown>>;\n}\n\nconst pathArg = { type: \"string\", description: \"File path (csv/tsv/json/jsonl)\" };\nconst optionalConfigArg = {\n type: \"string\",\n description: \"Optional path to YAML config file\",\n};\nconst optionalFieldsArg = {\n type: \"array\",\n items: { type: \"string\" },\n description: \"Column names\",\n};\nconst stringArg = { type: \"string\" };\nconst rowArg = {\n type: \"object\",\n additionalProperties: true,\n description: \"Record object (column -> value)\",\n};\n\nexport const TOOLS: readonly Tool[] = [\n {\n name: \"dedupe\",\n description:\n \"Deduplicate records in a file. Returns cluster counts and optional output path.\",\n inputSchema: {\n type: \"object\",\n properties: {\n path: pathArg,\n config: optionalConfigArg,\n exact: optionalFieldsArg,\n fuzzy: {\n type: \"object\",\n additionalProperties: { type: \"number\" },\n description: \"Map of field -> fuzzy threshold\",\n },\n blocking: optionalFieldsArg,\n threshold: { type: \"number\", description: \"Overall fuzzy threshold\" },\n output: { type: \"string\", description: \"Optional output path for golden records\" },\n },\n required: [\"path\"],\n },\n },\n {\n name: \"match\",\n description:\n \"Match a target file against a reference file. Returns matched/unmatched counts.\",\n inputSchema: {\n type: \"object\",\n properties: {\n target: pathArg,\n reference: pathArg,\n config: optionalConfigArg,\n exact: optionalFieldsArg,\n fuzzy: {\n type: \"object\",\n additionalProperties: { type: \"number\" },\n },\n blocking: optionalFieldsArg,\n threshold: { type: \"number\" },\n output: { type: \"string\" },\n },\n required: [\"target\", \"reference\"],\n },\n },\n {\n name: \"score_strings\",\n description:\n \"Score similarity between two strings using the requested scorer.\",\n inputSchema: {\n type: \"object\",\n properties: {\n a: stringArg,\n b: stringArg,\n scorer: {\n type: \"string\",\n description:\n \"Scorer name (exact, jaro_winkler, levenshtein, token_sort, soundex_match, dice, jaccard, ensemble)\",\n },\n },\n required: [\"a\", \"b\"],\n },\n },\n {\n name: \"score_pair\",\n description:\n \"Score two record objects across weighted fields. Returns a combined score.\",\n inputSchema: {\n type: \"object\",\n properties: {\n row_a: rowArg,\n row_b: rowArg,\n fields: {\n type: \"array\",\n items: {\n type: \"object\",\n properties: {\n field: { type: \"string\" },\n scorer: { type: \"string\" },\n weight: { type: \"number\" },\n transforms: { type: \"array\", items: { type: \"string\" } },\n },\n required: [\"field\"],\n },\n },\n },\n required: [\"row_a\", \"row_b\", \"fields\"],\n },\n },\n {\n name: \"explain_pair\",\n description:\n \"Explain why two records match (or don't) using a matchkey definition.\",\n inputSchema: {\n type: \"object\",\n properties: {\n row_a: rowArg,\n row_b: rowArg,\n fields: {\n type: \"array\",\n items: {\n type: \"object\",\n properties: {\n field: { type: \"string\" },\n scorer: { type: \"string\" },\n weight: { type: \"number\" },\n transforms: { type: \"array\", items: { type: \"string\" } },\n },\n required: [\"field\"],\n },\n },\n threshold: { type: \"number\" },\n },\n required: [\"row_a\", \"row_b\", \"fields\"],\n },\n },\n {\n name: \"explain_cluster\",\n description:\n \"Run dedupe on a file and explain the cluster containing the given row id.\",\n inputSchema: {\n type: \"object\",\n properties: {\n path: pathArg,\n config: optionalConfigArg,\n exact: optionalFieldsArg,\n fuzzy: {\n type: \"object\",\n additionalProperties: { type: \"number\" },\n },\n blocking: optionalFieldsArg,\n row_id: { type: \"number\" },\n },\n required: [\"path\", \"row_id\"],\n },\n },\n {\n name: \"profile\",\n description:\n \"Profile a dataset: per-column null rate, cardinality, inferred type, samples.\",\n inputSchema: {\n type: \"object\",\n properties: { path: pathArg },\n required: [\"path\"],\n },\n },\n {\n name: \"suggest_config\",\n description:\n \"Suggest a shorthand dedupe config based on a profile of the dataset.\",\n inputSchema: {\n type: \"object\",\n properties: { path: pathArg },\n required: [\"path\"],\n },\n },\n {\n name: \"evaluate\",\n description:\n \"Evaluate predicted pairs from a dedupe run against ground truth pairs.\",\n inputSchema: {\n type: \"object\",\n properties: {\n path: pathArg,\n ground_truth: pathArg,\n id_col_a: { type: \"string\", description: \"Ground truth id column A (default id_a)\" },\n id_col_b: { type: \"string\", description: \"Ground truth id column B (default id_b)\" },\n config: optionalConfigArg,\n exact: optionalFieldsArg,\n fuzzy: {\n type: \"object\",\n additionalProperties: { type: \"number\" },\n },\n blocking: optionalFieldsArg,\n threshold: { type: \"number\" },\n },\n required: [\"path\", \"ground_truth\"],\n },\n },\n {\n name: \"find_exact_matches\",\n description: \"Find exact matches on a field in a file. Returns pairs.\",\n inputSchema: {\n type: \"object\",\n properties: {\n path: pathArg,\n field: { type: \"string\" },\n transforms: {\n type: \"array\",\n items: { type: \"string\" },\n description: \"Transforms applied before matching (default lowercase, strip)\",\n },\n },\n required: [\"path\", \"field\"],\n },\n },\n {\n name: \"find_fuzzy_matches\",\n description: \"Find fuzzy matches in a block of rows. Returns scored pairs.\",\n inputSchema: {\n type: \"object\",\n properties: {\n path: pathArg,\n field: { type: \"string\" },\n scorer: { type: \"string\", description: \"Scorer (default jaro_winkler)\" },\n threshold: { type: \"number\", description: \"Threshold (default 0.85)\" },\n transforms: { type: \"array\", items: { type: \"string\" } },\n },\n required: [\"path\", \"field\"],\n },\n },\n {\n name: \"build_clusters\",\n description:\n \"Group records into clusters given a file and matchkey definition.\",\n inputSchema: {\n type: \"object\",\n properties: {\n path: pathArg,\n exact: optionalFieldsArg,\n fuzzy: {\n type: \"object\",\n additionalProperties: { type: \"number\" },\n },\n blocking: optionalFieldsArg,\n threshold: { type: \"number\" },\n },\n required: [\"path\"],\n },\n },\n {\n name: \"list_scorers\",\n description: \"List all available similarity scorers.\",\n inputSchema: { type: \"object\", properties: {} },\n },\n {\n name: \"list_transforms\",\n description: \"List all available field transforms.\",\n inputSchema: { type: \"object\", properties: {} },\n },\n {\n name: \"list_strategies\",\n description: \"List all golden-record survivorship strategies.\",\n inputSchema: { type: \"object\", properties: {} },\n },\n {\n name: \"list_blocking_strategies\",\n description: \"List all blocking strategy names.\",\n inputSchema: { type: \"object\", properties: {} },\n },\n {\n name: \"server_info\",\n description: \"Return metadata about this GoldenMatch MCP server.\",\n inputSchema: { type: \"object\", properties: {} },\n },\n {\n name: \"read_file\",\n description: \"Read a CSV/JSON file and return the first N records.\",\n inputSchema: {\n type: \"object\",\n properties: {\n path: pathArg,\n limit: { type: \"number\", description: \"Max rows to return (default 100)\" },\n },\n required: [\"path\"],\n },\n },\n {\n name: \"write_csv\",\n description: \"Write a list of record objects to a CSV file.\",\n inputSchema: {\n type: \"object\",\n properties: {\n path: pathArg,\n rows: { type: \"array\", items: { type: \"object\", additionalProperties: true } },\n },\n required: [\"path\", \"rows\"],\n },\n },\n];\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\nfunction sanitizePath(raw: string): string {\n if (typeof raw !== \"string\" || raw.length === 0) {\n throw new Error(\"path must be a non-empty string\");\n }\n const resolved = isAbsolute(raw) ? resolve(raw) : resolve(process.cwd(), raw);\n const cwd = resolve(process.cwd());\n // Guard against prefix-bypass: cwd=\"/app/foo\" must NOT accept \"/app/foobar\".\n if (resolved !== cwd && !resolved.startsWith(cwd + sep)) {\n throw new Error(`Path '${raw}' is outside the working directory`);\n }\n return resolved;\n}\n\nfunction asStringArray(v: unknown): string[] | undefined {\n if (v === undefined || v === null) return undefined;\n if (!Array.isArray(v)) return undefined;\n return v.map((x) => String(x));\n}\n\nfunction asNumberMap(v: unknown): Record<string, number> | undefined {\n if (v === undefined || v === null) return undefined;\n if (typeof v !== \"object\" || Array.isArray(v)) return undefined;\n const out: Record<string, number> = {};\n for (const [k, val] of Object.entries(v as Record<string, unknown>)) {\n const n = typeof val === \"number\" ? val : Number(val);\n if (Number.isFinite(n)) out[k] = n;\n }\n return out;\n}\n\ninterface ShorthandArgs {\n exact?: readonly string[];\n fuzzy?: Readonly<Record<string, number>>;\n blocking?: readonly string[];\n threshold?: number;\n configPath?: string;\n}\n\nfunction buildDedupeOptions(args: Record<string, unknown>): {\n config?: ReturnType<typeof loadConfigFile>;\n exact?: readonly string[];\n fuzzy?: Readonly<Record<string, number>>;\n blocking?: readonly string[];\n threshold?: number;\n} {\n const opts: {\n config?: ReturnType<typeof loadConfigFile>;\n exact?: readonly string[];\n fuzzy?: Readonly<Record<string, number>>;\n blocking?: readonly string[];\n threshold?: number;\n } = {};\n\n if (typeof args[\"config\"] === \"string\" && args[\"config\"]) {\n opts.config = loadConfigFile(sanitizePath(args[\"config\"] as string));\n }\n const exact = asStringArray(args[\"exact\"]);\n if (exact) opts.exact = exact;\n const fuzzy = asNumberMap(args[\"fuzzy\"]);\n if (fuzzy) opts.fuzzy = fuzzy;\n const blocking = asStringArray(args[\"blocking\"]);\n if (blocking) opts.blocking = blocking;\n if (typeof args[\"threshold\"] === \"number\") opts.threshold = args[\"threshold\"];\n\n return opts;\n}\n\nfunction buildFieldsFromArg(raw: unknown): MatchkeyField[] {\n if (!Array.isArray(raw)) {\n throw new Error(\"fields must be an array of field configs\");\n }\n const out: MatchkeyField[] = [];\n for (const entry of raw) {\n if (entry === null || typeof entry !== \"object\") continue;\n const e = entry as Record<string, unknown>;\n if (typeof e[\"field\"] !== \"string\") {\n throw new Error(\"each field entry needs a string 'field' property\");\n }\n const transforms = asStringArray(e[\"transforms\"]) ?? [\"lowercase\", \"strip\"];\n const scorer = typeof e[\"scorer\"] === \"string\" ? (e[\"scorer\"] as string) : \"jaro_winkler\";\n const weight = typeof e[\"weight\"] === \"number\" ? (e[\"weight\"] as number) : 1.0;\n out.push(\n makeMatchkeyField({\n field: e[\"field\"] as string,\n transforms,\n scorer,\n weight,\n }),\n );\n }\n return out;\n}\n\n// ---------------------------------------------------------------------------\n// Tool dispatch\n// ---------------------------------------------------------------------------\n\nexport async function handleTool(\n name: string,\n rawArgs: Record<string, unknown>,\n): Promise<unknown> {\n const args = rawArgs ?? {};\n try {\n switch (name) {\n case \"dedupe\": {\n const path = sanitizePath(String(args[\"path\"]));\n const rows = readFile(path);\n const options = buildDedupeOptions(args);\n const result = dedupe(rows, options);\n let output_written: string | null = null;\n if (typeof args[\"output\"] === \"string\" && args[\"output\"]) {\n const outPath = sanitizePath(args[\"output\"] as string);\n try {\n writeCsv(outPath, result.goldenRecords);\n output_written = outPath;\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n return {\n stats: result.stats,\n total_clusters: result.stats.totalClusters,\n total_records: result.stats.totalRecords,\n match_rate: result.stats.matchRate,\n output_error: msg,\n };\n }\n }\n return {\n total_records: result.stats.totalRecords,\n total_clusters: result.stats.totalClusters,\n match_rate: result.stats.matchRate,\n matched_records: result.stats.matchedRecords,\n unique_records: result.stats.uniqueRecords,\n golden_records_count: result.goldenRecords.length,\n output_written,\n };\n }\n\n case \"match\": {\n const targetPath = sanitizePath(String(args[\"target\"]));\n const referencePath = sanitizePath(String(args[\"reference\"]));\n const targetRows = readFile(targetPath);\n const referenceRows = readFile(referencePath);\n const options = buildDedupeOptions(args);\n const result = match(\n targetRows.map((r) => ({ ...r, __source__: \"target\" })),\n referenceRows.map((r) => ({ ...r, __source__: \"reference\" })),\n options,\n );\n let output_written: string | null = null;\n if (typeof args[\"output\"] === \"string\" && args[\"output\"]) {\n const outPath = sanitizePath(args[\"output\"] as string);\n try {\n writeCsv(outPath, result.matched);\n output_written = outPath;\n } catch (err) {\n return {\n matched: result.matched.length,\n unmatched: result.unmatched.length,\n output_error: err instanceof Error ? err.message : String(err),\n };\n }\n }\n return {\n matched: result.matched.length,\n unmatched: result.unmatched.length,\n output_written,\n };\n }\n\n case \"score_strings\": {\n const a = String(args[\"a\"] ?? \"\");\n const b = String(args[\"b\"] ?? \"\");\n const scorer =\n typeof args[\"scorer\"] === \"string\" ? (args[\"scorer\"] as string) : \"jaro_winkler\";\n const score = scoreStrings(a, b, scorer);\n return { scorer, score };\n }\n\n case \"score_pair\": {\n const rowA = args[\"row_a\"] as Row;\n const rowB = args[\"row_b\"] as Row;\n if (!rowA || !rowB) throw new Error(\"row_a and row_b are required\");\n const fields = buildFieldsFromArg(args[\"fields\"]);\n const score = scorePair(rowA, rowB, fields);\n return { score, field_count: fields.length };\n }\n\n case \"explain_pair\": {\n const rowA = args[\"row_a\"] as Row;\n const rowB = args[\"row_b\"] as Row;\n if (!rowA || !rowB) throw new Error(\"row_a and row_b are required\");\n const fields = buildFieldsFromArg(args[\"fields\"]);\n const threshold =\n typeof args[\"threshold\"] === \"number\" ? (args[\"threshold\"] as number) : 0.85;\n const mk = makeMatchkeyConfig({\n name: \"adhoc\",\n type: \"weighted\",\n fields,\n threshold,\n });\n const explanation = explainPair(rowA, rowB, mk);\n return {\n score: explanation.score,\n confidence: explanation.confidence,\n explanation: explanation.explanation,\n field_scores: explanation.fieldScores,\n };\n }\n\n case \"explain_cluster\": {\n const path = sanitizePath(String(args[\"path\"]));\n const rowId = Number(args[\"row_id\"]);\n if (!Number.isFinite(rowId)) {\n throw new Error(\"row_id must be a number\");\n }\n const rows = readFile(path);\n const options = buildDedupeOptions(args);\n const result = dedupe(rows, options);\n // Find cluster containing rowId\n let foundId: number | null = null;\n let found: typeof result.clusters extends ReadonlyMap<number, infer V> ? V : never;\n found = undefined as unknown as typeof found;\n for (const [cid, info] of result.clusters.entries()) {\n if (info.members.includes(rowId)) {\n foundId = cid;\n found = info;\n break;\n }\n }\n if (foundId === null || !found) {\n return { error: `row_id ${rowId} not found in any cluster` };\n }\n // Get matchkey\n const mks = (result.config.matchkeys ?? []) as readonly ReturnType<\n typeof makeMatchkeyConfig\n >[];\n const mk =\n mks.length > 0\n ? mks[0]!\n : makeMatchkeyConfig({\n name: \"placeholder\",\n type: \"weighted\",\n fields: [\n makeMatchkeyField({\n field: Object.keys(rows[0] ?? {})[0] ?? \"\",\n transforms: [\"lowercase\", \"strip\"],\n scorer: \"jaro_winkler\",\n }),\n ],\n });\n const withIds = addRowIds(rows);\n const explanation = explainCluster(foundId, found, withIds, mk);\n return {\n cluster_id: explanation.clusterId,\n size: explanation.size,\n confidence: explanation.confidence,\n quality: explanation.quality,\n summary: explanation.summary,\n };\n }\n\n case \"profile\": {\n const path = sanitizePath(String(args[\"path\"]));\n const rows = readFile(path);\n const profile = profileRows(rows);\n return {\n row_count: profile.rowCount,\n columns: profile.columns.map((c) => ({\n name: c.name,\n inferred_type: c.inferredType,\n null_count: c.nullCount,\n null_rate: c.nullRate,\n distinct_count: c.distinctCount,\n cardinality_ratio: c.cardinalityRatio,\n avg_length: c.avgLength,\n max_length: c.maxLength,\n sample_values: c.sampleValues,\n })),\n };\n }\n\n case \"suggest_config\": {\n const path = sanitizePath(String(args[\"path\"]));\n const rows = readFile(path);\n const profile = profileRows(rows);\n const exact: string[] = [];\n const fuzzy: Record<string, number> = {};\n const blocking: string[] = [];\n\n for (const col of profile.columns) {\n if (col.nullRate > 0.2) continue;\n if (col.inferredType === \"email\") {\n if (col.cardinalityRatio >= 0.5) exact.push(col.name);\n } else if (col.inferredType === \"zip\") {\n blocking.push(col.name);\n } else if (col.inferredType === \"name\") {\n fuzzy[col.name] = 0.85;\n } else if (col.inferredType === \"phone\") {\n if (col.cardinalityRatio >= 0.5) exact.push(col.name);\n } else if (col.inferredType === \"geo\") {\n blocking.push(col.name);\n } else if (col.inferredType === \"text\" && col.avgLength > 4) {\n fuzzy[col.name] = 0.8;\n }\n }\n\n return {\n row_count: profile.rowCount,\n suggested: {\n exact,\n fuzzy,\n blocking,\n threshold: 0.85,\n },\n };\n }\n\n case \"evaluate\": {\n const path = sanitizePath(String(args[\"path\"]));\n const gtPath = sanitizePath(String(args[\"ground_truth\"]));\n const idColA =\n typeof args[\"id_col_a\"] === \"string\" ? (args[\"id_col_a\"] as string) : \"id_a\";\n const idColB =\n typeof args[\"id_col_b\"] === \"string\" ? (args[\"id_col_b\"] as string) : \"id_b\";\n const rows = readFile(path);\n const gtRows = readFile(gtPath);\n const options = buildDedupeOptions(args);\n const result = dedupe(rows, options);\n const truth = loadGroundTruthPairs(gtRows, idColA, idColB);\n const metrics = evaluatePairs(result.scoredPairs, truth);\n return {\n tp: metrics.truePositives,\n fp: metrics.falsePositives,\n fn: metrics.falseNegatives,\n precision: metrics.precision,\n recall: metrics.recall,\n f1: metrics.f1,\n total_predicted: result.scoredPairs.length,\n total_truth: truth.length,\n };\n }\n\n case \"find_exact_matches\": {\n const path = sanitizePath(String(args[\"path\"]));\n const field = String(args[\"field\"]);\n const transforms = asStringArray(args[\"transforms\"]) ?? [\"lowercase\", \"strip\"];\n const rows = addRowIds(readFile(path));\n const mk = makeMatchkeyConfig({\n name: \"adhoc_exact\",\n type: \"exact\",\n fields: [makeMatchkeyField({ field, transforms, scorer: \"exact\" })],\n });\n const pairs = findExactMatches(rows, mk);\n return {\n pair_count: pairs.length,\n pairs: pairs.slice(0, 100).map((p) => [p.idA, p.idB, p.score]),\n };\n }\n\n case \"find_fuzzy_matches\": {\n const path = sanitizePath(String(args[\"path\"]));\n const field = String(args[\"field\"]);\n const scorer =\n typeof args[\"scorer\"] === \"string\" ? (args[\"scorer\"] as string) : \"jaro_winkler\";\n const threshold =\n typeof args[\"threshold\"] === \"number\" ? (args[\"threshold\"] as number) : 0.85;\n const transforms = asStringArray(args[\"transforms\"]) ?? [\"lowercase\", \"strip\"];\n const rows = addRowIds(readFile(path));\n const mk = makeMatchkeyConfig({\n name: \"adhoc_fuzzy\",\n type: \"weighted\",\n fields: [makeMatchkeyField({ field, transforms, scorer })],\n threshold,\n });\n const pairs = findFuzzyMatches(rows, mk);\n return {\n pair_count: pairs.length,\n pairs: pairs.slice(0, 100).map((p) => [p.idA, p.idB, p.score]),\n };\n }\n\n case \"build_clusters\": {\n const path = sanitizePath(String(args[\"path\"]));\n const options = buildDedupeOptions(args);\n const rows = readFile(path);\n const result = dedupe(rows, options);\n const clusters: Array<{\n cluster_id: number;\n size: number;\n confidence: number;\n quality: string;\n members: readonly number[];\n }> = [];\n for (const [cid, info] of result.clusters.entries()) {\n clusters.push({\n cluster_id: cid,\n size: info.size,\n confidence: info.confidence,\n quality: info.clusterQuality,\n members: info.members,\n });\n }\n return {\n cluster_count: clusters.length,\n clusters: clusters.slice(0, 200),\n };\n }\n\n case \"list_scorers\":\n return { scorers: [...VALID_SCORERS] };\n\n case \"list_transforms\":\n return { transforms: [...VALID_TRANSFORMS] };\n\n case \"list_strategies\":\n return { strategies: [...VALID_STRATEGIES] };\n\n case \"list_blocking_strategies\":\n return {\n strategies: [\n \"static\",\n \"adaptive\",\n \"sorted_neighborhood\",\n \"multi_pass\",\n \"ann\",\n \"canopy\",\n \"ann_pairs\",\n \"learned\",\n ],\n };\n\n case \"server_info\":\n return {\n name: \"goldenmatch-js\",\n version: \"0.1.0\",\n tool_count: TOOLS.length,\n description:\n \"Node-only GoldenMatch MCP server over stdio (JSON-RPC 2.0)\",\n };\n\n case \"read_file\": {\n const path = sanitizePath(String(args[\"path\"]));\n const limit =\n typeof args[\"limit\"] === \"number\" ? Math.max(0, Math.floor(args[\"limit\"] as number)) : 100;\n const rows = readFile(path);\n return {\n total: rows.length,\n returned: Math.min(rows.length, limit),\n rows: rows.slice(0, limit),\n };\n }\n\n case \"write_csv\": {\n const path = sanitizePath(String(args[\"path\"]));\n const rowsArg = args[\"rows\"];\n if (!Array.isArray(rowsArg)) {\n throw new Error(\"rows must be an array of objects\");\n }\n writeCsv(path, rowsArg as Row[]);\n return { written: rowsArg.length, path };\n }\n\n default:\n return { error: `Unknown tool: ${name}` };\n }\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n return { error: msg };\n }\n}\n\n// ---------------------------------------------------------------------------\n// JSON-RPC over stdio\n// ---------------------------------------------------------------------------\n\ninterface JsonRpcRequest {\n jsonrpc?: string;\n id?: number | string | null;\n method?: string;\n params?: Record<string, unknown>;\n}\n\nfunction writeMessage(msg: Record<string, unknown>): void {\n process.stdout.write(JSON.stringify(msg) + \"\\n\");\n}\n\n/**\n * Start the MCP server reading JSON-RPC messages one per line from stdin\n * and writing responses to stdout. Intended for Claude Desktop / any MCP\n * client using stdio transport.\n *\n * Unknown methods return a JSON-RPC error. Bad JSON is logged to stderr\n * (via console.warn) but does not crash the loop.\n */\nexport function startMcpServer(): void {\n const rl = createInterface({ input: process.stdin, terminal: false });\n\n rl.on(\"line\", (line: string) => {\n if (line.trim() === \"\") return;\n let req: JsonRpcRequest;\n try {\n req = JSON.parse(line) as JsonRpcRequest;\n } catch (err) {\n console.warn(\n \"MCP parse error:\",\n err instanceof Error ? err.message : String(err),\n );\n return;\n }\n\n const id = req.id ?? null;\n\n void (async () => {\n try {\n if (req.method === \"initialize\") {\n writeMessage({\n jsonrpc: \"2.0\",\n id,\n result: {\n protocolVersion: \"2024-11-05\",\n serverInfo: { name: \"goldenmatch-js\", version: \"0.1.0\" },\n capabilities: { tools: {} },\n },\n });\n return;\n }\n\n if (req.method === \"tools/list\") {\n writeMessage({\n jsonrpc: \"2.0\",\n id,\n result: { tools: TOOLS },\n });\n return;\n }\n\n if (req.method === \"tools/call\") {\n const params = req.params ?? {};\n const toolName = String(params[\"name\"] ?? \"\");\n const toolArgs =\n (params[\"arguments\"] as Record<string, unknown> | undefined) ?? {};\n const result = await handleTool(toolName, toolArgs);\n writeMessage({\n jsonrpc: \"2.0\",\n id,\n result: {\n content: [\n { type: \"text\", text: JSON.stringify(result) },\n ],\n },\n });\n return;\n }\n\n if (\n req.method === \"notifications/initialized\" ||\n req.method === \"notifications/cancelled\"\n ) {\n // No response to notifications.\n return;\n }\n\n writeMessage({\n jsonrpc: \"2.0\",\n id,\n error: { code: -32601, message: `Method not found: ${req.method}` },\n });\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n writeMessage({\n jsonrpc: \"2.0\",\n id,\n error: { code: -32603, message: msg },\n });\n }\n })();\n });\n\n rl.on(\"close\", () => {\n // Clean exit when stdin closes.\n process.exit(0);\n });\n}\n\n// Re-export for callers that want to pre-warm / test\nexport { readFileSync, isAbsolute };\nexport { writeJson };\n","/**\n * api/server.ts -- GoldenMatch REST API server (node:http).\n *\n * Node-only: uses node:http, node:path. NOT edge-safe.\n *\n * Endpoints:\n * GET /health - liveness check\n * POST /dedupe - dedupe a batch of rows (JSON body)\n * POST /match - match target vs reference\n * POST /score - score two strings\n * POST /explain - explain a pair\n * POST /profile - profile a batch of rows\n * POST /clusters - return clusters from dedupe\n * GET /reviews - list pending review items\n * POST /reviews/decide - accept/reject a review item\n *\n * Ports ideas from goldenmatch/api/server.py.\n */\n\nimport {\n createServer,\n type IncomingMessage,\n type ServerResponse,\n} from \"node:http\";\nimport { resolve, isAbsolute, sep } from \"node:path\";\nimport { dedupe, match, scoreStrings } from \"../../core/api.js\";\nimport type { Row } from \"../../core/types.js\";\nimport {\n makeMatchkeyConfig,\n makeMatchkeyField,\n} from \"../../core/types.js\";\nimport { explainPair } from \"../../core/explain.js\";\nimport { profileRows } from \"../../core/profiler.js\";\n\n// ---------------------------------------------------------------------------\n// In-memory review queue\n// ---------------------------------------------------------------------------\n\ninterface ReviewItem {\n readonly id: string;\n readonly idA: number;\n readonly idB: number;\n readonly score: number;\n readonly rowA: Row;\n readonly rowB: Row;\n status: \"pending\" | \"accepted\" | \"rejected\";\n decidedAt?: string;\n}\n\nclass ReviewQueue {\n private items = new Map<string, ReviewItem>();\n\n enqueue(item: Omit<ReviewItem, \"status\" | \"id\"> & { id?: string }): ReviewItem {\n const id = item.id ?? `${item.idA}:${item.idB}`;\n const rec: ReviewItem = {\n id,\n idA: item.idA,\n idB: item.idB,\n score: item.score,\n rowA: item.rowA,\n rowB: item.rowB,\n status: \"pending\",\n };\n this.items.set(id, rec);\n return rec;\n }\n\n pending(): ReviewItem[] {\n return [...this.items.values()].filter((r) => r.status === \"pending\");\n }\n\n decide(id: string, accept: boolean): ReviewItem | null {\n const existing = this.items.get(id);\n if (!existing) return null;\n existing.status = accept ? \"accepted\" : \"rejected\";\n existing.decidedAt = new Date().toISOString();\n return existing;\n }\n\n all(): ReviewItem[] {\n return [...this.items.values()];\n }\n}\n\nconst reviewQueue = new ReviewQueue();\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\nexport function sanitizePath(raw: string): string {\n const resolved = isAbsolute(raw) ? resolve(raw) : resolve(process.cwd(), raw);\n const cwd = resolve(process.cwd());\n // Guard against prefix-bypass: cwd=\"/app/foo\" must NOT accept \"/app/foobar\".\n if (resolved !== cwd && !resolved.startsWith(cwd + sep)) {\n throw new Error(`Path '${raw}' is outside the working directory`);\n }\n return resolved;\n}\n\nasync function readBody(req: IncomingMessage): Promise<string> {\n let body = \"\";\n for await (const chunk of req) {\n body += typeof chunk === \"string\" ? chunk : (chunk as Buffer).toString(\"utf8\");\n }\n return body;\n}\n\nasync function readJsonBody(req: IncomingMessage): Promise<Record<string, unknown>> {\n const raw = await readBody(req);\n if (!raw) return {};\n try {\n const parsed = JSON.parse(raw);\n if (parsed === null || typeof parsed !== \"object\" || Array.isArray(parsed)) {\n throw new Error(\"request body must be a JSON object\");\n }\n return parsed as Record<string, unknown>;\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n throw new Error(`invalid JSON body: ${msg}`);\n }\n}\n\nfunction sendJson(res: ServerResponse, status: number, data: unknown): void {\n res.statusCode = status;\n res.setHeader(\"Content-Type\", \"application/json\");\n res.end(JSON.stringify(data));\n}\n\nfunction asRowArray(v: unknown, label: string): Row[] {\n if (!Array.isArray(v)) throw new Error(`${label} must be an array of objects`);\n return v as Row[];\n}\n\ninterface ShorthandOpts {\n exact?: readonly string[];\n fuzzy?: Readonly<Record<string, number>>;\n blocking?: readonly string[];\n threshold?: number;\n}\n\nfunction extractShorthand(body: Record<string, unknown>): ShorthandOpts {\n const out: {\n exact?: readonly string[];\n fuzzy?: Readonly<Record<string, number>>;\n blocking?: readonly string[];\n threshold?: number;\n } = {};\n if (Array.isArray(body[\"exact\"])) out.exact = body[\"exact\"].map(String);\n if (Array.isArray(body[\"blocking\"])) out.blocking = body[\"blocking\"].map(String);\n if (body[\"fuzzy\"] && typeof body[\"fuzzy\"] === \"object\" && !Array.isArray(body[\"fuzzy\"])) {\n const f: Record<string, number> = {};\n for (const [k, v] of Object.entries(body[\"fuzzy\"] as Record<string, unknown>)) {\n const n = typeof v === \"number\" ? v : Number(v);\n if (Number.isFinite(n)) f[k] = n;\n }\n out.fuzzy = f;\n }\n if (typeof body[\"threshold\"] === \"number\") out.threshold = body[\"threshold\"];\n return out;\n}\n\n// ---------------------------------------------------------------------------\n// Route handlers\n// ---------------------------------------------------------------------------\n\nasync function handleRequest(\n req: IncomingMessage,\n res: ServerResponse,\n): Promise<void> {\n const url = new URL(req.url ?? \"/\", `http://${req.headers.host ?? \"localhost\"}`);\n const pathname = url.pathname;\n const method = req.method ?? \"GET\";\n\n try {\n if (pathname === \"/health\" && method === \"GET\") {\n sendJson(res, 200, { status: \"ok\", service: \"goldenmatch-js\" });\n return;\n }\n\n if (pathname === \"/dedupe\" && method === \"POST\") {\n const body = await readJsonBody(req);\n const rows = asRowArray(body[\"rows\"], \"rows\");\n const options = extractShorthand(body);\n const result = dedupe(rows, options);\n sendJson(res, 200, {\n stats: {\n total_records: result.stats.totalRecords,\n total_clusters: result.stats.totalClusters,\n match_rate: result.stats.matchRate,\n matched_records: result.stats.matchedRecords,\n unique_records: result.stats.uniqueRecords,\n },\n golden_records: result.goldenRecords,\n dupes: result.dupes,\n unique: result.unique,\n });\n return;\n }\n\n if (pathname === \"/match\" && method === \"POST\") {\n const body = await readJsonBody(req);\n const target = asRowArray(body[\"target\"], \"target\");\n const reference = asRowArray(body[\"reference\"], \"reference\");\n const options = extractShorthand(body);\n const result = match(\n target.map((r) => ({ ...r, __source__: \"target\" })),\n reference.map((r) => ({ ...r, __source__: \"reference\" })),\n options,\n );\n sendJson(res, 200, {\n matched: result.matched,\n unmatched: result.unmatched,\n stats: result.stats,\n });\n return;\n }\n\n if (pathname === \"/score\" && method === \"POST\") {\n const body = await readJsonBody(req);\n const a = String(body[\"a\"] ?? \"\");\n const b = String(body[\"b\"] ?? \"\");\n const scorer = typeof body[\"scorer\"] === \"string\" ? (body[\"scorer\"] as string) : \"jaro_winkler\";\n sendJson(res, 200, { scorer, score: scoreStrings(a, b, scorer) });\n return;\n }\n\n if (pathname === \"/explain\" && method === \"POST\") {\n const body = await readJsonBody(req);\n const rowA = body[\"row_a\"] as Row | undefined;\n const rowB = body[\"row_b\"] as Row | undefined;\n if (!rowA || !rowB) throw new Error(\"row_a and row_b are required\");\n const fieldsRaw = body[\"fields\"];\n if (!Array.isArray(fieldsRaw)) {\n throw new Error(\"fields must be an array\");\n }\n const fields = fieldsRaw.map((entry) => {\n if (!entry || typeof entry !== \"object\") {\n throw new Error(\"each field must be an object\");\n }\n const e = entry as Record<string, unknown>;\n if (typeof e[\"field\"] !== \"string\") {\n throw new Error(\"each field needs a 'field' property\");\n }\n return makeMatchkeyField({\n field: e[\"field\"] as string,\n transforms: Array.isArray(e[\"transforms\"])\n ? (e[\"transforms\"] as unknown[]).map(String)\n : [\"lowercase\", \"strip\"],\n scorer: typeof e[\"scorer\"] === \"string\" ? (e[\"scorer\"] as string) : \"jaro_winkler\",\n weight: typeof e[\"weight\"] === \"number\" ? (e[\"weight\"] as number) : 1.0,\n });\n });\n const threshold = typeof body[\"threshold\"] === \"number\" ? (body[\"threshold\"] as number) : 0.85;\n const mk = makeMatchkeyConfig({\n name: \"adhoc\",\n type: \"weighted\",\n fields,\n threshold,\n });\n const explanation = explainPair(rowA, rowB, mk);\n sendJson(res, 200, {\n score: explanation.score,\n confidence: explanation.confidence,\n explanation: explanation.explanation,\n field_scores: explanation.fieldScores,\n });\n return;\n }\n\n if (pathname === \"/profile\" && method === \"POST\") {\n const body = await readJsonBody(req);\n const rows = asRowArray(body[\"rows\"], \"rows\");\n const profile = profileRows(rows);\n sendJson(res, 200, {\n row_count: profile.rowCount,\n columns: profile.columns.map((c) => ({\n name: c.name,\n inferred_type: c.inferredType,\n null_count: c.nullCount,\n null_rate: c.nullRate,\n distinct_count: c.distinctCount,\n cardinality_ratio: c.cardinalityRatio,\n avg_length: c.avgLength,\n max_length: c.maxLength,\n sample_values: c.sampleValues,\n })),\n });\n return;\n }\n\n if (pathname === \"/clusters\" && method === \"POST\") {\n const body = await readJsonBody(req);\n const rows = asRowArray(body[\"rows\"], \"rows\");\n const options = extractShorthand(body);\n const result = dedupe(rows, options);\n const clusters: Array<{\n cluster_id: number;\n size: number;\n confidence: number;\n quality: string;\n members: readonly number[];\n }> = [];\n for (const [cid, info] of result.clusters.entries()) {\n clusters.push({\n cluster_id: cid,\n size: info.size,\n confidence: info.confidence,\n quality: info.clusterQuality,\n members: info.members,\n });\n }\n sendJson(res, 200, {\n cluster_count: clusters.length,\n clusters,\n });\n return;\n }\n\n if (pathname === \"/reviews\" && method === \"GET\") {\n sendJson(res, 200, { pending: reviewQueue.pending() });\n return;\n }\n\n if (pathname === \"/reviews/decide\" && method === \"POST\") {\n const body = await readJsonBody(req);\n const id = String(body[\"id\"] ?? \"\");\n const accept = Boolean(body[\"accept\"]);\n if (id === \"\") throw new Error(\"id is required\");\n const decided = reviewQueue.decide(id, accept);\n if (!decided) {\n sendJson(res, 404, { error: `review item ${id} not found` });\n return;\n }\n sendJson(res, 200, { decided });\n return;\n }\n\n if (pathname === \"/reviews/enqueue\" && method === \"POST\") {\n const body = await readJsonBody(req);\n const idA = Number(body[\"id_a\"]);\n const idB = Number(body[\"id_b\"]);\n const score = Number(body[\"score\"]);\n const rowA = body[\"row_a\"] as Row | undefined;\n const rowB = body[\"row_b\"] as Row | undefined;\n if (!Number.isFinite(idA) || !Number.isFinite(idB) || !rowA || !rowB) {\n throw new Error(\"id_a, id_b, row_a, row_b are required\");\n }\n const item = reviewQueue.enqueue({\n idA,\n idB,\n score: Number.isFinite(score) ? score : 0,\n rowA,\n rowB,\n });\n sendJson(res, 200, { item });\n return;\n }\n\n sendJson(res, 404, { error: `Not found: ${method} ${pathname}` });\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n sendJson(res, 500, { error: msg });\n }\n}\n\n// ---------------------------------------------------------------------------\n// Public: startApiServer\n// ---------------------------------------------------------------------------\n\nexport interface StartApiOptions {\n readonly port?: number;\n readonly host?: string;\n}\n\n/**\n * Start the REST API server.\n * Default: http://127.0.0.1:8000.\n *\n * Returns the http.Server so tests can close it.\n */\nexport function startApiServer(options: StartApiOptions = {}): ReturnType<typeof createServer> {\n const port = options.port ?? 8000;\n const host = options.host ?? \"127.0.0.1\";\n const server = createServer((req, res) => {\n handleRequest(req, res).catch((err: unknown) => {\n const msg = err instanceof Error ? err.message : String(err);\n console.warn(\"Unhandled request error:\", msg);\n try {\n if (!res.headersSent) {\n res.statusCode = 500;\n res.setHeader(\"Content-Type\", \"application/json\");\n res.end(JSON.stringify({ error: msg }));\n }\n } catch (writeErr) {\n // Response already committed or socket closed — log and move on.\n // eslint-disable-next-line no-console\n console.warn(\n \"Failed to write API error response:\",\n writeErr instanceof Error ? writeErr.message : String(writeErr),\n );\n }\n });\n });\n server.listen(port, host, () => {\n // eslint-disable-next-line no-console\n console.log(`GoldenMatch API listening on http://${host}:${port}`);\n });\n return server;\n}\n\nexport { reviewQueue, ReviewQueue };\n","/**\n * a2a/server.ts -- GoldenMatch A2A (Agent-to-Agent) protocol server.\n *\n * Node-only: uses node:http, node:crypto. NOT edge-safe.\n *\n * Endpoints:\n * GET /.well-known/agent.json - agent card (10+ skills)\n * POST /tasks - create a task (skill + input)\n * GET /tasks/{id} - fetch task status/result\n *\n * Ports ideas from goldenmatch/a2a/server.py. This is a simpler\n * synchronous variant (no SSE streaming, no persistent store).\n */\n\nimport {\n createServer,\n type IncomingMessage,\n type ServerResponse,\n} from \"node:http\";\nimport { randomUUID } from \"node:crypto\";\nimport { dedupe, match, scoreStrings } from \"../../core/api.js\";\nimport { profileRows } from \"../../core/profiler.js\";\nimport { explainPair } from \"../../core/explain.js\";\nimport type { Row } from \"../../core/types.js\";\nimport {\n makeMatchkeyConfig,\n makeMatchkeyField,\n VALID_SCORERS,\n VALID_TRANSFORMS,\n VALID_STRATEGIES,\n} from \"../../core/types.js\";\n\n// ---------------------------------------------------------------------------\n// Agent card\n// ---------------------------------------------------------------------------\n\nexport interface AgentSkill {\n readonly name: string;\n readonly description: string;\n readonly inputModes: readonly string[];\n readonly outputModes: readonly string[];\n}\n\nexport const AGENT_CARD: {\n readonly name: string;\n readonly description: string;\n readonly version: string;\n readonly provider: {\n readonly organization: string;\n readonly url: string;\n };\n readonly capabilities: Readonly<Record<string, boolean>>;\n readonly skills: readonly AgentSkill[];\n} = {\n name: \"goldenmatch-js\",\n description:\n \"Entity resolution agent -- dedupe, match, profile, score, explain, evaluate.\",\n version: \"0.1.0\",\n provider: {\n organization: \"goldenmatch\",\n url: \"https://github.com/benzsevern/goldenmatch\",\n },\n capabilities: {\n streaming: false,\n pushNotifications: false,\n stateTransitionHistory: false,\n },\n skills: [\n {\n name: \"dedupe\",\n description: \"Deduplicate a list of records and return golden records plus clusters.\",\n inputModes: [\"data/json\"],\n outputModes: [\"data/json\"],\n },\n {\n name: \"match\",\n description: \"Match target records against reference records.\",\n inputModes: [\"data/json\"],\n outputModes: [\"data/json\"],\n },\n {\n name: \"score\",\n description: \"Score similarity between two strings.\",\n inputModes: [\"text\"],\n outputModes: [\"text\"],\n },\n {\n name: \"profile\",\n description: \"Profile a dataset (types, null rates, cardinality).\",\n inputModes: [\"data/json\"],\n outputModes: [\"data/json\"],\n },\n {\n name: \"suggest_config\",\n description: \"Auto-generate a shorthand dedupe config from a dataset profile.\",\n inputModes: [\"data/json\"],\n outputModes: [\"data/json\"],\n },\n {\n name: \"explain_pair\",\n description: \"Explain why two records match using weighted field scorers.\",\n inputModes: [\"data/json\"],\n outputModes: [\"data/json\"],\n },\n {\n name: \"evaluate\",\n description: \"Evaluate predicted pairs vs ground truth (precision/recall/F1).\",\n inputModes: [\"data/json\"],\n outputModes: [\"data/json\"],\n },\n {\n name: \"list_scorers\",\n description: \"List all available similarity scorers.\",\n inputModes: [\"text\"],\n outputModes: [\"data/json\"],\n },\n {\n name: \"list_transforms\",\n description: \"List all available field transforms.\",\n inputModes: [\"text\"],\n outputModes: [\"data/json\"],\n },\n {\n name: \"list_strategies\",\n description: \"List all golden-record survivorship strategies.\",\n inputModes: [\"text\"],\n outputModes: [\"data/json\"],\n },\n ],\n};\n\n// ---------------------------------------------------------------------------\n// Task store\n// ---------------------------------------------------------------------------\n\ninterface Task {\n readonly id: string;\n readonly skill: string;\n status: \"pending\" | \"running\" | \"completed\" | \"failed\";\n readonly createdAt: string;\n completedAt?: string;\n result?: unknown;\n error?: string;\n}\n\n// ---------------------------------------------------------------------------\n// Skill dispatch\n// ---------------------------------------------------------------------------\n\nasync function dispatchSkill(\n skill: string,\n input: Record<string, unknown>,\n): Promise<unknown> {\n switch (skill) {\n case \"dedupe\": {\n if (!Array.isArray(input[\"rows\"])) throw new Error(\"rows must be an array\");\n const rows = input[\"rows\"] as Row[];\n const opts: {\n exact?: readonly string[];\n fuzzy?: Readonly<Record<string, number>>;\n blocking?: readonly string[];\n threshold?: number;\n } = {};\n if (Array.isArray(input[\"exact\"])) opts.exact = input[\"exact\"].map(String);\n if (Array.isArray(input[\"blocking\"])) opts.blocking = input[\"blocking\"].map(String);\n if (input[\"fuzzy\"] && typeof input[\"fuzzy\"] === \"object\" && !Array.isArray(input[\"fuzzy\"])) {\n const f: Record<string, number> = {};\n for (const [k, v] of Object.entries(input[\"fuzzy\"] as Record<string, unknown>)) {\n const n = typeof v === \"number\" ? v : Number(v);\n if (Number.isFinite(n)) f[k] = n;\n }\n opts.fuzzy = f;\n }\n if (typeof input[\"threshold\"] === \"number\") opts.threshold = input[\"threshold\"];\n const result = dedupe(rows, opts);\n return {\n stats: {\n total_records: result.stats.totalRecords,\n total_clusters: result.stats.totalClusters,\n match_rate: result.stats.matchRate,\n },\n golden_records: result.goldenRecords,\n };\n }\n\n case \"match\": {\n if (!Array.isArray(input[\"target\"])) throw new Error(\"target must be an array\");\n if (!Array.isArray(input[\"reference\"])) throw new Error(\"reference must be an array\");\n const target = (input[\"target\"] as Row[]).map((r) => ({ ...r, __source__: \"target\" }));\n const reference = (input[\"reference\"] as Row[]).map((r) => ({\n ...r,\n __source__: \"reference\",\n }));\n const opts: {\n exact?: readonly string[];\n fuzzy?: Readonly<Record<string, number>>;\n blocking?: readonly string[];\n threshold?: number;\n } = {};\n if (Array.isArray(input[\"exact\"])) opts.exact = input[\"exact\"].map(String);\n if (Array.isArray(input[\"blocking\"])) opts.blocking = input[\"blocking\"].map(String);\n if (input[\"fuzzy\"] && typeof input[\"fuzzy\"] === \"object\" && !Array.isArray(input[\"fuzzy\"])) {\n const f: Record<string, number> = {};\n for (const [k, v] of Object.entries(input[\"fuzzy\"] as Record<string, unknown>)) {\n const n = typeof v === \"number\" ? v : Number(v);\n if (Number.isFinite(n)) f[k] = n;\n }\n opts.fuzzy = f;\n }\n if (typeof input[\"threshold\"] === \"number\") opts.threshold = input[\"threshold\"];\n const result = match(target, reference, opts);\n return {\n matched: result.matched,\n unmatched: result.unmatched,\n };\n }\n\n case \"score\": {\n const a = String(input[\"a\"] ?? \"\");\n const b = String(input[\"b\"] ?? \"\");\n const scorer = typeof input[\"scorer\"] === \"string\" ? (input[\"scorer\"] as string) : \"jaro_winkler\";\n return { scorer, score: scoreStrings(a, b, scorer) };\n }\n\n case \"profile\": {\n if (!Array.isArray(input[\"rows\"])) throw new Error(\"rows must be an array\");\n const profile = profileRows(input[\"rows\"] as Row[]);\n return {\n row_count: profile.rowCount,\n columns: profile.columns.map((c) => ({\n name: c.name,\n inferred_type: c.inferredType,\n null_rate: c.nullRate,\n cardinality_ratio: c.cardinalityRatio,\n })),\n };\n }\n\n case \"suggest_config\": {\n if (!Array.isArray(input[\"rows\"])) throw new Error(\"rows must be an array\");\n const profile = profileRows(input[\"rows\"] as Row[]);\n const exact: string[] = [];\n const fuzzy: Record<string, number> = {};\n const blocking: string[] = [];\n for (const col of profile.columns) {\n if (col.nullRate > 0.2) continue;\n if (col.inferredType === \"email\" && col.cardinalityRatio >= 0.5) exact.push(col.name);\n else if (col.inferredType === \"phone\" && col.cardinalityRatio >= 0.5) exact.push(col.name);\n else if (col.inferredType === \"zip\" || col.inferredType === \"geo\") blocking.push(col.name);\n else if (col.inferredType === \"name\") fuzzy[col.name] = 0.85;\n else if (col.inferredType === \"text\" && col.avgLength > 4) fuzzy[col.name] = 0.8;\n }\n return { suggested: { exact, fuzzy, blocking, threshold: 0.85 } };\n }\n\n case \"explain_pair\": {\n const rowA = input[\"row_a\"] as Row | undefined;\n const rowB = input[\"row_b\"] as Row | undefined;\n if (!rowA || !rowB) throw new Error(\"row_a and row_b are required\");\n const fieldsRaw = input[\"fields\"];\n if (!Array.isArray(fieldsRaw)) throw new Error(\"fields must be an array\");\n const fields = fieldsRaw.map((entry) => {\n const e = entry as Record<string, unknown>;\n return makeMatchkeyField({\n field: String(e[\"field\"]),\n transforms: Array.isArray(e[\"transforms\"])\n ? (e[\"transforms\"] as unknown[]).map(String)\n : [\"lowercase\", \"strip\"],\n scorer: typeof e[\"scorer\"] === \"string\" ? (e[\"scorer\"] as string) : \"jaro_winkler\",\n weight: typeof e[\"weight\"] === \"number\" ? (e[\"weight\"] as number) : 1.0,\n });\n });\n const mk = makeMatchkeyConfig({\n name: \"adhoc\",\n type: \"weighted\",\n fields,\n threshold: typeof input[\"threshold\"] === \"number\" ? (input[\"threshold\"] as number) : 0.85,\n });\n const result = explainPair(rowA, rowB, mk);\n return {\n score: result.score,\n confidence: result.confidence,\n explanation: result.explanation,\n };\n }\n\n case \"evaluate\": {\n // Accept pre-computed predicted/truth pairs for simplicity.\n const predicted = Array.isArray(input[\"predicted\"])\n ? (input[\"predicted\"] as unknown[]).map((p) => {\n const pair = p as Record<string, unknown>;\n return [Number(pair[\"id_a\"]), Number(pair[\"id_b\"])] as const;\n })\n : [];\n const truth = Array.isArray(input[\"truth\"])\n ? (input[\"truth\"] as unknown[]).map((p) => {\n const pair = p as Record<string, unknown>;\n return [Number(pair[\"id_a\"]), Number(pair[\"id_b\"])] as const;\n })\n : [];\n const truthSet = new Set(truth.map(([a, b]) => `${Math.min(a, b)}:${Math.max(a, b)}`));\n const predSet = new Set(\n predicted.map(([a, b]) => `${Math.min(a, b)}:${Math.max(a, b)}`),\n );\n let tp = 0;\n let fp = 0;\n for (const p of predSet) {\n if (truthSet.has(p)) tp++;\n else fp++;\n }\n let fn = 0;\n for (const t of truthSet) {\n if (!predSet.has(t)) fn++;\n }\n const precision = tp + fp > 0 ? tp / (tp + fp) : 0;\n const recall = tp + fn > 0 ? tp / (tp + fn) : 0;\n const f1 = precision + recall > 0 ? (2 * precision * recall) / (precision + recall) : 0;\n return { tp, fp, fn, precision, recall, f1 };\n }\n\n case \"list_scorers\":\n return { scorers: [...VALID_SCORERS] };\n\n case \"list_transforms\":\n return { transforms: [...VALID_TRANSFORMS] };\n\n case \"list_strategies\":\n return { strategies: [...VALID_STRATEGIES] };\n\n default:\n throw new Error(`Unknown skill: ${skill}`);\n }\n}\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\nasync function readJsonBody(req: IncomingMessage): Promise<Record<string, unknown>> {\n let body = \"\";\n for await (const chunk of req) {\n body += typeof chunk === \"string\" ? chunk : (chunk as Buffer).toString(\"utf8\");\n }\n if (!body) return {};\n const parsed = JSON.parse(body);\n if (parsed === null || typeof parsed !== \"object\" || Array.isArray(parsed)) {\n throw new Error(\"body must be a JSON object\");\n }\n return parsed as Record<string, unknown>;\n}\n\nfunction sendJson(res: ServerResponse, status: number, data: unknown): void {\n res.statusCode = status;\n res.setHeader(\"Content-Type\", \"application/json\");\n res.end(JSON.stringify(data));\n}\n\n// ---------------------------------------------------------------------------\n// Public: startA2aServer\n// ---------------------------------------------------------------------------\n\nexport interface StartA2aOptions {\n readonly port?: number;\n readonly host?: string;\n}\n\nexport function startA2aServer(options: StartA2aOptions = {}): ReturnType<typeof createServer> {\n const port = options.port ?? 8200;\n const host = options.host ?? \"127.0.0.1\";\n const tasks = new Map<string, Task>();\n\n const server = createServer(async (req, res) => {\n const url = new URL(req.url ?? \"/\", `http://${req.headers.host ?? \"localhost\"}`);\n const pathname = url.pathname;\n const methodName = req.method ?? \"GET\";\n\n try {\n if (pathname === \"/.well-known/agent.json\" && methodName === \"GET\") {\n sendJson(res, 200, AGENT_CARD);\n return;\n }\n\n if (pathname === \"/health\" && methodName === \"GET\") {\n sendJson(res, 200, { status: \"ok\", agent: \"goldenmatch-js\" });\n return;\n }\n\n if (pathname === \"/tasks\" && methodName === \"POST\") {\n const body = await readJsonBody(req);\n const skill = String(body[\"skill\"] ?? \"\");\n const input =\n (body[\"input\"] as Record<string, unknown> | undefined) ??\n (body[\"params\"] as Record<string, unknown> | undefined) ??\n {};\n if (!skill) {\n sendJson(res, 400, { error: \"skill is required\" });\n return;\n }\n const id = randomUUID();\n const createdAt = new Date().toISOString();\n const task: Task = {\n id,\n skill,\n status: \"running\",\n createdAt,\n };\n tasks.set(id, task);\n\n try {\n const result = await dispatchSkill(skill, input);\n task.status = \"completed\";\n task.completedAt = new Date().toISOString();\n task.result = result;\n sendJson(res, 200, {\n id,\n status: task.status,\n skill,\n created_at: createdAt,\n completed_at: task.completedAt,\n result,\n });\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n task.status = \"failed\";\n task.completedAt = new Date().toISOString();\n task.error = msg;\n sendJson(res, 200, {\n id,\n status: task.status,\n skill,\n created_at: createdAt,\n completed_at: task.completedAt,\n error: msg,\n });\n }\n return;\n }\n\n if (pathname.startsWith(\"/tasks/\") && methodName === \"GET\") {\n const id = pathname.slice(\"/tasks/\".length);\n const task = tasks.get(id);\n if (!task) {\n sendJson(res, 404, { error: `Task not found: ${id}` });\n return;\n }\n sendJson(res, 200, {\n id: task.id,\n skill: task.skill,\n status: task.status,\n created_at: task.createdAt,\n completed_at: task.completedAt ?? null,\n result: task.result ?? null,\n error: task.error ?? null,\n });\n return;\n }\n\n sendJson(res, 404, { error: `Not found: ${methodName} ${pathname}` });\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n sendJson(res, 500, { error: msg });\n }\n });\n\n server.listen(port, host, () => {\n // eslint-disable-next-line no-console\n console.log(`GoldenMatch A2A agent listening on http://${host}:${port}`);\n });\n return server;\n}\n","/**\n * widgets.ts -- Optional ink ecosystem addon loaders.\n *\n * Each addon (ink-table, ink-select-input, ink-text-input, ink-spinner,\n * ink-gradient) is an optional peer dependency. We provide a uniform\n * mechanism to try-load them so callers can render rich UI when installed\n * and fall back to plain `ink.Text` / `ink.Box` output otherwise.\n *\n * Two loading styles are provided:\n * - `tryLoad<T>(name)`: synchronous `require`-based load. Works for CJS\n * packages (ink-select-input, ink-text-input, ink-spinner, ink-gradient\n * in older versions).\n * - `loadAddons()`: async dynamic `import()` load. Works for ESM-only\n * packages (ink-table v3+).\n *\n * Both return `null` for a missing package rather than throwing, so the\n * caller can branch on presence.\n */\n\nimport { createRequire } from \"node:module\";\n\n/* eslint-disable @typescript-eslint/no-explicit-any */\n\nconst require = createRequire(import.meta.url);\n\n/**\n * Synchronously try to require a package. Returns `null` if the package is\n * not installed (or fails to load for any reason).\n */\nexport function tryLoad<T = any>(name: string): T | null {\n try {\n return require(name) as T;\n } catch {\n return null;\n }\n}\n\n/**\n * Lazy-getter bag of synchronously-loaded ink addons. Each access retries\n * the require in case the environment changed, but most callers will prefer\n * `loadAddons()` (async) since ink-table is ESM-only.\n */\nexport const inkAddons = {\n get table(): any {\n return tryLoad(\"ink-table\");\n },\n get selectInput(): any {\n return tryLoad(\"ink-select-input\");\n },\n get textInput(): any {\n return tryLoad(\"ink-text-input\");\n },\n get spinner(): any {\n return tryLoad(\"ink-spinner\");\n },\n get gradient(): any {\n return tryLoad(\"ink-gradient\");\n },\n};\n\n/**\n * Collected addon components, each either the default export of its package\n * or `null` if the package isn't installed.\n */\nexport interface LoadedAddons {\n Table: any | null;\n SelectInput: any | null;\n TextInput: any | null;\n Spinner: any | null;\n Gradient: any | null;\n}\n\n/**\n * Asynchronously load all optional ink addons via dynamic `import()`.\n *\n * Uses `import()` rather than `require()` because ink-table v3+ ships as\n * ESM-only and cannot be loaded from CJS. The other addons work either\n * way; we standardise on import for consistency.\n *\n * Any addon that fails to load (missing package, import error, etc.) is\n * silently set to `null`. Callers should branch on each field.\n */\nexport async function loadAddons(): Promise<LoadedAddons> {\n const addons: LoadedAddons = {\n Table: null,\n SelectInput: null,\n TextInput: null,\n Spinner: null,\n Gradient: null,\n };\n\n // Wrap each import in its own try so a single missing addon doesn't\n // poison the others.\n try {\n const mod: any = await import(\"ink-table\" as string);\n addons.Table = mod.default ?? mod;\n } catch {\n /* optional */\n }\n try {\n const mod: any = await import(\"ink-select-input\" as string);\n addons.SelectInput = mod.default ?? mod;\n } catch {\n /* optional */\n }\n try {\n const mod: any = await import(\"ink-text-input\" as string);\n addons.TextInput = mod.default ?? mod;\n } catch {\n /* optional */\n }\n try {\n const mod: any = await import(\"ink-spinner\" as string);\n addons.Spinner = mod.default ?? mod;\n } catch {\n /* optional */\n }\n try {\n const mod: any = await import(\"ink-gradient\" as string);\n addons.Gradient = mod.default ?? mod;\n } catch {\n /* optional */\n }\n\n return addons;\n}\n\n/* eslint-enable @typescript-eslint/no-explicit-any */\n","/**\n * app.ts -- GoldenMatch interactive TUI built on `ink` (React for CLIs).\n *\n * This module loads `ink` and `react` lazily via `createRequire` so the rest\n * of the package stays usable without those optional peer dependencies.\n *\n * The UI mirrors the Python Textual TUI: 6 tabs (Data, Config, Matches,\n * Golden, Boost, Export) with keyboard navigation [1..6], [Tab] to cycle,\n * [r] to run dedupe, [q] / [Esc] to quit.\n *\n * Richer ink-ecosystem addons (ink-table, ink-select-input, ink-text-input,\n * ink-spinner, ink-gradient) are optional peer deps loaded lazily via\n * ./widgets.js. Each tab degrades gracefully to plain text when an addon is\n * not installed.\n *\n * Implementation notes:\n * - Uses React.createElement directly (no JSX) so we don't need a JSX\n * transform in the existing tsup build.\n * - The `ink` / `react` modules are typed as `any` at the boundary because\n * they're optional peer deps; we don't want to require `@types/react`\n * just to satisfy strict typecheck.\n */\n\nimport { createRequire } from \"node:module\";\nimport type { Row, GoldenMatchConfig, DedupeResult } from \"../../core/types.js\";\nimport { loadAddons, type LoadedAddons } from \"./widgets.js\";\n\nconst require = createRequire(import.meta.url);\n\n// ---------------------------------------------------------------------------\n// Optional peer dependency loaders\n// ---------------------------------------------------------------------------\n\n/* eslint-disable @typescript-eslint/no-explicit-any */\n\nfunction loadInk(): any {\n try {\n return require(\"ink\");\n } catch {\n throw new Error(\n \"'ink' and 'react' are required for the TUI. Install with: npm install ink react\",\n );\n }\n}\n\nfunction loadReact(): any {\n try {\n return require(\"react\");\n } catch {\n throw new Error(\n \"'react' is required for the TUI. Install with: npm install react\",\n );\n }\n}\n\n// ---------------------------------------------------------------------------\n// Public API\n// ---------------------------------------------------------------------------\n\nexport interface TuiOptions {\n readonly files?: readonly string[];\n readonly config?: GoldenMatchConfig;\n}\n\n/**\n * Launch the GoldenMatch TUI. Resolves once the user quits.\n */\nexport async function startTui(options: TuiOptions = {}): Promise<void> {\n const ink = loadInk();\n const React = loadReact();\n const h = React.createElement;\n\n // Load optional ink-ecosystem addons (each may be null).\n const addons: LoadedAddons = await loadAddons();\n\n // -------------------------------------------------------------------------\n // File loader (lazy import so the TUI module stays light)\n // -------------------------------------------------------------------------\n\n const loadFiles = async (files: readonly string[]): Promise<Row[]> => {\n const { readFile } = await import(\"../connectors/file.js\");\n const all: Row[] = [];\n for (let i = 0; i < files.length; i++) {\n const f = files[i]!;\n const fileRows = readFile(f);\n for (const r of fileRows) {\n all.push({ ...r, __source__: `file_${i}` });\n }\n }\n return all;\n };\n\n // -------------------------------------------------------------------------\n // Tab components\n // -------------------------------------------------------------------------\n\n const MAX_TABLE_COLS = 5;\n const MAX_TABLE_ROWS = 10;\n\n const visibleCols = (row: Row): string[] =>\n Object.keys(row).filter((c) => !c.startsWith(\"__\"));\n\n const DataTab = (props: { rows: readonly Row[] }) => {\n const { rows } = props;\n if (rows.length === 0) {\n return h(\n ink.Text,\n { dimColor: true },\n \"No data loaded. Pass files as CLI args.\",\n );\n }\n const cols = visibleCols(rows[0]!).slice(0, MAX_TABLE_COLS);\n\n if (addons.Table) {\n const display = rows.slice(0, MAX_TABLE_ROWS).map((r) => {\n const d: Record<string, string> = {};\n for (const c of cols) {\n const v = (r as Record<string, unknown>)[c];\n d[c] = v === undefined || v === null ? \"\" : String(v);\n }\n return d;\n });\n return h(\n ink.Box,\n { flexDirection: \"column\" },\n h(\n ink.Text,\n {},\n `${rows.length} rows, showing first ${Math.min(\n MAX_TABLE_ROWS,\n rows.length,\n )} (cols: ${cols.join(\", \")})`,\n ),\n h(addons.Table, { data: display }),\n );\n }\n\n return h(\n ink.Box,\n { flexDirection: \"column\" },\n h(ink.Text, {}, `${rows.length} rows loaded`),\n h(\n ink.Text,\n { dimColor: true },\n \"Columns: \" + (cols.length > 0 ? cols.join(\", \") : \"-\"),\n ),\n ...rows.slice(0, MAX_TABLE_ROWS).map((row, i) =>\n h(\n ink.Text,\n { key: `row-${i}`, dimColor: true },\n cols\n .map((c) => {\n const v = (row as Record<string, unknown>)[c];\n return `${c}=${v ?? \"\"}`;\n })\n .join(\" | \"),\n ),\n ),\n );\n };\n\n const ConfigTab = (props: { config: GoldenMatchConfig | null }) => {\n const { config } = props;\n const mks = config?.matchkeys ?? config?.matchSettings ?? [];\n const blockingDesc = config?.blocking?.strategy ?? \"-\";\n const blockingKeys =\n config?.blocking?.keys?.map((k) => k.fields.join(\"+\")).join(\", \") ?? \"-\";\n\n // Local UI state for interactive config editing. Hooks must be at the\n // top level of the component — we always declare them and only use the\n // interactive branch when SelectInput/TextInput are available.\n const [selectedMk, setSelectedMk] = React.useState(null) as [\n number | null,\n (v: number | null) => void,\n ];\n const [thresholdDraft, setThresholdDraft] = React.useState(\"\") as [\n string,\n (v: string) => void,\n ];\n\n const header = h(\n ink.Box,\n { flexDirection: \"column\" },\n h(ink.Text, { bold: true }, \"Config\"),\n h(ink.Text, {}, `Matchkeys: ${mks.length}`),\n h(ink.Text, {}, `Blocking: ${blockingDesc}, keys: ${blockingKeys}`),\n );\n\n if (mks.length === 0) {\n return header;\n }\n\n const mkThreshold = (mk: { readonly type: string }): string => {\n if (mk.type === \"exact\") return \"-\";\n const t = (mk as { threshold?: number }).threshold;\n return t === undefined ? \"-\" : String(t);\n };\n\n if (addons.SelectInput && selectedMk === null) {\n const items = mks.map((mk, i) => ({\n label: `${mk.name} (${mk.type}) threshold=${mkThreshold(mk)}`,\n value: String(i),\n }));\n return h(\n ink.Box,\n { flexDirection: \"column\" },\n header,\n h(ink.Text, { dimColor: true }, \"Select a matchkey to inspect:\"),\n h(addons.SelectInput, {\n items,\n onSelect: (item: { value: string }) => {\n const idx = Number(item.value);\n setSelectedMk(idx);\n const picked = mks[idx];\n const thr =\n picked && picked.type !== \"exact\"\n ? ((picked as { threshold?: number }).threshold ?? \"\")\n : \"\";\n setThresholdDraft(String(thr));\n },\n }),\n );\n }\n\n if (addons.SelectInput && selectedMk !== null) {\n const mk = mks[selectedMk];\n if (!mk) {\n setSelectedMk(null);\n return header;\n }\n const fields = mk.fields.map((f) => f.field).join(\", \");\n return h(\n ink.Box,\n { flexDirection: \"column\" },\n header,\n h(ink.Text, { bold: true }, `Editing matchkey: ${mk.name}`),\n h(ink.Text, {}, ` type: ${mk.type}`),\n h(ink.Text, {}, ` fields: ${fields}`),\n addons.TextInput\n ? h(\n ink.Box,\n {},\n h(ink.Text, {}, \" threshold: \"),\n h(addons.TextInput, {\n value: thresholdDraft,\n onChange: setThresholdDraft,\n onSubmit: (value: string) => {\n const n = Number(value);\n if (!Number.isNaN(n)) {\n (mk as { threshold?: number }).threshold = n;\n }\n setSelectedMk(null);\n },\n }),\n )\n : h(\n ink.Text,\n { dimColor: true },\n ` threshold: ${mkThreshold(mk)} (install ink-text-input to edit)`,\n ),\n h(ink.Text, { dimColor: true }, \"[Enter] save [Esc] back\"),\n );\n }\n\n // Fallback: plain listing\n return h(\n ink.Box,\n { flexDirection: \"column\" },\n header,\n ...mks.map((mk, i) =>\n h(\n ink.Text,\n { key: `mk-${i}`, dimColor: true },\n ` - ${mk.name} (${mk.type}), threshold=${mkThreshold(mk)}, fields: ${mk.fields\n .map((f) => f.field)\n .join(\", \")}`,\n ),\n ),\n );\n };\n\n const MatchesTab = (props: { result: DedupeResult | null }) => {\n const { result } = props;\n const [selectedPair, setSelectedPair] = React.useState(null) as [\n number | null,\n (v: number | null) => void,\n ];\n\n if (!result) {\n return h(\n ink.Text,\n { dimColor: true },\n \"No results yet. Press 'r' to run dedupe.\",\n );\n }\n const pairs = result.scoredPairs.slice(0, MAX_TABLE_ROWS);\n if (pairs.length === 0) {\n return h(ink.Text, {}, \"No scored pairs\");\n }\n\n // Drill-in view\n if (addons.SelectInput && selectedPair !== null) {\n const p = pairs[selectedPair];\n if (!p) {\n setSelectedPair(null);\n return h(ink.Text, {}, \"\");\n }\n return h(\n ink.Box,\n { flexDirection: \"column\" },\n h(ink.Text, { bold: true }, `Pair detail ${selectedPair + 1}/${pairs.length}`),\n h(ink.Text, {}, ` idA: ${p.idA}`),\n h(ink.Text, {}, ` idB: ${p.idB}`),\n h(ink.Text, {}, ` score: ${p.score.toFixed(4)}`),\n h(ink.Text, { dimColor: true }, \"(select another pair from list)\"),\n h(addons.SelectInput, {\n items: pairs.map((pp, i) => ({\n label: `${pp.idA} <-> ${pp.idB} (${pp.score.toFixed(3)})`,\n value: String(i),\n })),\n onSelect: (item: { value: string }) =>\n setSelectedPair(Number(item.value)),\n }),\n );\n }\n\n if (addons.Table) {\n const data = pairs.map((p) => ({\n idA: String(p.idA),\n idB: String(p.idB),\n score: p.score.toFixed(4),\n }));\n return h(\n ink.Box,\n { flexDirection: \"column\" },\n h(\n ink.Text,\n { bold: true },\n `Scored pairs: ${result.scoredPairs.length} (showing first ${pairs.length})`,\n ),\n h(addons.Table, { data }),\n addons.SelectInput\n ? h(addons.SelectInput, {\n items: pairs.map((p, i) => ({\n label: `Inspect ${p.idA} <-> ${p.idB}`,\n value: String(i),\n })),\n onSelect: (item: { value: string }) =>\n setSelectedPair(Number(item.value)),\n })\n : h(\n ink.Text,\n { dimColor: true },\n \"(install ink-select-input for drill-in)\",\n ),\n );\n }\n\n return h(\n ink.Box,\n { flexDirection: \"column\" },\n h(\n ink.Text,\n { bold: true },\n `Scored pairs: ${result.scoredPairs.length}`,\n ),\n ...pairs.map((p, i) =>\n h(\n ink.Text,\n { key: `pair-${i}` },\n ` ${p.idA} <-> ${p.idB}: ${p.score.toFixed(3)}`,\n ),\n ),\n );\n };\n\n const GoldenTab = (props: { result: DedupeResult | null }) => {\n const { result } = props;\n if (!result) return h(ink.Text, { dimColor: true }, \"No results yet.\");\n const records = result.goldenRecords.slice(0, MAX_TABLE_ROWS);\n\n if (records.length === 0) {\n return h(\n ink.Text,\n { bold: true },\n `Golden records: ${result.goldenRecords.length}`,\n );\n }\n\n if (addons.Table) {\n const cols = visibleCols(records[0]!).slice(0, MAX_TABLE_COLS);\n const data = records.map((r) => {\n const d: Record<string, string> = {};\n for (const c of cols) {\n const v = (r as Record<string, unknown>)[c];\n d[c] = v === undefined || v === null ? \"\" : String(v);\n }\n return d;\n });\n return h(\n ink.Box,\n { flexDirection: \"column\" },\n h(\n ink.Text,\n { bold: true },\n `Golden records: ${result.goldenRecords.length}`,\n ),\n h(addons.Table, { data }),\n );\n }\n\n return h(\n ink.Box,\n { flexDirection: \"column\" },\n h(\n ink.Text,\n { bold: true },\n `Golden records: ${result.goldenRecords.length}`,\n ),\n ...records.map((r, i) =>\n h(\n ink.Text,\n { key: `g-${i}`, dimColor: true },\n JSON.stringify(r).slice(0, 100),\n ),\n ),\n );\n };\n\n const BoostTab = (props: { result: DedupeResult | null }) => {\n const { result } = props;\n const [idx, setIdx] = React.useState(0) as [\n number,\n (v: number | ((prev: number) => number)) => void,\n ];\n const [labels, setLabels] = React.useState({}) as [\n Record<number, string>,\n (v: Record<number, string>) => void,\n ];\n\n if (!result) {\n return h(\n ink.Text,\n { dimColor: true },\n \"No results yet. Press 'r' to run dedupe.\",\n );\n }\n\n const borderline = result.scoredPairs\n .filter((p) => p.score >= 0.7 && p.score < 0.9)\n .slice(0, 20);\n\n if (borderline.length === 0) {\n return h(\n ink.Box,\n { flexDirection: \"column\" },\n h(ink.Text, { bold: true }, \"Boost - active learning\"),\n h(ink.Text, {}, \"No borderline pairs (0.7-0.9 score) to label.\"),\n );\n }\n\n if (idx >= borderline.length) {\n const counts = Object.values(labels).reduce(\n (acc, v) => {\n acc[v] = (acc[v] ?? 0) + 1;\n return acc;\n },\n {} as Record<string, number>,\n );\n return h(\n ink.Box,\n { flexDirection: \"column\" },\n h(ink.Text, { color: \"green\", bold: true }, \"All pairs labeled!\"),\n h(\n ink.Text,\n {},\n `y=${counts[\"y\"] ?? 0} n=${counts[\"n\"] ?? 0} s=${counts[\"s\"] ?? 0}`,\n ),\n );\n }\n\n const pair = borderline[idx]!;\n\n if (addons.SelectInput) {\n return h(\n ink.Box,\n { flexDirection: \"column\" },\n h(\n ink.Text,\n { bold: true },\n `Pair ${idx + 1}/${borderline.length} - Score: ${pair.score.toFixed(3)}`,\n ),\n h(ink.Text, {}, ` Record ${pair.idA}`),\n h(ink.Text, {}, ` Record ${pair.idB}`),\n h(addons.SelectInput, {\n items: [\n { label: \"Yes, this is a match\", value: \"y\" },\n { label: \"No, different entities\", value: \"n\" },\n { label: \"Skip\", value: \"s\" },\n ],\n onSelect: (item: { value: string }) => {\n setLabels({ ...labels, [idx]: item.value });\n setIdx((prev) => prev + 1);\n },\n }),\n );\n }\n\n return h(\n ink.Box,\n { flexDirection: \"column\" },\n h(ink.Text, { bold: true }, \"Boost - active learning\"),\n h(ink.Text, { dimColor: true }, \"Label borderline pairs: y/n/s (skip)\"),\n h(\n ink.Text,\n {},\n `Pair ${idx + 1}/${borderline.length}: ${pair.idA} <-> ${pair.idB} (${pair.score.toFixed(3)})`,\n ),\n h(\n ink.Text,\n { dimColor: true },\n \"Install ink-select-input for interactive labeling\",\n ),\n );\n };\n\n const ExportTab = (props: {\n result: DedupeResult | null;\n setStatus: (s: string) => void;\n }) => {\n const { result, setStatus } = props;\n const [exporting, setExporting] = React.useState(false) as [\n boolean,\n (v: boolean) => void,\n ];\n const [done, setDone] = React.useState(null) as [\n string | null,\n (v: string | null) => void,\n ];\n\n if (!result) {\n return h(ink.Text, { dimColor: true }, \"No results yet.\");\n }\n\n const doExport = (format: string) => {\n setExporting(true);\n setDone(null);\n setStatus(`Exporting as ${format}...`);\n // Simulate async write. Real impl would dispatch to a writer.\n setTimeout(() => {\n setExporting(false);\n setDone(format);\n setStatus(`Export complete (${format})`);\n }, 400);\n };\n\n if (exporting) {\n return h(\n ink.Box,\n { flexDirection: \"column\" },\n h(ink.Text, { bold: true }, \"Export\"),\n addons.Spinner\n ? h(\n ink.Box,\n {},\n h(addons.Spinner, { type: \"dots\" }),\n h(ink.Text, {}, \" writing...\"),\n )\n : h(ink.Text, {}, \"writing...\"),\n );\n }\n\n const summary = h(\n ink.Text,\n {},\n `Ready: ${result.goldenRecords.length} golden, ${result.dupes.length} dupes, ${result.unique.length} unique`,\n );\n\n if (addons.SelectInput) {\n return h(\n ink.Box,\n { flexDirection: \"column\" },\n h(ink.Text, { bold: true }, \"Export\"),\n summary,\n done\n ? h(\n ink.Text,\n { color: \"green\" },\n `Last export: ${done}. Choose another format to export again.`,\n )\n : h(ink.Text, { dimColor: true }, \"Choose output format:\"),\n h(addons.SelectInput, {\n items: [\n { label: \"CSV\", value: \"csv\" },\n { label: \"JSON\", value: \"json\" },\n ],\n onSelect: (item: { value: string }) => doExport(item.value),\n }),\n );\n }\n\n return h(\n ink.Box,\n { flexDirection: \"column\" },\n h(ink.Text, { bold: true }, \"Export\"),\n h(\n ink.Text,\n { dimColor: true },\n \"Press [g] for golden, [d] for dupes, [u] for unique\",\n ),\n summary,\n );\n };\n\n // -------------------------------------------------------------------------\n // Top-level App\n // -------------------------------------------------------------------------\n\n const App = (props: { options: TuiOptions }) => {\n const [tab, setTab] = React.useState(0) as [\n number,\n (v: number | ((prev: number) => number)) => void,\n ];\n const [rows, setRows] = React.useState([]) as [\n readonly Row[],\n (v: readonly Row[]) => void,\n ];\n const [result, setResult] = React.useState(null) as [\n DedupeResult | null,\n (v: DedupeResult | null) => void,\n ];\n const [config] = React.useState(props.options.config ?? null) as [\n GoldenMatchConfig | null,\n (v: GoldenMatchConfig | null) => void,\n ];\n const [status, setStatus] = React.useState(\"Ready\") as [\n string,\n (v: string) => void,\n ];\n\n const { exit } = ink.useApp();\n\n const runDedupe = React.useCallback(async () => {\n if (rows.length === 0) {\n setStatus(\"No rows loaded\");\n return;\n }\n setStatus(\"Running dedupe...\");\n try {\n const { dedupe } = await import(\"../../core/api.js\");\n const r = dedupe(rows, config ? { config } : {});\n setResult(r);\n setStatus(`Complete: ${r.stats.totalClusters} clusters`);\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n setStatus(`Error: ${msg}`);\n }\n }, [rows, config]);\n\n ink.useInput((input: string, key: any) => {\n if (key.escape || input === \"q\") {\n exit();\n return;\n }\n if (input === \"1\") setTab(0);\n else if (input === \"2\") setTab(1);\n else if (input === \"3\") setTab(2);\n else if (input === \"4\") setTab(3);\n else if (input === \"5\") setTab(4);\n else if (input === \"6\") setTab(5);\n else if (key.tab) setTab((t: number) => (t + 1) % 6);\n else if (input === \"r\") {\n void runDedupe();\n }\n });\n\n React.useEffect(() => {\n const files = props.options.files;\n if (files && files.length > 0) {\n loadFiles(files)\n .then((rs) => {\n setRows(rs);\n setStatus(`Loaded ${rs.length} rows from ${files.length} file(s)`);\n })\n .catch((err: unknown) => {\n const msg = err instanceof Error ? err.message : String(err);\n setStatus(`Error: ${msg}`);\n });\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n\n const tabs = [\"Data\", \"Config\", \"Matches\", \"Golden\", \"Boost\", \"Export\"];\n\n let body: any = null;\n if (tab === 0) body = h(DataTab, { rows });\n else if (tab === 1) body = h(ConfigTab, { config });\n else if (tab === 2) body = h(MatchesTab, { result });\n else if (tab === 3) body = h(GoldenTab, { result });\n else if (tab === 4) body = h(BoostTab, { result });\n else if (tab === 5) body = h(ExportTab, { result, setStatus });\n\n const titleText = \"GoldenMatch TUI - v0.1.0\";\n const title = addons.Gradient\n ? h(\n addons.Gradient,\n { name: \"rainbow\" },\n h(ink.Text, { bold: true }, titleText),\n )\n : h(ink.Text, { bold: true, color: \"cyan\" }, titleText);\n\n return h(\n ink.Box,\n { flexDirection: \"column\", padding: 1 },\n // Header\n h(ink.Box, { borderStyle: \"double\", paddingX: 1 }, title),\n // Tab bar\n h(\n ink.Box,\n { marginTop: 1 },\n ...tabs.map((name: string, i: number) =>\n h(\n ink.Box,\n { key: `tab-${i}`, marginRight: 2 },\n h(\n ink.Text,\n { color: tab === i ? \"green\" : \"gray\", bold: tab === i },\n `[${i + 1}] ${name}`,\n ),\n ),\n ),\n ),\n // Tab content\n h(\n ink.Box,\n { marginTop: 1, flexDirection: \"column\", minHeight: 10 },\n body,\n ),\n // Footer\n h(\n ink.Box,\n { marginTop: 1, borderStyle: \"single\", paddingX: 1 },\n h(\n ink.Text,\n { dimColor: true },\n `[q]uit [1-6] tabs [Tab] cycle [r]un dedupe * ${status}`,\n ),\n ),\n );\n };\n\n const { waitUntilExit } = ink.render(h(App, { options }));\n await waitUntilExit();\n}\n\n/* eslint-enable @typescript-eslint/no-explicit-any */\n","#!/usr/bin/env node\n/**\n * cli.ts -- GoldenMatch command-line interface.\n *\n * Built on commander. Exposes `dedupe`, `match`, `score`, `profile`,\n * `info`, and `demo` subcommands.\n */\n\nimport { Command } from \"commander\";\nimport { extname, basename } from \"node:path\";\nimport {\n readFile,\n writeCsv,\n writeJson,\n} from \"./node/connectors/file.js\";\nimport { dedupe, match, scoreStrings } from \"./core/api.js\";\nimport { loadConfigFile } from \"./node/config-file.js\";\nimport type { Row } from \"./core/types.js\";\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\nfunction parseFuzzyArg(raw: string): Record<string, number> {\n const out: Record<string, number> = {};\n for (const pair of raw.split(\",\")) {\n const trimmed = pair.trim();\n if (trimmed === \"\") continue;\n const idx = trimmed.indexOf(\":\");\n let field: string;\n let threshold = 0.85;\n if (idx === -1) {\n field = trimmed;\n } else {\n field = trimmed.slice(0, idx).trim();\n const rawThreshold = trimmed.slice(idx + 1).trim();\n const parsed = parseFloat(rawThreshold);\n if (Number.isFinite(parsed)) threshold = parsed;\n }\n if (field !== \"\") out[field] = threshold;\n }\n return out;\n}\n\nfunction parseCsvList(raw: string): string[] {\n return raw\n .split(\",\")\n .map((s) => s.trim())\n .filter((s) => s.length > 0);\n}\n\nfunction loadFilesWithSource(paths: readonly string[]): Row[] {\n const rows: Row[] = [];\n for (let i = 0; i < paths.length; i++) {\n const p = paths[i]!;\n const source = basename(p, extname(p)) || `file_${i}`;\n const fileRows = readFile(p);\n for (const r of fileRows) {\n rows.push({ ...r, __source__: source });\n }\n }\n return rows;\n}\n\ninterface SharedMatchOpts {\n config?: string;\n exact?: string;\n fuzzy?: string;\n blocking?: string;\n threshold?: number;\n output?: string;\n format?: string;\n}\n\nfunction buildOptionsFromFlags(opts: SharedMatchOpts) {\n const out: {\n config?: ReturnType<typeof loadConfigFile>;\n exact?: string[];\n fuzzy?: Record<string, number>;\n blocking?: string[];\n threshold?: number;\n } = {};\n if (opts.config) out.config = loadConfigFile(opts.config);\n if (opts.exact) out.exact = parseCsvList(opts.exact);\n if (opts.fuzzy) out.fuzzy = parseFuzzyArg(opts.fuzzy);\n if (opts.blocking) out.blocking = parseCsvList(opts.blocking);\n if (opts.threshold !== undefined) out.threshold = opts.threshold;\n return out;\n}\n\nfunction writeOutputRows(\n path: string,\n rows: readonly Row[],\n format: string,\n): void {\n const ext = extname(path).toLowerCase();\n const useJson =\n format === \"json\" ||\n ext === \".json\" ||\n ext === \".jsonl\" ||\n ext === \".ndjson\";\n if (useJson) {\n writeJson(path, rows);\n } else {\n const delimiter = ext === \".tsv\" ? \"\\t\" : \",\";\n writeCsv(path, rows, { delimiter });\n }\n}\n\n// ---------------------------------------------------------------------------\n// CLI definition\n// ---------------------------------------------------------------------------\n\nconst program = new Command();\n\nprogram\n .name(\"goldenmatch-js\")\n .description(\"Entity resolution toolkit -- dedupe, match, build golden records\")\n .version(\"0.1.0\");\n\n// ---------- dedupe ----------\nprogram\n .command(\"dedupe\")\n .description(\"Deduplicate records in one or more files\")\n .argument(\"<files...>\", \"input file paths (.csv, .tsv, .json, .jsonl)\")\n .option(\"-c, --config <path>\", \"path to YAML config file\")\n .option(\"-e, --exact <fields>\", \"comma-separated exact match fields\")\n .option(\n \"-f, --fuzzy <fields>\",\n \"fuzzy match fields, e.g. 'name:0.85,email:0.9'\",\n )\n .option(\"-b, --blocking <fields>\", \"comma-separated blocking keys\")\n .option(\"-t, --threshold <value>\", \"overall fuzzy threshold\", parseFloat)\n .option(\"-o, --output <path>\", \"output path for golden records\")\n .option(\"--format <format>\", \"output format: csv or json\", \"csv\")\n .action(async (files: string[], opts: SharedMatchOpts) => {\n const rows = loadFilesWithSource(files);\n const options = buildOptionsFromFlags(opts);\n const result = dedupe(rows, options);\n const pct = (result.stats.matchRate * 100).toFixed(1);\n process.stdout.write(\n `Dedupe complete: ${result.stats.totalRecords} records -> ${result.stats.totalClusters} clusters (${pct}% match rate)\\n`,\n );\n if (opts.output) {\n writeOutputRows(\n opts.output,\n result.goldenRecords,\n opts.format ?? \"csv\",\n );\n process.stdout.write(\n `Wrote ${result.goldenRecords.length} golden records to ${opts.output}\\n`,\n );\n }\n });\n\n// ---------- match ----------\nprogram\n .command(\"match\")\n .description(\"Match target records against a reference dataset\")\n .argument(\"<target>\", \"target file path\")\n .argument(\"<reference>\", \"reference file path\")\n .option(\"-c, --config <path>\", \"path to YAML config file\")\n .option(\"-e, --exact <fields>\", \"comma-separated exact match fields\")\n .option(\n \"-f, --fuzzy <fields>\",\n \"fuzzy match fields, e.g. 'name:0.85,email:0.9'\",\n )\n .option(\"-b, --blocking <fields>\", \"comma-separated blocking keys\")\n .option(\"-t, --threshold <value>\", \"overall fuzzy threshold\", parseFloat)\n .option(\"-o, --output <path>\", \"output path for matched records\")\n .option(\"--format <format>\", \"output format: csv or json\", \"csv\")\n .action(\n async (targetPath: string, referencePath: string, opts: SharedMatchOpts) => {\n const targetRows = readFile(targetPath).map((row) => ({\n ...row,\n __source__: \"target\",\n }));\n const referenceRows = readFile(referencePath).map((row) => ({\n ...row,\n __source__: \"reference\",\n }));\n const options = buildOptionsFromFlags(opts);\n const result = match(targetRows, referenceRows, options);\n process.stdout.write(\n `Match complete: ${result.matched.length} matched, ${result.unmatched.length} unmatched\\n`,\n );\n if (opts.output) {\n writeOutputRows(\n opts.output,\n result.matched,\n opts.format ?? \"csv\",\n );\n process.stdout.write(\n `Wrote ${result.matched.length} matched records to ${opts.output}\\n`,\n );\n }\n },\n );\n\n// ---------- score ----------\nprogram\n .command(\"score\")\n .description(\"Score similarity between two strings\")\n .argument(\"<a>\", \"first string\")\n .argument(\"<b>\", \"second string\")\n .option(\n \"-s, --scorer <name>\",\n \"scorer: exact, jaro_winkler, levenshtein, token_sort, soundex_match, dice, jaccard, ensemble\",\n \"jaro_winkler\",\n )\n .action((a: string, b: string, opts: { scorer: string }) => {\n const score = scoreStrings(a, b, opts.scorer);\n process.stdout.write(`${opts.scorer}: ${score.toFixed(4)}\\n`);\n });\n\n// ---------- info ----------\nprogram\n .command(\"info\")\n .description(\"Show information about the package\")\n .action(() => {\n process.stdout.write(\"GoldenMatch JS v0.1.0\\n\");\n process.stdout.write(\n \"Scorers: exact, jaro_winkler, levenshtein, token_sort, soundex_match, dice, jaccard, ensemble\\n\",\n );\n process.stdout.write(\n \"Strategies: most_complete, majority_vote, source_priority, most_recent, first_non_null\\n\",\n );\n process.stdout.write(\n \"Blocking: static, multi_pass, sorted_neighborhood, adaptive\\n\",\n );\n process.stdout.write(\n \"Transforms: lowercase, uppercase, strip, soundex, metaphone, digits_only, alpha_only, token_sort\\n\",\n );\n });\n\n// ---------- profile ----------\nprogram\n .command(\"profile\")\n .description(\"Profile a dataset (column stats, nulls, cardinality)\")\n .argument(\"<file>\", \"input file\")\n .action((file: string) => {\n const rows = readFile(file);\n const total = rows.length;\n process.stdout.write(`File: ${file}\\n`);\n process.stdout.write(`Rows: ${total}\\n`);\n if (total === 0) return;\n const columns = new Set<string>();\n for (const r of rows) for (const k of Object.keys(r)) columns.add(k);\n process.stdout.write(`Columns: ${columns.size}\\n`);\n process.stdout.write(\"\\n\");\n const colList = [...columns];\n const nameWidth = Math.max(6, ...colList.map((c) => c.length));\n const pad = (s: string, w: number) => s + \" \".repeat(Math.max(0, w - s.length));\n process.stdout.write(\n `${pad(\"column\", nameWidth)} ${pad(\"nulls\", 8)} ${pad(\"null%\", 7)} ${pad(\"distinct\", 9)} sample\\n`,\n );\n process.stdout.write(\n `${\"-\".repeat(nameWidth)} ${\"-\".repeat(8)} ${\"-\".repeat(7)} ${\"-\".repeat(9)} ------\\n`,\n );\n for (const col of colList) {\n let nulls = 0;\n const distinct = new Set<string>();\n let sample: string | null = null;\n for (const row of rows) {\n const v = row[col];\n if (v === null || v === undefined || v === \"\") {\n nulls++;\n } else {\n const s = String(v);\n distinct.add(s);\n if (sample === null) sample = s;\n }\n }\n const nullPct = ((nulls / total) * 100).toFixed(1);\n const sampleStr = sample === null ? \"-\" : sample.length > 30 ? sample.slice(0, 27) + \"...\" : sample;\n process.stdout.write(\n `${pad(col, nameWidth)} ${pad(String(nulls), 8)} ${pad(nullPct + \"%\", 7)} ${pad(String(distinct.size), 9)} ${sampleStr}\\n`,\n );\n }\n });\n\n// ---------- demo ----------\nprogram\n .command(\"demo\")\n .description(\"Run a quick demo on synthetic data\")\n .action(() => {\n const rows: Row[] = [\n { id: 1, name: \"John Smith\", email: \"john@example.com\", zip: \"01234\" },\n { id: 2, name: \"Jon Smith\", email: \"john@example.com\", zip: \"01234\" },\n { id: 3, name: \"Jane Doe\", email: \"jane@example.com\", zip: \"02139\" },\n { id: 4, name: \"J. Doe\", email: \"jane@example.com\", zip: \"02139\" },\n { id: 5, name: \"Bob Jones\", email: \"bob@example.com\", zip: \"10001\" },\n ];\n process.stdout.write(`Input: ${rows.length} synthetic records\\n`);\n const result = dedupe(rows, {\n exact: [\"email\"],\n fuzzy: { name: 0.8 },\n blocking: [\"zip\"],\n threshold: 0.8,\n });\n process.stdout.write(\n `Dedupe: ${result.stats.totalRecords} records -> ${result.stats.totalClusters} clusters\\n`,\n );\n process.stdout.write(\n `Match rate: ${(result.stats.matchRate * 100).toFixed(1)}%\\n`,\n );\n process.stdout.write(`Golden records: ${result.goldenRecords.length}\\n`);\n for (const g of result.goldenRecords) {\n process.stdout.write(` ${JSON.stringify(g)}\\n`);\n }\n });\n\n// ---------- mcp-serve ----------\nprogram\n .command(\"mcp-serve\")\n .description(\"Start MCP server over stdio (JSON-RPC 2.0)\")\n .action(async () => {\n const { startMcpServer } = await import(\"./node/mcp/server.js\");\n startMcpServer();\n });\n\n// ---------- serve (REST API) ----------\nprogram\n .command(\"serve\")\n .description(\"Start the REST API server\")\n .option(\"-p, --port <port>\", \"port\", \"8000\")\n .option(\"-h, --host <host>\", \"host\", \"127.0.0.1\")\n .action(async (opts: { port: string; host: string }) => {\n const { startApiServer } = await import(\"./node/api/server.js\");\n startApiServer({ port: parseInt(opts.port, 10), host: opts.host });\n });\n\n// ---------- agent-serve (A2A) ----------\nprogram\n .command(\"agent-serve\")\n .description(\"Start the A2A agent-to-agent server\")\n .option(\"-p, --port <port>\", \"port\", \"8200\")\n .option(\"-h, --host <host>\", \"host\", \"127.0.0.1\")\n .action(async (opts: { port: string; host: string }) => {\n const { startA2aServer } = await import(\"./node/a2a/server.js\");\n startA2aServer({ port: parseInt(opts.port, 10), host: opts.host });\n });\n\n// ---------- tui ----------\nprogram\n .command(\"tui\")\n .description(\"Launch interactive TUI (requires optional peer deps: ink + react)\")\n .argument(\"[files...]\", \"input files to load on startup\")\n .option(\"-c, --config <path>\", \"path to YAML config file\")\n .action(async (files: string[], opts: { config?: string }) => {\n try {\n const { startTui } = await import(\"./node/tui/app.js\");\n const tuiOpts: { files?: string[]; config?: ReturnType<typeof loadConfigFile> } = {};\n if (files && files.length > 0) tuiOpts.files = files;\n if (opts.config) tuiOpts.config = loadConfigFile(opts.config);\n await startTui(tuiOpts);\n } catch (err: unknown) {\n const message = err instanceof Error ? err.message : String(err);\n process.stderr.write(`TUI error: ${message}\\n`);\n process.exit(1);\n }\n });\n\n// ---------------------------------------------------------------------------\n// Entry point\n// ---------------------------------------------------------------------------\n\nprogram.parseAsync(process.argv).catch((err: unknown) => {\n const message = err instanceof Error ? err.message : String(err);\n process.stderr.write(`Error: ${message}\\n`);\n process.exit(1);\n});\n"]}