Centralized sourdough calculation library utilities
This skill provides centralized, tested calculation utilities for sourdough math used throughout the SourdoughSuite app.
The src/utils/sourdoughCalculations.ts library eliminates duplicated formulas across calculator screens by providing:
calculateAmountFromPercentage(flourWeight, percentage) // Ingredient amount from %
calculatePercentageFromAmount(ingredientWeight, flourWeight) // % from amounts
calculateHydrationPercent(waterWeight, flourWeight) // Hydration %
calculateWaterNeeded(flourWeight, targetHydration) // Water for target %
calculateFlourNeeded(waterWeight, targetHydration) // Flour for target %
calculateScaleFactor(original, target) // Scale multiplier
scaleAmount(amount, scaleFactor) // Scale an amount
decomposeLevain(totalLevainWeight, hydration) // { flour, water }
calculateStarterPercentage(starterFlour, totalFlour) // Starter %
calculatePrefermentFlour(totalFlour, prefermentPercent) // Preferment flour
calculatePreBakeWeight(postBakeWeight, bakingLossPercent) // Pre-bake weight
calculateWeightLoss(preBakeWeight, postBakeWeight) // Weight loss amount
calculateWeightLossPercent(preBakeWeight, postBakeWeight) // Loss %
calculateWaterTemperature(targetDDT, roomTemp, flourTemp, starterTemp, frictionFactor) // DDT method
roundTo(value, decimals = 1) // Round to decimal places
formatWeight(grams, decimals = 0) // Format as "500g"
formatPercent(percent, decimals = 1) // Format as "70.0%"
validatePositiveNumber(value, fieldName) // Validation with error message
validatePercentage(value, fieldName) // Validate 0-100% range
When working with calculator screens or recipe calculations:
Import functions from the centralized library:
import { calculateAmountFromPercentage, roundTo } from '../../utils/sourdoughCalculations';
Use functions instead of inline math:
// Before:
const waterAmount = ((flourWeight * waterPercent) / 100).toFixed(1);
// After:
const waterAmount = roundTo(calculateAmountFromPercentage(flourWeight, waterPercent));
Leverage validation helpers:
const error = validatePositiveNumber(parseFloat(flourWeight), 'Flour Weight');
if (error) {
Alert.alert('Validation Error', error);
return;
}
Use formatting utilities:
// Consistent formatting across all calculators
const displayWeight = formatWeight(waterAmount); // "700g"
const displayPercent = formatPercent(hydration); // "70.0%"
When refactoring existing calculators:
const handleCalculate = () => {
const flourNum = parseFloat(flourWeight);
const waterAmount = ((flourNum * 70) / 100).toFixed(1);
const saltAmount = ((flourNum * 2) / 100).toFixed(1);
setResults({
flour: flourNum.toFixed(0),
water: waterAmount,
salt: saltAmount,
});
};
import { calculateAmountFromPercentage, roundTo, formatWeight } from '../../utils/sourdoughCalculations';
const handleCalculate = () => {
const flourNum = parseFloat(flourWeight);
const waterAmount = roundTo(calculateAmountFromPercentage(flourNum, 70));
const saltAmount = roundTo(calculateAmountFromPercentage(flourNum, 2));
setResults({
flour: formatWeight(flourNum),
water: formatWeight(waterAmount),
salt: formatWeight(saltAmount),
});
};
This skill is automatic - use these functions whenever:
src/utils/sourdoughCalculations.tssrc/utils/__tests__/sourdoughCalculations.test.tssrc/screens/tools/import { calculateAmountFromPercentage, roundTo } from '../../utils/sourdoughCalculations';
const water = roundTo(calculateAmountFromPercentage(flourWeight, waterPercent));
const salt = roundTo(calculateAmountFromPercentage(flourWeight, saltPercent));
import { calculateHydrationPercent, calculateWaterNeeded } from '../../utils/sourdoughCalculations';
const hydration = calculateHydrationPercent(waterWeight, flourWeight);
const neededWater = calculateWaterNeeded(flourWeight, targetHydration);
import { decomposeLevain, calculateStarterPercentage } from '../../utils/sourdoughCalculations';
const { flour: levainFlour, water: levainWater } = decomposeLevain(levainWeight, hydration);
const starterPercent = calculateStarterPercentage(levainFlour, totalFlour);
Run tests with:
npm test sourdoughCalculations
All 68 tests should pass, covering: