# engine/select ## Purpose Resolve the default `RsaCryptoEngine` for the host runtime. When `globalThis.crypto.subtle` exposes the RSA algorithms this package needs, `subtleEngine` is returned for hardware-accelerated performance; otherwise the pure-JS `nobleEngine` is used. Increments `crypto_rsa.engine_selected_total{engine}` on every call so production dashboards can track engine distribution per deployment. ## Features - Auto-detects `subtle` availability at runtime - `prefer: "noble"` forces the pure-JS engine even when subtle is available (useful for deterministic-test scenarios) - `prefer: "subtle"` forces subtle and throws `ENGINE_UNAVAILABLE` if absent (caller commits to subtle, surfaces failure synchronously) - Counter increments on every call regardless of branch taken ## Usage: Basic Example ```ts import { defaultEngine } from "@suaveplan/crypto-rsa/engine"; const engine = defaultEngine(); const sig = await engine.sign(privateKey, message, { scheme: "pkcs1v15", hash: "SHA-256", }); ``` ## Usage: Advanced Example Force noble in test environments to make signature outputs reproducible (subtle's RSA-PSS internally generates the salt and is non-determinstic; noble's PSS path accepts a custom `Rng`): ```ts import { defaultEngine } from "@suaveplan/crypto-rsa/engine"; const engine = defaultEngine({ prefer: "noble" }); // Reproducible PSS signatures. ``` ## API Reference ### `defaultEngine(options?): RsaCryptoEngine` - `options.prefer?: "noble" | "subtle"` — forces the engine choice - **returns** `RsaCryptoEngine` - **throws** `CryptoRsaError(CRYPTO_RSA.ENGINE_UNAVAILABLE)` when `prefer: "subtle"` is set and `globalThis.crypto.subtle` is missing ### `DefaultEngineOptions` - `prefer?: RsaEngineName` ### `resetEngineSelectionCounterForTesting()` Test-only helper. ## Implementation Notes - The selection rule is: if `prefer` is set, use it (subtle requested but missing → throw); otherwise prefer subtle, fall back to noble. The counter records the actual choice made, not the request. - Detecting subtle availability is a single `globalThis.crypto.subtle` read. Cached lookups would be incorrect — runtimes can polyfill subtle mid-process (e.g. test setup adding a Web Crypto polyfill). - The counter cardinality is bounded to two label values (`noble`/`subtle`) so dashboards aggregate cleanly. - This selector is the recommended default entry point for engine consumers; calling `nobleEngine` / `subtleEngine` directly is appropriate only when the caller has committed to a specific engine for the lifetime of the operation.