phase-6: typescript introduction

This commit is contained in:
Kazuma
2026-06-04 22:16:48 -04:00
parent 16bd95aa85
commit 69d13c3dbe
69 changed files with 2323 additions and 1036 deletions
+20 -20
View File
@@ -1,4 +1,4 @@
<script>
<script lang="ts">
import { screenTickers, analyzeTickers } from '$lib/api.js';
import { sigOrd, sorted, verdictShort, vClass } from '$lib/utils.js';
import SignalBadge from '$lib/SignalBadge.svelte';
@@ -7,23 +7,24 @@
import MarketContextStrip from '$lib/MarketContextStrip.svelte';
import AssetTable from '$lib/AssetTable.svelte';
import AnalysisSidebar from '$lib/AnalysisSidebar.svelte';
import type { ScreenerResult, AssetType, SidebarState } from '$lib/types.js';
// Initial data comes from +page.js load (replaces _booted / $effect hack)
let { data } = $props();
interface PageData { results: ScreenerResult; catalystInput: string }
let { data }: { data: PageData } = $props();
let input = $state(data.catalystInput);
let results = $state(data.results);
let screenedAt = $state(new Date().toLocaleTimeString());
let loading = $state(false);
let loadingCats = $state(false);
let error = $state(null);
let searchOpen = $state(false);
let input: string = $state(data.catalystInput);
let results: ScreenerResult = $state(data.results);
let screenedAt: string = $state(new Date().toLocaleTimeString());
let loading: boolean = $state(false);
let loadingCats: boolean = $state(false);
let error: string | null = $state(null);
let searchOpen: boolean = $state(false);
// ── LLM Analysis sidebar ────────────────────────────────────────────────
let sidebar = $state({ open: false, loading: false, analysis: null, type: null, error: null });
let sidebar: SidebarState = $state({ open: false, loading: false, analysis: null, type: null, error: null });
async function runTabAnalysis(type) {
const tickers = (results?.[type] ?? []).map(r => r.asset.ticker);
async function runTabAnalysis(type: AssetType): Promise<void> {
const tickers = (results?.[type] ?? []).map((r) => r.asset.ticker);
if (!tickers.length) return;
sidebar = { open: true, loading: true, analysis: null, type, error: null };
try {
@@ -32,12 +33,12 @@
sidebar = { open: true, loading: false, analysis: res.analysis, type,
error: res.analysis ? null : (reason ?? 'Analysis failed — check server logs for details.') };
} catch (e) {
sidebar = { open: true, loading: false, analysis: null, type, error: e.message };
sidebar = { open: true, loading: false, analysis: null, type, error: (e as Error).message };
}
}
// ── Manual ticker search ─────────────────────────────────────────────────
async function screen() {
async function screen(): Promise<void> {
error = null;
loading = true;
try {
@@ -45,15 +46,14 @@
results = await screenTickers(tickers);
screenedAt = new Date().toLocaleTimeString();
} catch (e) {
error = e.message;
error = (e as Error).message;
} finally {
loading = false;
}
}
// ── Re-fetch today's catalysts ───────────────────────────────────────────
// Splits fetch (news) from screen (Yahoo) — each step has its own loading flag.
async function reloadCatalysts() {
async function reloadCatalysts(): Promise<void> {
const { fetchCatalysts } = await import('$lib/api.js');
loadingCats = true;
error = null;
@@ -64,7 +64,7 @@
results = await screenTickers(cat.tickers);
screenedAt = new Date().toLocaleTimeString();
} catch (e) {
error = e.message;
error = (e as Error).message;
} finally {
loading = false;
loadingCats = false;
@@ -157,7 +157,7 @@
</section>
<!-- ── Per-type detail tables ────────────────────────────────────── -->
{#each ['STOCK', 'ETF', 'BOND'] as type}
{#each (['STOCK', 'ETF', 'BOND'] as const) as type}
{#if results[type]?.length}
<AssetTable
{type}