Add event bus and storage layer
This commit is contained in:
parent
9ba51d8e96
commit
488ae82ed6
19 changed files with 537 additions and 21 deletions
12
packages/storage/package.json
Normal file
12
packages/storage/package.json
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
{
|
||||
"name": "@islandflow/storage",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"exports": {
|
||||
".": "./src/index.ts"
|
||||
},
|
||||
"dependencies": {
|
||||
"@clickhouse/client": "^0.2.6",
|
||||
"@islandflow/types": "workspace:*"
|
||||
}
|
||||
}
|
||||
39
packages/storage/src/clickhouse.ts
Normal file
39
packages/storage/src/clickhouse.ts
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
import { createClient, type ClickHouseClient } from "@clickhouse/client";
|
||||
import type { OptionPrint } from "@islandflow/types";
|
||||
import { normalizeOptionPrint, optionPrintsTableDDL, OPTION_PRINTS_TABLE } from "./option-prints";
|
||||
|
||||
export type ClickHouseOptions = {
|
||||
url: string;
|
||||
database?: string;
|
||||
username?: string;
|
||||
password?: string;
|
||||
};
|
||||
|
||||
export const createClickHouseClient = (options: ClickHouseOptions): ClickHouseClient => {
|
||||
return createClient({
|
||||
url: options.url,
|
||||
database: options.database,
|
||||
username: options.username,
|
||||
password: options.password
|
||||
});
|
||||
};
|
||||
|
||||
export const ensureOptionPrintsTable = async (
|
||||
client: ClickHouseClient
|
||||
): Promise<void> => {
|
||||
await client.exec({
|
||||
query: optionPrintsTableDDL()
|
||||
});
|
||||
};
|
||||
|
||||
export const insertOptionPrint = async (
|
||||
client: ClickHouseClient,
|
||||
print: OptionPrint
|
||||
): Promise<void> => {
|
||||
const record = normalizeOptionPrint(print);
|
||||
await client.insert({
|
||||
table: OPTION_PRINTS_TABLE,
|
||||
values: [record],
|
||||
format: "JSONEachRow"
|
||||
});
|
||||
};
|
||||
2
packages/storage/src/index.ts
Normal file
2
packages/storage/src/index.ts
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
export * from "./clickhouse";
|
||||
export * from "./option-prints";
|
||||
29
packages/storage/src/option-prints.ts
Normal file
29
packages/storage/src/option-prints.ts
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
import type { OptionPrint } from "@islandflow/types";
|
||||
|
||||
export const OPTION_PRINTS_TABLE = "option_prints";
|
||||
|
||||
export const optionPrintsTableDDL = (): string => {
|
||||
return `
|
||||
CREATE TABLE IF NOT EXISTS ${OPTION_PRINTS_TABLE} (
|
||||
source_ts UInt64,
|
||||
ingest_ts UInt64,
|
||||
seq UInt64,
|
||||
trace_id String,
|
||||
ts UInt64,
|
||||
option_contract_id String,
|
||||
price Float64,
|
||||
size UInt32,
|
||||
exchange String,
|
||||
conditions Array(String)
|
||||
)
|
||||
ENGINE = MergeTree
|
||||
ORDER BY (ts, option_contract_id)
|
||||
`;
|
||||
};
|
||||
|
||||
export const normalizeOptionPrint = (print: OptionPrint): OptionPrint => {
|
||||
return {
|
||||
...print,
|
||||
conditions: print.conditions ?? []
|
||||
};
|
||||
};
|
||||
27
packages/storage/tests/option-prints.test.ts
Normal file
27
packages/storage/tests/option-prints.test.ts
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
import { describe, expect, it } from "bun:test";
|
||||
import { normalizeOptionPrint, optionPrintsTableDDL, OPTION_PRINTS_TABLE } from "../src/option-prints";
|
||||
|
||||
const basePrint = {
|
||||
source_ts: 100,
|
||||
ingest_ts: 200,
|
||||
seq: 1,
|
||||
trace_id: "trace-1",
|
||||
ts: 100,
|
||||
option_contract_id: "SPY-2025-01-17-450-C",
|
||||
price: 1.25,
|
||||
size: 10,
|
||||
exchange: "TEST"
|
||||
};
|
||||
|
||||
describe("option-prints storage helpers", () => {
|
||||
it("normalizes missing conditions to empty array", () => {
|
||||
const normalized = normalizeOptionPrint(basePrint);
|
||||
expect(normalized.conditions).toEqual([]);
|
||||
});
|
||||
|
||||
it("includes the correct table name in the DDL", () => {
|
||||
const ddl = optionPrintsTableDDL();
|
||||
expect(ddl).toContain(OPTION_PRINTS_TABLE);
|
||||
expect(ddl).toContain("CREATE TABLE IF NOT EXISTS");
|
||||
});
|
||||
});
|
||||
7
packages/storage/tsconfig.json
Normal file
7
packages/storage/tsconfig.json
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
{
|
||||
"extends": "../../tsconfig.base.json",
|
||||
"compilerOptions": {
|
||||
"types": []
|
||||
},
|
||||
"include": ["src/**/*.ts", "tests/**/*.ts"]
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue