import path from "path" import { Global } from "@/global" import { onMount } from "solid-js" import { createStore } from "solid-js/store" import { createSimpleContext } from "../../context/helper" import { appendFile } from "fs/promises" function calculateFrecency(entry?: { frequency: number; lastOpen: number }): number { if (!entry) return 0 const daysSince = (Date.now() - entry.lastOpen) / 86400000 // ms per day const weight = 1 / (1 + daysSince) return entry.frequency * weight } const MAX_FRECENCY_ENTRIES = 1000 export const { use: useFrecency, provider: FrecencyProvider } = createSimpleContext({ name: "Frecency", init: () => { const frecencyFile = Bun.file(path.join(Global.Path.state, "frecency.jsonl")) onMount(async () => { const text = await frecencyFile.text().catch(() => "") const lines = text .split("\n") .filter(Boolean) .map((line) => { try { return JSON.parse(line) as { path: string; frequency: number; lastOpen: number } } catch { return null } }) .filter((line): line is { path: string; frequency: number; lastOpen: number } => line !== null) const latest = lines.reduce( (acc, entry) => { acc[entry.path] = entry return acc }, {} as Record, ) const sorted = Object.values(latest) .sort((a, b) => b.lastOpen - a.lastOpen) .slice(0, MAX_FRECENCY_ENTRIES) setStore( "data", Object.fromEntries( sorted.map((entry) => [entry.path, { frequency: entry.frequency, lastOpen: entry.lastOpen }]), ), ) if (sorted.length > 0) { const content = sorted.map((entry) => JSON.stringify(entry)).join("\n") + "\n" Bun.write(frecencyFile, content).catch(() => {}) } }) const [store, setStore] = createStore({ data: {} as Record, }) function updateFrecency(filePath: string) { const absolutePath = path.resolve(process.cwd(), filePath) const newEntry = { frequency: (store.data[absolutePath]?.frequency || 0) + 1, lastOpen: Date.now(), } setStore("data", absolutePath, newEntry) appendFile(frecencyFile.name!, JSON.stringify({ path: absolutePath, ...newEntry }) + "\n").catch(() => {}) if (Object.keys(store.data).length > MAX_FRECENCY_ENTRIES) { const sorted = Object.entries(store.data) .sort(([, a], [, b]) => b.lastOpen - a.lastOpen) .slice(0, MAX_FRECENCY_ENTRIES) setStore("data", Object.fromEntries(sorted)) const content = sorted.map(([path, entry]) => JSON.stringify({ path, ...entry })).join("\n") + "\n" Bun.write(frecencyFile, content).catch(() => {}) } } return { getFrecency: (filePath: string) => calculateFrecency(store.data[path.resolve(process.cwd(), filePath)]), updateFrecency, data: () => store.data, } }, })