/// 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 }), }; }, );