useTimelineDensity.ts 1.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546
  1. /**
  2. * Queries the SQLite index for daily block counts to drive
  3. * the TimelineRail density dots.
  4. */
  5. import { ref, watch } from "vue"
  6. import { useWorkspaceStore } from "~/stores/workspace"
  7. export function useTimelineDensity() {
  8. const ws = useWorkspaceStore()
  9. const densityMap = ref<Map<string, number>>(new Map())
  10. async function refresh() {
  11. const db = ws.db
  12. if (!db) {
  13. densityMap.value = new Map()
  14. return
  15. }
  16. try {
  17. const rows = await db.select<{ page_path: string; count: number }[]>(
  18. "SELECT page_path, COUNT(*) as count FROM blocks GROUP BY page_path",
  19. )
  20. const map = new Map<string, number>()
  21. for (const row of rows) {
  22. // Extract date from journal path: .../journals/YYYY-MM-DD.md
  23. const match = row.page_path.match(/journals\/(\d{4}-\d{2}-\d{2})\.md$/)
  24. if (match) {
  25. map.set(match[1], row.count)
  26. }
  27. }
  28. densityMap.value = map
  29. } catch (e) {
  30. console.warn("[useTimelineDensity] failed to query index:", e)
  31. densityMap.value = new Map()
  32. }
  33. }
  34. watch(
  35. () => ws.db,
  36. () => {
  37. refresh()
  38. },
  39. { immediate: true },
  40. )
  41. return { densityMap, refresh }
  42. }