@hugomrdias/foxer 0.0.7 → 0.1.9

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 (350) hide show
  1. package/CHANGELOG.md +79 -0
  2. package/README.md +90 -17
  3. package/dist/{src/api/runner.d.ts → api/create-api.d.ts} +2 -2
  4. package/dist/api/create-api.d.ts.map +1 -0
  5. package/dist/{src/api/runner.js → api/create-api.js} +2 -2
  6. package/dist/api/create-api.js.map +1 -0
  7. package/dist/api/index.d.ts.map +1 -0
  8. package/dist/api/index.js.map +1 -0
  9. package/dist/api/server.d.ts.map +1 -0
  10. package/dist/api/server.js.map +1 -0
  11. package/dist/api/sql-middleware.d.ts.map +1 -0
  12. package/dist/{src/api → api}/sql-middleware.js +3 -3
  13. package/dist/api/sql-middleware.js.map +1 -0
  14. package/dist/api/sql.d.ts.map +1 -0
  15. package/dist/api/sql.js.map +1 -0
  16. package/dist/api/sse.d.ts.map +1 -0
  17. package/dist/api/sse.js.map +1 -0
  18. package/dist/bin/create.d.ts.map +1 -0
  19. package/dist/{src/bin → bin}/create.js +4 -4
  20. package/dist/bin/create.js.map +1 -0
  21. package/dist/bin/dev.d.ts.map +1 -0
  22. package/dist/{src/bin → bin}/dev.js +9 -11
  23. package/dist/bin/dev.js.map +1 -0
  24. package/dist/{src/bin → bin}/flags.d.ts +2 -2
  25. package/dist/bin/flags.d.ts.map +1 -0
  26. package/dist/{src/bin → bin}/flags.js +1 -1
  27. package/dist/bin/flags.js.map +1 -0
  28. package/dist/{src/bin → bin}/index.d.ts.map +1 -1
  29. package/dist/{src/bin → bin}/index.js +4 -2
  30. package/dist/bin/index.js.map +1 -0
  31. package/dist/bin/serve.d.ts +3 -0
  32. package/dist/bin/serve.d.ts.map +1 -0
  33. package/dist/bin/serve.js +53 -0
  34. package/dist/bin/serve.js.map +1 -0
  35. package/dist/bin/start.d.ts +3 -0
  36. package/dist/bin/start.d.ts.map +1 -0
  37. package/dist/bin/start.js +72 -0
  38. package/dist/bin/start.js.map +1 -0
  39. package/dist/bin/utils.d.ts.map +1 -0
  40. package/dist/bin/utils.js +39 -0
  41. package/dist/bin/utils.js.map +1 -0
  42. package/dist/{src/config → config}/config.d.ts +1 -1
  43. package/dist/config/config.d.ts.map +1 -0
  44. package/dist/config/config.js.map +1 -0
  45. package/dist/{src/config → config}/env.d.ts +2 -2
  46. package/dist/config/env.d.ts.map +1 -0
  47. package/dist/{src/config → config}/env.js +2 -1
  48. package/dist/config/env.js.map +1 -0
  49. package/dist/contants.d.ts.map +1 -0
  50. package/dist/contants.js.map +1 -0
  51. package/dist/db/actions/blocks.d.ts.map +1 -0
  52. package/dist/{src/db → db}/actions/blocks.js +1 -1
  53. package/dist/db/actions/blocks.js.map +1 -0
  54. package/dist/db/actions/index.d.ts.map +1 -0
  55. package/dist/db/actions/index.js.map +1 -0
  56. package/dist/db/actions/transactions.d.ts.map +1 -0
  57. package/dist/db/actions/transactions.js.map +1 -0
  58. package/dist/{src/db → db}/client.d.ts +5 -5
  59. package/dist/db/client.d.ts.map +1 -0
  60. package/dist/{src/db → db}/client.js +4 -2
  61. package/dist/db/client.js.map +1 -0
  62. package/dist/db/column-types.d.ts.map +1 -0
  63. package/dist/db/column-types.js.map +1 -0
  64. package/dist/db/encode.d.ts.map +1 -0
  65. package/dist/db/encode.js.map +1 -0
  66. package/dist/db/migrate.d.ts.map +1 -0
  67. package/dist/{src/db → db}/migrate.js +9 -4
  68. package/dist/db/migrate.js.map +1 -0
  69. package/dist/{src/db → db}/schema/blocks.d.ts.map +1 -1
  70. package/dist/db/schema/blocks.js.map +1 -0
  71. package/dist/{src/db → db}/schema/index.d.ts.map +1 -1
  72. package/dist/db/schema/index.js.map +1 -0
  73. package/dist/{src/db → db}/schema/transactions.d.ts.map +1 -1
  74. package/dist/db/schema/transactions.js.map +1 -0
  75. package/dist/db/transaction.d.ts.map +1 -0
  76. package/dist/db/transaction.js.map +1 -0
  77. package/dist/{src/hooks → hooks}/registry.d.ts +4 -0
  78. package/dist/hooks/registry.d.ts.map +1 -0
  79. package/dist/{src/hooks → hooks}/registry.js +5 -0
  80. package/dist/hooks/registry.js.map +1 -0
  81. package/dist/index.d.ts.map +1 -0
  82. package/dist/index.js.map +1 -0
  83. package/dist/indexer/backfill.d.ts.map +1 -0
  84. package/dist/{src/indexer → indexer}/backfill.js +3 -7
  85. package/dist/indexer/backfill.js.map +1 -0
  86. package/dist/{src/indexer/runner.d.ts → indexer/create-indexer.d.ts} +2 -2
  87. package/dist/indexer/create-indexer.d.ts.map +1 -0
  88. package/dist/{src/indexer/runner.js → indexer/create-indexer.js} +2 -2
  89. package/dist/indexer/create-indexer.js.map +1 -0
  90. package/dist/indexer/live.d.ts.map +1 -0
  91. package/dist/{src/indexer → indexer}/live.js +3 -3
  92. package/dist/indexer/live.js.map +1 -0
  93. package/dist/indexer/process-block.d.ts.map +1 -0
  94. package/dist/{src/indexer → indexer}/process-block.js +2 -2
  95. package/dist/indexer/process-block.js.map +1 -0
  96. package/dist/indexer/queue-block.d.ts.map +1 -0
  97. package/dist/indexer/queue-block.js.map +1 -0
  98. package/dist/indexer/reorg.d.ts.map +1 -0
  99. package/dist/indexer/reorg.js.map +1 -0
  100. package/dist/rpc/client.d.ts.map +1 -0
  101. package/dist/rpc/client.js.map +1 -0
  102. package/dist/rpc/get-block.d.ts.map +1 -0
  103. package/dist/rpc/get-block.js.map +1 -0
  104. package/dist/rpc/get-logs.d.ts.map +1 -0
  105. package/dist/{src/rpc → rpc}/get-logs.js +1 -1
  106. package/dist/rpc/get-logs.js.map +1 -0
  107. package/dist/schema.d.ts.map +1 -0
  108. package/dist/schema.js.map +1 -0
  109. package/dist/types.d.ts.map +1 -0
  110. package/dist/types.js.map +1 -0
  111. package/dist/utils/bloom.d.ts.map +1 -0
  112. package/dist/utils/bloom.js.map +1 -0
  113. package/dist/utils/build-conflict-columns.d.ts.map +1 -0
  114. package/dist/utils/build-conflict-columns.js.map +1 -0
  115. package/dist/utils/common.d.ts.map +1 -0
  116. package/dist/utils/common.js.map +1 -0
  117. package/dist/utils/cursor.d.ts.map +1 -0
  118. package/dist/utils/cursor.js.map +1 -0
  119. package/dist/utils/format.d.ts.map +1 -0
  120. package/dist/utils/format.js.map +1 -0
  121. package/dist/utils/hash.d.ts.map +1 -0
  122. package/dist/utils/hash.js.map +1 -0
  123. package/dist/utils/json.d.ts.map +1 -0
  124. package/dist/utils/json.js.map +1 -0
  125. package/dist/utils/logger.d.ts.map +1 -0
  126. package/dist/{src/utils → utils}/logger.js +0 -3
  127. package/dist/utils/logger.js.map +1 -0
  128. package/dist/utils/shutdown.d.ts.map +1 -0
  129. package/dist/{src/utils → utils}/shutdown.js +3 -2
  130. package/dist/utils/shutdown.js.map +1 -0
  131. package/dist/utils/timer.d.ts.map +1 -0
  132. package/dist/utils/timer.js.map +1 -0
  133. package/dist/utils/types.d.ts.map +1 -0
  134. package/dist/{src → utils}/types.js.map +1 -1
  135. package/package.json +45 -35
  136. package/src/api/{runner.ts → create-api.ts} +2 -1
  137. package/src/api/server.ts +1 -0
  138. package/src/api/sql-middleware.ts +4 -3
  139. package/src/api/sql.ts +2 -1
  140. package/src/bin/create.ts +7 -8
  141. package/src/bin/dev.ts +11 -13
  142. package/src/bin/flags.ts +1 -1
  143. package/src/bin/index.ts +6 -2
  144. package/src/bin/serve.ts +65 -0
  145. package/src/bin/start.ts +87 -0
  146. package/src/bin/utils.ts +22 -25
  147. package/src/config/config.ts +1 -0
  148. package/src/config/env.ts +3 -1
  149. package/src/db/actions/blocks.ts +2 -1
  150. package/src/db/actions/transactions.ts +1 -0
  151. package/src/db/client.ts +7 -4
  152. package/src/db/encode.ts +1 -0
  153. package/src/db/migrate.ts +9 -4
  154. package/src/db/schema/blocks.ts +1 -0
  155. package/src/db/schema/transactions.ts +1 -0
  156. package/src/hooks/registry.ts +12 -0
  157. package/src/indexer/backfill.ts +3 -10
  158. package/src/indexer/{runner.ts → create-indexer.ts} +1 -1
  159. package/src/indexer/live.ts +4 -3
  160. package/src/indexer/process-block.ts +3 -2
  161. package/src/indexer/queue-block.ts +1 -0
  162. package/src/indexer/reorg.ts +1 -0
  163. package/src/rpc/client.ts +1 -0
  164. package/src/rpc/get-block.ts +1 -0
  165. package/src/rpc/get-logs.ts +2 -1
  166. package/src/types.ts +1 -0
  167. package/src/utils/logger.ts +1 -3
  168. package/src/utils/shutdown.ts +3 -2
  169. package/src/utils/types.ts +1 -0
  170. package/template/{package.json → package.json.tpl} +10 -8
  171. package/template/{pnpm-workspace.yaml → pnpm-workspace.yaml.tpl} +1 -1
  172. package/template/{tsconfig.json → tsconfig.json.tpl} +1 -2
  173. package/template/turbo.json.tpl +22 -0
  174. package/tsconfig.json +3 -1
  175. package/dist/src/api/index.d.ts.map +0 -1
  176. package/dist/src/api/index.js.map +0 -1
  177. package/dist/src/api/runner.d.ts.map +0 -1
  178. package/dist/src/api/runner.js.map +0 -1
  179. package/dist/src/api/server.d.ts.map +0 -1
  180. package/dist/src/api/server.js.map +0 -1
  181. package/dist/src/api/sql-middleware.d.ts.map +0 -1
  182. package/dist/src/api/sql-middleware.js.map +0 -1
  183. package/dist/src/api/sql.d.ts.map +0 -1
  184. package/dist/src/api/sql.js.map +0 -1
  185. package/dist/src/api/sse.d.ts.map +0 -1
  186. package/dist/src/api/sse.js.map +0 -1
  187. package/dist/src/bin/create.d.ts.map +0 -1
  188. package/dist/src/bin/create.js.map +0 -1
  189. package/dist/src/bin/dev.d.ts.map +0 -1
  190. package/dist/src/bin/dev.js.map +0 -1
  191. package/dist/src/bin/flags.d.ts.map +0 -1
  192. package/dist/src/bin/flags.js.map +0 -1
  193. package/dist/src/bin/index.js.map +0 -1
  194. package/dist/src/bin/utils.d.ts.map +0 -1
  195. package/dist/src/bin/utils.js +0 -52
  196. package/dist/src/bin/utils.js.map +0 -1
  197. package/dist/src/client/index.d.ts +0 -18
  198. package/dist/src/client/index.d.ts.map +0 -1
  199. package/dist/src/client/index.js +0 -150
  200. package/dist/src/client/index.js.map +0 -1
  201. package/dist/src/config/config.d.ts.map +0 -1
  202. package/dist/src/config/config.js.map +0 -1
  203. package/dist/src/config/env.d.ts.map +0 -1
  204. package/dist/src/config/env.js.map +0 -1
  205. package/dist/src/contants.d.ts.map +0 -1
  206. package/dist/src/contants.js.map +0 -1
  207. package/dist/src/db/actions/blocks.d.ts.map +0 -1
  208. package/dist/src/db/actions/blocks.js.map +0 -1
  209. package/dist/src/db/actions/index.d.ts.map +0 -1
  210. package/dist/src/db/actions/index.js.map +0 -1
  211. package/dist/src/db/actions/transactions.d.ts.map +0 -1
  212. package/dist/src/db/actions/transactions.js.map +0 -1
  213. package/dist/src/db/client.d.ts.map +0 -1
  214. package/dist/src/db/client.js.map +0 -1
  215. package/dist/src/db/column-types.d.ts.map +0 -1
  216. package/dist/src/db/column-types.js.map +0 -1
  217. package/dist/src/db/encode.d.ts.map +0 -1
  218. package/dist/src/db/encode.js.map +0 -1
  219. package/dist/src/db/migrate.d.ts.map +0 -1
  220. package/dist/src/db/migrate.js.map +0 -1
  221. package/dist/src/db/schema/blocks.js.map +0 -1
  222. package/dist/src/db/schema/index.js.map +0 -1
  223. package/dist/src/db/schema/transactions.js.map +0 -1
  224. package/dist/src/db/transaction.d.ts.map +0 -1
  225. package/dist/src/db/transaction.js.map +0 -1
  226. package/dist/src/hooks/default-hooks.d.ts +0 -2
  227. package/dist/src/hooks/default-hooks.d.ts.map +0 -1
  228. package/dist/src/hooks/default-hooks.js +0 -107
  229. package/dist/src/hooks/default-hooks.js.map +0 -1
  230. package/dist/src/hooks/registry.d.ts.map +0 -1
  231. package/dist/src/hooks/registry.js.map +0 -1
  232. package/dist/src/index.d.ts.map +0 -1
  233. package/dist/src/index.js.map +0 -1
  234. package/dist/src/indexer/backfill.d.ts.map +0 -1
  235. package/dist/src/indexer/backfill.js.map +0 -1
  236. package/dist/src/indexer/live.d.ts.map +0 -1
  237. package/dist/src/indexer/live.js.map +0 -1
  238. package/dist/src/indexer/process-block.d.ts.map +0 -1
  239. package/dist/src/indexer/process-block.js.map +0 -1
  240. package/dist/src/indexer/queue-block.d.ts.map +0 -1
  241. package/dist/src/indexer/queue-block.js.map +0 -1
  242. package/dist/src/indexer/reorg.d.ts.map +0 -1
  243. package/dist/src/indexer/reorg.js.map +0 -1
  244. package/dist/src/indexer/runner.d.ts.map +0 -1
  245. package/dist/src/indexer/runner.js.map +0 -1
  246. package/dist/src/rpc/client.d.ts.map +0 -1
  247. package/dist/src/rpc/client.js.map +0 -1
  248. package/dist/src/rpc/get-block.d.ts.map +0 -1
  249. package/dist/src/rpc/get-block.js.map +0 -1
  250. package/dist/src/rpc/get-logs.d.ts.map +0 -1
  251. package/dist/src/rpc/get-logs.js.map +0 -1
  252. package/dist/src/schema.d.ts.map +0 -1
  253. package/dist/src/schema.js.map +0 -1
  254. package/dist/src/types.d.ts.map +0 -1
  255. package/dist/src/utils/bloom.d.ts.map +0 -1
  256. package/dist/src/utils/bloom.js.map +0 -1
  257. package/dist/src/utils/build-conflict-columns.d.ts.map +0 -1
  258. package/dist/src/utils/build-conflict-columns.js.map +0 -1
  259. package/dist/src/utils/common.d.ts.map +0 -1
  260. package/dist/src/utils/common.js.map +0 -1
  261. package/dist/src/utils/cursor.d.ts.map +0 -1
  262. package/dist/src/utils/cursor.js.map +0 -1
  263. package/dist/src/utils/format.d.ts.map +0 -1
  264. package/dist/src/utils/format.js.map +0 -1
  265. package/dist/src/utils/hash.d.ts.map +0 -1
  266. package/dist/src/utils/hash.js.map +0 -1
  267. package/dist/src/utils/json.d.ts.map +0 -1
  268. package/dist/src/utils/json.js.map +0 -1
  269. package/dist/src/utils/logger.d.ts.map +0 -1
  270. package/dist/src/utils/logger.js.map +0 -1
  271. package/dist/src/utils/shutdown.d.ts.map +0 -1
  272. package/dist/src/utils/shutdown.js.map +0 -1
  273. package/dist/src/utils/timer.d.ts.map +0 -1
  274. package/dist/src/utils/timer.js.map +0 -1
  275. package/dist/src/utils/types.d.ts.map +0 -1
  276. package/dist/src/utils/types.js.map +0 -1
  277. package/dist/tsconfig.tsbuildinfo +0 -1
  278. package/template/biome.json +0 -50
  279. /package/dist/{src/api → api}/index.d.ts +0 -0
  280. /package/dist/{src/api → api}/index.js +0 -0
  281. /package/dist/{src/api → api}/server.d.ts +0 -0
  282. /package/dist/{src/api → api}/server.js +0 -0
  283. /package/dist/{src/api → api}/sql-middleware.d.ts +0 -0
  284. /package/dist/{src/api → api}/sql.d.ts +0 -0
  285. /package/dist/{src/api → api}/sql.js +0 -0
  286. /package/dist/{src/api → api}/sse.d.ts +0 -0
  287. /package/dist/{src/api → api}/sse.js +0 -0
  288. /package/dist/{src/bin → bin}/create.d.ts +0 -0
  289. /package/dist/{src/bin → bin}/dev.d.ts +0 -0
  290. /package/dist/{src/bin → bin}/index.d.ts +0 -0
  291. /package/dist/{src/bin → bin}/utils.d.ts +0 -0
  292. /package/dist/{src/config → config}/config.js +0 -0
  293. /package/dist/{src/contants.d.ts → contants.d.ts} +0 -0
  294. /package/dist/{src/contants.js → contants.js} +0 -0
  295. /package/dist/{src/db → db}/actions/blocks.d.ts +0 -0
  296. /package/dist/{src/db → db}/actions/index.d.ts +0 -0
  297. /package/dist/{src/db → db}/actions/index.js +0 -0
  298. /package/dist/{src/db → db}/actions/transactions.d.ts +0 -0
  299. /package/dist/{src/db → db}/actions/transactions.js +0 -0
  300. /package/dist/{src/db → db}/column-types.d.ts +0 -0
  301. /package/dist/{src/db → db}/column-types.js +0 -0
  302. /package/dist/{src/db → db}/encode.d.ts +0 -0
  303. /package/dist/{src/db → db}/encode.js +0 -0
  304. /package/dist/{src/db → db}/migrate.d.ts +0 -0
  305. /package/dist/{src/db → db}/schema/blocks.d.ts +0 -0
  306. /package/dist/{src/db → db}/schema/blocks.js +0 -0
  307. /package/dist/{src/db → db}/schema/index.d.ts +0 -0
  308. /package/dist/{src/db → db}/schema/index.js +0 -0
  309. /package/dist/{src/db → db}/schema/transactions.d.ts +0 -0
  310. /package/dist/{src/db → db}/schema/transactions.js +0 -0
  311. /package/dist/{src/db → db}/transaction.d.ts +0 -0
  312. /package/dist/{src/db → db}/transaction.js +0 -0
  313. /package/dist/{src/index.d.ts → index.d.ts} +0 -0
  314. /package/dist/{src/index.js → index.js} +0 -0
  315. /package/dist/{src/indexer → indexer}/backfill.d.ts +0 -0
  316. /package/dist/{src/indexer → indexer}/live.d.ts +0 -0
  317. /package/dist/{src/indexer → indexer}/process-block.d.ts +0 -0
  318. /package/dist/{src/indexer → indexer}/queue-block.d.ts +0 -0
  319. /package/dist/{src/indexer → indexer}/queue-block.js +0 -0
  320. /package/dist/{src/indexer → indexer}/reorg.d.ts +0 -0
  321. /package/dist/{src/indexer → indexer}/reorg.js +0 -0
  322. /package/dist/{src/rpc → rpc}/client.d.ts +0 -0
  323. /package/dist/{src/rpc → rpc}/client.js +0 -0
  324. /package/dist/{src/rpc → rpc}/get-block.d.ts +0 -0
  325. /package/dist/{src/rpc → rpc}/get-block.js +0 -0
  326. /package/dist/{src/rpc → rpc}/get-logs.d.ts +0 -0
  327. /package/dist/{src/schema.d.ts → schema.d.ts} +0 -0
  328. /package/dist/{src/schema.js → schema.js} +0 -0
  329. /package/dist/{src/types.d.ts → types.d.ts} +0 -0
  330. /package/dist/{src/types.js → types.js} +0 -0
  331. /package/dist/{src/utils → utils}/bloom.d.ts +0 -0
  332. /package/dist/{src/utils → utils}/bloom.js +0 -0
  333. /package/dist/{src/utils → utils}/build-conflict-columns.d.ts +0 -0
  334. /package/dist/{src/utils → utils}/build-conflict-columns.js +0 -0
  335. /package/dist/{src/utils → utils}/common.d.ts +0 -0
  336. /package/dist/{src/utils → utils}/common.js +0 -0
  337. /package/dist/{src/utils → utils}/cursor.d.ts +0 -0
  338. /package/dist/{src/utils → utils}/cursor.js +0 -0
  339. /package/dist/{src/utils → utils}/format.d.ts +0 -0
  340. /package/dist/{src/utils → utils}/format.js +0 -0
  341. /package/dist/{src/utils → utils}/hash.d.ts +0 -0
  342. /package/dist/{src/utils → utils}/hash.js +0 -0
  343. /package/dist/{src/utils → utils}/json.d.ts +0 -0
  344. /package/dist/{src/utils → utils}/json.js +0 -0
  345. /package/dist/{src/utils → utils}/logger.d.ts +0 -0
  346. /package/dist/{src/utils → utils}/shutdown.d.ts +0 -0
  347. /package/dist/{src/utils → utils}/timer.d.ts +0 -0
  348. /package/dist/{src/utils → utils}/timer.js +0 -0
  349. /package/dist/{src/utils → utils}/types.d.ts +0 -0
  350. /package/dist/{src/utils → utils}/types.js +0 -0
package/src/bin/index.ts CHANGED
@@ -3,12 +3,16 @@
3
3
  import { readFileSync } from 'node:fs'
4
4
  import { dirname, resolve } from 'node:path'
5
5
  import { fileURLToPath } from 'node:url'
6
+
6
7
  import { cli } from 'cleye'
8
+
7
9
  import { create } from './create.ts'
8
10
  import { dev } from './dev.ts'
11
+ import { serve } from './serve.ts'
12
+ import { start } from './start.ts'
9
13
 
10
14
  const __dirname = dirname(fileURLToPath(import.meta.url))
11
- const packageJsonPath = resolve(__dirname, '../../../package.json')
15
+ const packageJsonPath = resolve(__dirname, '../../package.json')
12
16
  const packageJson = JSON.parse(
13
17
  readFileSync(packageJsonPath, { encoding: 'utf8' })
14
18
  )
@@ -16,7 +20,7 @@ const packageJson = JSON.parse(
16
20
  const argv = cli({
17
21
  name: 'foxer',
18
22
  version: packageJson.version,
19
- commands: [dev, create],
23
+ commands: [dev, create, start, serve],
20
24
  help: {
21
25
  version: packageJson.version,
22
26
  },
@@ -0,0 +1,65 @@
1
+ import { type Command, command } from 'cleye'
2
+ import { gracefulExit } from 'exit-hook'
3
+
4
+ import { createApi } from '../api/create-api.ts'
5
+ import { createEnv } from '../config/env.ts'
6
+ import { createDatabase } from '../db/client.ts'
7
+ import * as InternalSchema from '../db/schema/index.ts'
8
+ import { createLogger } from '../utils/logger.ts'
9
+ import { createExit } from '../utils/shutdown.ts'
10
+ import { globalFlags } from './flags.ts'
11
+ import { loadConfig } from './utils.ts'
12
+
13
+ export const serve: Command = command(
14
+ {
15
+ name: 'serve',
16
+ flags: { ...globalFlags },
17
+ help: {
18
+ description: 'Serve the production HTTP API and without the indexer',
19
+ },
20
+ },
21
+ async (argv) => {
22
+ const logger = createLogger({
23
+ level: argv.flags.logLevel,
24
+ mode: 'json',
25
+ })
26
+
27
+ if (process.env.DATABASE_URL == null) {
28
+ logger.error('DATABASE_URL environment variable is not set')
29
+ gracefulExit(1)
30
+ }
31
+
32
+ try {
33
+ const env = createEnv(logger)
34
+ const config = await loadConfig(
35
+ logger,
36
+ argv.flags.root,
37
+ argv.flags.config
38
+ )
39
+
40
+ const dbContext = createDatabase({
41
+ env,
42
+ schema: { ...config.schema, ...InternalSchema.schema },
43
+ relations: { ...config.relations, ...InternalSchema.relations },
44
+ })
45
+
46
+ const api = createApi({
47
+ db: dbContext.db,
48
+ config,
49
+ logger,
50
+ port: argv.flags.port,
51
+ })
52
+
53
+ createExit({
54
+ logger,
55
+ stop: async () => {
56
+ api.stop()
57
+ await dbContext.stop()
58
+ },
59
+ })
60
+ } catch (error) {
61
+ logger.error({ error }, 'HTTP API server failed')
62
+ gracefulExit(1)
63
+ }
64
+ }
65
+ )
@@ -0,0 +1,87 @@
1
+ import path from 'node:path'
2
+
3
+ import { type Command, command } from 'cleye'
4
+ import { gracefulExit } from 'exit-hook'
5
+
6
+ import { createApi } from '../api/create-api.ts'
7
+ import { createEnv } from '../config/env.ts'
8
+ import { createDatabase } from '../db/client.ts'
9
+ import { runMigrations } from '../db/migrate.ts'
10
+ import * as InternalSchema from '../db/schema/index.ts'
11
+ import { createRegistry } from '../hooks/registry.ts'
12
+ import { createIndexer } from '../indexer/create-indexer.ts'
13
+ import { createLogger } from '../utils/logger.ts'
14
+ import { createExit } from '../utils/shutdown.ts'
15
+ import { globalFlags } from './flags.ts'
16
+ import { loadConfig } from './utils.ts'
17
+
18
+ export const start: Command = command(
19
+ {
20
+ name: 'start',
21
+ flags: { ...globalFlags },
22
+ help: {
23
+ description: 'Start the production server',
24
+ },
25
+ },
26
+ async (argv) => {
27
+ const logger = createLogger({
28
+ level: argv.flags.logLevel,
29
+ mode: 'json',
30
+ })
31
+
32
+ if (process.env.DATABASE_URL == null) {
33
+ logger.error('DATABASE_URL environment variable is not set')
34
+ gracefulExit(1)
35
+ }
36
+
37
+ try {
38
+ const env = createEnv(logger)
39
+ const config = await loadConfig(
40
+ logger,
41
+ argv.flags.root,
42
+ argv.flags.config
43
+ )
44
+
45
+ const dbContext = createDatabase({
46
+ env,
47
+ schema: { ...config.schema, ...InternalSchema.schema },
48
+ relations: { ...config.relations, ...InternalSchema.relations },
49
+ })
50
+
51
+ await runMigrations({
52
+ dbContext,
53
+ folder: path.resolve(argv.flags.root, config.drizzleFolder),
54
+ logger,
55
+ })
56
+
57
+ const registry = createRegistry({ config })
58
+
59
+ const [api, indexer] = await Promise.all([
60
+ createApi({
61
+ db: dbContext.db,
62
+ config,
63
+ logger,
64
+ port: argv.flags.port,
65
+ }),
66
+ createIndexer({
67
+ logger,
68
+ db: dbContext.db,
69
+ registry,
70
+ config,
71
+ }),
72
+ ])
73
+
74
+ createExit({
75
+ logger,
76
+ stop: async () => {
77
+ indexer.stop()
78
+ api.stop()
79
+ await dbContext.stop()
80
+ },
81
+ })
82
+ } catch (error) {
83
+ logger.error({ error }, 'start server failed')
84
+ gracefulExit(1)
85
+ }
86
+ }
87
+ )
package/src/bin/utils.ts CHANGED
@@ -1,50 +1,47 @@
1
1
  import path from 'node:path'
2
- import { pathToFileURL } from 'node:url'
3
- import { type LilconfigResult, lilconfig } from 'lilconfig'
2
+ import {
3
+ type LoadConfigResult,
4
+ loadConfig as unconfigLoadConfig,
5
+ } from 'unconfig'
6
+
4
7
  import type { InternalConfig } from '../config/config'
5
8
  import type { Logger } from '../utils/logger'
6
9
 
7
10
  const CLI_NAME = 'foxer'
8
11
 
9
- const loadEsm = async (filepath: string) => {
10
- const res = await import(pathToFileURL(filepath).href)
11
- return res.default ?? res
12
- }
13
-
14
- const configLoaders = {
15
- '.js': loadEsm,
16
- '.mjs': loadEsm,
17
- '.ts': loadEsm,
18
- '.mts': loadEsm,
19
- }
20
-
21
12
  export async function loadConfig(
22
13
  logger: Logger,
23
14
  root: string,
24
15
  filePath?: string
25
16
  ) {
26
- let configFile: LilconfigResult | undefined
17
+ let configFile: LoadConfigResult<{ config: InternalConfig }> | undefined
27
18
 
28
19
  try {
29
20
  if (filePath) {
30
21
  const configPath = path.resolve(root, filePath)
31
22
 
32
- configFile = await lilconfig(configPath, {
33
- loaders: configLoaders,
34
- searchPlaces: [],
35
- }).load(configPath)
23
+ configFile = await unconfigLoadConfig({
24
+ sources: [
25
+ {
26
+ files: configPath,
27
+ },
28
+ ],
29
+ })
36
30
  } else {
37
- configFile = await lilconfig(CLI_NAME, {
38
- loaders: configLoaders,
39
- searchPlaces: [`${CLI_NAME}.config.ts`, `${CLI_NAME}.config.mts`],
40
- }).search()
31
+ configFile = await unconfigLoadConfig({
32
+ sources: [
33
+ {
34
+ files: `${CLI_NAME}.config`,
35
+ },
36
+ ],
37
+ })
41
38
  }
42
39
  } catch (error) {
43
- logger.error(error, 'config evaluation failed')
40
+ logger.error({ error }, 'config evaluation failed')
44
41
  // ignore
45
42
  }
46
43
 
47
- if (!configFile || configFile.isEmpty) {
44
+ if (!configFile) {
48
45
  logger.error({
49
46
  msg: 'Config file not found',
50
47
  })
@@ -13,6 +13,7 @@ import {
13
13
  type PublicClientConfig,
14
14
  type WebSocketTransport,
15
15
  } from 'viem'
16
+
16
17
  import type { Database } from '../db/client.ts'
17
18
  import type { HookRegistry } from '../hooks/registry.ts'
18
19
  import { createRpcClients, type RpcClients } from '../rpc/client.ts'
package/src/config/env.ts CHANGED
@@ -1,9 +1,11 @@
1
1
  import dotenv from 'dotenv'
2
2
  import { z } from 'zod'
3
+
3
4
  import type { Logger } from '../utils/logger'
4
5
 
5
6
  dotenv.config({
6
7
  path: '.env.local',
8
+ quiet: true,
7
9
  })
8
10
 
9
11
  export type Env = z.infer<typeof envSchema>
@@ -20,7 +22,7 @@ export function createEnv(logger: Logger) {
20
22
 
21
23
  if (!parsed.success) {
22
24
  throw new Error(
23
- `Failed to parse environment variables: \n ${z.flattenError(parsed.error)}`
25
+ `Failed to parse environment variables: \n ${z.prettifyError(parsed.error)}`
24
26
  )
25
27
  }
26
28
  logger.debug({ env: parsed.data }, 'env parsed')
@@ -9,6 +9,7 @@ import {
9
9
  type PgTable,
10
10
  } from 'drizzle-orm/pg-core'
11
11
  import type { PublicClient } from 'viem'
12
+
12
13
  import type { FilteredContracts } from '../../config/config.ts'
13
14
  import { MAX_QUERY_PARAMS } from '../../contants.ts'
14
15
  import { safeGetBlock } from '../../rpc/get-block.ts'
@@ -175,7 +176,7 @@ export async function getBlocksInRange(
175
176
  })
176
177
  })
177
178
 
178
- logger.info(
179
+ logger.trace(
179
180
  {
180
181
  blocks: blocksByNumber.size,
181
182
  missing: missingBlockNumbers.length,
@@ -1,4 +1,5 @@
1
1
  import type { PgAsyncTransaction, PgQueryResultHKT } from 'drizzle-orm/pg-core'
2
+
2
3
  import { MAX_QUERY_PARAMS } from '../../contants.ts'
3
4
  import type { EncodedTransaction } from '../../types.ts'
4
5
  import { schema } from '../schema/index.ts'
package/src/db/client.ts CHANGED
@@ -10,6 +10,7 @@ import {
10
10
  } from 'drizzle-orm/pglite'
11
11
  import type { AnyRelations, EmptyRelations } from 'drizzle-orm/relations'
12
12
  import { Pool, type PoolConfig } from 'pg'
13
+
13
14
  import type { DatabaseConfig } from '../config/config.ts'
14
15
  import type { Env } from '../config/env.ts'
15
16
  import { type relations, schema } from './schema/index.ts'
@@ -39,7 +40,7 @@ export type DatabaseContext<
39
40
  $prepared: ReturnType<typeof generatePrepared>
40
41
  }
41
42
  driver: 'postgres'
42
- close: () => Promise<void>
43
+ stop: () => Promise<void>
43
44
  }
44
45
  | {
45
46
  db: PgliteDatabase<TSchema, TRelations> & {
@@ -47,7 +48,7 @@ export type DatabaseContext<
47
48
  $prepared: ReturnType<typeof generatePrepared>
48
49
  }
49
50
  driver: 'pglite'
50
- close: () => Promise<void>
51
+ stop: () => Promise<void>
51
52
  }
52
53
 
53
54
  /**
@@ -80,6 +81,7 @@ export function createDatabase<
80
81
  options = config.options
81
82
  }
82
83
 
84
+ // Postgres
83
85
  if (driver === 'postgres' && url) {
84
86
  const pool = new Pool({
85
87
  ...options,
@@ -101,12 +103,13 @@ export function createDatabase<
101
103
  return {
102
104
  db,
103
105
  driver: 'postgres',
104
- close: async () => {
106
+ stop: async () => {
105
107
  await pool.end()
106
108
  },
107
109
  }
108
110
  }
109
111
 
112
+ // PGlite
110
113
  const client = new PGlite(
111
114
  config?.driver === 'pglite' && config.directory
112
115
  ? config.directory
@@ -128,7 +131,7 @@ export function createDatabase<
128
131
  return {
129
132
  db,
130
133
  driver: 'pglite',
131
- close: async () => {
134
+ stop: async () => {
132
135
  await client.close()
133
136
  },
134
137
  }
package/src/db/encode.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  import type { Hash } from 'viem'
2
+
2
3
  import type {
3
4
  ChainBlock,
4
5
  ChainTransaction,
package/src/db/migrate.ts CHANGED
@@ -2,6 +2,7 @@ import { migrate as migratePostgresJs } from 'drizzle-orm/node-postgres/migrator
2
2
  import { getTableConfig, type PgTable } from 'drizzle-orm/pg-core'
3
3
  import { IndexedColumn } from 'drizzle-orm/pg-core/columns/common'
4
4
  import { migrate as migratePglite } from 'drizzle-orm/pglite/migrator'
5
+
5
6
  import { FOXER_TABLES, PUBLICATION_NAME } from '../contants.ts'
6
7
  import type { Logger } from '../utils/logger.ts'
7
8
  import { startClock } from '../utils/timer.ts'
@@ -214,8 +215,12 @@ function hasCascadeForeignKeyToBlockNumberTable(
214
215
  * @returns True if WAL is enabled, false otherwise
215
216
  */
216
217
  export async function isWalEnabled(db: Database) {
217
- const wal = await db
218
- .execute('SHOW WAL_LEVEL')
219
- .then((result) => result.rows[0].wal_level)
220
- return wal === 'logical'
218
+ try {
219
+ const wal = await db
220
+ .execute('SHOW WAL_LEVEL')
221
+ .then((result) => result.rows[0].wal_level)
222
+ return wal === 'logical'
223
+ } catch (error) {
224
+ throw new Error('Failed to check if WAL is enabled', { cause: error })
225
+ }
221
226
  }
@@ -1,4 +1,5 @@
1
1
  import { pgTable } from 'drizzle-orm/pg-core'
2
+
2
3
  import { address, bigint, bytea, hash, numeric78 } from '../column-types.ts'
3
4
 
4
5
  export const blocks = pgTable('blocks', {
@@ -1,5 +1,6 @@
1
1
  import { index, integer, jsonb, pgEnum, pgTable } from 'drizzle-orm/pg-core'
2
2
  import type { AccessList } from 'viem'
3
+
3
4
  import { address, bigint, bytea, hash, numeric78 } from '../column-types.ts'
4
5
 
5
6
  export const transactionTypeEnum = pgEnum('transaction_type', [
@@ -1,5 +1,7 @@
1
1
  import type { AnyRelations, EmptyRelations } from 'drizzle-orm/relations'
2
2
  import type { GetEventArgs, Log } from 'viem'
3
+
4
+ import type { InternalConfig } from '../config/config'
3
5
  import type { Database } from '../db/client'
4
6
  import type { EncodedBlockWithTransactions, EncodedTransaction } from '../types'
5
7
  import type { Logger } from '../utils/logger'
@@ -105,3 +107,13 @@ export class HookRegistry<
105
107
  })
106
108
  }
107
109
  }
110
+
111
+ export function createRegistry({
112
+ config,
113
+ }: {
114
+ config: InternalConfig
115
+ }): HookRegistry {
116
+ const registry = new HookRegistry()
117
+ config.hooks({ registry })
118
+ return registry
119
+ }
@@ -40,7 +40,7 @@ export async function runBackfill(args: {
40
40
  }
41
41
 
42
42
  const batchSize = config.batchSize
43
- logger.debug(
43
+ logger.info(
44
44
  {
45
45
  fromBlock: cursor.toString(),
46
46
  toBlock: safeHead.toString(),
@@ -54,14 +54,6 @@ export async function runBackfill(args: {
54
54
  const toBlock = windowEnd(cursor, batchSize, safeHead)
55
55
  const windowContracts = filterContracts(config, cursor, toBlock)
56
56
 
57
- logger.debug(
58
- {
59
- batchFromBlock: cursor.toString(),
60
- batchToBlock: toBlock.toString(),
61
- streamCount: windowContracts.addresses.length,
62
- },
63
- 'processing backfill batch'
64
- )
65
57
  const batchBlockNumbers: bigint[] = []
66
58
  let blockNumber = cursor
67
59
  while (blockNumber <= toBlock) {
@@ -104,7 +96,7 @@ export async function runBackfill(args: {
104
96
  blockIndex += 1
105
97
  }
106
98
  })
107
- logger.info(
99
+ logger.debug(
108
100
  { duration: endClockBatch() },
109
101
  'batch block and events processed'
110
102
  )
@@ -118,6 +110,7 @@ export async function runBackfill(args: {
118
110
  {
119
111
  indexedUpTo: toBlock.toString(),
120
112
  duration: batchElapsedMs,
113
+ contracts: windowContracts.addresses.length,
121
114
  throughput: Number(blocksPerSecond.toFixed(2)),
122
115
  },
123
116
  'backfill batch completed'
@@ -7,7 +7,7 @@ import { runBackfill } from './backfill.ts'
7
7
  import { startLiveSync } from './live.ts'
8
8
  import { verifyRecentBlocks } from './reorg.ts'
9
9
 
10
- export async function bootstrapIndexer(options: {
10
+ export async function createIndexer(options: {
11
11
  logger: Logger
12
12
  db: Database<typeof schema, typeof relations>
13
13
  registry: HookRegistry
@@ -1,5 +1,6 @@
1
1
  import PQueue from 'p-queue'
2
2
  import type { PublicClient } from 'viem'
3
+
3
4
  import type { InternalConfig } from '../config/config.ts'
4
5
  import type { Database } from '../db/client.ts'
5
6
  import type { relations, schema } from '../db/schema/index.ts'
@@ -25,7 +26,7 @@ export function startLiveSync(args: {
25
26
  const contracts = config.contractsForLive
26
27
 
27
28
  if (contracts.length === 0) {
28
- logger.debug(
29
+ logger.info(
29
30
  'all configured contracts have endBlock set; live sync disabled'
30
31
  )
31
32
  return { stop: noop }
@@ -44,7 +45,7 @@ export function startLiveSync(args: {
44
45
  onBlockNumber: (head) => {
45
46
  while (nextBlockToQueue <= head) {
46
47
  const blockNumber = nextBlockToQueue
47
- pqueue.add(async () => {
48
+ void pqueue.add(async () => {
48
49
  await queueBlock({
49
50
  logger,
50
51
  blockNumber,
@@ -67,7 +68,7 @@ export function startLiveSync(args: {
67
68
  },
68
69
  })
69
70
 
70
- logger.debug(
71
+ logger.info(
71
72
  { startBlock: nextBlockToQueue.toString() },
72
73
  'watching latest chain head'
73
74
  )
@@ -1,4 +1,5 @@
1
1
  import type { AbiEvent, Log, PublicClient } from 'viem'
2
+
2
3
  import type { FilteredContracts, InternalConfig } from '../config/config.ts'
3
4
  import { cacheBlockAndTransactions } from '../db/actions/blocks.ts'
4
5
  import type { Database } from '../db/client.ts'
@@ -96,7 +97,7 @@ export async function processBlock(args: {
96
97
  const contractName = contracts.contractNameByAddress[log.address]
97
98
 
98
99
  if (!contractName) {
99
- logger.trace(
100
+ logger.debug(
100
101
  { address: log.address },
101
102
  'contract not found in contract name by address'
102
103
  )
@@ -110,7 +111,7 @@ export async function processBlock(args: {
110
111
  const transaction = transactionByHash.get(log.transactionHash)
111
112
 
112
113
  if (!transaction) {
113
- logger.trace(
114
+ logger.debug(
114
115
  { transactionHash: log.transactionHash },
115
116
 
116
117
  'transaction not found in block transaction list'
@@ -1,5 +1,6 @@
1
1
  import type { Logger } from 'pino'
2
2
  import type { PublicClient } from 'viem'
3
+
3
4
  import { filterContracts, type InternalConfig } from '../config/config.ts'
4
5
  import type { Database } from '../db/client.ts'
5
6
  import type { relations, schema } from '../db/schema/index.ts'
@@ -1,4 +1,5 @@
1
1
  import type { PublicClient } from 'viem'
2
+
2
3
  import { deleteBlocksFrom } from '../db/actions/blocks.ts'
3
4
  import type { Database } from '../db/client.ts'
4
5
  import { safeGetBlock } from '../rpc/get-block.ts'
package/src/rpc/client.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  import { createPublicClient, type PublicClient } from 'viem'
2
+
2
3
  import type { ClientConfig } from '../config/config.ts'
3
4
 
4
5
  export type RpcClients = {
@@ -1,4 +1,5 @@
1
1
  import type { Hash, PublicClient } from 'viem'
2
+
2
3
  import type { Database } from '../db/client.ts'
3
4
  import {
4
5
  encodeBlockWithTransactions,
@@ -1,4 +1,5 @@
1
1
  import type { AbiEvent, Address, Log, PublicClient } from 'viem'
2
+
2
3
  import type { Logger } from '../utils/logger.ts'
3
4
  import { startClock } from '../utils/timer.ts'
4
5
 
@@ -27,7 +28,7 @@ export async function getLogsInRange(args: {
27
28
  byBlock.push(log)
28
29
  logsByBlock.set(log.blockNumber, byBlock)
29
30
  }
30
- logger.info(
31
+ logger.trace(
31
32
  {
32
33
  logs: logsByBlock.size,
33
34
  duration: endClock(),
package/src/types.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  import type { Simplify } from 'type-fest'
2
2
  import type { Block, Transaction } from 'viem'
3
+
3
4
  import type { Schema } from './db/schema/index'
4
5
  /**
5
6
  * Generic result with error
@@ -3,6 +3,7 @@ import type { DestinationStream, LevelWithSilent } from 'pino'
3
3
  import pino from 'pino'
4
4
  import type { Simplify } from 'type-fest'
5
5
  import { stringify } from 'viem'
6
+
6
7
  import { formatLogDuration } from './format.ts'
7
8
 
8
9
  export type LogMode = 'pretty' | 'json'
@@ -47,9 +48,6 @@ export function createLogger({
47
48
  } else {
48
49
  logger = pino({
49
50
  level,
50
- serializers: {
51
- error: errorSerializer,
52
- },
53
51
  // Removes "pid" and "hostname" properties from the log.
54
52
  base: undefined,
55
53
  })
@@ -8,15 +8,16 @@ export function createExit({
8
8
  logger: Logger
9
9
  stop: () => Promise<void>
10
10
  }) {
11
+ registerUnhandled({ logger })
11
12
  asyncExitHook(
12
13
  async () => {
13
14
  logger.warn('shutting down...')
14
15
  await stop()
15
16
  logger.info('shutdown complete')
16
- process.exit(0)
17
+ // process.exit(0)
17
18
  },
18
19
  {
19
- wait: 300,
20
+ wait: 1000,
20
21
  }
21
22
  )
22
23
  }
@@ -1,4 +1,5 @@
1
1
  import type { Abi, ExtractAbiEvent, ExtractAbiEventNames } from 'abitype'
2
+
2
3
  import type { UnknownObject } from '../types'
3
4
 
4
5
  export type EnsureUniqueTuple<
@@ -1,22 +1,24 @@
1
1
  {
2
2
  "name": "foxer-repo",
3
3
  "version": "0.0.0",
4
- "description": "",
5
- "main": "index.js",
6
4
  "private": true,
5
+ "description": "",
6
+ "keywords": [],
7
+ "license": "MIT",
7
8
  "workspaces": [
8
9
  "apps/*",
9
10
  "packages/*"
10
11
  ],
12
+ "main": "index.js",
11
13
  "scripts": {
12
14
  "test": "echo \"Error: no test specified\" && exit 1",
13
- "lint": "pnpm -r --if-present run lint",
14
- "build": "pnpm -r --if-present run build",
15
- "lint:fix": "biome check --write ."
15
+ "check": "turbo run check",
16
+ "build": "turbo run build",
17
+ "lint": "biome check ."
16
18
  },
17
- "keywords": [],
18
- "license": "MIT",
19
19
  "devDependencies": {
20
- "@biomejs/biome": "^2.4.5"
20
+ "@biomejs/biome": "^2.4.7",
21
+ "@hugomrdias/configs": "^1.1.3",
22
+ "turbo": "^2.8.17"
21
23
  }
22
24
  }