Архитектура фронтенда
Слои
pages/index.vue ← оркестрация: symbol, tf, dateRange, настройки
│ props
components/ ← только UI, логика вынесена в composables
│ вызывает
composables/ ← вся бизнес-логика
│
utils/ + api/ ← чистые функции, HTTP-фабрика
stores/marketConfig ← список символов и таймфреймов с бэка
Поток данных
onMounted → GET /api/symbols → symbol = default, tf = default
watch([symbol, tf, dateRange]) → useCandles → GET /api/candles → candles[]
watch(candles) → useSessions → GET /api/indicators/sessions (макс 50 дней) → blocks[]
candles[] → useChart.setData → LW Charts
→ useSessionBoxes.computeBoxes → SessionBoxesPrimitive
→ useDrawings.syncPrimitive → DrawingsPrimitive
Infinite history
useChart.subscribeVisibleLogicalRangeChange
→ logicalRange.from < visibleBars*0.5
→ onNeedMoreHistory(visibleBars)
→ loadMoreHistory(visibleBars)
→ GET /api/candles?to_ts=oldest-1&limit=max(500, visibleBars*1.5)
→ prepend к candles → setData (позиция не сбрасывается)
API и настройки
useApi — клиент инжектируется плагином plugins/charts-api.client.js (provide('chartsApi', api)). useApi() вызывает inject('chartsApi'); fallback на создание из runtimeConfig, если контекста нет (тесты, edge cases).
useSettings — обёртка над Pinia store settings (stores/settings.js). Состояние и persistence в сторе; composable возвращает computed refs (get/set) для совместимости с v-model.
Отмена запросов
При быстрой смене symbol/tf/dateRange или повторных вызовах подгрузки предыдущие запросы отменяются через AbortController. API-клиент принимает опциональный { signal } во всех методах. Игнорируются ответы после отмены, чтобы не перезаписывать актуальное состояние.
LW Charts примитивы
series.attachPrimitive(p) — точка расширения LW Charts. Примитив получает draw(target) на каждый перерисов. target.useBitmapCoordinateSpace даёт прямой доступ к canvas с учётом device pixel ratio.
SessionBoxesPrimitive — боксы сессий.
DrawingsPrimitive — линии, прямоугольники, кисть, текст.