A presentation at JSCONF.BE 2020 in June 2020 in by Sarah Dayan
Learning from the Mistakes of a v1 Sarah Dayan Software Engineer, Algolia @frontstuff_io
const price = Dinero({ amount: 5000, currency: ‘EUR’ }); const tip = price.percentage(20); const fullPrice = price.add(tip); fullPrice.toFormat(); // “€60.00” @frontstuff_io
2 400 29 years commits releases @frontstuff_io
A v2 usually marks a turning point. @frontstuff_io
🔢 It uses numbers to represent amounts @frontstuff_io
const price = Dinero({ amount: 5000, currency: ‘EUR’ }); @frontstuff_io
.1 + .2; // 0.30000000000000004 (1 + 2) / 10 // 0.3 @frontstuff_io
const price = Dinero({ // 5000 cents, or 50 euros amount: 5000, currency: ‘EUR’ }); @frontstuff_io
Number.MAX_SAFE_INTEGER; // 9007199254740991 Number.MIN_SAFE_INTEGER; // -9007199254740991 @frontstuff_io
Enter bigints. @frontstuff_io
const calculator = { add(a, b) { return a + b; }, subtract(a, b) { return a - b; }, // … }; @frontstuff_io
import { Decimal } from ‘decimal.js’; const bigDinero = createDinero({ calculator: { add: Decimal.add, subtract: Decimal.sub, // … }, }); const price = bigDinero({ amount: new Decimal(Number.MAX_SAFE_INTEGER), currency: ‘EUR’, }); @frontstuff_io
💰 It doesn’t handle different exponents @frontstuff_io
1 euro = 100 cents 1 x 10^2 = 100 @frontstuff_io
const price = Dinero({ amount: 5000, currency: ‘EUR’, }); price.toFormat(); // “€50.00” @frontstuff_io
@frontstuff_io
const price = Dinero({ amount: 1000, currency: ‘IQD’, precision: 3, }); @frontstuff_io
const IQD = { code: ‘IQD’, base: 10, exponent: 3, }; const price = Dinero({ amount: 1000, currency: IQD, }); @frontstuff_io
🔄 It expects a REST API for conversions @frontstuff_io
const options = { endpoint: ‘https://api/?base={{from}}’, propertyPath: ‘data.rates.{{to}}’, headers: { ‘user-key’: ‘xxxxxxxxx’, }, roundingMode: ‘HALF_UP’, }; Dinero({ amount: 5000, currency: ‘EUR’, }).convert(‘XBT’, options); @frontstuff_io
const price = Dinero({ amount: 5000, currency: ‘EUR’, }); price.convert(‘XBT’); @frontstuff_io
const rates = new Promise((resolve) => resolve({ XBT: 0.00012, }) ); Dinero({ amount: 5000 }) .convert(EUR, { rates }); @frontstuff_io
const rates = { rates: { XBT: 0.00012, }, }; Dinero({ amount: 5000, currency: ‘EUR’, }).convert(‘XBT’, { endpoint: new Promise((resolve) => resolve(rates) ), }); @frontstuff_io
🌎 It relies on the ECMAScript I18n API @frontstuff_io
const amount = 5; amount.toLocaleString(‘en-GB’, { style: ‘currency’, currency: ‘EUR’, }); // “€5.00” @frontstuff_io
const options = { style: ‘currency’, currency: ‘EUR’, }; amount.toLocaleString(‘en-GB’, options); // “€5.00” amount.toLocaleString(‘de-DE’, options); // “5,00 €” @frontstuff_io
const price = Dinero({ amount: 500, currency: ‘EUR’, }).setLocale(‘en-GB’); price.toFormat(); // “€5.00” @frontstuff_io
Tight coupling @frontstuff_io
Lack of flexibility @frontstuff_io
Inconsistent implementation @frontstuff_io
const price = Dinero({ amount: 500, currency: EUR, }); price.toFormat( ({ amount, currency }) => ${currency.code} ${amount}, { digits: 2, roundingMode: Math.round, } ); // “EUR 5” @frontstuff_io
${currency.code} ${amount}
function i18n({ amount, currency }) { return amount.toLocaleString(‘en-GB’, { style: ‘currency’, currency: currency.code, }); } price.toFormat(i18n, { digits: 2, roundingMode: Math.round, }); // “€5.00” @frontstuff_io
const currencySymbols = { EUR: ‘€’, USD: ‘$’, // … }; function manualI18n({ amount, currency }) { const { code } = currency; const symbol = currencySymbols[code] || code; return ${symbol}${amount.toFixed(2)}; } price.toFormat(manualI18n, { digits: 2, roundingMode: Math.round, }); // “€5.00” @frontstuff_io
${symbol}${amount.toFixed(2)}
🌳 You can’t tree-shake it @frontstuff_io
const price = Dinero({ amount: 500, currency: ‘EUR’, }); price.add(price).multiply(4); @frontstuff_io
const price = Dinero({ amount: 500, currency: ‘EUR’, }); multiply(add(price, price), 4); @frontstuff_io
🐞 It’s written in JavaScript @frontstuff_io
Maintaining types by hand doesn’t scale. And it’s a pain. @frontstuff_io
Static typing is extremely helpful. @frontstuff_io
🐦 TypeScript hits two birds with one stone. @frontstuff_io
What happened? @frontstuff_io
First library @frontstuff_io
No real-world experience @frontstuff_io
Many assumptions @frontstuff_io
Scalability Flexibility Agnosticism DX @frontstuff_io
Thank you! Sarah Dayan Software Engineer, Algolia Links Why Javascript Numbers Are Weird (And How to Fix It) youtu.be/Wq2AqONg7rs Dinero.js on GitHub github.com/dinerojs @frontstuff_io