///
import { Cell, Default, handler, lift, recipe, str } from "commontools";
interface RollingAverageArgs {
value: Default;
history: Default;
window: Default;
}
const recordAndAverage = handler(
(
event: { amount?: number } | undefined,
context: {
value: Cell;
history: Cell;
window: Cell;
},
) => {
const amount = typeof event?.amount === "number" ? event.amount : 1;
const currentValue = context.value.get();
const next = (typeof currentValue === "number" ? currentValue : 0) +
amount;
context.value.set(next);
const windowSize = context.window.get();
const limit = typeof windowSize === "number" && windowSize > 0
? Math.floor(windowSize)
: 5;
const current = context.history.get();
const currentList = Array.isArray(current) ? current : [];
const updated = [...currentList, next].slice(-limit);
context.history.set(updated);
},
);
export const counterWithRollingAverage = recipe(
"Counter With Rolling Average",
({ value, history, window }) => {
const average = lift((entries: number[] | undefined) => {
const list = Array.isArray(entries) ? entries : [];
if (list.length === 0) return 0;
const total = list.reduce((sum, item) => sum + item, 0);
return total / list.length;
})(history);
const currentValue = lift((count: number | undefined) =>
typeof count === "number" ? count : 0
)(value);
const historyView = lift((entries: number[] | undefined) =>
Array.isArray(entries) ? entries : []
)(history);
return {
value,
history,
window,
average,
currentValue,
historyView,
label: str`Average ${average}`,
increment: recordAndAverage({ value, history, window }),
};
},
);