# `RTL_LOCALES` and `RTL_LOCALE_LIST` — right-to-left locale set ## Purpose `RTL_LOCALES` and `RTL_LOCALE_LIST` are the canonical inventory of ISO 639-1 language codes whose primary script renders right-to-left. Together they let any consumer (the locale detector, a UI component deciding `dir="rtl"`, a logger annotating a span) determine text direction with one O(1) lookup and zero parsing. Centralising the list here means every package in the i18n family agrees on the same seven RTL codes — no drift between formatters that might independently hard-code Arabic + Hebrew while ignoring Persian or Urdu. ## Features - 7 ISO 639-1 codes: `ar`, `he`, `fa`, `ur`, `ps`, `sd`, `yi` - Two shapes — `ReadonlySet` for membership checks, `readonly tuple` for iteration / serialisation - Both shapes share the same data and the test suite asserts they agree on cardinality - Tree-shake-friendly subpath at `@suaveplan/i18n-shared/constants/rtl-locales` for size-sensitive consumers ## Usage: Basic Example ```ts import { RTL_LOCALES } from "@suaveplan/i18n-shared"; if (RTL_LOCALES.has("ar")) { document.documentElement.dir = "rtl"; } ``` ## Usage: Advanced Example ```ts import { RTL_LOCALE_LIST, RTL_LOCALES, } from "@suaveplan/i18n-shared/constants/rtl-locales"; // Membership check — O(1) on the Set function getDirection(locale: string): "ltr" | "rtl" { const language = locale.split("-")[0]?.toLowerCase() ?? ""; return RTL_LOCALES.has(language) ? "rtl" : "ltr"; } // Iteration — stable order from the tuple for (const code of RTL_LOCALE_LIST) { console.log(`Loading RTL bundle for ${code}`); } // Serialisation — bundlers can inline the tuple as a JSON literal const manifest = { rtl: [...RTL_LOCALE_LIST] }; ``` ## API Reference ### `RTL_LOCALES: ReadonlySet` Set of ISO 639-1 codes whose primary script is right-to-left. Use this for O(1) membership checks. ### `RTL_LOCALE_LIST: readonly ["ar", "he", "fa", "ur", "ps", "sd", "yi"]` Tuple form of the same data. Use this when iteration order matters, when bundling into a manifest, or when the consumer wants to ship the code list without the Set overhead. ## Implementation Notes - The two exports are deliberately not derived from one another at module-init time — the Set takes the array path on construction and the tuple is a literal. A unit test asserts `RTL_LOCALE_LIST.length === RTL_LOCALES.size` so any future addition to one stays in sync with the other. - The seven codes match the pre-split monolith exactly. Future additions (e.g. `dv` for Dhivehi) require updating both exports AND adding a corresponding `LOCALE_DESCRIPTORS` entry with `direction: "rtl"`.