Custom Dialects & Libraries
You can teach rosetta-date a new formatting language with defineDialect, or model a new tool on
top of an existing dialect with defineLibrary.
The key idea: map to meaning
Map each token to a canonical symbol — what it means (year, 2-digit month, …), not another
dialect’s spelling. Canonical is the neutral vocabulary every built-in dialect routes through, so
a token you map to Canonical.YearNumeric converts to and from every other dialect for free.
defineDialect
import { Canonical, convert, defineDialect } from 'rosetta-date'
import { ldml } from 'rosetta-date/dialects'
const custom = defineDialect({
name: 'custom',
literal: { open: '{', close: '}' },
tokens: [
{ token: 'yr', canonical: Canonical.YearNumeric },
{ token: 'mo', canonical: Canonical.MonthTwoDigit },
{ token: 'dy', canonical: Canonical.DayOfMonthTwoDigit },
],
})
convert('yr-mo-dy', { from: custom, to: ldml }) // 'yyyy-MM-dd'defineLibrary
A library extends a dialect — adding a tool’s own tokens via extends (and, in the built-ins,
declaring a supports set). Here we add an LDML-flavoured tool that understands the Unix epoch:
import { Canonical, convert, defineLibrary } from 'rosetta-date'
import { ldml } from 'rosetta-date/dialects'
import { dateFns } from 'rosetta-date/libraries'
const ldmlPlus = defineLibrary({
name: 'ldml-plus',
dialect: ldml,
extends: [{ token: 'u', canonical: Canonical.EpochSeconds }],
})
convert('u', { from: ldmlPlus, to: dateFns }) // 't' — bridged by the canonical symbolThe token u is not in the bare ldml dialect, but because it maps to Canonical.EpochSeconds, it
bridges straight to date-fns’s t.
Validation happens once
defineDialect and defineLibrary validate a definition once, at definition time — they
throw on an incoherent token table or literal rules — and return a stable object you reuse across
conversions. That object identity matters: per-dialect compilation is cached by object, so
constructing a fresh definition on every convert call silently misses the cache and recompiles
each time. Define once, reuse everywhere.
Canonical symbols
Canonical values are stable identifiers shaped as field/style, versioned by semver:
- Adding a symbol is a minor (additive) change.
- Renaming or removing one is breaking.
Prefer the named members (Canonical.YearNumeric) over the raw strings. The full vocabulary is
exported from the package root, and the TokenRule and LiteralRules types are available for
annotating your token tables and literals.
See the API Reference for the exact signatures and types.