// Generated, do not edit. sha256:48f77fc8fc8efc987ebeae10a9b33669b28691941eb865e07c2c66413d1ef0cf import { getPref, setPref } from '../data/preferences.js'; export const MOMENTUM = Object.freeze({ SIZE: 60, MAX_AGE_MS: 6 * 3600000, }); const PREF_SCOPE = 'momentum'; const recent = (moves, nowMs) => moves.filter(m => nowMs - m.at <= MOMENTUM.MAX_AGE_MS); export function addPrice(buffer, price, nowMs) { if (!Number.isFinite(price) || price <= 0) return buffer; const prev = buffer || { last: null, lastAt: 0, moves: [] }; const fresh = prev.last != null && nowMs - prev.lastAt <= MOMENTUM.MAX_AGE_MS; if (fresh && price === prev.last) return prev; const kept = recent(prev.moves, nowMs); const moves = fresh ? [...kept, { at: nowMs, dir: price > prev.last ? 1 : -1 }].slice(-MOMENTUM.SIZE) : kept; return { last: price, lastAt: nowMs, moves }; } export function restore(saved, nowMs) { if (!saved || !Number.isFinite(saved.last) || !Number.isFinite(saved.lastAt) || !Array.isArray(saved.moves)) return null; const moves = saved.moves .filter(m => m && Number.isFinite(m.at) && (m.dir === 1 || m.dir === -1)) .slice(-MOMENTUM.SIZE); return { last: saved.last, lastAt: saved.lastAt, moves: recent(moves, nowMs) }; } export function tally(buffer, nowMs) { const moves = recent(buffer?.moves || [], nowMs); let balance = 0, tone = null; for (const m of moves) { balance += m.dir; if (balance !== 0) tone = balance > 0 ? 'up' : 'down'; } const up = moves.filter(m => m.dir > 0).length; return { up, down: moves.length - up, tone }; } const buffers = new Map(); const loads = new Map(); export function loadMomentum(assetId, nowMs = Date.now()) { if (assetId == null) return Promise.resolve(); if (!loads.has(assetId)) { loads.set(assetId, (async () => { try { buffers.set(assetId, restore(await getPref(PREF_SCOPE, String(assetId), null), nowMs)); } catch { buffers.set(assetId, null); } })()); } return loads.get(assetId); } export async function recordSpot(assetId, price, nowMs = Date.now()) { if (assetId == null) return; await loadMomentum(assetId, nowMs); const prev = buffers.get(assetId) || null; const next = addPrice(prev, price, nowMs); if (next === prev) return; buffers.set(assetId, next); try { await setPref(PREF_SCOPE, String(assetId), next); } catch { } } export function momentumOf(assetId, nowMs = Date.now()) { return tally(buffers.get(assetId) || null, nowMs); } export function clearMomentum() { buffers.clear(); loads.clear(); }