main.js 2.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455
  1. // src/main.ts
  2. async function fetchData() {
  3. const [recipesResponse, exchangesResponse] = await Promise.all([
  4. fetch("https://api.prunplanner.org/data/recipes"),
  5. fetch("https://api.prunplanner.org/data/exchanges")
  6. ]);
  7. const [recipes, prices] = await Promise.all([
  8. recipesResponse.json(),
  9. exchangesResponse.json()
  10. ]);
  11. return { recipes, prices };
  12. }
  13. function render({ recipes, prices }) {
  14. const priceMap = new Map;
  15. for (const price of prices)
  16. if (price.ExchangeCode == "PP7D_IC1")
  17. priceMap.set(price.MaterialTicker, price);
  18. const profits = [];
  19. for (const recipe of recipes) {
  20. const runsPerDay = 1000 * 60 * 60 * 24 / recipe.TimeMs;
  21. if (recipe.Outputs.length !== 1) {
  22. console.warn(`${recipe.RecipeName} doesn't have 1 output`);
  23. continue;
  24. }
  25. const output = recipe.Outputs[0];
  26. const outputPrice = priceMap.get(output.Ticker);
  27. if (outputPrice === undefined)
  28. throw new Error(`missing price for ${output.Ticker}`);
  29. const revenuePerRun = output.Amount * outputPrice.PriceAverage;
  30. const costPerRun = recipe.Inputs.reduce((sum, input) => {
  31. const price = priceMap.get(input.Ticker);
  32. if (price === undefined)
  33. throw new Error(`missing price for ${input.Ticker}`);
  34. return sum + price.PriceAverage * input.Amount;
  35. }, 0);
  36. const dailyProfit = (revenuePerRun - costPerRun) * runsPerDay;
  37. profits.push({ recipeName: recipe.RecipeName, dailyProfit, traded: outputPrice.Traded });
  38. }
  39. profits.sort((a, b) => b.dailyProfit - a.dailyProfit);
  40. const fmt = new Intl.NumberFormat(undefined, { maximumFractionDigits: 2 });
  41. const tbody = document.querySelector("tbody");
  42. tbody.innerHTML = "";
  43. for (const profit of profits) {
  44. const row = document.createElement("tr");
  45. row.innerHTML = `
  46. <td>${profit.recipeName}</td>
  47. <td>${fmt.format(profit.dailyProfit)}</td>
  48. <td>${fmt.format(profit.traded)}</td>
  49. `;
  50. tbody.appendChild(row);
  51. }
  52. }
  53. fetchData().then(render);
  54. //# debugId=70C1D9063E5E875D64756E2164756E21