@suaveplan/currency - Universal currency conversion engine — pluggable CurrencyProvider interface, TTL-bounded RateCache with direct / inverse / triangulated lookup, primary + fallback chain with AbortSignal cancellation, Zod-validated public boundary, typed CurrencyError hierarchy with stable CURRENCY.* code registry, virtual-currency seeding with post-construction setVirtualRate / updateVirtualRate mutators, enriched ConversionResult carrying providerName and triangulatedThrough diagnostics. Built on @suaveplan/money minor-unit bigint arithmetic.
Universal currency conversion engine — pluggable CurrencyProvider
interface, TTL-bounded RateCache with direct / inverse / triangulated lookup,
primary + fallback chain with AbortSignal cancellation, Zod-validated public
boundary, typed CurrencyError hierarchy with stable CURRENCY.* code
registry, virtual-currency seeding with post-construction
setVirtualRate / updateVirtualRate mutators, and enriched ConversionResult
carrying providerName and triangulatedThrough diagnostics. Built on
@suaveplan/money minor-unit bigint arithmetic.
Documentation tree
- converter —
CurrencyConverteris the orchestration heart of@suaveplan/currency. It combines a pluggableCurrencyProvider(pl…- converter —
CurrencyConverteris the orchestration heart of@suaveplan/currency. It combines a pluggableCurrencyProvider(pl…
- converter —
- error-codes —
@suaveplan/currencyraises only typed errors. This module owns the stableCURRENCY_CODESregistry (built with `defi…- error-codes —
@suaveplan/currencyraises only typed errors. This module owns the stableCURRENCY_CODESregistry (built with `defi…
- error-codes —
- provider — The provider module ships two reference implementations of the
CurrencyProvidercontract: a mutable `InMemoryProvider…- provider — The provider module ships two reference implementations of the
CurrencyProvidercontract: a mutable `InMemoryProvider…
- provider — The provider module ships two reference implementations of the
- rate-cache —
RateCacheis the converter's in-memory rate store. It folds every successfulfetchRatesanswer into a single map ke…- rate-cache —
RateCacheis the converter's in-memory rate store. It folds every successfulfetchRatesanswer into a single map ke…
- rate-cache —
- schemas — The schemas module is the package's input-validation boundary. Every public options bundle that crosses into a `Currenc…
- schemas — The schemas module is the package's input-validation boundary. Every public options bundle that crosses into a `Currenc…
- types — Single home for every shared type the
@suaveplan/currencypublic surface exposes. The module defines the `CurrencyPro…- common — Single home for every shared type the
@suaveplan/currencypublic surface exposes. The module defines the `CurrencyPro…
- common — Single home for every shared type the
Install
bun add @suaveplan/currency @suaveplan/money
Quick start
import { CurrencyConverter, InMemoryProvider } from "@suaveplan/currency";
import { Money } from "@suaveplan/money";
const provider = new InMemoryProvider();
provider.setRates("USD", { EUR: 0.92, GBP: 0.79, JPY: 149.5 });
const converter = new CurrencyConverter({ provider });
const usd = Money.fromMajor("100", "USD");
const result = await converter.convert(usd, "EUR");
// result.amount === 9200n
// result.rate === 0.92
// result.providerName === "in-memory"
// result.triangulatedThrough === null
const eur = await converter.convertAmount(250, "USD", "EUR");
// eur === 230 (250 * 0.92)
Features
- Pluggable
CurrencyProviderinterface for any exchange-rate source. - In-memory
RateCachewith configurable TTL eviction. - Cross-rate triangulation via cached intermediate base (single-hop).
- Inverse rate calculation from cached data when only one direction is known.
- Provider fallback chain for resilience — tries providers in order.
AbortSignalcancellation onconvert/convertAmount/getRate, honoured between fallback attempts.- Zod-validated boundary on every public option bundle.
- Typed
CurrencyErrorhierarchy with stableCURRENCY.*codes (INVALID_CONFIG,INVALID_OPTIONS,PROVIDER_UNAVAILABLE,UNSUPPORTED_CURRENCY,RATE_UNAVAILABLE,TRIANGULATION_IMPOSSIBLE,ABORTED). - Virtual-currency seeding for game currencies, with
setVirtualRate/updateVirtualRatepost-construction mutation. - Enriched
ConversionResult—providerName("<identity>"/"<cache>"/"<virtual>"/ actual provider name) plustriangulatedThrough(chain of intermediate currencies for triangulated rates). - Built-in
InMemoryProvider+createStaticProviderfactory for tests and fixed-rate apps. - Tree-shakeable subpath exports per public module.
Modules
src/converter/converter.md—CurrencyConverterorchestrator (provider chain, cache, triangulation, virtual currency, AbortSignal).src/rate-cache/rate-cache.md— TTL-boundedRateCachewith direct / inverse / triangulated lookup.src/provider/provider.md—InMemoryProvider+createStaticProviderreference implementations.src/error-codes/error-codes.md—CURRENCY_CODESregistry +CurrencyErrordiscriminated class.src/schemas/schemas.md— Zod schemas + parse helpers for every public option bundle.src/types/common.md— public type surface (CurrencyProvider,ConversionResult,ConverterConfig, …).
Status
0.1.0 (pre-graduation). Migrated from
../suaveplan/packages/finance/currency/ with feature parity plus typed
errors, Zod boundary, AbortSignal support, and enriched
ConversionResult. See
the design proposal for the migration
record and the deferred-feature list.