@the-situation/indexer 0.17.1 → 0.18.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/aggregator/cohort.d.ts +30 -0
- package/dist/aggregator/cohort.d.ts.map +1 -0
- package/dist/aggregator/cohort.js +153 -0
- package/dist/aggregator/cohort.js.map +1 -0
- package/dist/aggregator/daily.d.ts +71 -0
- package/dist/aggregator/daily.d.ts.map +1 -0
- package/dist/aggregator/daily.js +249 -0
- package/dist/aggregator/daily.js.map +1 -0
- package/dist/aggregator/domains.d.ts +20 -0
- package/dist/aggregator/domains.d.ts.map +1 -0
- package/dist/aggregator/domains.js +38 -0
- package/dist/aggregator/domains.js.map +1 -0
- package/dist/aggregator/index.d.ts +31 -0
- package/dist/aggregator/index.d.ts.map +1 -0
- package/dist/aggregator/index.js +100 -0
- package/dist/aggregator/index.js.map +1 -0
- package/dist/aggregator/lifetime.d.ts +52 -0
- package/dist/aggregator/lifetime.d.ts.map +1 -0
- package/dist/aggregator/lifetime.js +222 -0
- package/dist/aggregator/lifetime.js.map +1 -0
- package/dist/aggregator/roi.d.ts +42 -0
- package/dist/aggregator/roi.d.ts.map +1 -0
- package/dist/aggregator/roi.js +153 -0
- package/dist/aggregator/roi.js.map +1 -0
- package/dist/aggregator/sources.d.ts +59 -0
- package/dist/aggregator/sources.d.ts.map +1 -0
- package/dist/aggregator/sources.js +53 -0
- package/dist/aggregator/sources.js.map +1 -0
- package/dist/aggregator/writers.d.ts +22 -0
- package/dist/aggregator/writers.d.ts.map +1 -0
- package/dist/aggregator/writers.js +147 -0
- package/dist/aggregator/writers.js.map +1 -0
- package/dist/api/app.d.ts +177 -13
- package/dist/api/app.d.ts.map +1 -1
- package/dist/api/app.js +4 -3
- package/dist/api/app.js.map +1 -1
- package/dist/api/routes/admin-subscriptions.d.ts +10 -10
- package/dist/api/routes/analytics.d.ts +205 -0
- package/dist/api/routes/analytics.d.ts.map +1 -0
- package/dist/api/routes/analytics.js +122 -0
- package/dist/api/routes/analytics.js.map +1 -0
- package/dist/api/routes/index.d.ts +1 -0
- package/dist/api/routes/index.d.ts.map +1 -1
- package/dist/api/routes/index.js +1 -0
- package/dist/api/routes/index.js.map +1 -1
- package/dist/api/routes/lp-history.d.ts +1 -1
- package/dist/api/routes/rankings.d.ts +17 -3
- package/dist/api/routes/rankings.d.ts.map +1 -1
- package/dist/api/routes/rankings.js +44 -5
- package/dist/api/routes/rankings.js.map +1 -1
- package/dist/api/routes/trader-stats.d.ts +11 -2
- package/dist/api/routes/trader-stats.d.ts.map +1 -1
- package/dist/api/routes/trader-stats.js +72 -2
- package/dist/api/routes/trader-stats.js.map +1 -1
- package/dist/client/IndexerClient.d.ts +30 -1
- package/dist/client/IndexerClient.d.ts.map +1 -1
- package/dist/client/IndexerClient.js.map +1 -1
- package/dist/client/IndexerClientLive.d.ts.map +1 -1
- package/dist/client/IndexerClientLive.js +50 -1
- package/dist/client/IndexerClientLive.js.map +1 -1
- package/dist/client/convenience.d.ts +9 -2
- package/dist/client/convenience.d.ts.map +1 -1
- package/dist/client/convenience.js +9 -1
- package/dist/client/convenience.js.map +1 -1
- package/dist/client/index.d.ts +3 -2
- package/dist/client/index.d.ts.map +1 -1
- package/dist/client/index.js +1 -1
- package/dist/client/index.js.map +1 -1
- package/dist/config.d.ts +9 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +2 -0
- package/dist/config.js.map +1 -1
- package/dist/etl/event-indexer.d.ts +1 -1
- package/dist/etl/lp-position-refresher.d.ts +2 -1
- package/dist/etl/lp-position-refresher.d.ts.map +1 -1
- package/dist/etl/lp-position-refresher.js +24 -11
- package/dist/etl/lp-position-refresher.js.map +1 -1
- package/dist/etl/position-refresher.d.ts +1 -1
- package/dist/etl/state-refresher.d.ts +1 -1
- package/dist/index.js +54 -5
- package/dist/index.js.map +1 -1
- package/dist/layers/ChainReaderLive.d.ts.map +1 -1
- package/dist/layers/ChainReaderLive.js +15 -0
- package/dist/layers/ChainReaderLive.js.map +1 -1
- package/dist/services/ChainReader.d.ts +10 -0
- package/dist/services/ChainReader.d.ts.map +1 -1
- package/dist/services/ChainReader.js.map +1 -1
- package/dist/types/analytics.d.ts +194 -0
- package/dist/types/analytics.d.ts.map +1 -0
- package/dist/types/analytics.js +10 -0
- package/dist/types/analytics.js.map +1 -0
- package/dist/types/index.d.ts +1 -0
- package/dist/types/index.d.ts.map +1 -1
- package/dist/warehouse/analytics-helpers.d.ts +36 -0
- package/dist/warehouse/analytics-helpers.d.ts.map +1 -0
- package/dist/warehouse/analytics-helpers.js +142 -0
- package/dist/warehouse/analytics-helpers.js.map +1 -0
- package/dist/warehouse/backfill.d.ts +26 -0
- package/dist/warehouse/backfill.d.ts.map +1 -0
- package/dist/warehouse/backfill.js +77 -0
- package/dist/warehouse/backfill.js.map +1 -0
- package/dist/warehouse/connection.d.ts +24 -0
- package/dist/warehouse/connection.d.ts.map +1 -0
- package/dist/warehouse/connection.js +30 -0
- package/dist/warehouse/connection.js.map +1 -0
- package/dist/warehouse/index.d.ts +14 -0
- package/dist/warehouse/index.d.ts.map +1 -0
- package/dist/warehouse/index.js +14 -0
- package/dist/warehouse/index.js.map +1 -0
- package/dist/warehouse/repositories/analytics.d.ts +61 -0
- package/dist/warehouse/repositories/analytics.d.ts.map +1 -0
- package/dist/warehouse/repositories/analytics.js +418 -0
- package/dist/warehouse/repositories/analytics.js.map +1 -0
- package/dist/warehouse/schema.d.ts +9 -0
- package/dist/warehouse/schema.d.ts.map +1 -0
- package/dist/warehouse/schema.js +219 -0
- package/dist/warehouse/schema.js.map +1 -0
- package/dist/warehouse/seed-domains.d.ts +29 -0
- package/dist/warehouse/seed-domains.d.ts.map +1 -0
- package/dist/warehouse/seed-domains.js +223 -0
- package/dist/warehouse/seed-domains.js.map +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cohort retention builder.
|
|
3
|
+
*
|
|
4
|
+
* For each (cohort_week, week_offset, domain_slug, entity_type) tuple, count
|
|
5
|
+
* the users from the cohort that were active during that week.
|
|
6
|
+
*
|
|
7
|
+
* `domain_slug = 'all'` is the un-segmented total. Per-domain rows are also
|
|
8
|
+
* emitted for every domain a cohort member touched.
|
|
9
|
+
*
|
|
10
|
+
* "Active" definitions:
|
|
11
|
+
* - trader: had >= 1 trade event in the week
|
|
12
|
+
* - lp: had >= 1 deposit or withdraw event in the week
|
|
13
|
+
*
|
|
14
|
+
* The week index is the ISO Monday (UTC). week_offset 0 is the cohort week
|
|
15
|
+
* itself; offsets > 0 are subsequent weeks.
|
|
16
|
+
*/
|
|
17
|
+
import { type AggEventRow } from './sources';
|
|
18
|
+
import { type MarketDomainMap } from './domains';
|
|
19
|
+
import type { LPLifetimeRow, TraderLifetimeRow } from './lifetime';
|
|
20
|
+
export interface CohortRetentionRow {
|
|
21
|
+
readonly cohort_week: string;
|
|
22
|
+
readonly week_offset: number;
|
|
23
|
+
readonly domain_slug: string;
|
|
24
|
+
readonly entity_type: 'trader' | 'lp';
|
|
25
|
+
readonly cohort_size: number;
|
|
26
|
+
readonly retained: number;
|
|
27
|
+
}
|
|
28
|
+
export declare function buildCohortRetention(events: readonly AggEventRow[], traderLifetime: readonly TraderLifetimeRow[], lpLifetime: readonly LPLifetimeRow[], marketDomains: MarketDomainMap): readonly CohortRetentionRow[];
|
|
29
|
+
export declare function writeCohortRetention(pg: import('bun').SQL, rows: readonly CohortRetentionRow[]): Promise<void>;
|
|
30
|
+
//# sourceMappingURL=cohort.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cohort.d.ts","sourceRoot":"","sources":["../../src/aggregator/cohort.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AACH,OAAO,EACL,KAAK,WAAW,EAIjB,MAAM,WAAW,CAAC;AACnB,OAAO,EAAE,KAAK,eAAe,EAAmB,MAAM,WAAW,CAAC;AAClE,OAAO,KAAK,EAAE,aAAa,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAEnE,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,WAAW,EAAE,QAAQ,GAAG,IAAI,CAAC;IACtC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;CAC3B;AAoBD,wBAAgB,oBAAoB,CAClC,MAAM,EAAE,SAAS,WAAW,EAAE,EAC9B,cAAc,EAAE,SAAS,iBAAiB,EAAE,EAC5C,UAAU,EAAE,SAAS,aAAa,EAAE,EACpC,aAAa,EAAE,eAAe,GAC7B,SAAS,kBAAkB,EAAE,CAqH/B;AAED,wBAAsB,oBAAoB,CACxC,EAAE,EAAE,OAAO,KAAK,EAAE,GAAG,EACrB,IAAI,EAAE,SAAS,kBAAkB,EAAE,GAClC,OAAO,CAAC,IAAI,CAAC,CAcf"}
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cohort retention builder.
|
|
3
|
+
*
|
|
4
|
+
* For each (cohort_week, week_offset, domain_slug, entity_type) tuple, count
|
|
5
|
+
* the users from the cohort that were active during that week.
|
|
6
|
+
*
|
|
7
|
+
* `domain_slug = 'all'` is the un-segmented total. Per-domain rows are also
|
|
8
|
+
* emitted for every domain a cohort member touched.
|
|
9
|
+
*
|
|
10
|
+
* "Active" definitions:
|
|
11
|
+
* - trader: had >= 1 trade event in the week
|
|
12
|
+
* - lp: had >= 1 deposit or withdraw event in the week
|
|
13
|
+
*
|
|
14
|
+
* The week index is the ISO Monday (UTC). week_offset 0 is the cohort week
|
|
15
|
+
* itself; offsets > 0 are subsequent weeks.
|
|
16
|
+
*/
|
|
17
|
+
import { LIQUIDITY_ADD_TYPES, LIQUIDITY_REMOVE_TYPES, TRADE_EVENT_TYPES, } from './sources';
|
|
18
|
+
import { primaryDomainOf } from './domains';
|
|
19
|
+
function isoWeekStart(ts) {
|
|
20
|
+
const d = new Date(ts * 1000);
|
|
21
|
+
const day = d.getUTCDay();
|
|
22
|
+
const diff = day === 0 ? -6 : 1 - day;
|
|
23
|
+
const monday = new Date(d.getTime());
|
|
24
|
+
monday.setUTCDate(d.getUTCDate() + diff);
|
|
25
|
+
const yyyy = monday.getUTCFullYear();
|
|
26
|
+
const mm = String(monday.getUTCMonth() + 1).padStart(2, '0');
|
|
27
|
+
const dd = String(monday.getUTCDate()).padStart(2, '0');
|
|
28
|
+
return `${yyyy}-${mm}-${dd}`;
|
|
29
|
+
}
|
|
30
|
+
function weekDiff(cohortWeekStr, eventWeekStr) {
|
|
31
|
+
const cohort = Date.parse(`${cohortWeekStr}T00:00:00Z`);
|
|
32
|
+
const eventW = Date.parse(`${eventWeekStr}T00:00:00Z`);
|
|
33
|
+
return Math.floor((eventW - cohort) / (7 * 24 * 60 * 60 * 1000));
|
|
34
|
+
}
|
|
35
|
+
export function buildCohortRetention(events, traderLifetime, lpLifetime, marketDomains) {
|
|
36
|
+
const traderCohort = new Map();
|
|
37
|
+
for (const t of traderLifetime) {
|
|
38
|
+
if (t.cohort_week)
|
|
39
|
+
traderCohort.set(t.trader, t.cohort_week);
|
|
40
|
+
}
|
|
41
|
+
const lpCohort = new Map();
|
|
42
|
+
for (const l of lpLifetime) {
|
|
43
|
+
if (l.cohort_week)
|
|
44
|
+
lpCohort.set(l.provider, l.cohort_week);
|
|
45
|
+
}
|
|
46
|
+
const activity = new Map();
|
|
47
|
+
activity.set('trader', new Map());
|
|
48
|
+
activity.set('lp', new Map());
|
|
49
|
+
function record(entityType, domain, cohortWeek, weekOffset, user) {
|
|
50
|
+
const byEntity = activity.get(entityType);
|
|
51
|
+
let byDomain = byEntity.get(domain);
|
|
52
|
+
if (!byDomain) {
|
|
53
|
+
byDomain = new Map();
|
|
54
|
+
byEntity.set(domain, byDomain);
|
|
55
|
+
}
|
|
56
|
+
let byCohort = byDomain.get(cohortWeek);
|
|
57
|
+
if (!byCohort) {
|
|
58
|
+
byCohort = new Map();
|
|
59
|
+
byDomain.set(cohortWeek, byCohort);
|
|
60
|
+
}
|
|
61
|
+
let byOffset = byCohort.get(weekOffset);
|
|
62
|
+
if (!byOffset) {
|
|
63
|
+
byOffset = new Set();
|
|
64
|
+
byCohort.set(weekOffset, byOffset);
|
|
65
|
+
}
|
|
66
|
+
byOffset.add(user);
|
|
67
|
+
}
|
|
68
|
+
for (const event of events) {
|
|
69
|
+
if (!event.trader)
|
|
70
|
+
continue;
|
|
71
|
+
const eventWeek = isoWeekStart(event.timestamp);
|
|
72
|
+
const domain = primaryDomainOf(marketDomains, event.market_address);
|
|
73
|
+
const isTrade = TRADE_EVENT_TYPES.has(event.event_type);
|
|
74
|
+
const isLPEvent = LIQUIDITY_ADD_TYPES.has(event.event_type) ||
|
|
75
|
+
LIQUIDITY_REMOVE_TYPES.has(event.event_type);
|
|
76
|
+
if (isTrade) {
|
|
77
|
+
const cohort = traderCohort.get(event.trader);
|
|
78
|
+
if (cohort) {
|
|
79
|
+
const offset = weekDiff(cohort, eventWeek);
|
|
80
|
+
if (offset >= 0) {
|
|
81
|
+
record('trader', 'all', cohort, offset, event.trader);
|
|
82
|
+
record('trader', domain, cohort, offset, event.trader);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
if (isLPEvent) {
|
|
87
|
+
const cohort = lpCohort.get(event.trader);
|
|
88
|
+
if (cohort) {
|
|
89
|
+
const offset = weekDiff(cohort, eventWeek);
|
|
90
|
+
if (offset >= 0) {
|
|
91
|
+
record('lp', 'all', cohort, offset, event.trader);
|
|
92
|
+
record('lp', domain, cohort, offset, event.trader);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
// Cohort sizes: count distinct users per (entity_type, domain, cohort_week).
|
|
98
|
+
// For 'all' it's the count from lifetime tables. For per-domain, it's the
|
|
99
|
+
// number of cohort members whose activity ever touched that domain
|
|
100
|
+
// (= the size of week_offset=0 PLUS any user whose first activity in the
|
|
101
|
+
// domain happened later — which we approximate by union over all offsets).
|
|
102
|
+
const out = [];
|
|
103
|
+
for (const entityType of ['trader', 'lp']) {
|
|
104
|
+
const byEntity = activity.get(entityType);
|
|
105
|
+
// Build cohort-level totals for the 'all' bucket from lifetime tables.
|
|
106
|
+
const cohortTotalAll = new Map();
|
|
107
|
+
const lifetimeRows = entityType === 'trader' ? traderLifetime : lpLifetime;
|
|
108
|
+
for (const row of lifetimeRows) {
|
|
109
|
+
const cw = row.cohort_week;
|
|
110
|
+
if (!cw)
|
|
111
|
+
continue;
|
|
112
|
+
cohortTotalAll.set(cw, (cohortTotalAll.get(cw) ?? 0) + 1);
|
|
113
|
+
}
|
|
114
|
+
for (const [domain, byDomain] of byEntity) {
|
|
115
|
+
for (const [cohortWeek, byCohort] of byDomain) {
|
|
116
|
+
// Cohort size = union of all users seen in this domain for this cohort.
|
|
117
|
+
const allUsers = new Set();
|
|
118
|
+
for (const users of byCohort.values()) {
|
|
119
|
+
for (const u of users)
|
|
120
|
+
allUsers.add(u);
|
|
121
|
+
}
|
|
122
|
+
const cohortSize = domain === 'all' ? (cohortTotalAll.get(cohortWeek) ?? allUsers.size) : allUsers.size;
|
|
123
|
+
for (const [weekOffset, users] of byCohort) {
|
|
124
|
+
out.push({
|
|
125
|
+
cohort_week: cohortWeek,
|
|
126
|
+
week_offset: weekOffset,
|
|
127
|
+
domain_slug: domain,
|
|
128
|
+
entity_type: entityType,
|
|
129
|
+
cohort_size: cohortSize,
|
|
130
|
+
retained: users.size,
|
|
131
|
+
});
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
return out;
|
|
137
|
+
}
|
|
138
|
+
export async function writeCohortRetention(pg, rows) {
|
|
139
|
+
await pg.begin(async (tx) => {
|
|
140
|
+
await tx `TRUNCATE TABLE cohort_retention`;
|
|
141
|
+
for (const r of rows) {
|
|
142
|
+
await tx `
|
|
143
|
+
INSERT INTO cohort_retention
|
|
144
|
+
(cohort_week, week_offset, domain_slug, entity_type,
|
|
145
|
+
cohort_size, retained, updated_at)
|
|
146
|
+
VALUES
|
|
147
|
+
(${r.cohort_week}, ${r.week_offset}, ${r.domain_slug}, ${r.entity_type},
|
|
148
|
+
${r.cohort_size}, ${r.retained}, now())
|
|
149
|
+
`;
|
|
150
|
+
}
|
|
151
|
+
});
|
|
152
|
+
}
|
|
153
|
+
//# sourceMappingURL=cohort.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cohort.js","sourceRoot":"","sources":["../../src/aggregator/cohort.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Daily fact table builders.
|
|
3
|
+
*
|
|
4
|
+
* Pure in-memory aggregation — input: events + positions + market→domain map.
|
|
5
|
+
* Output: arrays of rows ready to bulk-insert into Postgres.
|
|
6
|
+
*
|
|
7
|
+
* Approach: full recompute per cycle. With ~100k events this is sub-second.
|
|
8
|
+
* Switch to incremental if event count grows past ~10M.
|
|
9
|
+
*/
|
|
10
|
+
import { type AggEventRow } from './sources';
|
|
11
|
+
import { type MarketDomainMap } from './domains';
|
|
12
|
+
export interface DailyTraderStatRow {
|
|
13
|
+
readonly date: string;
|
|
14
|
+
readonly trader: string;
|
|
15
|
+
readonly domain_slug: string;
|
|
16
|
+
readonly trade_count: number;
|
|
17
|
+
readonly buy_count: number;
|
|
18
|
+
readonly sell_count: number;
|
|
19
|
+
readonly volume_collateral: number;
|
|
20
|
+
readonly markets_traded: number;
|
|
21
|
+
}
|
|
22
|
+
export interface DailyLPStatRow {
|
|
23
|
+
readonly date: string;
|
|
24
|
+
readonly provider: string;
|
|
25
|
+
readonly domain_slug: string;
|
|
26
|
+
readonly deposit_count: number;
|
|
27
|
+
readonly withdraw_count: number;
|
|
28
|
+
readonly deposited: number;
|
|
29
|
+
readonly withdrawn: number;
|
|
30
|
+
readonly markets_active: number;
|
|
31
|
+
}
|
|
32
|
+
export interface DailyMarketStatRow {
|
|
33
|
+
readonly date: string;
|
|
34
|
+
readonly market_address: string;
|
|
35
|
+
readonly trade_count: number;
|
|
36
|
+
readonly unique_traders: number;
|
|
37
|
+
readonly volume_collateral: number;
|
|
38
|
+
readonly liquidity_added: number;
|
|
39
|
+
readonly liquidity_removed: number;
|
|
40
|
+
readonly unique_lps: number;
|
|
41
|
+
}
|
|
42
|
+
export interface DailyDomainStatRow {
|
|
43
|
+
readonly date: string;
|
|
44
|
+
readonly domain_slug: string;
|
|
45
|
+
readonly trade_count: number;
|
|
46
|
+
readonly unique_traders: number;
|
|
47
|
+
readonly unique_lps: number;
|
|
48
|
+
readonly volume_collateral: number;
|
|
49
|
+
readonly liquidity_net: number;
|
|
50
|
+
readonly active_markets: number;
|
|
51
|
+
}
|
|
52
|
+
export interface DailyPlatformStatRow {
|
|
53
|
+
readonly date: string;
|
|
54
|
+
readonly trade_count: number;
|
|
55
|
+
readonly unique_traders: number;
|
|
56
|
+
readonly unique_lps: number;
|
|
57
|
+
readonly new_traders: number;
|
|
58
|
+
readonly new_lps: number;
|
|
59
|
+
readonly volume_collateral: number;
|
|
60
|
+
readonly liquidity_net: number;
|
|
61
|
+
readonly active_markets: number;
|
|
62
|
+
}
|
|
63
|
+
export interface DailyAggregates {
|
|
64
|
+
readonly trader: readonly DailyTraderStatRow[];
|
|
65
|
+
readonly lp: readonly DailyLPStatRow[];
|
|
66
|
+
readonly market: readonly DailyMarketStatRow[];
|
|
67
|
+
readonly domain: readonly DailyDomainStatRow[];
|
|
68
|
+
readonly platform: readonly DailyPlatformStatRow[];
|
|
69
|
+
}
|
|
70
|
+
export declare function buildDailyAggregates(events: readonly AggEventRow[], marketDomains: MarketDomainMap): DailyAggregates;
|
|
71
|
+
//# sourceMappingURL=daily.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"daily.d.ts","sourceRoot":"","sources":["../../src/aggregator/daily.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,249 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Daily fact table builders.
|
|
3
|
+
*
|
|
4
|
+
* Pure in-memory aggregation — input: events + positions + market→domain map.
|
|
5
|
+
* Output: arrays of rows ready to bulk-insert into Postgres.
|
|
6
|
+
*
|
|
7
|
+
* Approach: full recompute per cycle. With ~100k events this is sub-second.
|
|
8
|
+
* Switch to incremental if event count grows past ~10M.
|
|
9
|
+
*/
|
|
10
|
+
import { LIQUIDITY_ADD_TYPES, LIQUIDITY_REMOVE_TYPES, TRADE_EVENT_TYPES, parseCollateralAmount, } from './sources';
|
|
11
|
+
import { primaryDomainOf } from './domains';
|
|
12
|
+
function dateOf(ts) {
|
|
13
|
+
const d = new Date(ts * 1000);
|
|
14
|
+
const yyyy = d.getUTCFullYear();
|
|
15
|
+
const mm = String(d.getUTCMonth() + 1).padStart(2, '0');
|
|
16
|
+
const dd = String(d.getUTCDate()).padStart(2, '0');
|
|
17
|
+
return `${yyyy}-${mm}-${dd}`;
|
|
18
|
+
}
|
|
19
|
+
export function buildDailyAggregates(events, marketDomains) {
|
|
20
|
+
// Keys for nested maps
|
|
21
|
+
const traderBuckets = new Map(); // key: date|trader|domain
|
|
22
|
+
const lpBuckets = new Map(); // key: date|provider|domain
|
|
23
|
+
const marketBuckets = new Map(); // key: date|market_address
|
|
24
|
+
const domainBuckets = new Map(); // key: date|domain
|
|
25
|
+
const platformBuckets = new Map(); // key: date
|
|
26
|
+
// First-seen trackers for new_traders / new_lps
|
|
27
|
+
const traderFirstDate = new Map();
|
|
28
|
+
const lpFirstDate = new Map();
|
|
29
|
+
for (const event of events) {
|
|
30
|
+
const date = dateOf(event.timestamp);
|
|
31
|
+
const domain = primaryDomainOf(marketDomains, event.market_address);
|
|
32
|
+
const isTrade = TRADE_EVENT_TYPES.has(event.event_type);
|
|
33
|
+
const isLiqAdd = LIQUIDITY_ADD_TYPES.has(event.event_type);
|
|
34
|
+
const isLiqRemove = LIQUIDITY_REMOVE_TYPES.has(event.event_type);
|
|
35
|
+
const collateral = parseCollateralAmount(event.collateral_posted);
|
|
36
|
+
const isSell = (event.is_position_sell ?? 0) === 1;
|
|
37
|
+
// ── platform (date) ──
|
|
38
|
+
let platform = platformBuckets.get(date);
|
|
39
|
+
if (!platform) {
|
|
40
|
+
platform = {
|
|
41
|
+
trade_count: 0,
|
|
42
|
+
traders: new Set(),
|
|
43
|
+
lps: new Set(),
|
|
44
|
+
volume_collateral: 0,
|
|
45
|
+
liquidity_added: 0,
|
|
46
|
+
liquidity_removed: 0,
|
|
47
|
+
markets: new Set(),
|
|
48
|
+
};
|
|
49
|
+
platformBuckets.set(date, platform);
|
|
50
|
+
}
|
|
51
|
+
platform.markets.add(event.market_address);
|
|
52
|
+
// ── domain (date|domain) ──
|
|
53
|
+
const domainKey = `${date}|${domain}`;
|
|
54
|
+
let domainBucket = domainBuckets.get(domainKey);
|
|
55
|
+
if (!domainBucket) {
|
|
56
|
+
domainBucket = {
|
|
57
|
+
trade_count: 0,
|
|
58
|
+
traders: new Set(),
|
|
59
|
+
lps: new Set(),
|
|
60
|
+
volume_collateral: 0,
|
|
61
|
+
liquidity_added: 0,
|
|
62
|
+
liquidity_removed: 0,
|
|
63
|
+
markets: new Set(),
|
|
64
|
+
};
|
|
65
|
+
domainBuckets.set(domainKey, domainBucket);
|
|
66
|
+
}
|
|
67
|
+
domainBucket.markets.add(event.market_address);
|
|
68
|
+
// ── market (date|market) ──
|
|
69
|
+
const marketKey = `${date}|${event.market_address}`;
|
|
70
|
+
let marketBucket = marketBuckets.get(marketKey);
|
|
71
|
+
if (!marketBucket) {
|
|
72
|
+
marketBucket = {
|
|
73
|
+
trade_count: 0,
|
|
74
|
+
traders: new Set(),
|
|
75
|
+
lps: new Set(),
|
|
76
|
+
volume_collateral: 0,
|
|
77
|
+
liquidity_added: 0,
|
|
78
|
+
liquidity_removed: 0,
|
|
79
|
+
};
|
|
80
|
+
marketBuckets.set(marketKey, marketBucket);
|
|
81
|
+
}
|
|
82
|
+
if (isTrade && event.trader) {
|
|
83
|
+
const trader = event.trader;
|
|
84
|
+
platform.trade_count += 1;
|
|
85
|
+
platform.traders.add(trader);
|
|
86
|
+
platform.volume_collateral += collateral;
|
|
87
|
+
domainBucket.trade_count += 1;
|
|
88
|
+
domainBucket.traders.add(trader);
|
|
89
|
+
domainBucket.volume_collateral += collateral;
|
|
90
|
+
marketBucket.trade_count += 1;
|
|
91
|
+
marketBucket.traders.add(trader);
|
|
92
|
+
marketBucket.volume_collateral += collateral;
|
|
93
|
+
const traderKey = `${date}|${trader}|${domain}`;
|
|
94
|
+
let traderBucket = traderBuckets.get(traderKey);
|
|
95
|
+
if (!traderBucket) {
|
|
96
|
+
traderBucket = {
|
|
97
|
+
trade_count: 0,
|
|
98
|
+
buy_count: 0,
|
|
99
|
+
sell_count: 0,
|
|
100
|
+
volume_collateral: 0,
|
|
101
|
+
markets: new Set(),
|
|
102
|
+
};
|
|
103
|
+
traderBuckets.set(traderKey, traderBucket);
|
|
104
|
+
}
|
|
105
|
+
traderBucket.trade_count += 1;
|
|
106
|
+
if (isSell) {
|
|
107
|
+
traderBucket.sell_count += 1;
|
|
108
|
+
}
|
|
109
|
+
else {
|
|
110
|
+
traderBucket.buy_count += 1;
|
|
111
|
+
}
|
|
112
|
+
traderBucket.volume_collateral += collateral;
|
|
113
|
+
traderBucket.markets.add(event.market_address);
|
|
114
|
+
// first-seen trader date
|
|
115
|
+
const prev = traderFirstDate.get(trader);
|
|
116
|
+
if (!prev || date < prev) {
|
|
117
|
+
traderFirstDate.set(trader, date);
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
if ((isLiqAdd || isLiqRemove) && event.trader) {
|
|
121
|
+
const provider = event.trader;
|
|
122
|
+
platform.lps.add(provider);
|
|
123
|
+
domainBucket.lps.add(provider);
|
|
124
|
+
marketBucket.lps.add(provider);
|
|
125
|
+
const lpKey = `${date}|${provider}|${domain}`;
|
|
126
|
+
let lpBucket = lpBuckets.get(lpKey);
|
|
127
|
+
if (!lpBucket) {
|
|
128
|
+
lpBucket = {
|
|
129
|
+
deposit_count: 0,
|
|
130
|
+
withdraw_count: 0,
|
|
131
|
+
deposited: 0,
|
|
132
|
+
withdrawn: 0,
|
|
133
|
+
markets: new Set(),
|
|
134
|
+
};
|
|
135
|
+
lpBuckets.set(lpKey, lpBucket);
|
|
136
|
+
}
|
|
137
|
+
lpBucket.markets.add(event.market_address);
|
|
138
|
+
if (isLiqAdd) {
|
|
139
|
+
lpBucket.deposit_count += 1;
|
|
140
|
+
lpBucket.deposited += collateral;
|
|
141
|
+
marketBucket.liquidity_added += collateral;
|
|
142
|
+
domainBucket.liquidity_added += collateral;
|
|
143
|
+
platform.liquidity_added += collateral;
|
|
144
|
+
}
|
|
145
|
+
else {
|
|
146
|
+
lpBucket.withdraw_count += 1;
|
|
147
|
+
lpBucket.withdrawn += collateral;
|
|
148
|
+
marketBucket.liquidity_removed += collateral;
|
|
149
|
+
domainBucket.liquidity_removed += collateral;
|
|
150
|
+
platform.liquidity_removed += collateral;
|
|
151
|
+
}
|
|
152
|
+
const prev = lpFirstDate.get(provider);
|
|
153
|
+
if (!prev || date < prev) {
|
|
154
|
+
lpFirstDate.set(provider, date);
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
// ── Materialize ──
|
|
159
|
+
const trader = [];
|
|
160
|
+
for (const [key, b] of traderBuckets) {
|
|
161
|
+
const [date, traderId, domain_slug] = key.split('|');
|
|
162
|
+
if (!date || !traderId || !domain_slug)
|
|
163
|
+
continue;
|
|
164
|
+
trader.push({
|
|
165
|
+
date,
|
|
166
|
+
trader: traderId,
|
|
167
|
+
domain_slug,
|
|
168
|
+
trade_count: b.trade_count,
|
|
169
|
+
buy_count: b.buy_count,
|
|
170
|
+
sell_count: b.sell_count,
|
|
171
|
+
volume_collateral: b.volume_collateral,
|
|
172
|
+
markets_traded: b.markets.size,
|
|
173
|
+
});
|
|
174
|
+
}
|
|
175
|
+
const lp = [];
|
|
176
|
+
for (const [key, b] of lpBuckets) {
|
|
177
|
+
const [date, provider, domain_slug] = key.split('|');
|
|
178
|
+
if (!date || !provider || !domain_slug)
|
|
179
|
+
continue;
|
|
180
|
+
lp.push({
|
|
181
|
+
date,
|
|
182
|
+
provider,
|
|
183
|
+
domain_slug,
|
|
184
|
+
deposit_count: b.deposit_count,
|
|
185
|
+
withdraw_count: b.withdraw_count,
|
|
186
|
+
deposited: b.deposited,
|
|
187
|
+
withdrawn: b.withdrawn,
|
|
188
|
+
markets_active: b.markets.size,
|
|
189
|
+
});
|
|
190
|
+
}
|
|
191
|
+
const market = [];
|
|
192
|
+
for (const [key, b] of marketBuckets) {
|
|
193
|
+
const [date, market_address] = key.split('|');
|
|
194
|
+
if (!date || !market_address)
|
|
195
|
+
continue;
|
|
196
|
+
market.push({
|
|
197
|
+
date,
|
|
198
|
+
market_address,
|
|
199
|
+
trade_count: b.trade_count,
|
|
200
|
+
unique_traders: b.traders.size,
|
|
201
|
+
volume_collateral: b.volume_collateral,
|
|
202
|
+
liquidity_added: b.liquidity_added,
|
|
203
|
+
liquidity_removed: b.liquidity_removed,
|
|
204
|
+
unique_lps: b.lps.size,
|
|
205
|
+
});
|
|
206
|
+
}
|
|
207
|
+
const domain = [];
|
|
208
|
+
for (const [key, b] of domainBuckets) {
|
|
209
|
+
const [date, domain_slug] = key.split('|');
|
|
210
|
+
if (!date || !domain_slug)
|
|
211
|
+
continue;
|
|
212
|
+
domain.push({
|
|
213
|
+
date,
|
|
214
|
+
domain_slug,
|
|
215
|
+
trade_count: b.trade_count,
|
|
216
|
+
unique_traders: b.traders.size,
|
|
217
|
+
unique_lps: b.lps.size,
|
|
218
|
+
volume_collateral: b.volume_collateral,
|
|
219
|
+
liquidity_net: b.liquidity_added - b.liquidity_removed,
|
|
220
|
+
active_markets: b.markets.size,
|
|
221
|
+
});
|
|
222
|
+
}
|
|
223
|
+
const platform = [];
|
|
224
|
+
for (const [date, b] of platformBuckets) {
|
|
225
|
+
let new_traders = 0;
|
|
226
|
+
for (const [, firstDate] of traderFirstDate) {
|
|
227
|
+
if (firstDate === date)
|
|
228
|
+
new_traders += 1;
|
|
229
|
+
}
|
|
230
|
+
let new_lps = 0;
|
|
231
|
+
for (const [, firstDate] of lpFirstDate) {
|
|
232
|
+
if (firstDate === date)
|
|
233
|
+
new_lps += 1;
|
|
234
|
+
}
|
|
235
|
+
platform.push({
|
|
236
|
+
date,
|
|
237
|
+
trade_count: b.trade_count,
|
|
238
|
+
unique_traders: b.traders.size,
|
|
239
|
+
unique_lps: b.lps.size,
|
|
240
|
+
new_traders,
|
|
241
|
+
new_lps,
|
|
242
|
+
volume_collateral: b.volume_collateral,
|
|
243
|
+
liquidity_net: b.liquidity_added - b.liquidity_removed,
|
|
244
|
+
active_markets: b.markets.size,
|
|
245
|
+
});
|
|
246
|
+
}
|
|
247
|
+
return { trader, lp, market, domain, platform };
|
|
248
|
+
}
|
|
249
|
+
//# sourceMappingURL=daily.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"daily.js","sourceRoot":"","sources":["../../src/aggregator/daily.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,EAEL,mBAAmB,EACnB,sBAAsB,EACtB,iBAAiB,EACjB,qBAAqB,GACtB,MAAM,WAAW,CAAC;AACnB,OAAO,EAAwB,eAAe,EAAE,MAAM,WAAW,CAAC;AA+GlE,SAAS,MAAM,CAAC,EAAU;IACxB,MAAM,CAAC,GAAG,IAAI,IAAI,CAAC,EAAE,GAAG,IAAI,CAAC,CAAC;IAC9B,MAAM,IAAI,GAAG,CAAC,CAAC,cAAc,EAAE,CAAC;IAChC,MAAM,EAAE,GAAG,MAAM,CAAC,CAAC,CAAC,WAAW,EAAE,GAAG,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;IACxD,MAAM,EAAE,GAAG,MAAM,CAAC,CAAC,CAAC,UAAU,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;IACnD,OAAO,GAAG,IAAI,IAAI,EAAE,IAAI,EAAE,EAAE,CAAC;AAC/B,CAAC;AAED,MAAM,UAAU,oBAAoB,CAClC,MAA8B,EAC9B,aAA8B;IAE9B,uBAAuB;IACvB,MAAM,aAAa,GAAG,IAAI,GAAG,EAAwB,CAAC,CAAC,0BAA0B;IACjF,MAAM,SAAS,GAAG,IAAI,GAAG,EAAoB,CAAC,CAAC,4BAA4B;IAC3E,MAAM,aAAa,GAAG,IAAI,GAAG,EAAwB,CAAC,CAAC,2BAA2B;IAClF,MAAM,aAAa,GAAG,IAAI,GAAG,EAAwB,CAAC,CAAC,mBAAmB;IAC1E,MAAM,eAAe,GAAG,IAAI,GAAG,EAA0B,CAAC,CAAC,YAAY;IAEvE,gDAAgD;IAChD,MAAM,eAAe,GAAG,IAAI,GAAG,EAAkB,CAAC;IAClD,MAAM,WAAW,GAAG,IAAI,GAAG,EAAkB,CAAC;IAE9C,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;QAC3B,MAAM,IAAI,GAAG,MAAM,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;QACrC,MAAM,MAAM,GAAG,eAAe,CAAC,aAAa,EAAE,KAAK,CAAC,cAAc,CAAC,CAAC;QACpE,MAAM,OAAO,GAAG,iBAAiB,CAAC,GAAG,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;QACxD,MAAM,QAAQ,GAAG,mBAAmB,CAAC,GAAG,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;QAC3D,MAAM,WAAW,GAAG,sBAAsB,CAAC,GAAG,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;QACjE,MAAM,UAAU,GAAG,qBAAqB,CAAC,KAAK,CAAC,iBAAiB,CAAC,CAAC;QAClE,MAAM,MAAM,GAAG,CAAC,KAAK,CAAC,gBAAgB,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC;QAEnD,wBAAwB;QACxB,IAAI,QAAQ,GAAG,eAAe,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QACzC,IAAI,CAAC,QAAQ,EAAE,CAAC;YACd,QAAQ,GAAG;gBACT,WAAW,EAAE,CAAC;gBACd,OAAO,EAAE,IAAI,GAAG,EAAE;gBAClB,GAAG,EAAE,IAAI,GAAG,EAAE;gBACd,iBAAiB,EAAE,CAAC;gBACpB,eAAe,EAAE,CAAC;gBAClB,iBAAiB,EAAE,CAAC;gBACpB,OAAO,EAAE,IAAI,GAAG,EAAE;aACnB,CAAC;YACF,eAAe,CAAC,GAAG,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;QACtC,CAAC;QACD,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC;QAE3C,6BAA6B;QAC7B,MAAM,SAAS,GAAG,GAAG,IAAI,IAAI,MAAM,EAAE,CAAC;QACtC,IAAI,YAAY,GAAG,aAAa,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;QAChD,IAAI,CAAC,YAAY,EAAE,CAAC;YAClB,YAAY,GAAG;gBACb,WAAW,EAAE,CAAC;gBACd,OAAO,EAAE,IAAI,GAAG,EAAE;gBAClB,GAAG,EAAE,IAAI,GAAG,EAAE;gBACd,iBAAiB,EAAE,CAAC;gBACpB,eAAe,EAAE,CAAC;gBAClB,iBAAiB,EAAE,CAAC;gBACpB,OAAO,EAAE,IAAI,GAAG,EAAE;aACnB,CAAC;YACF,aAAa,CAAC,GAAG,CAAC,SAAS,EAAE,YAAY,CAAC,CAAC;QAC7C,CAAC;QACD,YAAY,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC;QAE/C,6BAA6B;QAC7B,MAAM,SAAS,GAAG,GAAG,IAAI,IAAI,KAAK,CAAC,cAAc,EAAE,CAAC;QACpD,IAAI,YAAY,GAAG,aAAa,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;QAChD,IAAI,CAAC,YAAY,EAAE,CAAC;YAClB,YAAY,GAAG;gBACb,WAAW,EAAE,CAAC;gBACd,OAAO,EAAE,IAAI,GAAG,EAAE;gBAClB,GAAG,EAAE,IAAI,GAAG,EAAE;gBACd,iBAAiB,EAAE,CAAC;gBACpB,eAAe,EAAE,CAAC;gBAClB,iBAAiB,EAAE,CAAC;aACrB,CAAC;YACF,aAAa,CAAC,GAAG,CAAC,SAAS,EAAE,YAAY,CAAC,CAAC;QAC7C,CAAC;QAED,IAAI,OAAO,IAAI,KAAK,CAAC,MAAM,EAAE,CAAC;YAC5B,MAAM,MAAM,GAAG,KAAK,CAAC,MAAM,CAAC;YAC5B,QAAQ,CAAC,WAAW,IAAI,CAAC,CAAC;YAC1B,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;YAC7B,QAAQ,CAAC,iBAAiB,IAAI,UAAU,CAAC;YAEzC,YAAY,CAAC,WAAW,IAAI,CAAC,CAAC;YAC9B,YAAY,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;YACjC,YAAY,CAAC,iBAAiB,IAAI,UAAU,CAAC;YAE7C,YAAY,CAAC,WAAW,IAAI,CAAC,CAAC;YAC9B,YAAY,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;YACjC,YAAY,CAAC,iBAAiB,IAAI,UAAU,CAAC;YAE7C,MAAM,SAAS,GAAG,GAAG,IAAI,IAAI,MAAM,IAAI,MAAM,EAAE,CAAC;YAChD,IAAI,YAAY,GAAG,aAAa,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;YAChD,IAAI,CAAC,YAAY,EAAE,CAAC;gBAClB,YAAY,GAAG;oBACb,WAAW,EAAE,CAAC;oBACd,SAAS,EAAE,CAAC;oBACZ,UAAU,EAAE,CAAC;oBACb,iBAAiB,EAAE,CAAC;oBACpB,OAAO,EAAE,IAAI,GAAG,EAAE;iBACnB,CAAC;gBACF,aAAa,CAAC,GAAG,CAAC,SAAS,EAAE,YAAY,CAAC,CAAC;YAC7C,CAAC;YACD,YAAY,CAAC,WAAW,IAAI,CAAC,CAAC;YAC9B,IAAI,MAAM,EAAE,CAAC;gBACX,YAAY,CAAC,UAAU,IAAI,CAAC,CAAC;YAC/B,CAAC;iBAAM,CAAC;gBACN,YAAY,CAAC,SAAS,IAAI,CAAC,CAAC;YAC9B,CAAC;YACD,YAAY,CAAC,iBAAiB,IAAI,UAAU,CAAC;YAC7C,YAAY,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC;YAE/C,yBAAyB;YACzB,MAAM,IAAI,GAAG,eAAe,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;YACzC,IAAI,CAAC,IAAI,IAAI,IAAI,GAAG,IAAI,EAAE,CAAC;gBACzB,eAAe,CAAC,GAAG,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;YACpC,CAAC;QACH,CAAC;QAED,IAAI,CAAC,QAAQ,IAAI,WAAW,CAAC,IAAI,KAAK,CAAC,MAAM,EAAE,CAAC;YAC9C,MAAM,QAAQ,GAAG,KAAK,CAAC,MAAM,CAAC;YAC9B,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;YAC3B,YAAY,CAAC,GAAG,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;YAC/B,YAAY,CAAC,GAAG,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;YAE/B,MAAM,KAAK,GAAG,GAAG,IAAI,IAAI,QAAQ,IAAI,MAAM,EAAE,CAAC;YAC9C,IAAI,QAAQ,GAAG,SAAS,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;YACpC,IAAI,CAAC,QAAQ,EAAE,CAAC;gBACd,QAAQ,GAAG;oBACT,aAAa,EAAE,CAAC;oBAChB,cAAc,EAAE,CAAC;oBACjB,SAAS,EAAE,CAAC;oBACZ,SAAS,EAAE,CAAC;oBACZ,OAAO,EAAE,IAAI,GAAG,EAAE;iBACnB,CAAC;gBACF,SAAS,CAAC,GAAG,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;YACjC,CAAC;YACD,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC;YAE3C,IAAI,QAAQ,EAAE,CAAC;gBACb,QAAQ,CAAC,aAAa,IAAI,CAAC,CAAC;gBAC5B,QAAQ,CAAC,SAAS,IAAI,UAAU,CAAC;gBACjC,YAAY,CAAC,eAAe,IAAI,UAAU,CAAC;gBAC3C,YAAY,CAAC,eAAe,IAAI,UAAU,CAAC;gBAC3C,QAAQ,CAAC,eAAe,IAAI,UAAU,CAAC;YACzC,CAAC;iBAAM,CAAC;gBACN,QAAQ,CAAC,cAAc,IAAI,CAAC,CAAC;gBAC7B,QAAQ,CAAC,SAAS,IAAI,UAAU,CAAC;gBACjC,YAAY,CAAC,iBAAiB,IAAI,UAAU,CAAC;gBAC7C,YAAY,CAAC,iBAAiB,IAAI,UAAU,CAAC;gBAC7C,QAAQ,CAAC,iBAAiB,IAAI,UAAU,CAAC;YAC3C,CAAC;YAED,MAAM,IAAI,GAAG,WAAW,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;YACvC,IAAI,CAAC,IAAI,IAAI,IAAI,GAAG,IAAI,EAAE,CAAC;gBACzB,WAAW,CAAC,GAAG,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;YAClC,CAAC;QACH,CAAC;IACH,CAAC;IAED,oBAAoB;IACpB,MAAM,MAAM,GAAyB,EAAE,CAAC;IACxC,KAAK,MAAM,CAAC,GAAG,EAAE,CAAC,CAAC,IAAI,aAAa,EAAE,CAAC;QACrC,MAAM,CAAC,IAAI,EAAE,QAAQ,EAAE,WAAW,CAAC,GAAG,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QACrD,IAAI,CAAC,IAAI,IAAI,CAAC,QAAQ,IAAI,CAAC,WAAW;YAAE,SAAS;QACjD,MAAM,CAAC,IAAI,CAAC;YACV,IAAI;YACJ,MAAM,EAAE,QAAQ;YAChB,WAAW;YACX,WAAW,EAAE,CAAC,CAAC,WAAW;YAC1B,SAAS,EAAE,CAAC,CAAC,SAAS;YACtB,UAAU,EAAE,CAAC,CAAC,UAAU;YACxB,iBAAiB,EAAE,CAAC,CAAC,iBAAiB;YACtC,cAAc,EAAE,CAAC,CAAC,OAAO,CAAC,IAAI;SAC/B,CAAC,CAAC;IACL,CAAC;IAED,MAAM,EAAE,GAAqB,EAAE,CAAC;IAChC,KAAK,MAAM,CAAC,GAAG,EAAE,CAAC,CAAC,IAAI,SAAS,EAAE,CAAC;QACjC,MAAM,CAAC,IAAI,EAAE,QAAQ,EAAE,WAAW,CAAC,GAAG,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QACrD,IAAI,CAAC,IAAI,IAAI,CAAC,QAAQ,IAAI,CAAC,WAAW;YAAE,SAAS;QACjD,EAAE,CAAC,IAAI,CAAC;YACN,IAAI;YACJ,QAAQ;YACR,WAAW;YACX,aAAa,EAAE,CAAC,CAAC,aAAa;YAC9B,cAAc,EAAE,CAAC,CAAC,cAAc;YAChC,SAAS,EAAE,CAAC,CAAC,SAAS;YACtB,SAAS,EAAE,CAAC,CAAC,SAAS;YACtB,cAAc,EAAE,CAAC,CAAC,OAAO,CAAC,IAAI;SAC/B,CAAC,CAAC;IACL,CAAC;IAED,MAAM,MAAM,GAAyB,EAAE,CAAC;IACxC,KAAK,MAAM,CAAC,GAAG,EAAE,CAAC,CAAC,IAAI,aAAa,EAAE,CAAC;QACrC,MAAM,CAAC,IAAI,EAAE,cAAc,CAAC,GAAG,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QAC9C,IAAI,CAAC,IAAI,IAAI,CAAC,cAAc;YAAE,SAAS;QACvC,MAAM,CAAC,IAAI,CAAC;YACV,IAAI;YACJ,cAAc;YACd,WAAW,EAAE,CAAC,CAAC,WAAW;YAC1B,cAAc,EAAE,CAAC,CAAC,OAAO,CAAC,IAAI;YAC9B,iBAAiB,EAAE,CAAC,CAAC,iBAAiB;YACtC,eAAe,EAAE,CAAC,CAAC,eAAe;YAClC,iBAAiB,EAAE,CAAC,CAAC,iBAAiB;YACtC,UAAU,EAAE,CAAC,CAAC,GAAG,CAAC,IAAI;SACvB,CAAC,CAAC;IACL,CAAC;IAED,MAAM,MAAM,GAAyB,EAAE,CAAC;IACxC,KAAK,MAAM,CAAC,GAAG,EAAE,CAAC,CAAC,IAAI,aAAa,EAAE,CAAC;QACrC,MAAM,CAAC,IAAI,EAAE,WAAW,CAAC,GAAG,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QAC3C,IAAI,CAAC,IAAI,IAAI,CAAC,WAAW;YAAE,SAAS;QACpC,MAAM,CAAC,IAAI,CAAC;YACV,IAAI;YACJ,WAAW;YACX,WAAW,EAAE,CAAC,CAAC,WAAW;YAC1B,cAAc,EAAE,CAAC,CAAC,OAAO,CAAC,IAAI;YAC9B,UAAU,EAAE,CAAC,CAAC,GAAG,CAAC,IAAI;YACtB,iBAAiB,EAAE,CAAC,CAAC,iBAAiB;YACtC,aAAa,EAAE,CAAC,CAAC,eAAe,GAAG,CAAC,CAAC,iBAAiB;YACtD,cAAc,EAAE,CAAC,CAAC,OAAO,CAAC,IAAI;SAC/B,CAAC,CAAC;IACL,CAAC;IAED,MAAM,QAAQ,GAA2B,EAAE,CAAC;IAC5C,KAAK,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,eAAe,EAAE,CAAC;QACxC,IAAI,WAAW,GAAG,CAAC,CAAC;QACpB,KAAK,MAAM,CAAC,EAAE,SAAS,CAAC,IAAI,eAAe,EAAE,CAAC;YAC5C,IAAI,SAAS,KAAK,IAAI;gBAAE,WAAW,IAAI,CAAC,CAAC;QAC3C,CAAC;QACD,IAAI,OAAO,GAAG,CAAC,CAAC;QAChB,KAAK,MAAM,CAAC,EAAE,SAAS,CAAC,IAAI,WAAW,EAAE,CAAC;YACxC,IAAI,SAAS,KAAK,IAAI;gBAAE,OAAO,IAAI,CAAC,CAAC;QACvC,CAAC;QACD,QAAQ,CAAC,IAAI,CAAC;YACZ,IAAI;YACJ,WAAW,EAAE,CAAC,CAAC,WAAW;YAC1B,cAAc,EAAE,CAAC,CAAC,OAAO,CAAC,IAAI;YAC9B,UAAU,EAAE,CAAC,CAAC,GAAG,CAAC,IAAI;YACtB,WAAW;YACX,OAAO;YACP,iBAAiB,EAAE,CAAC,CAAC,iBAAiB;YACtC,aAAa,EAAE,CAAC,CAAC,eAAe,GAAG,CAAC,CAAC,iBAAiB;YACtD,cAAc,EAAE,CAAC,CAAC,OAAO,CAAC,IAAI;SAC/B,CAAC,CAAC;IACL,CAAC;IAED,OAAO,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC;AAClD,CAAC"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Market → primary domain map, fetched once per aggregator cycle.
|
|
3
|
+
*
|
|
4
|
+
* Returned as a plain Map<marketAddress, primaryDomainSlug>. Markets without
|
|
5
|
+
* any domain assignment fall back to 'other' so every event has a domain to
|
|
6
|
+
* attribute to.
|
|
7
|
+
*/
|
|
8
|
+
import type { SQL } from 'bun';
|
|
9
|
+
export type MarketDomainMap = ReadonlyMap<string, string>;
|
|
10
|
+
/** All primary-domain rows. */
|
|
11
|
+
export declare function loadMarketPrimaryDomains(pg: SQL): Promise<MarketDomainMap>;
|
|
12
|
+
/** Lookup with `'other'` fallback. */
|
|
13
|
+
export declare function primaryDomainOf(map: MarketDomainMap, marketAddress: string): string;
|
|
14
|
+
/**
|
|
15
|
+
* Returns all (market, slug) pairs — useful for "user touched N domains"
|
|
16
|
+
* style metrics. A market may be tagged with multiple domains; this returns
|
|
17
|
+
* every assignment.
|
|
18
|
+
*/
|
|
19
|
+
export declare function loadAllMarketDomains(pg: SQL): Promise<ReadonlyMap<string, ReadonlySet<string>>>;
|
|
20
|
+
//# sourceMappingURL=domains.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"domains.d.ts","sourceRoot":"","sources":["../../src/aggregator/domains.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,KAAK,CAAC;AAE/B,MAAM,MAAM,eAAe,GAAG,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;AAE1D,+BAA+B;AAC/B,wBAAsB,wBAAwB,CAAC,EAAE,EAAE,GAAG,GAAG,OAAO,CAAC,eAAe,CAAC,CAYhF;AAED,sCAAsC;AACtC,wBAAgB,eAAe,CAAC,GAAG,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,GAAG,MAAM,CAEnF;AAED;;;;GAIG;AACH,wBAAsB,oBAAoB,CACxC,EAAE,EAAE,GAAG,GACN,OAAO,CAAC,WAAW,CAAC,MAAM,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC,CAenD"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/** All primary-domain rows. */
|
|
2
|
+
export async function loadMarketPrimaryDomains(pg) {
|
|
3
|
+
const rows = (await pg `
|
|
4
|
+
SELECT market_address, domain_slug
|
|
5
|
+
FROM market_domains
|
|
6
|
+
WHERE is_primary
|
|
7
|
+
`);
|
|
8
|
+
const map = new Map();
|
|
9
|
+
for (const row of rows) {
|
|
10
|
+
map.set(row.market_address, row.domain_slug);
|
|
11
|
+
}
|
|
12
|
+
return map;
|
|
13
|
+
}
|
|
14
|
+
/** Lookup with `'other'` fallback. */
|
|
15
|
+
export function primaryDomainOf(map, marketAddress) {
|
|
16
|
+
return map.get(marketAddress) ?? 'other';
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Returns all (market, slug) pairs — useful for "user touched N domains"
|
|
20
|
+
* style metrics. A market may be tagged with multiple domains; this returns
|
|
21
|
+
* every assignment.
|
|
22
|
+
*/
|
|
23
|
+
export async function loadAllMarketDomains(pg) {
|
|
24
|
+
const rows = (await pg `
|
|
25
|
+
SELECT market_address, domain_slug FROM market_domains
|
|
26
|
+
`);
|
|
27
|
+
const map = new Map();
|
|
28
|
+
for (const row of rows) {
|
|
29
|
+
let set = map.get(row.market_address);
|
|
30
|
+
if (!set) {
|
|
31
|
+
set = new Set();
|
|
32
|
+
map.set(row.market_address, set);
|
|
33
|
+
}
|
|
34
|
+
set.add(row.domain_slug);
|
|
35
|
+
}
|
|
36
|
+
return map;
|
|
37
|
+
}
|
|
38
|
+
//# sourceMappingURL=domains.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"domains.js","sourceRoot":"","sources":["../../src/aggregator/domains.ts"],"names":[],"mappings":"AAWA,+BAA+B;AAC/B,MAAM,CAAC,KAAK,UAAU,wBAAwB,CAAC,EAAO;IACpD,MAAM,IAAI,GAAG,CAAC,MAAM,EAAE,CAAA;;;;GAIrB,CAA2D,CAAC;IAE7D,MAAM,GAAG,GAAG,IAAI,GAAG,EAAkB,CAAC;IACtC,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;QACvB,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,cAAc,EAAE,GAAG,CAAC,WAAW,CAAC,CAAC;IAC/C,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED,sCAAsC;AACtC,MAAM,UAAU,eAAe,CAAC,GAAoB,EAAE,aAAqB;IACzE,OAAO,GAAG,CAAC,GAAG,CAAC,aAAa,CAAC,IAAI,OAAO,CAAC;AAC3C,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,oBAAoB,CACxC,EAAO;IAEP,MAAM,IAAI,GAAG,CAAC,MAAM,EAAE,CAAA;;GAErB,CAA2D,CAAC;IAE7D,MAAM,GAAG,GAAG,IAAI,GAAG,EAAuB,CAAC;IAC3C,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;QACvB,IAAI,GAAG,GAAG,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;QACtC,IAAI,CAAC,GAAG,EAAE,CAAC;YACT,GAAG,GAAG,IAAI,GAAG,EAAU,CAAC;YACxB,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,cAAc,EAAE,GAAG,CAAC,CAAC;QACnC,CAAC;QACD,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;IAC3B,CAAC;IACD,OAAO,GAA+C,CAAC;AACzD,CAAC"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Aggregator orchestrator.
|
|
3
|
+
*
|
|
4
|
+
* Reads OLTP rows from SQLite, computes derived analytics in memory, and bulk-
|
|
5
|
+
* writes them into the Postgres warehouse. Intended to run on a non-overlapping
|
|
6
|
+
* loop (default 5 min) alongside the existing event/state/position refreshers.
|
|
7
|
+
*
|
|
8
|
+
* Strategy: full recompute per cycle. Cheap at current scale (~100k events).
|
|
9
|
+
* Switch to incremental once event volume justifies it.
|
|
10
|
+
*/
|
|
11
|
+
import type { SQL } from 'bun';
|
|
12
|
+
import type { Database as SqliteDatabase } from 'bun:sqlite';
|
|
13
|
+
export interface AggregatorRunSummary {
|
|
14
|
+
readonly events: number;
|
|
15
|
+
readonly traders: number;
|
|
16
|
+
readonly lps: number;
|
|
17
|
+
readonly dailyRows: number;
|
|
18
|
+
readonly cohortRows: number;
|
|
19
|
+
readonly roiRows: number;
|
|
20
|
+
readonly durationMs: number;
|
|
21
|
+
}
|
|
22
|
+
export declare function runAggregatorOnce(sqlite: SqliteDatabase, pg: SQL): Promise<AggregatorRunSummary>;
|
|
23
|
+
export interface AggregatorHandles {
|
|
24
|
+
readonly stop: () => void;
|
|
25
|
+
readonly runNow: () => Promise<AggregatorRunSummary>;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Start a non-overlapping aggregator loop. Returns handles for shutdown.
|
|
29
|
+
*/
|
|
30
|
+
export declare function startAggregator(sqlite: SqliteDatabase, pg: SQL, intervalMs: number): AggregatorHandles;
|
|
31
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/aggregator/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,KAAK,CAAC;AAC/B,OAAO,KAAK,EAAE,QAAQ,IAAI,cAAc,EAAE,MAAM,YAAY,CAAC;AA+B7D,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;CAC7B;AAED,wBAAsB,iBAAiB,CACrC,MAAM,EAAE,cAAc,EACtB,EAAE,EAAE,GAAG,GACN,OAAO,CAAC,oBAAoB,CAAC,CA6C/B;AAED,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,IAAI,EAAE,MAAM,IAAI,CAAC;IAC1B,QAAQ,CAAC,MAAM,EAAE,MAAM,OAAO,CAAC,oBAAoB,CAAC,CAAC;CACtD;AAED;;GAEG;AACH,wBAAgB,eAAe,CAC7B,MAAM,EAAE,cAAc,EACtB,EAAE,EAAE,GAAG,EACP,UAAU,EAAE,MAAM,GACjB,iBAAiB,CA+CnB"}
|