@the-situation/indexer 0.17.0 → 0.18.0

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.
Files changed (133) hide show
  1. package/README.md +43 -4
  2. package/dist/aggregator/cohort.d.ts +30 -0
  3. package/dist/aggregator/cohort.d.ts.map +1 -0
  4. package/dist/aggregator/cohort.js +153 -0
  5. package/dist/aggregator/cohort.js.map +1 -0
  6. package/dist/aggregator/daily.d.ts +71 -0
  7. package/dist/aggregator/daily.d.ts.map +1 -0
  8. package/dist/aggregator/daily.js +249 -0
  9. package/dist/aggregator/daily.js.map +1 -0
  10. package/dist/aggregator/domains.d.ts +20 -0
  11. package/dist/aggregator/domains.d.ts.map +1 -0
  12. package/dist/aggregator/domains.js +38 -0
  13. package/dist/aggregator/domains.js.map +1 -0
  14. package/dist/aggregator/index.d.ts +31 -0
  15. package/dist/aggregator/index.d.ts.map +1 -0
  16. package/dist/aggregator/index.js +100 -0
  17. package/dist/aggregator/index.js.map +1 -0
  18. package/dist/aggregator/lifetime.d.ts +52 -0
  19. package/dist/aggregator/lifetime.d.ts.map +1 -0
  20. package/dist/aggregator/lifetime.js +222 -0
  21. package/dist/aggregator/lifetime.js.map +1 -0
  22. package/dist/aggregator/roi.d.ts +42 -0
  23. package/dist/aggregator/roi.d.ts.map +1 -0
  24. package/dist/aggregator/roi.js +153 -0
  25. package/dist/aggregator/roi.js.map +1 -0
  26. package/dist/aggregator/sources.d.ts +59 -0
  27. package/dist/aggregator/sources.d.ts.map +1 -0
  28. package/dist/aggregator/sources.js +53 -0
  29. package/dist/aggregator/sources.js.map +1 -0
  30. package/dist/aggregator/writers.d.ts +22 -0
  31. package/dist/aggregator/writers.d.ts.map +1 -0
  32. package/dist/aggregator/writers.js +147 -0
  33. package/dist/aggregator/writers.js.map +1 -0
  34. package/dist/api/app.d.ts +177 -13
  35. package/dist/api/app.d.ts.map +1 -1
  36. package/dist/api/app.js +4 -3
  37. package/dist/api/app.js.map +1 -1
  38. package/dist/api/routes/admin-subscriptions.d.ts +11 -11
  39. package/dist/api/routes/analytics.d.ts +205 -0
  40. package/dist/api/routes/analytics.d.ts.map +1 -0
  41. package/dist/api/routes/analytics.js +122 -0
  42. package/dist/api/routes/analytics.js.map +1 -0
  43. package/dist/api/routes/health.d.ts.map +1 -1
  44. package/dist/api/routes/health.js +2 -0
  45. package/dist/api/routes/health.js.map +1 -1
  46. package/dist/api/routes/index.d.ts +1 -0
  47. package/dist/api/routes/index.d.ts.map +1 -1
  48. package/dist/api/routes/index.js +1 -0
  49. package/dist/api/routes/index.js.map +1 -1
  50. package/dist/api/routes/rankings.d.ts +17 -3
  51. package/dist/api/routes/rankings.d.ts.map +1 -1
  52. package/dist/api/routes/rankings.js +44 -5
  53. package/dist/api/routes/rankings.js.map +1 -1
  54. package/dist/api/routes/trader-stats.d.ts +11 -2
  55. package/dist/api/routes/trader-stats.d.ts.map +1 -1
  56. package/dist/api/routes/trader-stats.js +72 -2
  57. package/dist/api/routes/trader-stats.js.map +1 -1
  58. package/dist/client/IndexerClient.d.ts +30 -1
  59. package/dist/client/IndexerClient.d.ts.map +1 -1
  60. package/dist/client/IndexerClient.js.map +1 -1
  61. package/dist/client/IndexerClientLive.d.ts.map +1 -1
  62. package/dist/client/IndexerClientLive.js +50 -1
  63. package/dist/client/IndexerClientLive.js.map +1 -1
  64. package/dist/client/convenience.d.ts +9 -2
  65. package/dist/client/convenience.d.ts.map +1 -1
  66. package/dist/client/convenience.js +9 -1
  67. package/dist/client/convenience.js.map +1 -1
  68. package/dist/client/index.d.ts +3 -2
  69. package/dist/client/index.d.ts.map +1 -1
  70. package/dist/client/index.js +1 -1
  71. package/dist/client/index.js.map +1 -1
  72. package/dist/config.d.ts +17 -1
  73. package/dist/config.d.ts.map +1 -1
  74. package/dist/config.js +39 -3
  75. package/dist/config.js.map +1 -1
  76. package/dist/etl/event-indexer.d.ts +1 -1
  77. package/dist/etl/lp-position-refresher.d.ts +2 -1
  78. package/dist/etl/lp-position-refresher.d.ts.map +1 -1
  79. package/dist/etl/lp-position-refresher.js +24 -11
  80. package/dist/etl/lp-position-refresher.js.map +1 -1
  81. package/dist/index.js +64 -8
  82. package/dist/index.js.map +1 -1
  83. package/dist/layers/ChainReaderLive.d.ts.map +1 -1
  84. package/dist/layers/ChainReaderLive.js +15 -0
  85. package/dist/layers/ChainReaderLive.js.map +1 -1
  86. package/dist/layers/VoyagerClientLive.d.ts +2 -1
  87. package/dist/layers/VoyagerClientLive.d.ts.map +1 -1
  88. package/dist/layers/VoyagerClientLive.js +89 -55
  89. package/dist/layers/VoyagerClientLive.js.map +1 -1
  90. package/dist/services/ChainReader.d.ts +10 -0
  91. package/dist/services/ChainReader.d.ts.map +1 -1
  92. package/dist/services/ChainReader.js.map +1 -1
  93. package/dist/services/VoyagerRateLimit.d.ts +11 -8
  94. package/dist/services/VoyagerRateLimit.d.ts.map +1 -1
  95. package/dist/services/VoyagerRateLimit.js +51 -26
  96. package/dist/services/VoyagerRateLimit.js.map +1 -1
  97. package/dist/types/analytics.d.ts +194 -0
  98. package/dist/types/analytics.d.ts.map +1 -0
  99. package/dist/types/analytics.js +10 -0
  100. package/dist/types/analytics.js.map +1 -0
  101. package/dist/types/api.d.ts +2 -0
  102. package/dist/types/api.d.ts.map +1 -1
  103. package/dist/types/index.d.ts +1 -0
  104. package/dist/types/index.d.ts.map +1 -1
  105. package/dist/warehouse/analytics-helpers.d.ts +36 -0
  106. package/dist/warehouse/analytics-helpers.d.ts.map +1 -0
  107. package/dist/warehouse/analytics-helpers.js +142 -0
  108. package/dist/warehouse/analytics-helpers.js.map +1 -0
  109. package/dist/warehouse/backfill.d.ts +26 -0
  110. package/dist/warehouse/backfill.d.ts.map +1 -0
  111. package/dist/warehouse/backfill.js +77 -0
  112. package/dist/warehouse/backfill.js.map +1 -0
  113. package/dist/warehouse/connection.d.ts +18 -0
  114. package/dist/warehouse/connection.d.ts.map +1 -0
  115. package/dist/warehouse/connection.js +24 -0
  116. package/dist/warehouse/connection.js.map +1 -0
  117. package/dist/warehouse/index.d.ts +14 -0
  118. package/dist/warehouse/index.d.ts.map +1 -0
  119. package/dist/warehouse/index.js +14 -0
  120. package/dist/warehouse/index.js.map +1 -0
  121. package/dist/warehouse/repositories/analytics.d.ts +61 -0
  122. package/dist/warehouse/repositories/analytics.d.ts.map +1 -0
  123. package/dist/warehouse/repositories/analytics.js +418 -0
  124. package/dist/warehouse/repositories/analytics.js.map +1 -0
  125. package/dist/warehouse/schema.d.ts +9 -0
  126. package/dist/warehouse/schema.d.ts.map +1 -0
  127. package/dist/warehouse/schema.js +219 -0
  128. package/dist/warehouse/schema.js.map +1 -0
  129. package/dist/warehouse/seed-domains.d.ts +29 -0
  130. package/dist/warehouse/seed-domains.d.ts.map +1 -0
  131. package/dist/warehouse/seed-domains.js +223 -0
  132. package/dist/warehouse/seed-domains.js.map +1 -0
  133. package/package.json +1 -1
@@ -0,0 +1,153 @@
1
+ /**
2
+ * Histogram bucket boundaries in percent. The last bucket is [200, +Inf).
3
+ * The first is (-Inf, -100]. Centered on 0 with finer granularity near it.
4
+ */
5
+ const BUCKET_BOUNDARIES = [
6
+ -Infinity,
7
+ -100,
8
+ -75,
9
+ -50,
10
+ -25,
11
+ -10,
12
+ 0,
13
+ 10,
14
+ 25,
15
+ 50,
16
+ 75,
17
+ 100,
18
+ 200,
19
+ Infinity,
20
+ ];
21
+ function bucketIndexFor(roiPct) {
22
+ for (let i = 0; i < BUCKET_BOUNDARIES.length - 1; i++) {
23
+ const lo = BUCKET_BOUNDARIES[i] ?? -Infinity;
24
+ const hi = BUCKET_BOUNDARIES[i + 1] ?? Infinity;
25
+ if (roiPct >= lo && roiPct < hi)
26
+ return i;
27
+ }
28
+ return BUCKET_BOUNDARIES.length - 2;
29
+ }
30
+ function percentile(sorted, p) {
31
+ if (sorted.length === 0)
32
+ return null;
33
+ const idx = (sorted.length - 1) * p;
34
+ const lo = Math.floor(idx);
35
+ const hi = Math.ceil(idx);
36
+ if (lo === hi)
37
+ return sorted[lo] ?? null;
38
+ const a = sorted[lo];
39
+ const b = sorted[hi];
40
+ if (a == null || b == null)
41
+ return null;
42
+ return a + (b - a) * (idx - lo);
43
+ }
44
+ export function buildRoi(traderLifetime, lpLifetime) {
45
+ // For traders: domain attribution is via domains_json (every domain touched).
46
+ // For LPs: same idea, via lp domains_json.
47
+ const traderRoiByDomain = new Map();
48
+ traderRoiByDomain.set('all', []);
49
+ for (const t of traderLifetime) {
50
+ if (t.roi_pct == null)
51
+ continue;
52
+ traderRoiByDomain.get('all').push(t.roi_pct);
53
+ for (const d of t.domains_json) {
54
+ let arr = traderRoiByDomain.get(d);
55
+ if (!arr) {
56
+ arr = [];
57
+ traderRoiByDomain.set(d, arr);
58
+ }
59
+ arr.push(t.roi_pct);
60
+ }
61
+ }
62
+ const lpRoiByDomain = new Map();
63
+ lpRoiByDomain.set('all', []);
64
+ for (const l of lpLifetime) {
65
+ if (l.roi_pct == null)
66
+ continue;
67
+ lpRoiByDomain.get('all').push(l.roi_pct);
68
+ for (const d of l.domains_json) {
69
+ let arr = lpRoiByDomain.get(d);
70
+ if (!arr) {
71
+ arr = [];
72
+ lpRoiByDomain.set(d, arr);
73
+ }
74
+ arr.push(l.roi_pct);
75
+ }
76
+ }
77
+ const distribution = [];
78
+ const summary = [];
79
+ function emitForBucket(domain, entityType, values) {
80
+ const sorted = [...values].sort((a, b) => a - b);
81
+ const total = sorted.length;
82
+ const positive = sorted.filter((v) => v > 0).length;
83
+ const positivePct = total > 0 ? (positive / total) * 100 : 0;
84
+ const mean = total > 0 ? sorted.reduce((s, v) => s + v, 0) / total : null;
85
+ summary.push({
86
+ domain_slug: domain,
87
+ entity_type: entityType,
88
+ total_users: total,
89
+ positive_roi_users: positive,
90
+ positive_roi_pct: positivePct,
91
+ median_roi_pct: percentile(sorted, 0.5),
92
+ p25_roi_pct: percentile(sorted, 0.25),
93
+ p75_roi_pct: percentile(sorted, 0.75),
94
+ p90_roi_pct: percentile(sorted, 0.9),
95
+ mean_roi_pct: mean,
96
+ });
97
+ // Histogram
98
+ const counts = new Array(BUCKET_BOUNDARIES.length - 1).fill(0);
99
+ for (const v of sorted) {
100
+ counts[bucketIndexFor(v)] += 1;
101
+ }
102
+ for (let i = 0; i < counts.length; i++) {
103
+ distribution.push({
104
+ domain_slug: domain,
105
+ entity_type: entityType,
106
+ bucket_index: i,
107
+ bucket_lower_pct: BUCKET_BOUNDARIES[i] ?? -Infinity,
108
+ bucket_upper_pct: BUCKET_BOUNDARIES[i + 1] ?? Infinity,
109
+ user_count: counts[i],
110
+ });
111
+ }
112
+ }
113
+ for (const [domain, values] of traderRoiByDomain) {
114
+ emitForBucket(domain, 'trader', values);
115
+ }
116
+ for (const [domain, values] of lpRoiByDomain) {
117
+ emitForBucket(domain, 'lp', values);
118
+ }
119
+ return { distribution, summary };
120
+ }
121
+ export async function writeRoi(pg, out) {
122
+ await pg.begin(async (tx) => {
123
+ await tx `TRUNCATE TABLE roi_distribution`;
124
+ for (const r of out.distribution) {
125
+ const lower = Number.isFinite(r.bucket_lower_pct) ? r.bucket_lower_pct : -1e9;
126
+ const upper = Number.isFinite(r.bucket_upper_pct) ? r.bucket_upper_pct : 1e9;
127
+ await tx `
128
+ INSERT INTO roi_distribution
129
+ (domain_slug, entity_type, bucket_index, bucket_lower_pct,
130
+ bucket_upper_pct, user_count, computed_at)
131
+ VALUES
132
+ (${r.domain_slug}, ${r.entity_type}, ${r.bucket_index}, ${lower},
133
+ ${upper}, ${r.user_count}, now())
134
+ `;
135
+ }
136
+ });
137
+ await pg.begin(async (tx) => {
138
+ await tx `TRUNCATE TABLE roi_summary`;
139
+ for (const r of out.summary) {
140
+ await tx `
141
+ INSERT INTO roi_summary
142
+ (domain_slug, entity_type, total_users, positive_roi_users,
143
+ positive_roi_pct, median_roi_pct, p25_roi_pct, p75_roi_pct,
144
+ p90_roi_pct, mean_roi_pct, computed_at)
145
+ VALUES
146
+ (${r.domain_slug}, ${r.entity_type}, ${r.total_users}, ${r.positive_roi_users},
147
+ ${r.positive_roi_pct}, ${r.median_roi_pct}, ${r.p25_roi_pct}, ${r.p75_roi_pct},
148
+ ${r.p90_roi_pct}, ${r.mean_roi_pct}, now())
149
+ `;
150
+ }
151
+ });
152
+ }
153
+ //# sourceMappingURL=roi.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"roi.js","sourceRoot":"","sources":["../../src/aggregator/roi.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,59 @@
1
+ /**
2
+ * Aggregator data sources — synchronous reads from SQLite.
3
+ *
4
+ * These functions extract the minimum columns needed for analytics rollups.
5
+ * Keeping the projection narrow keeps memory usage bounded even at 10M+ events.
6
+ */
7
+ import type { Database as SqliteDatabase } from 'bun:sqlite';
8
+ /** Magnitude divisor for `collateral_posted` raw values (token has 18 decimals). */
9
+ export declare const TOKEN_DECIMALS = 1000000000000000000;
10
+ export interface AggEventRow {
11
+ readonly id: number;
12
+ readonly market_address: string;
13
+ readonly event_type: string;
14
+ readonly trader: string | null;
15
+ readonly timestamp: number;
16
+ readonly collateral_posted: string | null;
17
+ readonly is_position_sell: number | null;
18
+ }
19
+ export interface AggPositionRow {
20
+ readonly market_address: string;
21
+ readonly trader: string;
22
+ readonly has_position: number;
23
+ readonly settlement_state: string;
24
+ readonly unrealized_pnl: number | null;
25
+ readonly realized_pnl: number | null;
26
+ readonly expected_value: number | null;
27
+ readonly delta_count: number;
28
+ readonly claimed: number;
29
+ }
30
+ export interface AggLPPositionRow {
31
+ readonly market_address: string;
32
+ readonly provider: string;
33
+ readonly total_deposited: number;
34
+ readonly total_withdrawn: number;
35
+ readonly current_value: number | null;
36
+ readonly unrealized_pnl: number | null;
37
+ readonly deposit_count: number;
38
+ readonly withdrawal_count: number;
39
+ readonly first_deposit_at: number | null;
40
+ readonly last_activity_at: number | null;
41
+ readonly claimed_at: number | null;
42
+ readonly claim_payout: number | null;
43
+ }
44
+ export declare function readAllEvents(db: SqliteDatabase): readonly AggEventRow[];
45
+ export declare function readAllPositions(db: SqliteDatabase): readonly AggPositionRow[];
46
+ export declare function readAllLPPositions(db: SqliteDatabase): readonly AggLPPositionRow[];
47
+ /**
48
+ * Parse the raw SQ128x128-style magnitude string into a human-readable token
49
+ * amount. Mirrors `parseCollateral` in services/ActivityEnricher.ts.
50
+ */
51
+ export declare function parseCollateralAmount(raw: string | null): number;
52
+ /**
53
+ * Trade-like events count toward trader volume. Liquidity events are tracked
54
+ * separately for LPs.
55
+ */
56
+ export declare const TRADE_EVENT_TYPES: Set<string>;
57
+ export declare const LIQUIDITY_ADD_TYPES: Set<string>;
58
+ export declare const LIQUIDITY_REMOVE_TYPES: Set<string>;
59
+ //# sourceMappingURL=sources.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sources.d.ts","sourceRoot":"","sources":["../../src/aggregator/sources.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,KAAK,EAAE,QAAQ,IAAI,cAAc,EAAE,MAAM,YAAY,CAAC;AAE7D,oFAAoF;AACpF,eAAO,MAAM,cAAc,sBAAO,CAAC;AAEnC,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,iBAAiB,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1C,QAAQ,CAAC,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;CAC1C;AAED,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,gBAAgB,EAAE,MAAM,CAAC;IAClC,QAAQ,CAAC,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IACvC,QAAQ,CAAC,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IACrC,QAAQ,CAAC,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IACvC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAC;IACjC,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAC;IACjC,QAAQ,CAAC,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IACtC,QAAQ,CAAC,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IACvC,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,gBAAgB,EAAE,MAAM,CAAC;IAClC,QAAQ,CAAC,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;IACzC,QAAQ,CAAC,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;IACzC,QAAQ,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IACnC,QAAQ,CAAC,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;CACtC;AAED,wBAAgB,aAAa,CAAC,EAAE,EAAE,cAAc,GAAG,SAAS,WAAW,EAAE,CASxE;AAED,wBAAgB,gBAAgB,CAAC,EAAE,EAAE,cAAc,GAAG,SAAS,cAAc,EAAE,CAQ9E;AAED,wBAAgB,kBAAkB,CAAC,EAAE,EAAE,cAAc,GAAG,SAAS,gBAAgB,EAAE,CASlF;AAED;;;GAGG;AACH,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,GAAG,MAAM,CAKhE;AAED;;;GAGG;AACH,eAAO,MAAM,iBAAiB,aAI5B,CAAC;AAEH,eAAO,MAAM,mBAAmB,aAI9B,CAAC;AAEH,eAAO,MAAM,sBAAsB,aAAiC,CAAC"}
@@ -0,0 +1,53 @@
1
+ /** Magnitude divisor for `collateral_posted` raw values (token has 18 decimals). */
2
+ export const TOKEN_DECIMALS = 1e18;
3
+ export function readAllEvents(db) {
4
+ return db
5
+ .query(`SELECT id, market_address, event_type, trader, timestamp,
6
+ collateral_posted, is_position_sell
7
+ FROM market_events
8
+ ORDER BY id ASC`)
9
+ .all();
10
+ }
11
+ export function readAllPositions(db) {
12
+ return db
13
+ .query(`SELECT market_address, trader, has_position, settlement_state,
14
+ unrealized_pnl, realized_pnl, expected_value, delta_count, claimed
15
+ FROM user_positions`)
16
+ .all();
17
+ }
18
+ export function readAllLPPositions(db) {
19
+ return db
20
+ .query(`SELECT market_address, provider, total_deposited, total_withdrawn,
21
+ current_value, unrealized_pnl, deposit_count, withdrawal_count,
22
+ first_deposit_at, last_activity_at, claimed_at, claim_payout
23
+ FROM lp_positions`)
24
+ .all();
25
+ }
26
+ /**
27
+ * Parse the raw SQ128x128-style magnitude string into a human-readable token
28
+ * amount. Mirrors `parseCollateral` in services/ActivityEnricher.ts.
29
+ */
30
+ export function parseCollateralAmount(raw) {
31
+ if (raw == null || raw.length === 0)
32
+ return 0;
33
+ const val = Number(raw);
34
+ if (!Number.isFinite(val))
35
+ return 0;
36
+ return val / TOKEN_DECIMALS;
37
+ }
38
+ /**
39
+ * Trade-like events count toward trader volume. Liquidity events are tracked
40
+ * separately for LPs.
41
+ */
42
+ export const TRADE_EVENT_TYPES = new Set([
43
+ 'trade_executed',
44
+ 'trade_moved',
45
+ 'multinoulli_trade_executed',
46
+ ]);
47
+ export const LIQUIDITY_ADD_TYPES = new Set([
48
+ 'liquidity_added',
49
+ 'market_initialized',
50
+ 'bootstrapped',
51
+ ]);
52
+ export const LIQUIDITY_REMOVE_TYPES = new Set(['liquidity_removed']);
53
+ //# sourceMappingURL=sources.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sources.js","sourceRoot":"","sources":["../../src/aggregator/sources.ts"],"names":[],"mappings":"AAQA,oFAAoF;AACpF,MAAM,CAAC,MAAM,cAAc,GAAG,IAAI,CAAC;AAuCnC,MAAM,UAAU,aAAa,CAAC,EAAkB;IAC9C,OAAO,EAAE;SACN,KAAK,CACJ;;;uBAGiB,CAClB;SACA,GAAG,EAA4B,CAAC;AACrC,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,EAAkB;IACjD,OAAO,EAAE;SACN,KAAK,CACJ;;2BAEqB,CACtB;SACA,GAAG,EAA+B,CAAC;AACxC,CAAC;AAED,MAAM,UAAU,kBAAkB,CAAC,EAAkB;IACnD,OAAO,EAAE;SACN,KAAK,CACJ;;;yBAGmB,CACpB;SACA,GAAG,EAAiC,CAAC;AAC1C,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,qBAAqB,CAAC,GAAkB;IACtD,IAAI,GAAG,IAAI,IAAI,IAAI,GAAG,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,CAAC,CAAC;IAC9C,MAAM,GAAG,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC;IACxB,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC;QAAE,OAAO,CAAC,CAAC;IACpC,OAAO,GAAG,GAAG,cAAc,CAAC;AAC9B,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG,IAAI,GAAG,CAAC;IACvC,gBAAgB;IAChB,aAAa;IACb,4BAA4B;CAC7B,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,mBAAmB,GAAG,IAAI,GAAG,CAAC;IACzC,iBAAiB;IACjB,oBAAoB;IACpB,cAAc;CACf,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,sBAAsB,GAAG,IAAI,GAAG,CAAC,CAAC,mBAAmB,CAAC,CAAC,CAAC"}
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Bulk-write builders.
3
+ *
4
+ * Each writer truncates its target table and re-inserts. Truncate-and-reload
5
+ * is fine while the data set is small (~100k events) and avoids subtle
6
+ * incremental-update bugs. Switch to UPSERT-by-key once event volume justifies it.
7
+ *
8
+ * All writes happen inside a single transaction per table so readers never
9
+ * see a partially-written warehouse state.
10
+ */
11
+ import type { SQL } from 'bun';
12
+ import type { DailyDomainStatRow, DailyLPStatRow, DailyMarketStatRow, DailyPlatformStatRow, DailyTraderStatRow } from './daily';
13
+ import type { LPLifetimeRow, TraderLifetimeRow } from './lifetime';
14
+ export declare function writeDailyTraderStats(pg: SQL, rows: readonly DailyTraderStatRow[]): Promise<void>;
15
+ export declare function writeDailyLPStats(pg: SQL, rows: readonly DailyLPStatRow[]): Promise<void>;
16
+ export declare function writeDailyMarketStats(pg: SQL, rows: readonly DailyMarketStatRow[]): Promise<void>;
17
+ export declare function writeDailyDomainStats(pg: SQL, rows: readonly DailyDomainStatRow[]): Promise<void>;
18
+ export declare function writeDailyPlatformStats(pg: SQL, rows: readonly DailyPlatformStatRow[]): Promise<void>;
19
+ export declare function writeTraderLifetime(pg: SQL, rows: readonly TraderLifetimeRow[]): Promise<void>;
20
+ export declare function writeLPLifetime(pg: SQL, rows: readonly LPLifetimeRow[]): Promise<void>;
21
+ export declare function recordAggregatorRun(pg: SQL, jobName: string, ok: boolean, error: string | null): Promise<void>;
22
+ //# sourceMappingURL=writers.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"writers.d.ts","sourceRoot":"","sources":["../../src/aggregator/writers.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,KAAK,CAAC;AAC/B,OAAO,KAAK,EACV,kBAAkB,EAClB,cAAc,EACd,kBAAkB,EAClB,oBAAoB,EACpB,kBAAkB,EACnB,MAAM,SAAS,CAAC;AACjB,OAAO,KAAK,EAAE,aAAa,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAKnE,wBAAsB,qBAAqB,CACzC,EAAE,EAAE,GAAG,EACP,IAAI,EAAE,SAAS,kBAAkB,EAAE,GAClC,OAAO,CAAC,IAAI,CAAC,CAcf;AAED,wBAAsB,iBAAiB,CACrC,EAAE,EAAE,GAAG,EACP,IAAI,EAAE,SAAS,cAAc,EAAE,GAC9B,OAAO,CAAC,IAAI,CAAC,CAcf;AAED,wBAAsB,qBAAqB,CACzC,EAAE,EAAE,GAAG,EACP,IAAI,EAAE,SAAS,kBAAkB,EAAE,GAClC,OAAO,CAAC,IAAI,CAAC,CAef;AAED,wBAAsB,qBAAqB,CACzC,EAAE,EAAE,GAAG,EACP,IAAI,EAAE,SAAS,kBAAkB,EAAE,GAClC,OAAO,CAAC,IAAI,CAAC,CAcf;AAED,wBAAsB,uBAAuB,CAC3C,EAAE,EAAE,GAAG,EACP,IAAI,EAAE,SAAS,oBAAoB,EAAE,GACpC,OAAO,CAAC,IAAI,CAAC,CAef;AAED,wBAAsB,mBAAmB,CACvC,EAAE,EAAE,GAAG,EACP,IAAI,EAAE,SAAS,iBAAiB,EAAE,GACjC,OAAO,CAAC,IAAI,CAAC,CAsBf;AAED,wBAAsB,eAAe,CACnC,EAAE,EAAE,GAAG,EACP,IAAI,EAAE,SAAS,aAAa,EAAE,GAC7B,OAAO,CAAC,IAAI,CAAC,CAuBf;AAED,wBAAsB,mBAAmB,CACvC,EAAE,EAAE,GAAG,EACP,OAAO,EAAE,MAAM,EACf,EAAE,EAAE,OAAO,EACX,KAAK,EAAE,MAAM,GAAG,IAAI,GACnB,OAAO,CAAC,IAAI,CAAC,CAmBf"}
@@ -0,0 +1,147 @@
1
+ const TIMESTAMP_OR_NULL = (ts) => ts == null ? null : new Date(ts * 1000).toISOString();
2
+ export async function writeDailyTraderStats(pg, rows) {
3
+ await pg.begin(async (tx) => {
4
+ await tx `TRUNCATE TABLE daily_trader_stats`;
5
+ for (const r of rows) {
6
+ await tx `
7
+ INSERT INTO daily_trader_stats
8
+ (date, trader, domain_slug, trade_count, buy_count, sell_count,
9
+ volume_collateral, markets_traded, updated_at)
10
+ VALUES
11
+ (${r.date}, ${r.trader}, ${r.domain_slug}, ${r.trade_count}, ${r.buy_count},
12
+ ${r.sell_count}, ${r.volume_collateral}, ${r.markets_traded}, now())
13
+ `;
14
+ }
15
+ });
16
+ }
17
+ export async function writeDailyLPStats(pg, rows) {
18
+ await pg.begin(async (tx) => {
19
+ await tx `TRUNCATE TABLE daily_lp_stats`;
20
+ for (const r of rows) {
21
+ await tx `
22
+ INSERT INTO daily_lp_stats
23
+ (date, provider, domain_slug, deposit_count, withdraw_count,
24
+ deposited, withdrawn, net_position, markets_active, updated_at)
25
+ VALUES
26
+ (${r.date}, ${r.provider}, ${r.domain_slug}, ${r.deposit_count}, ${r.withdraw_count},
27
+ ${r.deposited}, ${r.withdrawn}, ${r.deposited - r.withdrawn}, ${r.markets_active}, now())
28
+ `;
29
+ }
30
+ });
31
+ }
32
+ export async function writeDailyMarketStats(pg, rows) {
33
+ await pg.begin(async (tx) => {
34
+ await tx `TRUNCATE TABLE daily_market_stats`;
35
+ for (const r of rows) {
36
+ await tx `
37
+ INSERT INTO daily_market_stats
38
+ (date, market_address, trade_count, unique_traders, volume_collateral,
39
+ liquidity_added, liquidity_removed, unique_lps, updated_at)
40
+ VALUES
41
+ (${r.date}, ${r.market_address}, ${r.trade_count}, ${r.unique_traders},
42
+ ${r.volume_collateral}, ${r.liquidity_added}, ${r.liquidity_removed},
43
+ ${r.unique_lps}, now())
44
+ `;
45
+ }
46
+ });
47
+ }
48
+ export async function writeDailyDomainStats(pg, rows) {
49
+ await pg.begin(async (tx) => {
50
+ await tx `TRUNCATE TABLE daily_domain_stats`;
51
+ for (const r of rows) {
52
+ await tx `
53
+ INSERT INTO daily_domain_stats
54
+ (date, domain_slug, trade_count, unique_traders, unique_lps,
55
+ volume_collateral, liquidity_net, active_markets, updated_at)
56
+ VALUES
57
+ (${r.date}, ${r.domain_slug}, ${r.trade_count}, ${r.unique_traders}, ${r.unique_lps},
58
+ ${r.volume_collateral}, ${r.liquidity_net}, ${r.active_markets}, now())
59
+ `;
60
+ }
61
+ });
62
+ }
63
+ export async function writeDailyPlatformStats(pg, rows) {
64
+ await pg.begin(async (tx) => {
65
+ await tx `TRUNCATE TABLE daily_platform_stats`;
66
+ for (const r of rows) {
67
+ await tx `
68
+ INSERT INTO daily_platform_stats
69
+ (date, trade_count, unique_traders, unique_lps, new_traders, new_lps,
70
+ volume_collateral, liquidity_net, active_markets, updated_at)
71
+ VALUES
72
+ (${r.date}, ${r.trade_count}, ${r.unique_traders}, ${r.unique_lps},
73
+ ${r.new_traders}, ${r.new_lps}, ${r.volume_collateral}, ${r.liquidity_net},
74
+ ${r.active_markets}, now())
75
+ `;
76
+ }
77
+ });
78
+ }
79
+ export async function writeTraderLifetime(pg, rows) {
80
+ await pg.begin(async (tx) => {
81
+ await tx `TRUNCATE TABLE trader_lifetime`;
82
+ for (const r of rows) {
83
+ const domainsJson = JSON.stringify(r.domains_json);
84
+ await tx `
85
+ INSERT INTO trader_lifetime
86
+ (trader, first_trade_at, last_trade_at, cohort_week,
87
+ total_trades, buy_count, sell_count, markets_traded,
88
+ domains_traded, domains_json, total_volume, total_collateral_at_risk,
89
+ realized_pnl, unrealized_pnl, total_pnl, roi_pct, active_days, updated_at)
90
+ VALUES
91
+ (${r.trader}, ${TIMESTAMP_OR_NULL(r.first_trade_at)},
92
+ ${TIMESTAMP_OR_NULL(r.last_trade_at)}, ${r.cohort_week},
93
+ ${r.total_trades}, ${r.buy_count}, ${r.sell_count}, ${r.markets_traded},
94
+ ${r.domains_traded}, ${domainsJson}::jsonb,
95
+ ${r.total_volume}, ${r.total_collateral_at_risk},
96
+ ${r.realized_pnl}, ${r.unrealized_pnl}, ${r.total_pnl},
97
+ ${r.roi_pct}, ${r.active_days}, now())
98
+ `;
99
+ }
100
+ });
101
+ }
102
+ export async function writeLPLifetime(pg, rows) {
103
+ await pg.begin(async (tx) => {
104
+ await tx `TRUNCATE TABLE lp_lifetime`;
105
+ for (const r of rows) {
106
+ const domainsJson = JSON.stringify(r.domains_json);
107
+ await tx `
108
+ INSERT INTO lp_lifetime
109
+ (provider, first_deposit_at, last_activity_at, cohort_week,
110
+ deposit_count, withdraw_count, total_deposited, total_withdrawn,
111
+ net_position, current_value, unrealized_pnl, realized_pnl,
112
+ markets_provided, domains_provided, domains_json, active_days,
113
+ roi_pct, updated_at)
114
+ VALUES
115
+ (${r.provider}, ${TIMESTAMP_OR_NULL(r.first_deposit_at)},
116
+ ${TIMESTAMP_OR_NULL(r.last_activity_at)}, ${r.cohort_week},
117
+ ${r.deposit_count}, ${r.withdraw_count}, ${r.total_deposited},
118
+ ${r.total_withdrawn}, ${r.net_position}, ${r.current_value},
119
+ ${r.unrealized_pnl}, ${r.realized_pnl}, ${r.markets_provided},
120
+ ${r.domains_provided}, ${domainsJson}::jsonb, ${r.active_days},
121
+ ${r.roi_pct}, now())
122
+ `;
123
+ }
124
+ });
125
+ }
126
+ export async function recordAggregatorRun(pg, jobName, ok, error) {
127
+ if (ok) {
128
+ await pg `
129
+ INSERT INTO aggregator_state (job_name, last_run_at, last_success_at, last_error)
130
+ VALUES (${jobName}, now(), now(), NULL)
131
+ ON CONFLICT (job_name) DO UPDATE SET
132
+ last_run_at = EXCLUDED.last_run_at,
133
+ last_success_at = EXCLUDED.last_success_at,
134
+ last_error = NULL
135
+ `;
136
+ }
137
+ else {
138
+ await pg `
139
+ INSERT INTO aggregator_state (job_name, last_run_at, last_error)
140
+ VALUES (${jobName}, now(), ${error})
141
+ ON CONFLICT (job_name) DO UPDATE SET
142
+ last_run_at = EXCLUDED.last_run_at,
143
+ last_error = EXCLUDED.last_error
144
+ `;
145
+ }
146
+ }
147
+ //# sourceMappingURL=writers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"writers.js","sourceRoot":"","sources":["../../src/aggregator/writers.ts"],"names":[],"mappings":"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"}