ponder 0.14.13 → 0.15.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 (237) hide show
  1. package/CHANGELOG.md +16 -0
  2. package/dist/esm/bin/commands/createViews.js +28 -11
  3. package/dist/esm/bin/commands/createViews.js.map +1 -1
  4. package/dist/esm/bin/commands/dev.js +42 -22
  5. package/dist/esm/bin/commands/dev.js.map +1 -1
  6. package/dist/esm/bin/commands/prune.js +3 -0
  7. package/dist/esm/bin/commands/prune.js.map +1 -1
  8. package/dist/esm/bin/commands/serve.js +4 -1
  9. package/dist/esm/bin/commands/serve.js.map +1 -1
  10. package/dist/esm/bin/commands/start.js +18 -6
  11. package/dist/esm/bin/commands/start.js.map +1 -1
  12. package/dist/esm/bin/isolatedController.js +200 -0
  13. package/dist/esm/bin/isolatedController.js.map +1 -0
  14. package/dist/esm/bin/isolatedWorker.js +146 -0
  15. package/dist/esm/bin/isolatedWorker.js.map +1 -0
  16. package/dist/esm/build/config.js +322 -402
  17. package/dist/esm/build/config.js.map +1 -1
  18. package/dist/esm/build/index.js +8 -11
  19. package/dist/esm/build/index.js.map +1 -1
  20. package/dist/esm/build/pre.js +1 -4
  21. package/dist/esm/build/pre.js.map +1 -1
  22. package/dist/esm/build/schema.js +25 -3
  23. package/dist/esm/build/schema.js.map +1 -1
  24. package/dist/esm/client/index.js +306 -42
  25. package/dist/esm/client/index.js.map +1 -1
  26. package/dist/esm/database/actions.js +264 -104
  27. package/dist/esm/database/actions.js.map +1 -1
  28. package/dist/esm/database/index.js +39 -33
  29. package/dist/esm/database/index.js.map +1 -1
  30. package/dist/esm/database/queryBuilder.js +1 -0
  31. package/dist/esm/database/queryBuilder.js.map +1 -1
  32. package/dist/esm/drizzle/index.js +11 -7
  33. package/dist/esm/drizzle/index.js.map +1 -1
  34. package/dist/esm/drizzle/onchain.js +18 -0
  35. package/dist/esm/drizzle/onchain.js.map +1 -1
  36. package/dist/esm/indexing/client.js +32 -25
  37. package/dist/esm/indexing/client.js.map +1 -1
  38. package/dist/esm/indexing/index.js +110 -178
  39. package/dist/esm/indexing/index.js.map +1 -1
  40. package/dist/esm/indexing/profile.js +1 -1
  41. package/dist/esm/indexing/profile.js.map +1 -1
  42. package/dist/esm/indexing-store/cache.js +196 -274
  43. package/dist/esm/indexing-store/cache.js.map +1 -1
  44. package/dist/esm/indexing-store/historical.js +17 -13
  45. package/dist/esm/indexing-store/historical.js.map +1 -1
  46. package/dist/esm/indexing-store/index.js +10 -1
  47. package/dist/esm/indexing-store/index.js.map +1 -1
  48. package/dist/esm/indexing-store/profile.js +3 -3
  49. package/dist/esm/indexing-store/profile.js.map +1 -1
  50. package/dist/esm/indexing-store/realtime.js +27 -2
  51. package/dist/esm/indexing-store/realtime.js.map +1 -1
  52. package/dist/esm/internal/errors.js +28 -0
  53. package/dist/esm/internal/errors.js.map +1 -1
  54. package/dist/esm/internal/metrics.js +279 -82
  55. package/dist/esm/internal/metrics.js.map +1 -1
  56. package/dist/esm/internal/options.js +1 -0
  57. package/dist/esm/internal/options.js.map +1 -1
  58. package/dist/esm/internal/telemetry.js +1 -1
  59. package/dist/esm/internal/telemetry.js.map +1 -1
  60. package/dist/esm/rpc/http.js +130 -0
  61. package/dist/esm/rpc/http.js.map +1 -0
  62. package/dist/esm/rpc/index.js +38 -7
  63. package/dist/esm/rpc/index.js.map +1 -1
  64. package/dist/esm/runtime/events.js +179 -212
  65. package/dist/esm/runtime/events.js.map +1 -1
  66. package/dist/esm/runtime/filter.js +71 -0
  67. package/dist/esm/runtime/filter.js.map +1 -1
  68. package/dist/esm/runtime/fragments.js +78 -73
  69. package/dist/esm/runtime/fragments.js.map +1 -1
  70. package/dist/esm/runtime/historical.js +306 -130
  71. package/dist/esm/runtime/historical.js.map +1 -1
  72. package/dist/esm/runtime/index.js +183 -58
  73. package/dist/esm/runtime/index.js.map +1 -1
  74. package/dist/esm/runtime/isolated.js +462 -0
  75. package/dist/esm/runtime/isolated.js.map +1 -0
  76. package/dist/esm/runtime/multichain.js +80 -73
  77. package/dist/esm/runtime/multichain.js.map +1 -1
  78. package/dist/esm/runtime/omnichain.js +82 -75
  79. package/dist/esm/runtime/omnichain.js.map +1 -1
  80. package/dist/esm/runtime/realtime.js +198 -66
  81. package/dist/esm/runtime/realtime.js.map +1 -1
  82. package/dist/esm/sync-historical/index.js +416 -457
  83. package/dist/esm/sync-historical/index.js.map +1 -1
  84. package/dist/esm/sync-realtime/bloom.js +3 -3
  85. package/dist/esm/sync-realtime/bloom.js.map +1 -1
  86. package/dist/esm/sync-realtime/index.js +27 -46
  87. package/dist/esm/sync-realtime/index.js.map +1 -1
  88. package/dist/esm/sync-store/index.js +112 -63
  89. package/dist/esm/sync-store/index.js.map +1 -1
  90. package/dist/esm/utils/abi.js +20 -32
  91. package/dist/esm/utils/abi.js.map +1 -1
  92. package/dist/esm/utils/chunk.js +8 -0
  93. package/dist/esm/utils/chunk.js.map +1 -0
  94. package/dist/esm/utils/promiseAllSettledWithThrow.js +19 -0
  95. package/dist/esm/utils/promiseAllSettledWithThrow.js.map +1 -0
  96. package/dist/esm/{client/parse.js → utils/sql-parse.js} +94 -80
  97. package/dist/esm/utils/sql-parse.js.map +1 -0
  98. package/dist/types/bin/commands/createViews.d.ts.map +1 -1
  99. package/dist/types/bin/commands/dev.d.ts.map +1 -1
  100. package/dist/types/bin/commands/prune.d.ts.map +1 -1
  101. package/dist/types/bin/commands/serve.d.ts.map +1 -1
  102. package/dist/types/bin/commands/start.d.ts.map +1 -1
  103. package/dist/types/bin/isolatedController.d.ts +13 -0
  104. package/dist/types/bin/isolatedController.d.ts.map +1 -0
  105. package/dist/types/bin/isolatedWorker.d.ts +9 -0
  106. package/dist/types/bin/isolatedWorker.d.ts.map +1 -0
  107. package/dist/types/build/config.d.ts +29 -11
  108. package/dist/types/build/config.d.ts.map +1 -1
  109. package/dist/types/build/index.d.ts +3 -2
  110. package/dist/types/build/index.d.ts.map +1 -1
  111. package/dist/types/build/pre.d.ts +1 -1
  112. package/dist/types/build/pre.d.ts.map +1 -1
  113. package/dist/types/build/schema.d.ts +5 -3
  114. package/dist/types/build/schema.d.ts.map +1 -1
  115. package/dist/types/client/index.d.ts +1 -1
  116. package/dist/types/client/index.d.ts.map +1 -1
  117. package/dist/types/config/index.d.ts +3 -3
  118. package/dist/types/config/index.d.ts.map +1 -1
  119. package/dist/types/database/actions.d.ts +53 -7
  120. package/dist/types/database/actions.d.ts.map +1 -1
  121. package/dist/types/database/index.d.ts +21 -21
  122. package/dist/types/database/index.d.ts.map +1 -1
  123. package/dist/types/database/queryBuilder.d.ts.map +1 -1
  124. package/dist/types/drizzle/index.d.ts +4 -5
  125. package/dist/types/drizzle/index.d.ts.map +1 -1
  126. package/dist/types/drizzle/onchain.d.ts +6 -0
  127. package/dist/types/drizzle/onchain.d.ts.map +1 -1
  128. package/dist/types/indexing/client.d.ts.map +1 -1
  129. package/dist/types/indexing/index.d.ts +2 -5
  130. package/dist/types/indexing/index.d.ts.map +1 -1
  131. package/dist/types/indexing-store/cache.d.ts +3 -2
  132. package/dist/types/indexing-store/cache.d.ts.map +1 -1
  133. package/dist/types/indexing-store/historical.d.ts +2 -1
  134. package/dist/types/indexing-store/historical.d.ts.map +1 -1
  135. package/dist/types/indexing-store/index.d.ts +1 -0
  136. package/dist/types/indexing-store/index.d.ts.map +1 -1
  137. package/dist/types/indexing-store/realtime.d.ts +2 -1
  138. package/dist/types/indexing-store/realtime.d.ts.map +1 -1
  139. package/dist/types/internal/errors.d.ts +5 -0
  140. package/dist/types/internal/errors.d.ts.map +1 -1
  141. package/dist/types/internal/metrics.d.ts +21 -0
  142. package/dist/types/internal/metrics.d.ts.map +1 -1
  143. package/dist/types/internal/options.d.ts +2 -0
  144. package/dist/types/internal/options.d.ts.map +1 -1
  145. package/dist/types/internal/types.d.ts +66 -58
  146. package/dist/types/internal/types.d.ts.map +1 -1
  147. package/dist/types/rpc/http.d.ts +17 -0
  148. package/dist/types/rpc/http.d.ts.map +1 -0
  149. package/dist/types/rpc/index.d.ts.map +1 -1
  150. package/dist/types/runtime/events.d.ts +4 -4
  151. package/dist/types/runtime/events.d.ts.map +1 -1
  152. package/dist/types/runtime/filter.d.ts +5 -1
  153. package/dist/types/runtime/filter.d.ts.map +1 -1
  154. package/dist/types/runtime/fragments.d.ts +4 -3
  155. package/dist/types/runtime/fragments.d.ts.map +1 -1
  156. package/dist/types/runtime/historical.d.ts +29 -13
  157. package/dist/types/runtime/historical.d.ts.map +1 -1
  158. package/dist/types/runtime/index.d.ts +49 -6
  159. package/dist/types/runtime/index.d.ts.map +1 -1
  160. package/dist/types/runtime/init.d.ts +5 -5
  161. package/dist/types/runtime/init.d.ts.map +1 -1
  162. package/dist/types/runtime/isolated.d.ts +14 -0
  163. package/dist/types/runtime/isolated.d.ts.map +1 -0
  164. package/dist/types/runtime/multichain.d.ts.map +1 -1
  165. package/dist/types/runtime/omnichain.d.ts.map +1 -1
  166. package/dist/types/runtime/realtime.d.ts +21 -10
  167. package/dist/types/runtime/realtime.d.ts.map +1 -1
  168. package/dist/types/sync-historical/index.d.ts +18 -8
  169. package/dist/types/sync-historical/index.d.ts.map +1 -1
  170. package/dist/types/sync-realtime/bloom.d.ts.map +1 -1
  171. package/dist/types/sync-realtime/index.d.ts +2 -2
  172. package/dist/types/sync-realtime/index.d.ts.map +1 -1
  173. package/dist/types/sync-store/index.d.ts +9 -9
  174. package/dist/types/sync-store/index.d.ts.map +1 -1
  175. package/dist/types/utils/abi.d.ts +3 -34
  176. package/dist/types/utils/abi.d.ts.map +1 -1
  177. package/dist/types/utils/chunk.d.ts +2 -0
  178. package/dist/types/utils/chunk.d.ts.map +1 -0
  179. package/dist/types/utils/promiseAllSettledWithThrow.d.ts +8 -0
  180. package/dist/types/utils/promiseAllSettledWithThrow.d.ts.map +1 -0
  181. package/dist/types/utils/sql-parse.d.ts +21 -0
  182. package/dist/types/utils/sql-parse.d.ts.map +1 -0
  183. package/package.json +2 -2
  184. package/src/bin/commands/createViews.ts +35 -15
  185. package/src/bin/commands/dev.ts +43 -21
  186. package/src/bin/commands/prune.ts +6 -0
  187. package/src/bin/commands/serve.ts +4 -1
  188. package/src/bin/commands/start.ts +20 -5
  189. package/src/bin/isolatedController.ts +300 -0
  190. package/src/bin/isolatedWorker.ts +192 -0
  191. package/src/build/config.ts +570 -632
  192. package/src/build/index.ts +14 -14
  193. package/src/build/pre.ts +1 -4
  194. package/src/build/schema.ts +49 -4
  195. package/src/client/index.ts +386 -48
  196. package/src/config/index.ts +3 -3
  197. package/src/database/actions.ts +469 -120
  198. package/src/database/index.ts +85 -58
  199. package/src/database/queryBuilder.ts +1 -0
  200. package/src/drizzle/index.ts +15 -7
  201. package/src/drizzle/onchain.ts +19 -0
  202. package/src/indexing/client.ts +38 -25
  203. package/src/indexing/index.ts +137 -230
  204. package/src/indexing/profile.ts +1 -1
  205. package/src/indexing-store/cache.ts +285 -414
  206. package/src/indexing-store/historical.ts +20 -10
  207. package/src/indexing-store/index.ts +16 -0
  208. package/src/indexing-store/profile.ts +3 -3
  209. package/src/indexing-store/realtime.ts +28 -0
  210. package/src/internal/errors.ts +26 -0
  211. package/src/internal/metrics.ts +341 -111
  212. package/src/internal/options.ts +4 -0
  213. package/src/internal/telemetry.ts +1 -1
  214. package/src/internal/types.ts +70 -87
  215. package/src/rpc/http.ts +164 -0
  216. package/src/rpc/index.ts +39 -7
  217. package/src/runtime/events.ts +195 -240
  218. package/src/runtime/filter.ts +85 -1
  219. package/src/runtime/fragments.ts +109 -113
  220. package/src/runtime/historical.ts +467 -189
  221. package/src/runtime/index.ts +337 -69
  222. package/src/runtime/init.ts +5 -5
  223. package/src/runtime/isolated.ts +768 -0
  224. package/src/runtime/multichain.ts +137 -102
  225. package/src/runtime/omnichain.ts +138 -106
  226. package/src/runtime/realtime.ts +322 -123
  227. package/src/sync-historical/index.ts +556 -692
  228. package/src/sync-realtime/bloom.ts +7 -3
  229. package/src/sync-realtime/index.ts +31 -46
  230. package/src/sync-store/index.ts +189 -95
  231. package/src/utils/abi.ts +33 -90
  232. package/src/utils/chunk.ts +7 -0
  233. package/src/utils/promiseAllSettledWithThrow.ts +27 -0
  234. package/src/{client/parse.ts → utils/sql-parse.ts} +100 -90
  235. package/dist/esm/client/parse.js.map +0 -1
  236. package/dist/types/client/parse.d.ts +0 -14
  237. package/dist/types/client/parse.d.ts.map +0 -1
@@ -11,7 +11,7 @@ import {
11
11
  } from "@/internal/errors.js";
12
12
  import type {
13
13
  Chain,
14
- ContractSource,
14
+ Contract,
15
15
  Event,
16
16
  Filter,
17
17
  IndexingBuild,
@@ -33,7 +33,6 @@ import {
33
33
  defaultTransactionInclude,
34
34
  defaultTransactionReceiptInclude,
35
35
  defaultTransferFilterInclude,
36
- isAddressFactory,
37
36
  requiredBlockFilterInclude,
38
37
  requiredLogFilterInclude,
39
38
  requiredTraceFilterInclude,
@@ -85,9 +84,7 @@ export type Context = {
85
84
  };
86
85
 
87
86
  export type Indexing = {
88
- processSetupEvents: (params: {
89
- db: IndexingStore;
90
- }) => Promise<void>;
87
+ processSetupEvents: (params: { db: IndexingStore }) => Promise<void>;
91
88
  processHistoricalEvents: (params: {
92
89
  events: Event[];
93
90
  db: IndexingStore;
@@ -104,7 +101,7 @@ export const getEventCount = (
104
101
  indexingFunctions: IndexingBuild["indexingFunctions"],
105
102
  ) => {
106
103
  const eventCount: { [eventName: string]: number } = {};
107
- for (const eventName of Object.keys(indexingFunctions)) {
104
+ for (const { name: eventName } of indexingFunctions) {
108
105
  eventCount[eventName] = 0;
109
106
  }
110
107
  return eventCount;
@@ -128,7 +125,7 @@ export const createColumnAccessPattern = ({
128
125
  }): ColumnAccessPattern => {
129
126
  const columnAccessPattern = new Map<string, ColumnAccessProfile>();
130
127
 
131
- for (const eventName of Object.keys(indexingBuild.indexingFunctions)) {
128
+ for (const { name: eventName } of indexingBuild.indexingFunctions) {
132
129
  columnAccessPattern.set(eventName, {
133
130
  block: new Set(),
134
131
  trace: new Set(),
@@ -144,19 +141,17 @@ export const createColumnAccessPattern = ({
144
141
 
145
142
  export const createIndexing = ({
146
143
  common,
147
- indexingBuild: { sources, chains, indexingFunctions },
144
+ indexingBuild: { eventCallbacks, setupCallbacks, chains, contracts },
148
145
  client,
149
- eventCount,
150
146
  indexingErrorHandler,
151
147
  columnAccessPattern,
152
148
  }: {
153
149
  common: Common;
154
150
  indexingBuild: Pick<
155
151
  IndexingBuild,
156
- "sources" | "chains" | "indexingFunctions"
152
+ "eventCallbacks" | "setupCallbacks" | "chains" | "contracts"
157
153
  >;
158
154
  client: CachedViemClient;
159
- eventCount: { [eventName: string]: number };
160
155
  indexingErrorHandler: IndexingErrorHandler;
161
156
  columnAccessPattern: ColumnAccessPattern;
162
157
  }): Indexing => {
@@ -167,93 +162,41 @@ export const createIndexing = ({
167
162
  db: undefined!,
168
163
  };
169
164
 
170
- const chainById: { [chainId: number]: Chain } = {};
171
165
  const clientByChainId: { [chainId: number]: ReadonlyClient } = {};
172
166
  const contractsByChainId: {
173
- [chainId: number]: Record<
174
- string,
175
- {
176
- abi: Abi;
177
- address?: Address | readonly Address[];
178
- startBlock?: number;
179
- endBlock?: number;
180
- }
181
- >;
167
+ [chainId: number]: { [name: string]: Contract };
182
168
  } = {};
183
169
 
184
- // build chainById
185
- for (const chain of chains) {
186
- chainById[chain.id] = chain;
187
- }
188
-
189
170
  // build clientByChainId
190
171
  for (const chain of chains) {
191
172
  clientByChainId[chain.id] = client.getClient(chain);
192
173
  }
193
174
 
194
- // build contractsByChainId
195
- for (const source of sources) {
196
- if (source.type === "block" || source.type === "account") continue;
197
-
198
- let address: Address | undefined;
199
-
200
- if (source.filter.type === "log") {
201
- const _address = source.filter.address;
202
- if (
203
- isAddressFactory(_address) === false &&
204
- Array.isArray(_address) === false &&
205
- _address !== undefined
206
- ) {
207
- address = _address as Address;
208
- }
209
- } else {
210
- const _address = source.filter.toAddress;
211
- if (isAddressFactory(_address) === false && _address !== undefined) {
212
- address = (_address as Address[])[0];
213
- }
214
- }
215
-
216
- if (contractsByChainId[source.filter.chainId] === undefined) {
217
- contractsByChainId[source.filter.chainId] = {};
218
- }
219
-
220
- // Note: multiple sources with the same contract (logs and traces)
221
- // should only create one entry in the `contracts` object
222
- if (contractsByChainId[source.filter.chainId]![source.name] !== undefined)
223
- continue;
224
-
225
- contractsByChainId[source.filter.chainId]![source.name] = {
226
- abi: source.abi,
227
- address,
228
- startBlock: source.filter.fromBlock,
229
- endBlock: source.filter.toBlock,
230
- };
175
+ for (let i = 0; i < chains.length; i++) {
176
+ const chain = chains[i]!;
177
+ contractsByChainId[chain.id] = contracts[i]!;
231
178
  }
232
179
 
233
- const updateCompletedEvents = () => {
234
- for (const event of Object.keys(eventCount)) {
235
- const metricLabel = { event };
236
- common.metrics.ponder_indexing_completed_events.set(
237
- metricLabel,
238
- eventCount[event]!,
239
- );
240
- }
241
- };
242
-
243
- const executeSetup = async ({
244
- event,
245
- }: { event: SetupEvent }): Promise<void> => {
246
- const indexingFunction = indexingFunctions[event.name];
247
- const metricLabel = { event: event.name };
180
+ const executeSetup = async (event: SetupEvent): Promise<void> => {
181
+ const metricLabel = { event: event.setupCallback.name };
248
182
 
249
183
  try {
250
- context.chain.id = event.chainId;
251
- context.chain.name = chainById[event.chainId]!.name;
252
- context.contracts = contractsByChainId[event.chainId]!;
184
+ context.chain.id = event.chain.id;
185
+ context.chain.name = event.chain.name;
186
+ context.contracts = contractsByChainId[event.chain.id]!;
253
187
 
254
188
  const endClock = startClock();
255
189
 
256
- await indexingFunction!({ context });
190
+ await event.setupCallback.fn({ context });
191
+
192
+ // Note: Check `getRetryableError` to handle user-code catching errors
193
+ // from the indexing store.
194
+
195
+ if (indexingErrorHandler.getRetryableError()) {
196
+ const retryableError = indexingErrorHandler.getRetryableError()!;
197
+ indexingErrorHandler.clearRetryableError();
198
+ throw retryableError;
199
+ }
257
200
 
258
201
  common.metrics.ponder_indexing_function_duration.observe(
259
202
  metricLabel,
@@ -268,7 +211,7 @@ export const createIndexing = ({
268
211
  if (indexingErrorHandler.getRetryableError()) {
269
212
  const retryableError = indexingErrorHandler.getRetryableError()!;
270
213
  indexingErrorHandler.clearRetryableError();
271
- throw retryableError;
214
+ error = retryableError;
272
215
  }
273
216
 
274
217
  if (common.shutdown.isKilled) {
@@ -281,9 +224,9 @@ export const createIndexing = ({
281
224
  const decodedCheckpoint = decodeCheckpoint(event.checkpoint);
282
225
  common.logger.error({
283
226
  msg: "Error while processing event",
284
- event: event.name,
285
- chain: chainById[event.chainId]!.name,
286
- chain_id: event.chainId,
227
+ event: event.setupCallback.name,
228
+ chain: event.chain.name,
229
+ chain_id: event.chain.id,
287
230
  block_number: decodedCheckpoint.blockNumber,
288
231
  error,
289
232
  });
@@ -296,35 +239,34 @@ export const createIndexing = ({
296
239
 
297
240
  throw error;
298
241
  }
299
-
300
- // Note: Check `getRetryableError` to handle user-code catching errors
301
- // from the indexing store.
302
-
303
- if (indexingErrorHandler.getRetryableError()) {
304
- const retryableError = indexingErrorHandler.getRetryableError()!;
305
- indexingErrorHandler.clearRetryableError();
306
- throw retryableError;
307
- }
308
242
  };
309
243
 
310
244
  // metric label for "ponder_indexing_function_duration"
311
245
  const executeEvent = async (event: Event): Promise<void> => {
312
- const indexingFunction = indexingFunctions[event.name];
313
- const metricLabel: { event: string } = { event: event.name };
246
+ const metricLabel: { event: string } = { event: event.eventCallback.name };
314
247
 
315
248
  try {
316
- context.chain.id = event.chainId;
317
- context.chain.name = chainById[event.chainId]!.name;
318
- context.contracts = contractsByChainId[event.chainId]!;
249
+ context.chain.id = event.chain.id;
250
+ context.chain.name = event.chain.name;
251
+ context.contracts = contractsByChainId[event.chain.id]!;
319
252
 
320
253
  const endClock = startClock();
321
254
 
322
- await indexingFunction!({ event: event.event, context });
255
+ await event.eventCallback.fn({ event: event.event, context });
323
256
 
324
257
  common.metrics.ponder_indexing_function_duration.observe(
325
258
  metricLabel,
326
259
  endClock(),
327
260
  );
261
+
262
+ // Note: Check `getRetryableError` to handle user-code catching errors
263
+ // from the indexing store.
264
+
265
+ if (indexingErrorHandler.getRetryableError()) {
266
+ const retryableError = indexingErrorHandler.getRetryableError()!;
267
+ indexingErrorHandler.clearRetryableError();
268
+ throw retryableError;
269
+ }
328
270
  } catch (_error) {
329
271
  let error = _error instanceof Error ? _error : new Error(String(_error));
330
272
 
@@ -334,7 +276,7 @@ export const createIndexing = ({
334
276
  if (indexingErrorHandler.getRetryableError()) {
335
277
  const retryableError = indexingErrorHandler.getRetryableError()!;
336
278
  indexingErrorHandler.clearRetryableError();
337
- throw retryableError;
279
+ error = retryableError;
338
280
  }
339
281
 
340
282
  if (common.shutdown.isKilled) {
@@ -352,9 +294,9 @@ export const createIndexing = ({
352
294
 
353
295
  common.logger.error({
354
296
  msg: "Error while processing event",
355
- event: event.name,
356
- chain: chainById[event.chainId]!.name,
357
- chain_id: event.chainId,
297
+ event: event.eventCallback.name,
298
+ chain: event.chain.name,
299
+ chain_id: event.chain.id,
358
300
  block_number: decodedCheckpoint.blockNumber,
359
301
  error,
360
302
  });
@@ -367,15 +309,6 @@ export const createIndexing = ({
367
309
 
368
310
  throw error;
369
311
  }
370
-
371
- // Note: Check `getRetryableError` to handle user-code catching errors
372
- // from the indexing store.
373
-
374
- if (indexingErrorHandler.getRetryableError()) {
375
- const retryableError = indexingErrorHandler.getRetryableError()!;
376
- indexingErrorHandler.clearRetryableError();
377
- throw retryableError;
378
- }
379
312
  };
380
313
 
381
314
  const resetFilterInclude = (eventName: string) => {
@@ -456,74 +389,40 @@ export const createIndexing = ({
456
389
  );
457
390
  // Note: There is no `log` proxy because all log columns are required.
458
391
 
459
- // Note: Filters and indexing functions have a many-to-many relationship.
460
- const perFilterEventNames = new Map<Filter, string[]>();
392
+ // Note: Indexing functions map to one or more filters.
461
393
  const perEventFilters = new Map<string, Filter[]>();
462
394
  const isFilterResolved = new Map<Filter, boolean>();
463
- for (const eventName of Object.keys(indexingFunctions)) {
464
- let sourceName: string;
465
- if (eventName.includes(":")) {
466
- [sourceName] = eventName.split(":") as [string];
395
+ for (const eventCallback of eventCallbacks.flat()) {
396
+ if (perEventFilters.has(eventCallback.name) === false) {
397
+ perEventFilters.set(eventCallback.name, [eventCallback.filter]);
467
398
  } else {
468
- [sourceName] = eventName.split(".") as [string];
469
- }
470
-
471
- const _sources = sources.filter((s) => s.name === sourceName);
472
- for (const source of _sources) {
473
- if (perFilterEventNames.has(source.filter) === false) {
474
- perFilterEventNames.set(source.filter, []);
475
- }
476
- perFilterEventNames.get(source.filter)!.push(eventName);
399
+ perEventFilters.get(eventCallback.name)!.push(eventCallback.filter);
477
400
  }
478
- perEventFilters.set(
479
- eventName,
480
- _sources.map((s) => s.filter),
481
- );
482
- }
483
401
 
484
- for (const source of sources) {
485
- isFilterResolved.set(source.filter, false);
402
+ isFilterResolved.set(eventCallback.filter, false);
486
403
  }
487
404
 
488
405
  return {
489
406
  async processSetupEvents({ db }) {
490
407
  context.db = db;
491
- for (const eventName of Object.keys(indexingFunctions)) {
492
- if (!eventName.endsWith(":setup")) continue;
493
-
494
- const [contractName] = eventName.split(":");
495
-
496
- for (const chain of chains) {
497
- const source = sources.find(
498
- (s) =>
499
- s.type === "contract" &&
500
- s.name === contractName &&
501
- s.filter.chainId === chain.id,
502
- ) as ContractSource | undefined;
503
408
 
504
- if (source === undefined) continue;
409
+ for (const setupCallback of setupCallbacks.flat()) {
410
+ const event = {
411
+ type: "setup",
412
+ chain: setupCallback.chain,
413
+ setupCallback,
414
+ checkpoint: encodeCheckpoint({
415
+ ...ZERO_CHECKPOINT,
416
+ chainId: BigInt(setupCallback.chain.id),
417
+ blockNumber: BigInt(setupCallback.block ?? 0),
418
+ }),
419
+ block: BigInt(setupCallback.block ?? 0),
420
+ } satisfies SetupEvent;
505
421
 
506
- const event = {
507
- type: "setup",
508
- chainId: chain.id,
509
- checkpoint: encodeCheckpoint({
510
- ...ZERO_CHECKPOINT,
511
- chainId: BigInt(chain.id),
512
- blockNumber: BigInt(source.filter.fromBlock ?? 0),
513
- }),
514
-
515
- name: eventName,
516
-
517
- block: BigInt(source.filter.fromBlock ?? 0),
518
- } satisfies SetupEvent;
519
-
520
- client.event = event;
521
- context.client = clientByChainId[chain.id]!;
522
-
523
- eventCount[eventName]!++;
422
+ client.event = event;
423
+ context.client = clientByChainId[setupCallback.chain.id]!;
524
424
 
525
- await executeSetup({ event });
526
- }
425
+ await executeSetup(event);
527
426
  }
528
427
  },
529
428
  async processHistoricalEvents({
@@ -540,7 +439,7 @@ export const createIndexing = ({
540
439
  const event = events[i]!;
541
440
 
542
441
  client.event = event;
543
- context.client = clientByChainId[event.chainId]!;
442
+ context.client = clientByChainId[event.chain.id]!;
544
443
  cache.event = event;
545
444
 
546
445
  // Note: Create a new event object instead of mutuating the original one because
@@ -549,25 +448,25 @@ export const createIndexing = ({
549
448
 
550
449
  switch (event.type) {
551
450
  case "block": {
552
- blockProxy.eventName = event.name;
451
+ blockProxy.eventName = event.eventCallback.name;
553
452
  blockProxy.underlying = event.event.block as Block;
554
453
  proxyEvent.block = blockProxy.proxy;
555
454
 
556
455
  break;
557
456
  }
558
457
  case "transaction": {
559
- blockProxy.eventName = event.name;
458
+ blockProxy.eventName = event.eventCallback.name;
560
459
  blockProxy.underlying = event.event.block as Block;
561
460
  proxyEvent.block = blockProxy.proxy;
562
461
 
563
- transactionProxy.eventName = event.name;
462
+ transactionProxy.eventName = event.eventCallback.name;
564
463
  transactionProxy.underlying = event.event
565
464
  .transaction as Transaction;
566
465
  // @ts-expect-error
567
466
  proxyEvent.transaction = transactionProxy.proxy;
568
467
 
569
468
  if (event.event.transactionReceipt !== undefined) {
570
- transactionReceiptProxy.eventName = event.name;
469
+ transactionReceiptProxy.eventName = event.eventCallback.name;
571
470
  transactionReceiptProxy.underlying = event.event
572
471
  .transactionReceipt as TransactionReceipt;
573
472
  // @ts-expect-error
@@ -578,25 +477,25 @@ export const createIndexing = ({
578
477
  }
579
478
  case "trace":
580
479
  case "transfer": {
581
- blockProxy.eventName = event.name;
480
+ blockProxy.eventName = event.eventCallback.name;
582
481
  blockProxy.underlying = event.event.block as Block;
583
482
  proxyEvent.block = blockProxy.proxy;
584
483
 
585
- transactionProxy.eventName = event.name;
484
+ transactionProxy.eventName = event.eventCallback.name;
586
485
  transactionProxy.underlying = event.event
587
486
  .transaction as Transaction;
588
487
  // @ts-expect-error
589
488
  proxyEvent.transaction = transactionProxy.proxy;
590
489
 
591
490
  if (event.event.transactionReceipt !== undefined) {
592
- transactionReceiptProxy.eventName = event.name;
491
+ transactionReceiptProxy.eventName = event.eventCallback.name;
593
492
  transactionReceiptProxy.underlying = event.event
594
493
  .transactionReceipt as TransactionReceipt;
595
494
  // @ts-expect-error
596
495
  proxyEvent.transactionReceipt = transactionReceiptProxy.proxy;
597
496
  }
598
497
 
599
- traceProxy.eventName = event.name;
498
+ traceProxy.eventName = event.eventCallback.name;
600
499
  traceProxy.underlying = event.event.trace as Trace;
601
500
  // @ts-expect-error
602
501
  proxyEvent.trace = traceProxy.proxy;
@@ -604,12 +503,12 @@ export const createIndexing = ({
604
503
  break;
605
504
  }
606
505
  case "log": {
607
- blockProxy.eventName = event.name;
506
+ blockProxy.eventName = event.eventCallback.name;
608
507
  blockProxy.underlying = event.event.block as Block;
609
508
  proxyEvent.block = blockProxy.proxy;
610
509
 
611
510
  if (event.event.transaction !== undefined) {
612
- transactionProxy.eventName = event.name;
511
+ transactionProxy.eventName = event.eventCallback.name;
613
512
  transactionProxy.underlying = event.event
614
513
  .transaction as Transaction;
615
514
  // @ts-expect-error
@@ -617,7 +516,7 @@ export const createIndexing = ({
617
516
  }
618
517
 
619
518
  if (event.event.transactionReceipt !== undefined) {
620
- transactionReceiptProxy.eventName = event.name;
519
+ transactionReceiptProxy.eventName = event.eventCallback.name;
621
520
  transactionReceiptProxy.underlying = event.event
622
521
  .transactionReceipt as TransactionReceipt;
623
522
  // @ts-expect-error
@@ -631,8 +530,11 @@ export const createIndexing = ({
631
530
  // @ts-expect-error
632
531
  await executeEvent({ ...event, event: proxyEvent });
633
532
 
634
- eventCount[event.name]!++;
635
- columnAccessPattern.get(event.name)!.count++;
533
+ common.metrics.ponder_indexing_completed_events.inc(
534
+ { event: event.eventCallback.name },
535
+ 1,
536
+ );
537
+ columnAccessPattern.get(event.eventCallback.name)!.count++;
636
538
 
637
539
  const now = performance.now();
638
540
 
@@ -643,55 +545,48 @@ export const createIndexing = ({
643
545
 
644
546
  if (now - lastMetricsUpdate > METRICS_UPDATE_INTERVAL) {
645
547
  lastMetricsUpdate = now;
646
- updateCompletedEvents();
647
- updateIndexingSeconds(event, chainById[event.chainId]!);
548
+ updateIndexingSeconds(event, event.chain);
648
549
  }
649
550
  }
650
551
 
651
552
  let isEveryFilterResolvedBefore = true;
652
553
  let isEveryFilterResolvedAfter = true;
653
554
 
654
- for (const source of sources) {
655
- const eventNames = perFilterEventNames.get(source.filter)!;
656
-
657
- if (isFilterResolved.get(source.filter)) continue;
555
+ for (const eventCallback of eventCallbacks.flat()) {
556
+ if (isFilterResolved.get(eventCallback.filter)) continue;
658
557
 
659
558
  isEveryFilterResolvedBefore = false;
660
559
 
661
- if (
662
- eventNames.some(
663
- (eventName) => columnAccessPattern.get(eventName)!.count < 100,
664
- )
665
- ) {
560
+ if (columnAccessPattern.get(eventCallback.name)!.count < 100) {
666
561
  isEveryFilterResolvedAfter = false;
667
562
  continue;
668
563
  }
669
- isFilterResolved.set(source.filter, true);
564
+ isFilterResolved.set(eventCallback.filter, true);
670
565
 
671
566
  const filterInclude: Filter["include"] = [];
672
567
 
673
- for (const eventName of eventNames) {
674
- const columnAccessProfile = columnAccessPattern.get(eventName)!;
675
- columnAccessProfile.resolved = true;
568
+ const columnAccessProfile = columnAccessPattern.get(
569
+ eventCallback.name,
570
+ )!;
571
+ columnAccessProfile.resolved = true;
676
572
 
677
- for (const column of columnAccessProfile.block) {
678
- filterInclude.push(`block.${column}` as const);
679
- }
680
- for (const column of columnAccessProfile.transaction) {
681
- // @ts-expect-error
682
- filterInclude.push(`transaction.${column}` as const);
683
- }
684
- for (const column of columnAccessProfile.transactionReceipt) {
685
- // @ts-expect-error
686
- filterInclude.push(`transactionReceipt.${column}` as const);
687
- }
688
- for (const column of columnAccessProfile.trace) {
689
- // @ts-expect-error
690
- filterInclude.push(`trace.${column}` as const);
691
- }
573
+ for (const column of columnAccessProfile.block) {
574
+ filterInclude.push(`block.${column}` as const);
575
+ }
576
+ for (const column of columnAccessProfile.transaction) {
577
+ // @ts-expect-error
578
+ filterInclude.push(`transaction.${column}` as const);
579
+ }
580
+ for (const column of columnAccessProfile.transactionReceipt) {
581
+ // @ts-expect-error
582
+ filterInclude.push(`transactionReceipt.${column}` as const);
583
+ }
584
+ for (const column of columnAccessProfile.trace) {
585
+ // @ts-expect-error
586
+ filterInclude.push(`trace.${column}` as const);
692
587
  }
693
588
 
694
- switch (source.filter.type) {
589
+ switch (eventCallback.filter.type) {
695
590
  case "block": {
696
591
  filterInclude.push(...requiredBlockFilterInclude);
697
592
  break;
@@ -704,34 +599,46 @@ export const createIndexing = ({
704
599
  case "trace": {
705
600
  // @ts-expect-error
706
601
  filterInclude.push(...requiredTraceFilterInclude);
707
- if (source.filter.hasTransactionReceipt) {
708
- // @ts-expect-error
709
- filterInclude.push(...requiredTransactionReceiptInclude);
602
+ if (eventCallback.filter.hasTransactionReceipt) {
603
+ filterInclude.push(
604
+ // @ts-expect-error
605
+ ...requiredTransactionReceiptInclude.map(
606
+ (value) => `transactionReceipt.${value}` as const,
607
+ ),
608
+ );
710
609
  }
711
610
  break;
712
611
  }
713
612
  case "log": {
714
613
  // @ts-expect-error
715
614
  filterInclude.push(...requiredLogFilterInclude);
716
- if (source.filter.hasTransactionReceipt) {
717
- // @ts-expect-error
718
- filterInclude.push(...requiredTransactionReceiptInclude);
615
+ if (eventCallback.filter.hasTransactionReceipt) {
616
+ filterInclude.push(
617
+ // @ts-expect-error
618
+ ...requiredTransactionReceiptInclude.map(
619
+ (value) => `transactionReceipt.${value}` as const,
620
+ ),
621
+ );
719
622
  }
720
623
  break;
721
624
  }
722
625
  case "transfer": {
723
626
  // @ts-expect-error
724
627
  filterInclude.push(...requiredTransferFilterInclude);
725
- if (source.filter.hasTransactionReceipt) {
726
- // @ts-expect-error
727
- filterInclude.push(...requiredTransactionReceiptInclude);
628
+ if (eventCallback.filter.hasTransactionReceipt) {
629
+ filterInclude.push(
630
+ // @ts-expect-error
631
+ ...requiredTransactionReceiptInclude.map(
632
+ (value) => `transactionReceipt.${value}` as const,
633
+ ),
634
+ );
728
635
  }
729
636
  break;
730
637
  }
731
638
  }
732
639
 
733
640
  // @ts-expect-error
734
- source.filter.include = dedupe(filterInclude);
641
+ eventCallback.filter.include = dedupe(filterInclude);
735
642
  }
736
643
 
737
644
  if (isEveryFilterResolvedBefore === false && isEveryFilterResolvedAfter) {
@@ -773,11 +680,10 @@ export const createIndexing = ({
773
680
  }
774
681
 
775
682
  await new Promise(setImmediate);
776
- updateCompletedEvents();
777
683
  if (events.length > 0) {
778
684
  updateIndexingSeconds(
779
685
  events[events.length - 1]!,
780
- chainById[events[events.length - 1]!.chainId]!,
686
+ events[events.length - 1]!.chain,
781
687
  );
782
688
  }
783
689
  },
@@ -787,14 +693,15 @@ export const createIndexing = ({
787
693
  const event = events[i]!;
788
694
 
789
695
  client.event = event;
790
- context.client = clientByChainId[event.chainId]!;
696
+ context.client = clientByChainId[event.chain.id]!;
791
697
 
792
- eventCount[event.name]!++;
698
+ common.metrics.ponder_indexing_completed_events.inc(
699
+ { event: event.eventCallback.name },
700
+ 1,
701
+ );
793
702
 
794
703
  await executeEvent(event);
795
704
  }
796
-
797
- updateCompletedEvents();
798
705
  },
799
706
  };
800
707
  };
@@ -766,6 +766,6 @@ export const recoverProfilePattern = (
766
766
  args,
767
767
  blockNumber:
768
768
  pattern.cache === "immutable" ? "latest" : event.event.block.number,
769
- chainId: event.chainId,
769
+ chainId: event.chain.id,
770
770
  };
771
771
  };