Implement server-backed live history

This commit is contained in:
dirtydishes 2026-05-04 03:29:38 -04:00
parent b4f87b50d2
commit ba0daf5208
10 changed files with 402 additions and 44 deletions

View file

@ -1264,6 +1264,22 @@ export const fetchEquityPrintsBefore = async (
return EquityPrintSchema.array().parse(rows.map(normalizeEquityRow));
};
export const fetchEquityQuotesBefore = async (
client: ClickHouseClient,
beforeTs: number,
beforeSeq: number,
limit: number
): Promise<EquityQuote[]> => {
const safeLimit = clampLimit(limit);
const result = await client.query({
query: `SELECT * FROM ${EQUITY_QUOTES_TABLE} WHERE ${buildBeforeTupleCondition("ts", "seq", beforeTs, beforeSeq)} ORDER BY ts DESC, seq DESC LIMIT ${safeLimit}`,
format: "JSONEachRow"
});
const rows = await result.json<unknown[]>();
return EquityQuoteSchema.array().parse(rows.map(normalizeEquityQuoteRow));
};
export const fetchEquityPrintJoinsBefore = async (
client: ClickHouseClient,
beforeTs: number,

View file

@ -4,6 +4,7 @@ import {
EQUITY_QUOTES_TABLE,
normalizeEquityQuote
} from "../src/equity-quotes";
import { fetchEquityQuotesBefore, type ClickHouseClient } from "../src/clickhouse";
const baseQuote = {
source_ts: 100,
@ -27,4 +28,35 @@ describe("equity-quotes storage helpers", () => {
expect(ddl).toContain(EQUITY_QUOTES_TABLE);
expect(ddl).toContain("CREATE TABLE IF NOT EXISTS");
});
it("fetches older quotes with tuple cursor ordering", async () => {
let queryText = "";
const client = {
query: async ({ query }: { query: string }) => {
queryText = query;
return {
async json<T>() {
return [
{
...baseQuote,
source_ts: 90,
ingest_ts: 201,
seq: 2,
trace_id: "trace-2",
ts: 90
}
] as T;
}
};
}
} as unknown as ClickHouseClient;
const rows = await fetchEquityQuotesBefore(client, 100, 3, 25);
expect(rows).toHaveLength(1);
expect(rows[0]?.trace_id).toBe("trace-2");
expect(queryText).toContain(EQUITY_QUOTES_TABLE);
expect(queryText).toContain("WHERE (ts, seq) < (100, 3)");
expect(queryText).toContain("ORDER BY ts DESC, seq DESC LIMIT 25");
});
});