Skip to content

detect: rank only systems whose source script matches the input - #28

Merged
ronaldtse merged 1 commit into
mainfrom
fix/detect-script-prefilter2
Sep 28, 2026
Merged

ronaldtse merged 1 commit into
mainfrom
fix/detect-script-prefilter2

Conversation

@ronaldtse

Copy link
Copy Markdown
Contributor

Problem

detect transliterated the input through all 288 systems per request. On the Workers free plan (10 ms CPU budget) that intermittently exceeds the limit — production returns partial rankings that vary per call (47–96 entries of 288) or fails outright with error 1102 (Worker exceeded CPU time limit):

$ for i in 1..12; curl /v1/detect ... → 5×47 entries, 2×96, 5×HTTP 503 (1102)

Fix

  • detectInputScript() — majority Unicode-block scan of the input; a single non-Latin letter outranks any amount of Latin.
  • maps/scripts.js — build-time generated code → source_script index (emitted by scripts/build-maps.mjs from the artifact metadata).
  • detect() walks only the matching family: Georgian input → 8 systems (was 288); Hangul input also matches the mixed Kore sources; Han input also matches Hans/Kore/Hrkt.
  • Script-less input (digits/punctuation only) returns an empty ranking instead of walking the corpus.

Top hits are unchanged for real queries (ქართული → alalc-kat-Geor-Latn-1997 @ 0, 한국 → distance 0, 阜康 → acadsin-zho).

Tests

  • new test/detect.test.ts: script detection, prefilter (asserts the asset-fetch count drops to ≤ 10), Korean/Han family matching, script-less input
  • full suite 37/37; detect fixture re-recorded from the prefiltered engine

Capacity note for the owner (not addressed here)

The API sits on the Workers free plan (10 ms CPU); even single transliterations of library-dependent maps 1102 on cold isolates. The durable fix is a plan tier with real CPU — Workers Standard (usage-priced) plus limits.cpu_ms in the deploy wrangler.jsonc. That is a spending decision, so it is only documented here.

The detect walk loaded all 288 maps per request. On the Workers free
plan (10ms CPU) that intermittently dies with 1102 — production
returns anywhere between 47 and 96 partial rankings per call, or 503s.
Loading every map to rank unrelated scripts was also semantically
empty: Georgian input ranked 280 irrelevant systems at distance 9.

detectInputScript() picks the majority Unicode script of the input
(non-Latin beats Latin when tied); a build-time generated
maps/scripts.js maps each system to its source script, and detect
walks only the matching family (Hangul input also matches the mixed
Kore sources, Han input also matches Hans/Kore/Hrkt). Georgian input
now loads 8 systems instead of 288 and the top hits are unchanged.

Test fixtures: the detect fixture records the prefiltered ranking.
@ronaldtse
ronaldtse merged commit 28310a0 into main Sep 28, 2026
6 checks passed
@ronaldtse
ronaldtse deleted the fix/detect-script-prefilter2 branch September 28, 2026 14:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant