@notuslabs/yail 0.1.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 (168) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +226 -0
  3. package/bin/yail.js +7 -0
  4. package/dist/addresses/registry.d.ts +57 -0
  5. package/dist/addresses/registry.d.ts.map +1 -0
  6. package/dist/addresses/registry.js +131 -0
  7. package/dist/addresses/registry.js.map +1 -0
  8. package/dist/cli/index.d.ts +2 -0
  9. package/dist/cli/index.d.ts.map +1 -0
  10. package/dist/cli/index.js +204 -0
  11. package/dist/cli/index.js.map +1 -0
  12. package/dist/config/address.d.ts +32 -0
  13. package/dist/config/address.d.ts.map +1 -0
  14. package/dist/config/address.js +31 -0
  15. package/dist/config/address.js.map +1 -0
  16. package/dist/config/chain-ref.d.ts +5 -0
  17. package/dist/config/chain-ref.d.ts.map +1 -0
  18. package/dist/config/chain-ref.js +13 -0
  19. package/dist/config/chain-ref.js.map +1 -0
  20. package/dist/config/create-config.d.ts +9 -0
  21. package/dist/config/create-config.d.ts.map +1 -0
  22. package/dist/config/create-config.js +86 -0
  23. package/dist/config/create-config.js.map +1 -0
  24. package/dist/config/index.d.ts +5 -0
  25. package/dist/config/index.d.ts.map +1 -0
  26. package/dist/config/index.js +3 -0
  27. package/dist/config/index.js.map +1 -0
  28. package/dist/config/types.d.ts +113 -0
  29. package/dist/config/types.d.ts.map +1 -0
  30. package/dist/config/types.js +2 -0
  31. package/dist/config/types.js.map +1 -0
  32. package/dist/db/batch.d.ts +33 -0
  33. package/dist/db/batch.d.ts.map +1 -0
  34. package/dist/db/batch.js +71 -0
  35. package/dist/db/batch.js.map +1 -0
  36. package/dist/db/client.d.ts +50 -0
  37. package/dist/db/client.d.ts.map +1 -0
  38. package/dist/db/client.js +104 -0
  39. package/dist/db/client.js.map +1 -0
  40. package/dist/db/index.d.ts +11 -0
  41. package/dist/db/index.d.ts.map +1 -0
  42. package/dist/db/index.js +7 -0
  43. package/dist/db/index.js.map +1 -0
  44. package/dist/db/internal.d.ts +2332 -0
  45. package/dist/db/internal.d.ts.map +1 -0
  46. package/dist/db/internal.js +75 -0
  47. package/dist/db/internal.js.map +1 -0
  48. package/dist/db/migrate.d.ts +22 -0
  49. package/dist/db/migrate.d.ts.map +1 -0
  50. package/dist/db/migrate.js +72 -0
  51. package/dist/db/migrate.js.map +1 -0
  52. package/dist/db/serialize.d.ts +14 -0
  53. package/dist/db/serialize.d.ts.map +1 -0
  54. package/dist/db/serialize.js +133 -0
  55. package/dist/db/serialize.js.map +1 -0
  56. package/dist/db/sql.d.ts +44 -0
  57. package/dist/db/sql.d.ts.map +1 -0
  58. package/dist/db/sql.js +122 -0
  59. package/dist/db/sql.js.map +1 -0
  60. package/dist/http/client.d.ts +40 -0
  61. package/dist/http/client.d.ts.map +1 -0
  62. package/dist/http/client.js +128 -0
  63. package/dist/http/client.js.map +1 -0
  64. package/dist/index.d.ts +21 -0
  65. package/dist/index.d.ts.map +1 -0
  66. package/dist/index.js +15 -0
  67. package/dist/index.js.map +1 -0
  68. package/dist/indexer/context.d.ts +84 -0
  69. package/dist/indexer/context.d.ts.map +1 -0
  70. package/dist/indexer/context.js +45 -0
  71. package/dist/indexer/context.js.map +1 -0
  72. package/dist/indexer/events.d.ts +87 -0
  73. package/dist/indexer/events.d.ts.map +1 -0
  74. package/dist/indexer/events.js +88 -0
  75. package/dist/indexer/events.js.map +1 -0
  76. package/dist/indexer/indexer.d.ts +114 -0
  77. package/dist/indexer/indexer.d.ts.map +1 -0
  78. package/dist/indexer/indexer.js +237 -0
  79. package/dist/indexer/indexer.js.map +1 -0
  80. package/dist/indexer/jobs.d.ts +61 -0
  81. package/dist/indexer/jobs.d.ts.map +1 -0
  82. package/dist/indexer/jobs.js +170 -0
  83. package/dist/indexer/jobs.js.map +1 -0
  84. package/dist/indexer/plan.d.ts +73 -0
  85. package/dist/indexer/plan.d.ts.map +1 -0
  86. package/dist/indexer/plan.js +238 -0
  87. package/dist/indexer/plan.js.map +1 -0
  88. package/dist/indexer/runtime.d.ts +100 -0
  89. package/dist/indexer/runtime.d.ts.map +1 -0
  90. package/dist/indexer/runtime.js +572 -0
  91. package/dist/indexer/runtime.js.map +1 -0
  92. package/dist/observability/logger.d.ts +23 -0
  93. package/dist/observability/logger.d.ts.map +1 -0
  94. package/dist/observability/logger.js +72 -0
  95. package/dist/observability/logger.js.map +1 -0
  96. package/dist/observability/metrics.d.ts +61 -0
  97. package/dist/observability/metrics.d.ts.map +1 -0
  98. package/dist/observability/metrics.js +131 -0
  99. package/dist/observability/metrics.js.map +1 -0
  100. package/dist/observability/otel.d.ts +28 -0
  101. package/dist/observability/otel.d.ts.map +1 -0
  102. package/dist/observability/otel.js +49 -0
  103. package/dist/observability/otel.js.map +1 -0
  104. package/dist/rpc/cached-client.d.ts +33 -0
  105. package/dist/rpc/cached-client.d.ts.map +1 -0
  106. package/dist/rpc/cached-client.js +50 -0
  107. package/dist/rpc/cached-client.js.map +1 -0
  108. package/dist/schema/column.d.ts +61 -0
  109. package/dist/schema/column.d.ts.map +1 -0
  110. package/dist/schema/column.js +76 -0
  111. package/dist/schema/column.js.map +1 -0
  112. package/dist/schema/ddl.d.ts +9 -0
  113. package/dist/schema/ddl.d.ts.map +1 -0
  114. package/dist/schema/ddl.js +58 -0
  115. package/dist/schema/ddl.js.map +1 -0
  116. package/dist/schema/index.d.ts +8 -0
  117. package/dist/schema/index.d.ts.map +1 -0
  118. package/dist/schema/index.js +5 -0
  119. package/dist/schema/index.js.map +1 -0
  120. package/dist/schema/table.d.ts +69 -0
  121. package/dist/schema/table.d.ts.map +1 -0
  122. package/dist/schema/table.js +35 -0
  123. package/dist/schema/table.js.map +1 -0
  124. package/dist/schema/view.d.ts +19 -0
  125. package/dist/schema/view.d.ts.map +1 -0
  126. package/dist/schema/view.js +16 -0
  127. package/dist/schema/view.js.map +1 -0
  128. package/dist/server/api.d.ts +11 -0
  129. package/dist/server/api.d.ts.map +1 -0
  130. package/dist/server/api.js +71 -0
  131. package/dist/server/api.js.map +1 -0
  132. package/dist/sources/cached.d.ts +27 -0
  133. package/dist/sources/cached.d.ts.map +1 -0
  134. package/dist/sources/cached.js +111 -0
  135. package/dist/sources/cached.js.map +1 -0
  136. package/dist/sources/esplora.d.ts +22 -0
  137. package/dist/sources/esplora.d.ts.map +1 -0
  138. package/dist/sources/esplora.js +138 -0
  139. package/dist/sources/esplora.js.map +1 -0
  140. package/dist/sources/fixture.d.ts +51 -0
  141. package/dist/sources/fixture.d.ts.map +1 -0
  142. package/dist/sources/fixture.js +102 -0
  143. package/dist/sources/fixture.js.map +1 -0
  144. package/dist/sources/hypersync.d.ts +19 -0
  145. package/dist/sources/hypersync.d.ts.map +1 -0
  146. package/dist/sources/hypersync.js +169 -0
  147. package/dist/sources/hypersync.js.map +1 -0
  148. package/dist/sources/index.d.ts +13 -0
  149. package/dist/sources/index.d.ts.map +1 -0
  150. package/dist/sources/index.js +7 -0
  151. package/dist/sources/index.js.map +1 -0
  152. package/dist/sources/rpc.d.ts +21 -0
  153. package/dist/sources/rpc.d.ts.map +1 -0
  154. package/dist/sources/rpc.js +187 -0
  155. package/dist/sources/rpc.js.map +1 -0
  156. package/dist/sources/types.d.ts +137 -0
  157. package/dist/sources/types.d.ts.map +1 -0
  158. package/dist/sources/types.js +17 -0
  159. package/dist/sources/types.js.map +1 -0
  160. package/dist/testing/index.d.ts +20 -0
  161. package/dist/testing/index.d.ts.map +1 -0
  162. package/dist/testing/index.js +44 -0
  163. package/dist/testing/index.js.map +1 -0
  164. package/dist/util.d.ts +9 -0
  165. package/dist/util.d.ts.map +1 -0
  166. package/dist/util.js +25 -0
  167. package/dist/util.js.map +1 -0
  168. package/package.json +100 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"internal.d.ts","sourceRoot":"","sources":["../../src/db/internal.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,75 @@
1
+ import { t, table } from "../schema/index.js";
2
+ /** Per-chain indexing progress. `cursor` is the next block to index. */
3
+ export const checkpoints = table("_yail_checkpoints", {
4
+ chain: t.string(),
5
+ cursor: t.uint64(),
6
+ head: t.uint64(),
7
+ updatedAt: t.dateTime64(3),
8
+ }, { orderBy: ["chain"], engineArgs: ["updated_at"], indexMeta: false });
9
+ /** Dynamic address registry. One row per (set, chain, address); latest version wins. */
10
+ export const addresses = table("_yail_addresses", {
11
+ set: t.string(),
12
+ chain: t.string(),
13
+ address: t.address(),
14
+ status: t.enum(["pending", "backfilling", "live", "failed"]),
15
+ /** First block the address should be indexed from. */
16
+ fromBlock: t.uint64(),
17
+ /** True once the live loop has adopted the address (it is included in live queries from `adoptedAtBlock` on). */
18
+ adopted: t.bool().default("false"),
19
+ /** Block at which the live loop adopted the address; backfill covers [fromBlock, adoptedAtBlock). */
20
+ adoptedAtBlock: t.uint64(),
21
+ /** Optional user-defined label / metadata (JSON). */
22
+ meta: t.json().default("'{}'"),
23
+ error: t.string().default("''"),
24
+ registeredAt: t.dateTime64(3),
25
+ updatedAt: t.dateTime64(3),
26
+ }, { orderBy: ["set", "chain", "address"], engineArgs: ["updated_at"], indexMeta: false });
27
+ /** Durable job queue: address backfills and range re-indexes. */
28
+ export const jobs = table("_yail_jobs", {
29
+ id: t.string(),
30
+ chain: t.string(),
31
+ kind: t.enum(["backfill_address", "reindex_range", "reindex_scope"]),
32
+ payload: t.json(),
33
+ status: t.enum(["pending", "running", "done", "failed"]),
34
+ attempts: t.uint32().default("0"),
35
+ error: t.string().default("''"),
36
+ createdAt: t.dateTime64(3),
37
+ updatedAt: t.dateTime64(3),
38
+ }, { orderBy: ["id"], engineArgs: ["updated_at"], indexMeta: false });
39
+ /** Optional cache of raw source batches (HyperSync/RPC pages), keyed by query shape. */
40
+ export const sourceCache = table("_yail_source_cache", {
41
+ chain: t.string(),
42
+ queryHash: t.string(),
43
+ fromBlock: t.uint64(),
44
+ nextBlock: t.uint64(),
45
+ payload: t.string().codec("ZSTD(3)"),
46
+ createdAt: t.dateTime64(3),
47
+ }, { orderBy: ["chain", "queryHash", "fromBlock"], engineArgs: ["created_at"], indexMeta: false });
48
+ /** Cached HTTP responses for `context.http`. */
49
+ export const httpCache = table("_yail_http_cache", {
50
+ key: t.string(),
51
+ url: t.string(),
52
+ status: t.uint16(),
53
+ headers: t.string().codec("ZSTD(3)"),
54
+ body: t.string().codec("ZSTD(3)"),
55
+ fetchedAt: t.dateTime64(3),
56
+ expiresAt: t.dateTime64(3),
57
+ }, { orderBy: ["key"], engineArgs: ["fetched_at"], indexMeta: false });
58
+ /** Cached `eth_call` results for `context.client.readContract`, keyed by block. */
59
+ export const rpcCache = table("_yail_rpc_cache", {
60
+ chain: t.string(),
61
+ block: t.uint64(),
62
+ to: t.address(),
63
+ data: t.string(),
64
+ result: t.string(),
65
+ createdAt: t.dateTime64(3),
66
+ }, { orderBy: ["chain", "block", "to", "data"], engineArgs: ["created_at"], indexMeta: false });
67
+ /** Recent block hashes per chain, used to detect reorgs against the source's rollback guard. */
68
+ export const blockHashes = table("_yail_block_hashes", {
69
+ chain: t.string(),
70
+ block: t.uint64(),
71
+ hash: t.hash(),
72
+ createdAt: t.dateTime64(3),
73
+ }, { orderBy: ["chain", "block"], engineArgs: ["created_at"], indexMeta: false, ttl: "created_at + INTERVAL 7 DAY" });
74
+ export const INTERNAL_TABLES = [checkpoints, addresses, jobs, sourceCache, httpCache, rpcCache, blockHashes];
75
+ //# sourceMappingURL=internal.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"internal.js","sourceRoot":"","sources":["../../src/db/internal.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,22 @@
1
+ import { type MaterializedView, type Table } from "../schema/index.js";
2
+ import type { Db } from "./client.js";
3
+ export type SchemaModule = Record<string, unknown>;
4
+ export declare function collectSchema(schema: SchemaModule | ReadonlyArray<Table<any> | MaterializedView>): {
5
+ tables: Table<any>[];
6
+ views: MaterializedView[];
7
+ };
8
+ export interface MigrateOptions {
9
+ /** Re-run each materialized view's SELECT as INSERT into its target (backfills MVs over existing data). */
10
+ populate?: boolean;
11
+ /** Drop and recreate user tables/views (dev only). Internal tables are kept. */
12
+ reset?: boolean;
13
+ log?: (msg: string) => void;
14
+ }
15
+ /**
16
+ * Create the database, internal bookkeeping tables, user tables and
17
+ * materialized views. Idempotent (`CREATE ... IF NOT EXISTS`).
18
+ */
19
+ export declare function migrate(db: Db, schema: SchemaModule | ReadonlyArray<Table<any> | MaterializedView>, options?: MigrateOptions): Promise<void>;
20
+ /** Ordered DDL statements, useful for review or applying with another tool. */
21
+ export declare function schemaDdl(schema: SchemaModule | ReadonlyArray<Table<any> | MaterializedView>, database?: string): string[];
22
+ //# sourceMappingURL=migrate.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"migrate.d.ts","sourceRoot":"","sources":["../../src/db/migrate.ts"],"names":[],"mappings":"AAAA,OAAO,EAA2F,KAAK,gBAAgB,EAAE,KAAK,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAChK,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,aAAa,CAAC;AAGtC,MAAM,MAAM,YAAY,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAEnD,wBAAgB,aAAa,CAAC,MAAM,EAAE,YAAY,GAAG,aAAa,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,gBAAgB,CAAC,GAAG;IAClG,MAAM,EAAE,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC;IACrB,KAAK,EAAE,gBAAgB,EAAE,CAAC;CAC3B,CAoBA;AAED,MAAM,WAAW,cAAc;IAC7B,2GAA2G;IAC3G,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,gFAAgF;IAChF,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,GAAG,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;CAC7B;AAED;;;GAGG;AACH,wBAAsB,OAAO,CAAC,EAAE,EAAE,EAAE,EAAE,MAAM,EAAE,YAAY,GAAG,aAAa,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,gBAAgB,CAAC,EAAE,OAAO,GAAE,cAAmB,GAAG,OAAO,CAAC,IAAI,CAAC,CAmCtJ;AAED,+EAA+E;AAC/E,wBAAgB,SAAS,CAAC,MAAM,EAAE,YAAY,GAAG,aAAa,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,gBAAgB,CAAC,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAO1H"}
@@ -0,0 +1,72 @@
1
+ import { isMaterializedView, isTable, materializedViewDdl, materializedViewPopulateSql, tableDdl } from "../schema/index.js";
2
+ import { INTERNAL_TABLES } from "./internal.js";
3
+ export function collectSchema(schema) {
4
+ let values;
5
+ if (Array.isArray(schema))
6
+ values = [...schema];
7
+ else
8
+ values = Object.values(schema);
9
+ const tables = [];
10
+ const views = [];
11
+ const seen = new Set();
12
+ for (const v of values) {
13
+ if (isTable(v) && !seen.has(v.name)) {
14
+ seen.add(v.name);
15
+ tables.push(v);
16
+ }
17
+ else if (isMaterializedView(v)) {
18
+ views.push(v);
19
+ if (!seen.has(v.to.name)) {
20
+ seen.add(v.to.name);
21
+ tables.push(v.to);
22
+ }
23
+ }
24
+ }
25
+ return { tables, views };
26
+ }
27
+ /**
28
+ * Create the database, internal bookkeeping tables, user tables and
29
+ * materialized views. Idempotent (`CREATE ... IF NOT EXISTS`).
30
+ */
31
+ export async function migrate(db, schema, options = {}) {
32
+ const log = options.log ?? (() => { });
33
+ const { tables, views } = collectSchema(schema);
34
+ await db.createDatabase();
35
+ for (const t of INTERNAL_TABLES) {
36
+ await db.command(tableDdl(t, db.database));
37
+ }
38
+ if (options.reset) {
39
+ for (const v of views) {
40
+ log(`drop view ${v.name}`);
41
+ await db.command(`DROP VIEW IF EXISTS \`${db.database}\`.\`${v.name}\``);
42
+ }
43
+ for (const t of tables) {
44
+ log(`drop table ${t.name}`);
45
+ await db.command(`DROP TABLE IF EXISTS \`${db.database}\`.\`${t.name}\``);
46
+ }
47
+ }
48
+ for (const t of tables) {
49
+ log(`create table ${t.name}`);
50
+ await db.command(tableDdl(t, db.database));
51
+ }
52
+ for (const v of views) {
53
+ log(`create materialized view ${v.name}`);
54
+ await db.command(materializedViewDdl(v, db.database));
55
+ }
56
+ if (options.populate) {
57
+ for (const v of views) {
58
+ log(`populate ${v.name} -> ${v.to.name}`);
59
+ await db.command(materializedViewPopulateSql(v, db.database));
60
+ }
61
+ }
62
+ }
63
+ /** Ordered DDL statements, useful for review or applying with another tool. */
64
+ export function schemaDdl(schema, database) {
65
+ const { tables, views } = collectSchema(schema);
66
+ return [
67
+ ...INTERNAL_TABLES.map((t) => tableDdl(t, database)),
68
+ ...tables.map((t) => tableDdl(t, database)),
69
+ ...views.map((v) => materializedViewDdl(v, database)),
70
+ ];
71
+ }
72
+ //# sourceMappingURL=migrate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"migrate.js","sourceRoot":"","sources":["../../src/db/migrate.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ import type { Column } from "../schema/column.js";
2
+ import { type Table } from "../schema/table.js";
3
+ export interface RowMeta {
4
+ chain?: string;
5
+ block?: number | bigint;
6
+ version?: number | bigint;
7
+ }
8
+ /** Convert a TS row into the JSONEachRow representation ClickHouse accepts. */
9
+ export declare function serializeRow(table: Table<any>, row: Record<string, unknown>, meta?: RowMeta): Record<string, unknown>;
10
+ export declare function serializeValue(col: Column, value: unknown, path: string): unknown;
11
+ /** Parse a JSONEachRow row (with `date_time_output_format='iso'`) back into TS values. */
12
+ export declare function deserializeRow<T extends Table<any>>(table: T, raw: Record<string, unknown>): Record<string, unknown>;
13
+ export declare function deserializeValue(col: Column, v: unknown): unknown;
14
+ //# sourceMappingURL=serialize.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"serialize.d.ts","sourceRoot":"","sources":["../../src/db/serialize.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAClD,OAAO,EAAsB,KAAK,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAIpE,MAAM,WAAW,OAAO;IACtB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACxB,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;CAC3B;AAED,+EAA+E;AAC/E,wBAAgB,YAAY,CAAC,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,EAAE,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,IAAI,CAAC,EAAE,OAAO,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAqBrH;AAED,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAyCjF;AAQD,0FAA0F;AAC1F,wBAAgB,cAAc,CAAC,CAAC,SAAS,KAAK,CAAC,GAAG,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAQpH;AAED,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,EAAE,CAAC,EAAE,OAAO,GAAG,OAAO,CA2BjE"}
@@ -0,0 +1,133 @@
1
+ import { INDEX_META_COLUMNS } from "../schema/table.js";
2
+ import { formatDateTime64 } from "./sql.js";
3
+ import { bigintReplacer } from "../util.js";
4
+ /** Convert a TS row into the JSONEachRow representation ClickHouse accepts. */
5
+ export function serializeRow(table, row, meta) {
6
+ const out = {};
7
+ for (const key of table.columnKeys) {
8
+ const col = table.columns[key];
9
+ const value = row[key];
10
+ if (value === undefined) {
11
+ if (col.hasDefault || col.isNullable)
12
+ continue;
13
+ throw new Error(`Table "${table.name}": missing required column "${key}"`);
14
+ }
15
+ out[table.columnName(key)] = serializeValue(col, value, `${table.name}.${key}`);
16
+ }
17
+ if (table.options.indexMeta !== false) {
18
+ out[INDEX_META_COLUMNS.chain] = meta?.chain ?? "";
19
+ let block = 0;
20
+ if (meta?.block !== undefined)
21
+ block = Number(meta.block);
22
+ let version = "0";
23
+ if (meta?.version !== undefined)
24
+ version = meta.version.toString();
25
+ out[INDEX_META_COLUMNS.block] = block;
26
+ out[INDEX_META_COLUMNS.version] = version;
27
+ }
28
+ return out;
29
+ }
30
+ export function serializeValue(col, value, path) {
31
+ if (value === null) {
32
+ if (!col.isNullable)
33
+ throw new Error(`Column ${path} is not nullable`);
34
+ return null;
35
+ }
36
+ switch (col.kind) {
37
+ case "string":
38
+ case "hash":
39
+ return String(value);
40
+ case "address": {
41
+ const text = String(value);
42
+ if (text.startsWith("0x"))
43
+ return text.toLowerCase();
44
+ return text;
45
+ }
46
+ case "bool":
47
+ return Boolean(value);
48
+ case "int":
49
+ case "float":
50
+ if (typeof value === "bigint")
51
+ return Number(value);
52
+ return value;
53
+ case "bigint": {
54
+ if (typeof value === "bigint")
55
+ return value.toString();
56
+ if (typeof value === "number")
57
+ return Math.trunc(value).toString();
58
+ if (typeof value === "string")
59
+ return BigInt(value).toString();
60
+ throw new Error(`Column ${path}: expected bigint, got ${typeof value}`);
61
+ }
62
+ case "date": {
63
+ const d = toDate(value);
64
+ if (Number.isNaN(d.getTime()))
65
+ throw new Error(`Column ${path}: invalid date ${String(value)}`);
66
+ if (col.chType === "Date")
67
+ return d.toISOString().slice(0, 10);
68
+ if (col.chType.startsWith("DateTime64"))
69
+ return formatDateTime64(d);
70
+ return Math.floor(d.getTime() / 1000);
71
+ }
72
+ case "enum":
73
+ return String(value);
74
+ case "json":
75
+ if (typeof value === "string")
76
+ return value;
77
+ return JSON.stringify(value, bigintReplacer);
78
+ case "array":
79
+ return value.map((v) => serializeValue(col.items, v, path + "[]"));
80
+ }
81
+ }
82
+ function toDate(value) {
83
+ if (value instanceof Date)
84
+ return value;
85
+ if (typeof value === "number" && value < 1e12)
86
+ return new Date(value * 1000);
87
+ return new Date(value);
88
+ }
89
+ /** Parse a JSONEachRow row (with `date_time_output_format='iso'`) back into TS values. */
90
+ export function deserializeRow(table, raw) {
91
+ const out = {};
92
+ for (const key of table.columnKeys) {
93
+ const col = table.columns[key];
94
+ const v = raw[table.columnName(key)];
95
+ out[key] = deserializeValue(col, v);
96
+ }
97
+ return out;
98
+ }
99
+ export function deserializeValue(col, v) {
100
+ if (v === null || v === undefined)
101
+ return null;
102
+ switch (col.kind) {
103
+ case "bigint":
104
+ return BigInt(v);
105
+ case "int":
106
+ case "float":
107
+ return Number(v);
108
+ case "bool":
109
+ if (typeof v === "string")
110
+ return v === "true" || v === "1";
111
+ return Boolean(v);
112
+ case "date": {
113
+ if (typeof v === "number")
114
+ return new Date(v * 1000);
115
+ const s = String(v);
116
+ // 'iso' output: 2024-01-01T00:00:00Z or 2024-01-01 (Date); 'simple': 2024-01-01 00:00:00
117
+ if (/^\d{4}-\d{2}-\d{2}$/.test(s))
118
+ return new Date(s + "T00:00:00Z");
119
+ if (s.includes("T"))
120
+ return new Date(s);
121
+ return new Date(s.replace(" ", "T") + "Z");
122
+ }
123
+ case "json":
124
+ if (typeof v === "string")
125
+ return JSON.parse(v);
126
+ return v;
127
+ case "array":
128
+ return v.map((x) => deserializeValue(col.items, x));
129
+ default:
130
+ return v;
131
+ }
132
+ }
133
+ //# sourceMappingURL=serialize.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"serialize.js","sourceRoot":"","sources":["../../src/db/serialize.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,44 @@
1
+ import { type Table } from "../schema/table.js";
2
+ export type SqlValue = string | number | bigint | boolean | Date | null | undefined | SqlValue[];
3
+ export interface SqlFragment {
4
+ readonly __brand: "yail.sql";
5
+ readonly strings: ReadonlyArray<string>;
6
+ readonly values: ReadonlyArray<SqlValue | SqlFragment | Table<any> | SqlRaw>;
7
+ }
8
+ export interface SqlRaw {
9
+ readonly __brand: "yail.sqlRaw";
10
+ readonly text: string;
11
+ }
12
+ export declare function isSqlFragment(v: unknown): v is SqlFragment;
13
+ /**
14
+ * Tagged template for parameterized ClickHouse SQL.
15
+ *
16
+ * Interpolated tables render as identifiers, nested fragments are inlined,
17
+ * everything else becomes a typed `{pN:Type}` query parameter.
18
+ *
19
+ * @example
20
+ * sql`SELECT * FROM ${ledger} WHERE wallet = ${wallet} AND block_number > ${100n}`
21
+ */
22
+ export declare function sql(strings: TemplateStringsArray, ...values: SqlFragment["values"][number][]): SqlFragment;
23
+ export declare namespace sql {
24
+ var raw: (text: string) => SqlRaw;
25
+ var identifier: (name: string) => SqlRaw;
26
+ var join: (fragments: ReadonlyArray<SqlFragment | SqlRaw>, separator?: string) => SqlFragment;
27
+ var empty: () => SqlFragment;
28
+ }
29
+ export interface RenderedSql {
30
+ text: string;
31
+ params: Record<string, unknown>;
32
+ }
33
+ export interface RenderOptions {
34
+ /** Inline literals instead of `{pN:Type}` placeholders (needed for DDL such as materialized views). */
35
+ inline?: boolean;
36
+ /** Optional database to qualify table identifiers with. */
37
+ database?: string;
38
+ }
39
+ export declare function renderSql(input: SqlFragment | string, options?: RenderOptions): RenderedSql;
40
+ export declare function literal(v: SqlValue): string;
41
+ /** Backtick-quote a table name, optionally qualified with its database. */
42
+ export declare function qualify(name: string, database?: string): string;
43
+ export declare function formatDateTime64(d: Date): string;
44
+ //# sourceMappingURL=sql.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sql.d.ts","sourceRoot":"","sources":["../../src/db/sql.ts"],"names":[],"mappings":"AAAA,OAAO,EAAW,KAAK,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAEzD,MAAM,MAAM,QAAQ,GAAG,MAAM,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,IAAI,GAAG,IAAI,GAAG,SAAS,GAAG,QAAQ,EAAE,CAAC;AAEjG,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,OAAO,EAAE,UAAU,CAAC;IAC7B,QAAQ,CAAC,OAAO,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC;IACxC,QAAQ,CAAC,MAAM,EAAE,aAAa,CAAC,QAAQ,GAAG,WAAW,GAAG,KAAK,CAAC,GAAG,CAAC,GAAG,MAAM,CAAC,CAAC;CAC9E;AAED,MAAM,WAAW,MAAM;IACrB,QAAQ,CAAC,OAAO,EAAE,aAAa,CAAC;IAChC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACvB;AAED,wBAAgB,aAAa,CAAC,CAAC,EAAE,OAAO,GAAG,CAAC,IAAI,WAAW,CAE1D;AAKD;;;;;;;;GAQG;AACH,wBAAgB,GAAG,CAAC,OAAO,EAAE,oBAAoB,EAAE,GAAG,MAAM,EAAE,WAAW,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,EAAE,GAAG,WAAW,CAE1G;yBAFe,GAAG;oBAKF,MAAM,KAAG,MAAM;2BAGR,MAAM,KAAG,MAAM;0BAGhB,aAAa,CAAC,WAAW,GAAG,MAAM,CAAC,yBAAqB,WAAW;qBAW1E,WAAW;;AAE3B,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACjC;AAED,MAAM,WAAW,aAAa;IAC5B,uGAAuG;IACvG,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,2DAA2D;IAC3D,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,wBAAgB,SAAS,CAAC,KAAK,EAAE,WAAW,GAAG,MAAM,EAAE,OAAO,GAAE,aAAkB,GAAG,WAAW,CA2B/F;AAqBD,wBAAgB,OAAO,CAAC,CAAC,EAAE,QAAQ,GAAG,MAAM,CAY3C;AAED,2EAA2E;AAC3E,wBAAgB,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,CAG/D;AAED,wBAAgB,gBAAgB,CAAC,CAAC,EAAE,IAAI,GAAG,MAAM,CAEhD"}
package/dist/db/sql.js ADDED
@@ -0,0 +1,122 @@
1
+ import { isTable } from "../schema/table.js";
2
+ export function isSqlFragment(v) {
3
+ return typeof v === "object" && v !== null && v.__brand === "yail.sql";
4
+ }
5
+ function isRaw(v) {
6
+ return typeof v === "object" && v !== null && v.__brand === "yail.sqlRaw";
7
+ }
8
+ /**
9
+ * Tagged template for parameterized ClickHouse SQL.
10
+ *
11
+ * Interpolated tables render as identifiers, nested fragments are inlined,
12
+ * everything else becomes a typed `{pN:Type}` query parameter.
13
+ *
14
+ * @example
15
+ * sql`SELECT * FROM ${ledger} WHERE wallet = ${wallet} AND block_number > ${100n}`
16
+ */
17
+ export function sql(strings, ...values) {
18
+ return { __brand: "yail.sql", strings: [...strings], values };
19
+ }
20
+ /** Insert raw SQL text without parameterization. Use only for trusted, static text. */
21
+ sql.raw = (text) => ({ __brand: "yail.sqlRaw", text });
22
+ /** Quote an identifier (column/table name). */
23
+ sql.identifier = (name) => ({ __brand: "yail.sqlRaw", text: `\`${name.replace(/`/g, "``")}\`` });
24
+ /** Join fragments with a separator (default `, `). */
25
+ sql.join = (fragments, separator = ", ") => {
26
+ const strings = [""];
27
+ const values = [];
28
+ fragments.forEach((f, i) => {
29
+ if (i > 0)
30
+ strings[strings.length - 1] += separator;
31
+ values.push(f);
32
+ strings.push("");
33
+ });
34
+ return { __brand: "yail.sql", strings, values };
35
+ };
36
+ sql.empty = () => ({ __brand: "yail.sql", strings: [""], values: [] });
37
+ export function renderSql(input, options = {}) {
38
+ if (typeof input === "string")
39
+ return { text: input, params: {} };
40
+ const params = {};
41
+ let counter = 0;
42
+ const next = () => `p${counter++}`;
43
+ const render = (frag) => {
44
+ let out = "";
45
+ frag.strings.forEach((s, i) => {
46
+ out += s;
47
+ if (i < frag.values.length)
48
+ out += renderValue(frag.values[i]);
49
+ });
50
+ return out;
51
+ };
52
+ const renderValue = (v) => {
53
+ if (isSqlFragment(v))
54
+ return render(v);
55
+ if (isRaw(v))
56
+ return v.text;
57
+ if (isTable(v))
58
+ return qualify(v.name, options.database);
59
+ if (options.inline)
60
+ return literal(v);
61
+ const name = next();
62
+ const { type, value } = paramType(v);
63
+ params[name] = value;
64
+ return `{${name}:${type}}`;
65
+ };
66
+ return { text: render(input), params };
67
+ }
68
+ function paramType(v) {
69
+ if (v === null || v === undefined)
70
+ return { type: "Nullable(String)", value: null };
71
+ if (typeof v === "string")
72
+ return { type: "String", value: v };
73
+ if (typeof v === "boolean")
74
+ return { type: "Bool", value: v };
75
+ if (typeof v === "bigint")
76
+ return { type: "Int256", value: v.toString() };
77
+ if (typeof v === "number") {
78
+ if (Number.isInteger(v))
79
+ return { type: "Int64", value: v };
80
+ return { type: "Float64", value: v };
81
+ }
82
+ if (v instanceof Date)
83
+ return { type: "DateTime64(3)", value: formatDateTime64(v) };
84
+ if (Array.isArray(v)) {
85
+ const first = v.find((x) => x !== null && x !== undefined);
86
+ let inner = "String";
87
+ if (first !== undefined)
88
+ inner = paramType(first).type;
89
+ return { type: `Array(${inner})`, value: v.map((x) => paramType(x).value) };
90
+ }
91
+ throw new Error(`Unsupported SQL parameter: ${String(v)}`);
92
+ }
93
+ export function literal(v) {
94
+ if (v === null || v === undefined)
95
+ return "NULL";
96
+ if (typeof v === "string")
97
+ return `'${v.replace(/\\/g, "\\\\").replace(/'/g, "\\'")}'`;
98
+ if (typeof v === "boolean")
99
+ return String(v);
100
+ if (typeof v === "bigint")
101
+ return v.toString();
102
+ if (typeof v === "number") {
103
+ if (Number.isFinite(v))
104
+ return String(v);
105
+ return "NULL";
106
+ }
107
+ if (v instanceof Date)
108
+ return `'${formatDateTime64(v)}'`;
109
+ if (Array.isArray(v))
110
+ return `[${v.map((x) => literal(x)).join(", ")}]`;
111
+ throw new Error(`Unsupported SQL literal: ${String(v)}`);
112
+ }
113
+ /** Backtick-quote a table name, optionally qualified with its database. */
114
+ export function qualify(name, database) {
115
+ if (database)
116
+ return `\`${database}\`.\`${name}\``;
117
+ return `\`${name}\``;
118
+ }
119
+ export function formatDateTime64(d) {
120
+ return d.toISOString().replace("T", " ").replace("Z", "");
121
+ }
122
+ //# sourceMappingURL=sql.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sql.js","sourceRoot":"","sources":["../../src/db/sql.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,40 @@
1
+ import type { Db } from "../db/client.js";
2
+ export interface HttpCacheOptions {
3
+ /** Cache the response. `true` caches forever (right for historical lookups); a number is a TTL in ms. */
4
+ cache?: boolean | number;
5
+ /** Extra string mixed into the cache key (e.g. a schema version) to invalidate old entries. */
6
+ cacheKey?: string;
7
+ }
8
+ export interface HttpResponse {
9
+ status: number;
10
+ ok: boolean;
11
+ headers: Record<string, string>;
12
+ body: string;
13
+ cached: boolean;
14
+ json<T = unknown>(): T;
15
+ }
16
+ /** `fetch` init without the browser `cache` mode, plus YAIL's cache options. */
17
+ export type HttpRequestInit = Omit<RequestInit, "cache"> & HttpCacheOptions;
18
+ export interface HttpClient {
19
+ get(url: string, init?: HttpRequestInit): Promise<HttpResponse>;
20
+ post(url: string, body: unknown, init?: HttpRequestInit): Promise<HttpResponse>;
21
+ fetch(url: string, init?: HttpRequestInit): Promise<HttpResponse>;
22
+ }
23
+ export interface HttpClientOptions {
24
+ db?: Db;
25
+ /** Persist to ClickHouse (`_yail_http_cache`). When false, only the in-memory LRU is used. */
26
+ persist?: boolean;
27
+ /** In-memory entries. Default 5000. */
28
+ memorySize?: number;
29
+ fetch?: typeof fetch;
30
+ onCache?: (hit: boolean) => void;
31
+ /** Retries on 429/5xx/network errors. Default 3. */
32
+ retries?: number;
33
+ }
34
+ /**
35
+ * HTTP client with an optional response cache. Cached calls are deterministic
36
+ * across re-indexes, which is what you want for price lookups, swap
37
+ * classification via aggregator APIs, token metadata, etc.
38
+ */
39
+ export declare function createHttpClient(options?: HttpClientOptions): HttpClient;
40
+ //# sourceMappingURL=client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/http/client.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,iBAAiB,CAAC;AAI1C,MAAM,WAAW,gBAAgB;IAC/B,yGAAyG;IACzG,KAAK,CAAC,EAAE,OAAO,GAAG,MAAM,CAAC;IACzB,+FAA+F;IAC/F,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,MAAM,CAAC;IACf,EAAE,EAAE,OAAO,CAAC;IACZ,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,OAAO,CAAC;IAChB,IAAI,CAAC,CAAC,GAAG,OAAO,KAAK,CAAC,CAAC;CACxB;AAED,gFAAgF;AAChF,MAAM,MAAM,eAAe,GAAG,IAAI,CAAC,WAAW,EAAE,OAAO,CAAC,GAAG,gBAAgB,CAAC;AAE5E,MAAM,WAAW,UAAU;IACzB,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,eAAe,GAAG,OAAO,CAAC,YAAY,CAAC,CAAC;IAChE,IAAI,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE,eAAe,GAAG,OAAO,CAAC,YAAY,CAAC,CAAC;IAChF,KAAK,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,eAAe,GAAG,OAAO,CAAC,YAAY,CAAC,CAAC;CACnE;AAED,MAAM,WAAW,iBAAiB;IAChC,EAAE,CAAC,EAAE,EAAE,CAAC;IACR,8FAA8F;IAC9F,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,uCAAuC;IACvC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,KAAK,CAAC,EAAE,OAAO,KAAK,CAAC;IACrB,OAAO,CAAC,EAAE,CAAC,GAAG,EAAE,OAAO,KAAK,IAAI,CAAC;IACjC,oDAAoD;IACpD,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,GAAE,iBAAsB,GAAG,UAAU,CA0F5E"}