diff --git a/README.fr.md b/README.fr.md index bfcdce1..98dd58c 100644 --- a/README.fr.md +++ b/README.fr.md @@ -345,11 +345,11 @@ matchigo émet un `console.warn` **une seule fois** quand il détecte un mésusa - Reconstruire `rules` à chaque appel de `match(value, rules)` (l'anti-pattern « cold-path inline »). - Créer des milliers d'instances distinctes de `matcher()` (typiquement, le builder est dans une boucle chaude). -Les avertissements sont pilotés par `NODE_ENV` (`production`/`prod` les désactive). La vérification se fait une fois au chargement du module, donc **production a un coût nul** — pas de lecture d'env, pas de compteur, pas de formatage de string. +Les avertissements sont **actifs par défaut** et ne se déclenchent qu'une fois par processus. Appelle `silenceWarnings()` dans ton point d'entrée de production pour les désactiver. Aucune lecture d'env, aucun compteur, aucun formatage de string après ça. ```ts import { silenceWarnings } from "matchigo"; -silenceWarnings(); // désactivation programmatique +silenceWarnings(); // à appeler une fois au démarrage pour tout désactiver ``` ## Benchmarks diff --git a/README.md b/README.md index 63b7b1e..cb5597c 100644 --- a/README.md +++ b/README.md @@ -399,11 +399,11 @@ matchigo emits a `console.warn` **once** when it detects misuse that defeats cac - Reconstructing `rules` on every `match(value, rules)` call (the "cold-path inline" anti-pattern). - Creating thousands of distinct `matcher()` instances (usually means the builder is inside a hot loop). -Warnings are controlled by `NODE_ENV` (`production`/`prod` disables them). The check happens once at module load, so **production has zero cost** — no env reads, no counters, no string formatting. +Warnings are **on by default** and fire at most once per process. Call `silenceWarnings()` in your production entry point to opt out. No env reads, no counters, no string formatting after that. ```ts import { silenceWarnings } from "matchigo"; -silenceWarnings(); // disable programmatically +silenceWarnings(); // call once at startup to disable all warnings ``` ## Benchmarks diff --git a/src/dev.ts b/src/dev.ts index 3934977..c91cbdc 100644 --- a/src/dev.ts +++ b/src/dev.ts @@ -1,23 +1,9 @@ // Dev-only cold-path instrumentation. -// Resolution policy (evaluated ONCE at module load → zero runtime cost): -// -// 1. NODE_ENV — matches "production", "prod" (case-insensitive) → off. -// 2. Else default → on (verbose dev). -// -// Programmatic override: silenceWarnings() at startup mutes everything. -// No NODE_ENV at all? Dev mode is ON. The counters still cost only a few `++` -// ops per call; the console.warn only ever fires ONCE per counter per process. +// Warnings are ON by default and fire at most once per counter per process. +// Call silenceWarnings() at startup to opt out (e.g. in production entry points). +// The counters cost only a few `++` ops per call; no env reads, no allocations. -const DEV: boolean = (() => { - try { - if (typeof process === "undefined" || !process?.env) return true; - const node = (process.env.NODE_ENV ?? "").toLowerCase(); - if (node === "production" || node === "prod") return false; - return true; - } catch { - return true; - } -})(); +const DEV = true; let matchCalls = 0; let matchMisses = 0; @@ -44,7 +30,7 @@ export function trackMatch(cacheHit: boolean): void { ` • Or compile once with compile():\n` + ` const dispatch = compile([...]);\n` + ` dispatch(value);\n` + - ` Silence: silenceWarnings() — or set NODE_ENV=production.`, + ` Silence: call silenceWarnings() in your production entry point.`, ); warnedMatch = true; } @@ -61,7 +47,7 @@ export function trackMatcher(): void { ` .with(...)\n` + ` .otherwise(...); // builds + compiles once\n` + ` classify(value); // reused hot path\n` + - ` Silence: silenceWarnings() — or set NODE_ENV=production.`, + ` Silence: call silenceWarnings() in your production entry point.`, ); warnedMatcher = true; } diff --git a/src/p.ts b/src/p.ts index 7b51750..486ca5c 100644 --- a/src/p.ts +++ b/src/p.ts @@ -230,8 +230,8 @@ export const P = { // Composers array: (item: Item): PArray => ({ [PATTERN]: "array", item }), /** - * Literal union — matches if the value is strictly equal (`Object.is`) to - * any of the given values. Apply it on a discriminant field to narrow a + * Literal union — matches if the value is strictly equal (SameValue equality) + * to any of the given values. Apply it on a discriminant field to narrow a * tagged union: `{ kind: P.union("a", "b") }`. * * @example