@apibara/indexer 2.1.0-beta.57 → 2.1.0-beta.59

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -115,8 +115,13 @@ async function runWithReconnect(client, indexer, options = {}) {
115
115
  const maxRetries = options.maxRetries ?? 10;
116
116
  const retryDelay = options.retryDelay ?? 1e3;
117
117
  const maxWait = options.maxWait ?? 3e4;
118
+ const { signal } = options;
118
119
  while (true) {
120
+ if (signal?.aborted)
121
+ return;
119
122
  const abortController = new AbortController();
123
+ const forwardAbort = () => abortController.abort(signal?.reason);
124
+ signal?.addEventListener("abort", forwardAbort, { once: true });
120
125
  const runOptions = {
121
126
  onConnect() {
122
127
  retryCount = 0;
@@ -125,11 +130,11 @@ async function runWithReconnect(client, indexer, options = {}) {
125
130
  };
126
131
  try {
127
132
  await run(client, indexer, runOptions);
128
- abortController.abort();
129
133
  return;
130
134
  } catch (error) {
131
135
  retryCount++;
132
- abortController.abort();
136
+ if (signal?.aborted)
137
+ return;
133
138
  if (error instanceof protocol.ClientError || error instanceof protocol.ServerError) {
134
139
  const isServerError = error instanceof protocol.ServerError;
135
140
  if (error.code === protocol.Status.INTERNAL) {
@@ -140,14 +145,27 @@ async function runWithReconnect(client, indexer, options = {}) {
140
145
  consola__default.start("Reconnecting...");
141
146
  console.log();
142
147
  const delay = Math.random() * (retryDelay * 0.2) + retryDelay;
143
- await new Promise(
144
- (resolve) => setTimeout(resolve, Math.min(retryCount * delay, maxWait))
145
- );
148
+ await new Promise((resolve) => {
149
+ const t = setTimeout(
150
+ resolve,
151
+ Math.min(retryCount * delay, maxWait)
152
+ );
153
+ signal?.addEventListener(
154
+ "abort",
155
+ () => {
156
+ clearTimeout(t);
157
+ resolve();
158
+ },
159
+ { once: true }
160
+ );
161
+ });
146
162
  continue;
147
163
  }
148
164
  }
149
165
  }
150
166
  throw error;
167
+ } finally {
168
+ signal?.removeEventListener("abort", forwardAbort);
151
169
  }
152
170
  }
153
171
  }
@@ -195,8 +213,19 @@ async function run(client, indexer, runOptions = {}) {
195
213
  let stream = client.streamData(request, options)[Symbol.asyncIterator]();
196
214
  await indexer.hooks.callHook("connect:after", { request, abortSignal });
197
215
  let onConnectCalled = false;
216
+ const abortPromise = abortSignal ? waitForAbort(abortSignal) : null;
198
217
  while (true) {
199
- const { value: message, done } = await stream.next();
218
+ let result;
219
+ try {
220
+ result = abortPromise ? await Promise.race([stream.next(), abortPromise]) : await stream.next();
221
+ } catch (e) {
222
+ if (abortSignal?.aborted) {
223
+ await stream.return?.();
224
+ break;
225
+ }
226
+ throw e;
227
+ }
228
+ const { value: message, done } = result;
200
229
  if (done) {
201
230
  break;
202
231
  }
@@ -353,6 +382,17 @@ async function run(client, indexer, runOptions = {}) {
353
382
  await indexer.hooks.callHook("run:after", { abortSignal });
354
383
  });
355
384
  }
385
+ function waitForAbort(signal) {
386
+ return new Promise((_, reject) => {
387
+ if (signal.aborted) {
388
+ reject(signal.reason);
389
+ return;
390
+ }
391
+ signal.addEventListener("abort", () => reject(signal.reason), {
392
+ once: true
393
+ });
394
+ });
395
+ }
356
396
  async function registerMiddleware(indexer, abortSignal) {
357
397
  const middleware = [];
358
398
  const use = (fn) => {
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs","sources":["../src/compose.ts","../src/otel.ts","../src/utils/index.ts","../src/indexer.ts"],"sourcesContent":["/*\n * MIT License\n *\n * Copyright (c) 2021 - present, Yusuke Wada and Hono contributors\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in all\n * copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n * SOFTWARE.\n */\n\nimport type { IndexerContext } from \"./context\";\n\nexport type NextFunction = () => Promise<void>;\nexport type MiddlewareFunction<C> = (\n context: C,\n next: NextFunction,\n) => Promise<void>;\n\nexport function compose<C extends IndexerContext>(\n middleware: MiddlewareFunction<C>[],\n): (context: C, next?: NextFunction) => Promise<void> {\n return (context, next) => {\n let index = -1;\n\n return dispatch(0);\n\n /// Dispatch the middleware functions.\n async function dispatch(i: number): Promise<void> {\n if (i <= index) {\n throw new Error(\"next() called multiple times\");\n }\n index = i;\n\n let handler: MiddlewareFunction<C> | undefined;\n\n if (i >= middleware.length) {\n if (next) {\n await next();\n }\n\n return;\n }\n\n if (middleware[i]) {\n handler = middleware[i];\n } else {\n handler = i === middleware.length ? next : undefined;\n }\n\n if (!handler) {\n throw new Error(\"Handler not found\");\n }\n\n await handler(context, () => dispatch(i + 1));\n }\n };\n}\n","import { metrics, trace } from \"@opentelemetry/api\";\n\nexport function createTracer() {\n return trace.getTracer(\"@apibara/indexer\");\n}\n\nexport function createIndexerMetrics() {\n const meter = metrics.getMeter(\"@apibara/indexer\");\n\n const currentBlockGauge = meter.createGauge(\"current_block\", {\n description: \"Current block number being processed\",\n unit: \"{block}\",\n });\n\n const processedBlockCounter = meter.createCounter(\"processed_blocks\", {\n description: \"Number of blocks processed\",\n unit: \"{blocks}\",\n });\n\n const reorgCounter = meter.createCounter(\"reorgs\", {\n description: \"Number of reorgs (invalidate messages) received\",\n unit: \"{reorgs}\",\n });\n\n return {\n currentBlockGauge,\n processedBlockCounter,\n reorgCounter,\n };\n}\n","import { useIndexerContext } from \"../context\";\n\nexport function reloadIndexer() {\n const context = useIndexerContext();\n context._reload = true;\n}\n\nexport function reloadIfNeeded() {\n const context = useIndexerContext();\n if (context._reload) {\n context._reload = false;\n throw new ReloadIndexerRequest();\n }\n}\n\nexport class ReloadIndexerRequest extends Error {\n constructor(message?: string) {\n super(message);\n this.name = \"ReloadIndexerRequest\";\n }\n}\n","import {\n type Client,\n ClientError,\n type CreateClientOptions,\n type Cursor,\n type DataFinality,\n type DataProduction,\n type Finalize,\n type Invalidate,\n ServerError,\n Status,\n type StreamConfig,\n type StreamDataOptions,\n type StreamDataRequest,\n type StreamDataResponse,\n type SystemMessage,\n} from \"@apibara/protocol\";\nimport consola from \"consola\";\nimport {\n type Hookable,\n type NestedHooks,\n createDebugger,\n createHooks,\n} from \"hookable\";\n\nimport assert from \"node:assert\";\nimport { type MiddlewareFunction, type NextFunction, compose } from \"./compose\";\nimport {\n type IndexerContext,\n indexerAsyncContext,\n useIndexerContext,\n} from \"./context\";\nimport { createIndexerMetrics, createTracer } from \"./otel\";\nimport type { IndexerPlugin } from \"./plugins\";\nimport { useInternalContext } from \"./plugins/context\";\nimport { reloadIfNeeded } from \"./utils\";\n\nexport type UseMiddlewareFunction = (\n fn: MiddlewareFunction<IndexerContext>,\n) => void;\n\nexport interface IndexerHooks<TFilter, TBlock> {\n \"plugins:init\": ({ abortSignal }: { abortSignal?: AbortSignal }) => void;\n \"run:before\": ({ abortSignal }: { abortSignal?: AbortSignal }) => void;\n \"run:after\": ({ abortSignal }: { abortSignal?: AbortSignal }) => void;\n \"connect:before\": ({\n request,\n options,\n }: {\n request: StreamDataRequest<TFilter>;\n options: StreamDataOptions;\n abortSignal?: AbortSignal;\n }) => void;\n \"connect:after\": ({\n request,\n }: {\n request: StreamDataRequest<TFilter>;\n abortSignal?: AbortSignal;\n }) => void;\n \"connect:factory\": ({\n request,\n endCursor,\n abortSignal,\n }: {\n request: StreamDataRequest<TFilter>;\n endCursor?: Cursor;\n abortSignal?: AbortSignal;\n }) => void;\n \"handler:middleware\": ({\n use,\n abortSignal,\n }: { use: UseMiddlewareFunction; abortSignal?: AbortSignal }) => void;\n message: ({\n message,\n abortSignal,\n }: {\n message: StreamDataResponse<TBlock>;\n abortSignal?: AbortSignal;\n }) => void;\n \"message:invalidate\": ({\n message,\n abortSignal,\n }: { message: Invalidate; abortSignal?: AbortSignal }) => void;\n \"message:finalize\": ({\n message,\n abortSignal,\n }: { message: Finalize; abortSignal?: AbortSignal }) => void;\n \"message:heartbeat\": ({ abortSignal }: { abortSignal?: AbortSignal }) => void;\n \"message:systemMessage\": ({\n message,\n abortSignal,\n }: { message: SystemMessage; abortSignal?: AbortSignal }) => void;\n}\n\nexport type IndexerStartingCursor =\n | {\n startingCursor?: never;\n startingBlock: bigint;\n }\n | {\n startingCursor: Cursor;\n startingBlock?: never;\n }\n | {\n startingCursor?: never;\n startingBlock?: never;\n };\n\nexport type HandlerArgs<TBlock> = {\n block: TBlock;\n cursor?: Cursor | undefined;\n endCursor?: Cursor | undefined;\n finality: DataFinality;\n production: DataProduction;\n context: IndexerContext;\n abortSignal?: AbortSignal;\n};\n\nexport type IndexerConfig<TFilter, TBlock> = {\n streamUrl: string;\n filter: TFilter;\n finality?: DataFinality;\n clientOptions?: CreateClientOptions;\n factory?: (args: HandlerArgs<TBlock>) => Promise<{\n filter?: TFilter;\n }>;\n transform: (args: HandlerArgs<TBlock>) => Promise<void>;\n hooks?: NestedHooks<IndexerHooks<TFilter, TBlock>>;\n plugins?: ReadonlyArray<IndexerPlugin<TFilter, TBlock>>;\n debug?: boolean;\n} & IndexerStartingCursor;\n\nexport type IndexerWithStreamConfig<TFilter, TBlock> = IndexerConfig<\n TFilter,\n TBlock\n> & {\n streamConfig: StreamConfig<TFilter, TBlock>;\n};\n\nexport function defineIndexer<TFilter, TBlock>(\n streamConfig: StreamConfig<TFilter, TBlock>,\n) {\n return (\n config: IndexerConfig<TFilter, TBlock>,\n ): IndexerWithStreamConfig<TFilter, TBlock> => ({\n streamConfig,\n ...config,\n });\n}\n\nexport interface Indexer<TFilter, TBlock> {\n streamConfig: StreamConfig<TFilter, TBlock>;\n options: IndexerConfig<TFilter, TBlock>;\n hooks: Hookable<IndexerHooks<TFilter, TBlock>>;\n}\n\nexport function createIndexer<TFilter, TBlock>({\n streamConfig,\n ...options\n}: IndexerWithStreamConfig<TFilter, TBlock>) {\n const indexer: Indexer<TFilter, TBlock> = {\n options,\n streamConfig,\n hooks: createHooks<IndexerHooks<TFilter, TBlock>>(),\n };\n\n if (indexer.options.debug) {\n createDebugger(indexer.hooks, { tag: \"indexer\" });\n }\n\n indexer.hooks.addHooks(indexer.options.hooks ?? {});\n\n for (const plugin of indexer.options.plugins ?? []) {\n plugin(indexer);\n }\n\n return indexer;\n}\n\nexport interface ReconnectOptions {\n maxRetries?: number;\n retryDelay?: number;\n maxWait?: number;\n}\n\nexport async function runWithReconnect<TFilter, TBlock>(\n client: Client<TFilter, TBlock>,\n indexer: Indexer<TFilter, TBlock>,\n options: ReconnectOptions = {},\n) {\n let retryCount = 0;\n\n const maxRetries = options.maxRetries ?? 10;\n const retryDelay = options.retryDelay ?? 1_000;\n const maxWait = options.maxWait ?? 30_000;\n\n while (true) {\n const abortController = new AbortController();\n\n const runOptions: RunOptions = {\n onConnect() {\n retryCount = 0;\n },\n abortSignal: abortController.signal,\n };\n\n try {\n await run(client, indexer, runOptions);\n abortController.abort();\n return;\n } catch (error) {\n // Only reconnect on internal/server errors.\n // All other errors should be rethrown.\n\n retryCount++;\n\n abortController.abort();\n\n if (error instanceof ClientError || error instanceof ServerError) {\n const isServerError = error instanceof ServerError;\n\n if (error.code === Status.INTERNAL) {\n if (retryCount < maxRetries) {\n consola.error(\n `Internal ${isServerError ? \"server\" : \"client\"} error: ${\n error.message\n }`,\n );\n consola.start(\"Reconnecting...\");\n console.log();\n\n // Add jitter to the retry delay to avoid all clients retrying at the same time.\n const delay = Math.random() * (retryDelay * 0.2) + retryDelay;\n await new Promise((resolve) =>\n setTimeout(resolve, Math.min(retryCount * delay, maxWait)),\n );\n\n continue;\n }\n }\n }\n throw error;\n }\n }\n}\n\nexport interface RunOptions {\n onConnect?: () => void | Promise<void>;\n abortSignal?: AbortSignal;\n}\n\nexport async function run<TFilter, TBlock>(\n client: Client<TFilter, TBlock>,\n indexer: Indexer<TFilter, TBlock>,\n runOptions: RunOptions = {},\n) {\n await indexerAsyncContext.callAsync({}, async () => {\n const context = useIndexerContext();\n\n if (indexer.options.debug) {\n context.debug = true;\n }\n\n const { abortSignal } = runOptions;\n\n await indexer.hooks.callHook(\"plugins:init\", { abortSignal });\n\n const middleware = await registerMiddleware(indexer, abortSignal);\n\n const indexerMetrics = createIndexerMetrics();\n const tracer = createTracer();\n\n await indexer.hooks.callHook(\"run:before\", { abortSignal });\n\n const { indexerName: indexerId } = useInternalContext();\n\n const isFactoryMode = indexer.options.factory !== undefined;\n\n // Give priority to startingCursor over startingBlock.\n let startingCursor: Cursor | undefined;\n if (indexer.options.startingCursor) {\n startingCursor = indexer.options.startingCursor;\n } else if (indexer.options.startingBlock !== undefined) {\n if (indexer.options.startingBlock === 0n) {\n startingCursor = undefined;\n } else if (indexer.options.startingBlock > 0n) {\n startingCursor = {\n orderKey: indexer.options.startingBlock - 1n,\n };\n }\n }\n\n // if factory mode we add a empty filter at the end of the filter array.\n const request = {\n filter: isFactoryMode\n ? [indexer.options.filter, {} as TFilter]\n : [indexer.options.filter],\n finality: indexer.options.finality,\n startingCursor,\n } as StreamDataRequest<TFilter>;\n\n const options: StreamDataOptions = {};\n\n await indexer.hooks.callHook(\"connect:before\", {\n request,\n options,\n abortSignal,\n });\n\n // store main filter, so later it can be merged\n let mainFilter: TFilter;\n if (isFactoryMode) {\n mainFilter = request.filter[1];\n }\n\n let stream: AsyncIterator<\n StreamDataResponse<TBlock>,\n StreamDataResponse<TBlock>\n > = client.streamData(request, options)[Symbol.asyncIterator]();\n\n await indexer.hooks.callHook(\"connect:after\", { request, abortSignal });\n\n let onConnectCalled = false;\n\n while (true) {\n const { value: message, done } = await stream.next();\n\n if (done) {\n break;\n }\n\n if (!onConnectCalled) {\n onConnectCalled = true;\n if (runOptions.onConnect) {\n await runOptions.onConnect();\n }\n }\n\n await indexer.hooks.callHook(\"message\", { message, abortSignal });\n\n switch (message._tag) {\n case \"data\": {\n await tracer.startActiveSpan(\"message data\", async (span) => {\n const blocks = message.data.data;\n const { cursor, endCursor, finality, production } = message.data;\n\n context.cursor = cursor;\n context.endCursor = endCursor;\n context.finality = finality;\n\n // Record current block number being processed\n indexerMetrics.currentBlockGauge.record(\n Number(endCursor?.orderKey),\n {\n indexer_id: indexerId,\n },\n );\n\n reloadIfNeeded();\n\n await middleware(context, async () => {\n let block: TBlock | null;\n\n // when factory mode\n if (isFactoryMode && finality !== \"pending\") {\n assert(indexer.options.factory !== undefined);\n\n const [factoryBlock, mainBlock] = blocks;\n\n block = mainBlock;\n\n if (factoryBlock !== null) {\n const { filter } = await indexer.options.factory({\n block: factoryBlock,\n cursor,\n endCursor,\n finality,\n production,\n context,\n abortSignal,\n });\n\n // write returned data from factory function if filter is not defined\n if (filter) {\n // when filter is defined\n // merge old and new filters\n mainFilter = indexer.streamConfig.mergeFilter(\n mainFilter,\n filter,\n );\n\n // create request with new filters\n const request = {\n filter: [indexer.options.filter, mainFilter],\n finality: indexer.options.finality,\n startingCursor: cursor,\n } as StreamDataRequest<TFilter>;\n\n await indexer.hooks.callHook(\"connect:factory\", {\n request,\n endCursor,\n abortSignal,\n });\n\n // create new stream with new request\n stream = client\n .streamData(request, options)\n [Symbol.asyncIterator]();\n\n const { value: message } = await stream.next();\n\n assert(message._tag === \"data\");\n\n const [_factoryBlock, _block] = message.data.data;\n\n block = _block;\n }\n }\n } else {\n // when not in factory mode\n block = blocks[0];\n }\n\n // if block is not null\n if (block) {\n await tracer.startActiveSpan(\"handler\", async (span) => {\n await indexer.options.transform({\n block,\n cursor,\n endCursor,\n finality,\n production,\n context,\n abortSignal,\n });\n\n span.end();\n });\n }\n });\n\n reloadIfNeeded();\n\n span.end();\n });\n\n // Record processed block metric\n indexerMetrics.processedBlockCounter.add(1, {\n indexer_id: indexerId,\n });\n\n context.cursor = undefined;\n context.endCursor = undefined;\n context.finality = undefined;\n\n break;\n }\n case \"invalidate\": {\n await tracer.startActiveSpan(\"message invalidate\", async (span) => {\n // Record reorg metric\n indexerMetrics.reorgCounter.add(1, {\n indexer_id: indexerId,\n });\n await indexer.hooks.callHook(\"message:invalidate\", {\n message: message.invalidate,\n abortSignal,\n });\n span.end();\n });\n break;\n }\n case \"finalize\": {\n await tracer.startActiveSpan(\"message finalize\", async (span) => {\n await indexer.hooks.callHook(\"message:finalize\", {\n message: message.finalize,\n abortSignal,\n });\n span.end();\n });\n break;\n }\n case \"heartbeat\": {\n await tracer.startActiveSpan(\"message heartbeat\", async (span) => {\n reloadIfNeeded();\n\n await indexer.hooks.callHook(\"message:heartbeat\", { abortSignal });\n reloadIfNeeded();\n\n span.end();\n });\n break;\n }\n case \"systemMessage\": {\n await tracer.startActiveSpan(\n \"message systemMessage\",\n async (span) => {\n switch (message.systemMessage.output?._tag) {\n case \"stderr\": {\n consola.warn(message.systemMessage.output.stderr);\n break;\n }\n case \"stdout\": {\n consola.info(message.systemMessage.output.stdout);\n break;\n }\n default: {\n }\n }\n\n await indexer.hooks.callHook(\"message:systemMessage\", {\n message: message.systemMessage,\n abortSignal,\n });\n span.end();\n },\n );\n break;\n }\n default: {\n consola.warn(\"unexpected message\", message);\n throw new Error(\"not implemented\");\n }\n }\n }\n\n await indexer.hooks.callHook(\"run:after\", { abortSignal });\n });\n}\n\nasync function registerMiddleware<TFilter, TBlock>(\n indexer: Indexer<TFilter, TBlock>,\n abortSignal?: AbortSignal,\n): Promise<MiddlewareFunction<IndexerContext>> {\n const middleware: MiddlewareFunction<IndexerContext>[] = [];\n const use = (fn: MiddlewareFunction<IndexerContext>) => {\n middleware.push(fn);\n };\n\n await indexer.hooks.callHook(\"handler:middleware\", { use, abortSignal });\n\n const composed = compose(middleware);\n\n // Return a named function to help debugging\n return async function _composedIndexerMiddleware(\n context: IndexerContext,\n next?: NextFunction,\n ) {\n await composed(context, next);\n };\n}\n"],"names":["trace","metrics","useIndexerContext","createHooks","createDebugger","ClientError","ServerError","Status","consola","indexerAsyncContext","useInternalContext","assert","request","message","span"],"mappings":"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"}
1
+ {"version":3,"file":"index.cjs","sources":["../src/compose.ts","../src/otel.ts","../src/utils/index.ts","../src/indexer.ts"],"sourcesContent":["/*\n * MIT License\n *\n * Copyright (c) 2021 - present, Yusuke Wada and Hono contributors\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in all\n * copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n * SOFTWARE.\n */\n\nimport type { IndexerContext } from \"./context\";\n\nexport type NextFunction = () => Promise<void>;\nexport type MiddlewareFunction<C> = (\n context: C,\n next: NextFunction,\n) => Promise<void>;\n\nexport function compose<C extends IndexerContext>(\n middleware: MiddlewareFunction<C>[],\n): (context: C, next?: NextFunction) => Promise<void> {\n return (context, next) => {\n let index = -1;\n\n return dispatch(0);\n\n /// Dispatch the middleware functions.\n async function dispatch(i: number): Promise<void> {\n if (i <= index) {\n throw new Error(\"next() called multiple times\");\n }\n index = i;\n\n let handler: MiddlewareFunction<C> | undefined;\n\n if (i >= middleware.length) {\n if (next) {\n await next();\n }\n\n return;\n }\n\n if (middleware[i]) {\n handler = middleware[i];\n } else {\n handler = i === middleware.length ? next : undefined;\n }\n\n if (!handler) {\n throw new Error(\"Handler not found\");\n }\n\n await handler(context, () => dispatch(i + 1));\n }\n };\n}\n","import { metrics, trace } from \"@opentelemetry/api\";\n\nexport function createTracer() {\n return trace.getTracer(\"@apibara/indexer\");\n}\n\nexport function createIndexerMetrics() {\n const meter = metrics.getMeter(\"@apibara/indexer\");\n\n const currentBlockGauge = meter.createGauge(\"current_block\", {\n description: \"Current block number being processed\",\n unit: \"{block}\",\n });\n\n const processedBlockCounter = meter.createCounter(\"processed_blocks\", {\n description: \"Number of blocks processed\",\n unit: \"{blocks}\",\n });\n\n const reorgCounter = meter.createCounter(\"reorgs\", {\n description: \"Number of reorgs (invalidate messages) received\",\n unit: \"{reorgs}\",\n });\n\n return {\n currentBlockGauge,\n processedBlockCounter,\n reorgCounter,\n };\n}\n","import { useIndexerContext } from \"../context\";\n\nexport function reloadIndexer() {\n const context = useIndexerContext();\n context._reload = true;\n}\n\nexport function reloadIfNeeded() {\n const context = useIndexerContext();\n if (context._reload) {\n context._reload = false;\n throw new ReloadIndexerRequest();\n }\n}\n\nexport class ReloadIndexerRequest extends Error {\n constructor(message?: string) {\n super(message);\n this.name = \"ReloadIndexerRequest\";\n }\n}\n","import {\n type Client,\n ClientError,\n type CreateClientOptions,\n type Cursor,\n type DataFinality,\n type DataProduction,\n type Finalize,\n type Invalidate,\n ServerError,\n Status,\n type StreamConfig,\n type StreamDataOptions,\n type StreamDataRequest,\n type StreamDataResponse,\n type SystemMessage,\n} from \"@apibara/protocol\";\nimport consola from \"consola\";\nimport {\n type Hookable,\n type NestedHooks,\n createDebugger,\n createHooks,\n} from \"hookable\";\n\nimport assert from \"node:assert\";\nimport { type MiddlewareFunction, type NextFunction, compose } from \"./compose\";\nimport {\n type IndexerContext,\n indexerAsyncContext,\n useIndexerContext,\n} from \"./context\";\nimport { createIndexerMetrics, createTracer } from \"./otel\";\nimport type { IndexerPlugin } from \"./plugins\";\nimport { useInternalContext } from \"./plugins/context\";\nimport { reloadIfNeeded } from \"./utils\";\n\nexport type UseMiddlewareFunction = (\n fn: MiddlewareFunction<IndexerContext>,\n) => void;\n\nexport interface IndexerHooks<TFilter, TBlock> {\n \"plugins:init\": ({ abortSignal }: { abortSignal?: AbortSignal }) => void;\n \"run:before\": ({ abortSignal }: { abortSignal?: AbortSignal }) => void;\n \"run:after\": ({ abortSignal }: { abortSignal?: AbortSignal }) => void;\n \"connect:before\": ({\n request,\n options,\n }: {\n request: StreamDataRequest<TFilter>;\n options: StreamDataOptions;\n abortSignal?: AbortSignal;\n }) => void;\n \"connect:after\": ({\n request,\n }: {\n request: StreamDataRequest<TFilter>;\n abortSignal?: AbortSignal;\n }) => void;\n \"connect:factory\": ({\n request,\n endCursor,\n abortSignal,\n }: {\n request: StreamDataRequest<TFilter>;\n endCursor?: Cursor;\n abortSignal?: AbortSignal;\n }) => void;\n \"handler:middleware\": ({\n use,\n abortSignal,\n }: { use: UseMiddlewareFunction; abortSignal?: AbortSignal }) => void;\n message: ({\n message,\n abortSignal,\n }: {\n message: StreamDataResponse<TBlock>;\n abortSignal?: AbortSignal;\n }) => void;\n \"message:invalidate\": ({\n message,\n abortSignal,\n }: { message: Invalidate; abortSignal?: AbortSignal }) => void;\n \"message:finalize\": ({\n message,\n abortSignal,\n }: { message: Finalize; abortSignal?: AbortSignal }) => void;\n \"message:heartbeat\": ({ abortSignal }: { abortSignal?: AbortSignal }) => void;\n \"message:systemMessage\": ({\n message,\n abortSignal,\n }: { message: SystemMessage; abortSignal?: AbortSignal }) => void;\n}\n\nexport type IndexerStartingCursor =\n | {\n startingCursor?: never;\n startingBlock: bigint;\n }\n | {\n startingCursor: Cursor;\n startingBlock?: never;\n }\n | {\n startingCursor?: never;\n startingBlock?: never;\n };\n\nexport type HandlerArgs<TBlock> = {\n block: TBlock;\n cursor?: Cursor | undefined;\n endCursor?: Cursor | undefined;\n finality: DataFinality;\n production: DataProduction;\n context: IndexerContext;\n abortSignal?: AbortSignal;\n};\n\nexport type IndexerConfig<TFilter, TBlock> = {\n streamUrl: string;\n filter: TFilter;\n finality?: DataFinality;\n clientOptions?: CreateClientOptions;\n factory?: (args: HandlerArgs<TBlock>) => Promise<{\n filter?: TFilter;\n }>;\n transform: (args: HandlerArgs<TBlock>) => Promise<void>;\n hooks?: NestedHooks<IndexerHooks<TFilter, TBlock>>;\n plugins?: ReadonlyArray<IndexerPlugin<TFilter, TBlock>>;\n debug?: boolean;\n} & IndexerStartingCursor;\n\nexport type IndexerWithStreamConfig<TFilter, TBlock> = IndexerConfig<\n TFilter,\n TBlock\n> & {\n streamConfig: StreamConfig<TFilter, TBlock>;\n};\n\nexport function defineIndexer<TFilter, TBlock>(\n streamConfig: StreamConfig<TFilter, TBlock>,\n) {\n return (\n config: IndexerConfig<TFilter, TBlock>,\n ): IndexerWithStreamConfig<TFilter, TBlock> => ({\n streamConfig,\n ...config,\n });\n}\n\nexport interface Indexer<TFilter, TBlock> {\n streamConfig: StreamConfig<TFilter, TBlock>;\n options: IndexerConfig<TFilter, TBlock>;\n hooks: Hookable<IndexerHooks<TFilter, TBlock>>;\n}\n\nexport function createIndexer<TFilter, TBlock>({\n streamConfig,\n ...options\n}: IndexerWithStreamConfig<TFilter, TBlock>) {\n const indexer: Indexer<TFilter, TBlock> = {\n options,\n streamConfig,\n hooks: createHooks<IndexerHooks<TFilter, TBlock>>(),\n };\n\n if (indexer.options.debug) {\n createDebugger(indexer.hooks, { tag: \"indexer\" });\n }\n\n indexer.hooks.addHooks(indexer.options.hooks ?? {});\n\n for (const plugin of indexer.options.plugins ?? []) {\n plugin(indexer);\n }\n\n return indexer;\n}\n\nexport interface ReconnectOptions {\n maxRetries?: number;\n retryDelay?: number;\n maxWait?: number;\n signal?: AbortSignal;\n}\n\nexport async function runWithReconnect<TFilter, TBlock>(\n client: Client<TFilter, TBlock>,\n indexer: Indexer<TFilter, TBlock>,\n options: ReconnectOptions = {},\n) {\n let retryCount = 0;\n\n const maxRetries = options.maxRetries ?? 10;\n const retryDelay = options.retryDelay ?? 1_000;\n const maxWait = options.maxWait ?? 30_000;\n const { signal } = options;\n\n while (true) {\n if (signal?.aborted) return;\n\n const abortController = new AbortController();\n\n // Forward external abort into the per-run internal controller so that\n // run() sees the abort signal and can break its loop cleanly.\n const forwardAbort = () => abortController.abort(signal?.reason);\n signal?.addEventListener(\"abort\", forwardAbort, { once: true });\n\n const runOptions: RunOptions = {\n onConnect() {\n retryCount = 0;\n },\n abortSignal: abortController.signal,\n };\n\n try {\n await run(client, indexer, runOptions);\n return;\n } catch (error) {\n // Only reconnect on internal/server errors.\n // All other errors should be rethrown.\n\n retryCount++;\n\n if (signal?.aborted) return;\n\n if (error instanceof ClientError || error instanceof ServerError) {\n const isServerError = error instanceof ServerError;\n\n if (error.code === Status.INTERNAL) {\n if (retryCount < maxRetries) {\n consola.error(\n `Internal ${isServerError ? \"server\" : \"client\"} error: ${\n error.message\n }`,\n );\n consola.start(\"Reconnecting...\");\n console.log();\n\n // Add jitter to the retry delay to avoid all clients retrying at the same time.\n const delay = Math.random() * (retryDelay * 0.2) + retryDelay;\n await new Promise<void>((resolve) => {\n const t = setTimeout(\n resolve,\n Math.min(retryCount * delay, maxWait),\n );\n // wake up immediately if externally aborted during the delay.\n signal?.addEventListener(\n \"abort\",\n () => {\n clearTimeout(t);\n resolve();\n },\n { once: true },\n );\n });\n\n continue;\n }\n }\n }\n throw error;\n } finally {\n signal?.removeEventListener(\"abort\", forwardAbort);\n }\n }\n}\n\nexport interface RunOptions {\n onConnect?: () => void | Promise<void>;\n abortSignal?: AbortSignal;\n}\n\nexport async function run<TFilter, TBlock>(\n client: Client<TFilter, TBlock>,\n indexer: Indexer<TFilter, TBlock>,\n runOptions: RunOptions = {},\n) {\n await indexerAsyncContext.callAsync({}, async () => {\n const context = useIndexerContext();\n\n if (indexer.options.debug) {\n context.debug = true;\n }\n\n const { abortSignal } = runOptions;\n\n await indexer.hooks.callHook(\"plugins:init\", { abortSignal });\n\n const middleware = await registerMiddleware(indexer, abortSignal);\n\n const indexerMetrics = createIndexerMetrics();\n const tracer = createTracer();\n\n await indexer.hooks.callHook(\"run:before\", { abortSignal });\n\n const { indexerName: indexerId } = useInternalContext();\n\n const isFactoryMode = indexer.options.factory !== undefined;\n\n // Give priority to startingCursor over startingBlock.\n let startingCursor: Cursor | undefined;\n if (indexer.options.startingCursor) {\n startingCursor = indexer.options.startingCursor;\n } else if (indexer.options.startingBlock !== undefined) {\n if (indexer.options.startingBlock === 0n) {\n startingCursor = undefined;\n } else if (indexer.options.startingBlock > 0n) {\n startingCursor = {\n orderKey: indexer.options.startingBlock - 1n,\n };\n }\n }\n\n // if factory mode we add a empty filter at the end of the filter array.\n const request = {\n filter: isFactoryMode\n ? [indexer.options.filter, {} as TFilter]\n : [indexer.options.filter],\n finality: indexer.options.finality,\n startingCursor,\n } as StreamDataRequest<TFilter>;\n\n const options: StreamDataOptions = {};\n\n await indexer.hooks.callHook(\"connect:before\", {\n request,\n options,\n abortSignal,\n });\n\n // store main filter, so later it can be merged\n let mainFilter: TFilter;\n if (isFactoryMode) {\n mainFilter = request.filter[1];\n }\n\n let stream: AsyncIterator<\n StreamDataResponse<TBlock>,\n StreamDataResponse<TBlock>\n > = client.streamData(request, options)[Symbol.asyncIterator]();\n\n await indexer.hooks.callHook(\"connect:after\", { request, abortSignal });\n\n let onConnectCalled = false;\n\n const abortPromise = abortSignal ? waitForAbort(abortSignal) : null;\n\n while (true) {\n let result: IteratorResult<\n StreamDataResponse<TBlock>,\n StreamDataResponse<TBlock>\n >;\n\n try {\n result = abortPromise\n ? await Promise.race([stream.next(), abortPromise])\n : await stream.next();\n } catch (e) {\n if (abortSignal?.aborted) {\n // cancel the underlying gRPC stream and exit the loop cleanly so\n // that run:after hooks are still called below.\n await stream.return?.();\n break;\n }\n throw e;\n }\n\n const { value: message, done } = result;\n\n if (done) {\n break;\n }\n\n if (!onConnectCalled) {\n onConnectCalled = true;\n if (runOptions.onConnect) {\n await runOptions.onConnect();\n }\n }\n\n await indexer.hooks.callHook(\"message\", { message, abortSignal });\n\n switch (message._tag) {\n case \"data\": {\n await tracer.startActiveSpan(\"message data\", async (span) => {\n const blocks = message.data.data;\n const { cursor, endCursor, finality, production } = message.data;\n\n context.cursor = cursor;\n context.endCursor = endCursor;\n context.finality = finality;\n\n // Record current block number being processed\n indexerMetrics.currentBlockGauge.record(\n Number(endCursor?.orderKey),\n {\n indexer_id: indexerId,\n },\n );\n\n reloadIfNeeded();\n\n await middleware(context, async () => {\n let block: TBlock | null;\n\n // when factory mode\n if (isFactoryMode && finality !== \"pending\") {\n assert(indexer.options.factory !== undefined);\n\n const [factoryBlock, mainBlock] = blocks;\n\n block = mainBlock;\n\n if (factoryBlock !== null) {\n const { filter } = await indexer.options.factory({\n block: factoryBlock,\n cursor,\n endCursor,\n finality,\n production,\n context,\n abortSignal,\n });\n\n // write returned data from factory function if filter is not defined\n if (filter) {\n // when filter is defined\n // merge old and new filters\n mainFilter = indexer.streamConfig.mergeFilter(\n mainFilter,\n filter,\n );\n\n // create request with new filters\n const request = {\n filter: [indexer.options.filter, mainFilter],\n finality: indexer.options.finality,\n startingCursor: cursor,\n } as StreamDataRequest<TFilter>;\n\n await indexer.hooks.callHook(\"connect:factory\", {\n request,\n endCursor,\n abortSignal,\n });\n\n // create new stream with new request\n stream = client\n .streamData(request, options)\n [Symbol.asyncIterator]();\n\n const { value: message } = await stream.next();\n\n assert(message._tag === \"data\");\n\n const [_factoryBlock, _block] = message.data.data;\n\n block = _block;\n }\n }\n } else {\n // when not in factory mode\n block = blocks[0];\n }\n\n // if block is not null\n if (block) {\n await tracer.startActiveSpan(\"handler\", async (span) => {\n await indexer.options.transform({\n block,\n cursor,\n endCursor,\n finality,\n production,\n context,\n abortSignal,\n });\n\n span.end();\n });\n }\n });\n\n reloadIfNeeded();\n\n span.end();\n });\n\n // Record processed block metric\n indexerMetrics.processedBlockCounter.add(1, {\n indexer_id: indexerId,\n });\n\n context.cursor = undefined;\n context.endCursor = undefined;\n context.finality = undefined;\n\n break;\n }\n case \"invalidate\": {\n await tracer.startActiveSpan(\"message invalidate\", async (span) => {\n // Record reorg metric\n indexerMetrics.reorgCounter.add(1, {\n indexer_id: indexerId,\n });\n await indexer.hooks.callHook(\"message:invalidate\", {\n message: message.invalidate,\n abortSignal,\n });\n span.end();\n });\n break;\n }\n case \"finalize\": {\n await tracer.startActiveSpan(\"message finalize\", async (span) => {\n await indexer.hooks.callHook(\"message:finalize\", {\n message: message.finalize,\n abortSignal,\n });\n span.end();\n });\n break;\n }\n case \"heartbeat\": {\n await tracer.startActiveSpan(\"message heartbeat\", async (span) => {\n reloadIfNeeded();\n\n await indexer.hooks.callHook(\"message:heartbeat\", { abortSignal });\n reloadIfNeeded();\n\n span.end();\n });\n break;\n }\n case \"systemMessage\": {\n await tracer.startActiveSpan(\n \"message systemMessage\",\n async (span) => {\n switch (message.systemMessage.output?._tag) {\n case \"stderr\": {\n consola.warn(message.systemMessage.output.stderr);\n break;\n }\n case \"stdout\": {\n consola.info(message.systemMessage.output.stdout);\n break;\n }\n default: {\n }\n }\n\n await indexer.hooks.callHook(\"message:systemMessage\", {\n message: message.systemMessage,\n abortSignal,\n });\n span.end();\n },\n );\n break;\n }\n default: {\n consola.warn(\"unexpected message\", message);\n throw new Error(\"not implemented\");\n }\n }\n }\n\n await indexer.hooks.callHook(\"run:after\", { abortSignal });\n });\n}\n\n/**\n * Returns a promise that rejects as soon as the given AbortSignal fires.\n * Used to race against stream.next() so the loop can break on abort.\n */\nfunction waitForAbort(signal: AbortSignal): Promise<never> {\n return new Promise<never>((_, reject) => {\n if (signal.aborted) {\n reject(signal.reason);\n return;\n }\n signal.addEventListener(\"abort\", () => reject(signal.reason), {\n once: true,\n });\n });\n}\n\nasync function registerMiddleware<TFilter, TBlock>(\n indexer: Indexer<TFilter, TBlock>,\n abortSignal?: AbortSignal,\n): Promise<MiddlewareFunction<IndexerContext>> {\n const middleware: MiddlewareFunction<IndexerContext>[] = [];\n const use = (fn: MiddlewareFunction<IndexerContext>) => {\n middleware.push(fn);\n };\n\n await indexer.hooks.callHook(\"handler:middleware\", { use, abortSignal });\n\n const composed = compose(middleware);\n\n // Return a named function to help debugging\n return async function _composedIndexerMiddleware(\n context: IndexerContext,\n next?: NextFunction,\n ) {\n await composed(context, next);\n };\n}\n"],"names":["trace","metrics","useIndexerContext","createHooks","createDebugger","ClientError","ServerError","Status","consola","indexerAsyncContext","useInternalContext","assert","request","message","span"],"mappings":"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"}
package/dist/index.d.cts CHANGED
@@ -1,4 +1,4 @@
1
- export { H as HandlerArgs, e as Indexer, b as IndexerConfig, I as IndexerHooks, a as IndexerStartingCursor, c as IndexerWithStreamConfig, R as ReconnectOptions, g as RunOptions, U as UseMiddlewareFunction, f as createIndexer, d as defineIndexer, h as run, r as runWithReconnect, u as useIndexerContext } from './shared/indexer.4ef52548.cjs';
1
+ export { H as HandlerArgs, e as Indexer, b as IndexerConfig, I as IndexerHooks, a as IndexerStartingCursor, c as IndexerWithStreamConfig, R as ReconnectOptions, g as RunOptions, U as UseMiddlewareFunction, f as createIndexer, d as defineIndexer, h as run, r as runWithReconnect, u as useIndexerContext } from './shared/indexer.576be164.cjs';
2
2
  import '@apibara/protocol';
3
3
  import 'hookable';
4
4
 
package/dist/index.d.mts CHANGED
@@ -1,4 +1,4 @@
1
- export { H as HandlerArgs, e as Indexer, b as IndexerConfig, I as IndexerHooks, a as IndexerStartingCursor, c as IndexerWithStreamConfig, R as ReconnectOptions, g as RunOptions, U as UseMiddlewareFunction, f as createIndexer, d as defineIndexer, h as run, r as runWithReconnect, u as useIndexerContext } from './shared/indexer.4ef52548.mjs';
1
+ export { H as HandlerArgs, e as Indexer, b as IndexerConfig, I as IndexerHooks, a as IndexerStartingCursor, c as IndexerWithStreamConfig, R as ReconnectOptions, g as RunOptions, U as UseMiddlewareFunction, f as createIndexer, d as defineIndexer, h as run, r as runWithReconnect, u as useIndexerContext } from './shared/indexer.576be164.mjs';
2
2
  import '@apibara/protocol';
3
3
  import 'hookable';
4
4
 
package/dist/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- export { H as HandlerArgs, e as Indexer, b as IndexerConfig, I as IndexerHooks, a as IndexerStartingCursor, c as IndexerWithStreamConfig, R as ReconnectOptions, g as RunOptions, U as UseMiddlewareFunction, f as createIndexer, d as defineIndexer, h as run, r as runWithReconnect, u as useIndexerContext } from './shared/indexer.4ef52548.js';
1
+ export { H as HandlerArgs, e as Indexer, b as IndexerConfig, I as IndexerHooks, a as IndexerStartingCursor, c as IndexerWithStreamConfig, R as ReconnectOptions, g as RunOptions, U as UseMiddlewareFunction, f as createIndexer, d as defineIndexer, h as run, r as runWithReconnect, u as useIndexerContext } from './shared/indexer.576be164.js';
2
2
  import '@apibara/protocol';
3
3
  import 'hookable';
4
4
 
package/dist/index.mjs CHANGED
@@ -108,8 +108,13 @@ async function runWithReconnect(client, indexer, options = {}) {
108
108
  const maxRetries = options.maxRetries ?? 10;
109
109
  const retryDelay = options.retryDelay ?? 1e3;
110
110
  const maxWait = options.maxWait ?? 3e4;
111
+ const { signal } = options;
111
112
  while (true) {
113
+ if (signal?.aborted)
114
+ return;
112
115
  const abortController = new AbortController();
116
+ const forwardAbort = () => abortController.abort(signal?.reason);
117
+ signal?.addEventListener("abort", forwardAbort, { once: true });
113
118
  const runOptions = {
114
119
  onConnect() {
115
120
  retryCount = 0;
@@ -118,11 +123,11 @@ async function runWithReconnect(client, indexer, options = {}) {
118
123
  };
119
124
  try {
120
125
  await run(client, indexer, runOptions);
121
- abortController.abort();
122
126
  return;
123
127
  } catch (error) {
124
128
  retryCount++;
125
- abortController.abort();
129
+ if (signal?.aborted)
130
+ return;
126
131
  if (error instanceof ClientError || error instanceof ServerError) {
127
132
  const isServerError = error instanceof ServerError;
128
133
  if (error.code === Status.INTERNAL) {
@@ -133,14 +138,27 @@ async function runWithReconnect(client, indexer, options = {}) {
133
138
  consola.start("Reconnecting...");
134
139
  console.log();
135
140
  const delay = Math.random() * (retryDelay * 0.2) + retryDelay;
136
- await new Promise(
137
- (resolve) => setTimeout(resolve, Math.min(retryCount * delay, maxWait))
138
- );
141
+ await new Promise((resolve) => {
142
+ const t = setTimeout(
143
+ resolve,
144
+ Math.min(retryCount * delay, maxWait)
145
+ );
146
+ signal?.addEventListener(
147
+ "abort",
148
+ () => {
149
+ clearTimeout(t);
150
+ resolve();
151
+ },
152
+ { once: true }
153
+ );
154
+ });
139
155
  continue;
140
156
  }
141
157
  }
142
158
  }
143
159
  throw error;
160
+ } finally {
161
+ signal?.removeEventListener("abort", forwardAbort);
144
162
  }
145
163
  }
146
164
  }
@@ -188,8 +206,19 @@ async function run(client, indexer, runOptions = {}) {
188
206
  let stream = client.streamData(request, options)[Symbol.asyncIterator]();
189
207
  await indexer.hooks.callHook("connect:after", { request, abortSignal });
190
208
  let onConnectCalled = false;
209
+ const abortPromise = abortSignal ? waitForAbort(abortSignal) : null;
191
210
  while (true) {
192
- const { value: message, done } = await stream.next();
211
+ let result;
212
+ try {
213
+ result = abortPromise ? await Promise.race([stream.next(), abortPromise]) : await stream.next();
214
+ } catch (e) {
215
+ if (abortSignal?.aborted) {
216
+ await stream.return?.();
217
+ break;
218
+ }
219
+ throw e;
220
+ }
221
+ const { value: message, done } = result;
193
222
  if (done) {
194
223
  break;
195
224
  }
@@ -346,6 +375,17 @@ async function run(client, indexer, runOptions = {}) {
346
375
  await indexer.hooks.callHook("run:after", { abortSignal });
347
376
  });
348
377
  }
378
+ function waitForAbort(signal) {
379
+ return new Promise((_, reject) => {
380
+ if (signal.aborted) {
381
+ reject(signal.reason);
382
+ return;
383
+ }
384
+ signal.addEventListener("abort", () => reject(signal.reason), {
385
+ once: true
386
+ });
387
+ });
388
+ }
349
389
  async function registerMiddleware(indexer, abortSignal) {
350
390
  const middleware = [];
351
391
  const use = (fn) => {
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","sources":["../src/compose.ts","../src/otel.ts","../src/utils/index.ts","../src/indexer.ts"],"sourcesContent":["/*\n * MIT License\n *\n * Copyright (c) 2021 - present, Yusuke Wada and Hono contributors\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in all\n * copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n * SOFTWARE.\n */\n\nimport type { IndexerContext } from \"./context\";\n\nexport type NextFunction = () => Promise<void>;\nexport type MiddlewareFunction<C> = (\n context: C,\n next: NextFunction,\n) => Promise<void>;\n\nexport function compose<C extends IndexerContext>(\n middleware: MiddlewareFunction<C>[],\n): (context: C, next?: NextFunction) => Promise<void> {\n return (context, next) => {\n let index = -1;\n\n return dispatch(0);\n\n /// Dispatch the middleware functions.\n async function dispatch(i: number): Promise<void> {\n if (i <= index) {\n throw new Error(\"next() called multiple times\");\n }\n index = i;\n\n let handler: MiddlewareFunction<C> | undefined;\n\n if (i >= middleware.length) {\n if (next) {\n await next();\n }\n\n return;\n }\n\n if (middleware[i]) {\n handler = middleware[i];\n } else {\n handler = i === middleware.length ? next : undefined;\n }\n\n if (!handler) {\n throw new Error(\"Handler not found\");\n }\n\n await handler(context, () => dispatch(i + 1));\n }\n };\n}\n","import { metrics, trace } from \"@opentelemetry/api\";\n\nexport function createTracer() {\n return trace.getTracer(\"@apibara/indexer\");\n}\n\nexport function createIndexerMetrics() {\n const meter = metrics.getMeter(\"@apibara/indexer\");\n\n const currentBlockGauge = meter.createGauge(\"current_block\", {\n description: \"Current block number being processed\",\n unit: \"{block}\",\n });\n\n const processedBlockCounter = meter.createCounter(\"processed_blocks\", {\n description: \"Number of blocks processed\",\n unit: \"{blocks}\",\n });\n\n const reorgCounter = meter.createCounter(\"reorgs\", {\n description: \"Number of reorgs (invalidate messages) received\",\n unit: \"{reorgs}\",\n });\n\n return {\n currentBlockGauge,\n processedBlockCounter,\n reorgCounter,\n };\n}\n","import { useIndexerContext } from \"../context\";\n\nexport function reloadIndexer() {\n const context = useIndexerContext();\n context._reload = true;\n}\n\nexport function reloadIfNeeded() {\n const context = useIndexerContext();\n if (context._reload) {\n context._reload = false;\n throw new ReloadIndexerRequest();\n }\n}\n\nexport class ReloadIndexerRequest extends Error {\n constructor(message?: string) {\n super(message);\n this.name = \"ReloadIndexerRequest\";\n }\n}\n","import {\n type Client,\n ClientError,\n type CreateClientOptions,\n type Cursor,\n type DataFinality,\n type DataProduction,\n type Finalize,\n type Invalidate,\n ServerError,\n Status,\n type StreamConfig,\n type StreamDataOptions,\n type StreamDataRequest,\n type StreamDataResponse,\n type SystemMessage,\n} from \"@apibara/protocol\";\nimport consola from \"consola\";\nimport {\n type Hookable,\n type NestedHooks,\n createDebugger,\n createHooks,\n} from \"hookable\";\n\nimport assert from \"node:assert\";\nimport { type MiddlewareFunction, type NextFunction, compose } from \"./compose\";\nimport {\n type IndexerContext,\n indexerAsyncContext,\n useIndexerContext,\n} from \"./context\";\nimport { createIndexerMetrics, createTracer } from \"./otel\";\nimport type { IndexerPlugin } from \"./plugins\";\nimport { useInternalContext } from \"./plugins/context\";\nimport { reloadIfNeeded } from \"./utils\";\n\nexport type UseMiddlewareFunction = (\n fn: MiddlewareFunction<IndexerContext>,\n) => void;\n\nexport interface IndexerHooks<TFilter, TBlock> {\n \"plugins:init\": ({ abortSignal }: { abortSignal?: AbortSignal }) => void;\n \"run:before\": ({ abortSignal }: { abortSignal?: AbortSignal }) => void;\n \"run:after\": ({ abortSignal }: { abortSignal?: AbortSignal }) => void;\n \"connect:before\": ({\n request,\n options,\n }: {\n request: StreamDataRequest<TFilter>;\n options: StreamDataOptions;\n abortSignal?: AbortSignal;\n }) => void;\n \"connect:after\": ({\n request,\n }: {\n request: StreamDataRequest<TFilter>;\n abortSignal?: AbortSignal;\n }) => void;\n \"connect:factory\": ({\n request,\n endCursor,\n abortSignal,\n }: {\n request: StreamDataRequest<TFilter>;\n endCursor?: Cursor;\n abortSignal?: AbortSignal;\n }) => void;\n \"handler:middleware\": ({\n use,\n abortSignal,\n }: { use: UseMiddlewareFunction; abortSignal?: AbortSignal }) => void;\n message: ({\n message,\n abortSignal,\n }: {\n message: StreamDataResponse<TBlock>;\n abortSignal?: AbortSignal;\n }) => void;\n \"message:invalidate\": ({\n message,\n abortSignal,\n }: { message: Invalidate; abortSignal?: AbortSignal }) => void;\n \"message:finalize\": ({\n message,\n abortSignal,\n }: { message: Finalize; abortSignal?: AbortSignal }) => void;\n \"message:heartbeat\": ({ abortSignal }: { abortSignal?: AbortSignal }) => void;\n \"message:systemMessage\": ({\n message,\n abortSignal,\n }: { message: SystemMessage; abortSignal?: AbortSignal }) => void;\n}\n\nexport type IndexerStartingCursor =\n | {\n startingCursor?: never;\n startingBlock: bigint;\n }\n | {\n startingCursor: Cursor;\n startingBlock?: never;\n }\n | {\n startingCursor?: never;\n startingBlock?: never;\n };\n\nexport type HandlerArgs<TBlock> = {\n block: TBlock;\n cursor?: Cursor | undefined;\n endCursor?: Cursor | undefined;\n finality: DataFinality;\n production: DataProduction;\n context: IndexerContext;\n abortSignal?: AbortSignal;\n};\n\nexport type IndexerConfig<TFilter, TBlock> = {\n streamUrl: string;\n filter: TFilter;\n finality?: DataFinality;\n clientOptions?: CreateClientOptions;\n factory?: (args: HandlerArgs<TBlock>) => Promise<{\n filter?: TFilter;\n }>;\n transform: (args: HandlerArgs<TBlock>) => Promise<void>;\n hooks?: NestedHooks<IndexerHooks<TFilter, TBlock>>;\n plugins?: ReadonlyArray<IndexerPlugin<TFilter, TBlock>>;\n debug?: boolean;\n} & IndexerStartingCursor;\n\nexport type IndexerWithStreamConfig<TFilter, TBlock> = IndexerConfig<\n TFilter,\n TBlock\n> & {\n streamConfig: StreamConfig<TFilter, TBlock>;\n};\n\nexport function defineIndexer<TFilter, TBlock>(\n streamConfig: StreamConfig<TFilter, TBlock>,\n) {\n return (\n config: IndexerConfig<TFilter, TBlock>,\n ): IndexerWithStreamConfig<TFilter, TBlock> => ({\n streamConfig,\n ...config,\n });\n}\n\nexport interface Indexer<TFilter, TBlock> {\n streamConfig: StreamConfig<TFilter, TBlock>;\n options: IndexerConfig<TFilter, TBlock>;\n hooks: Hookable<IndexerHooks<TFilter, TBlock>>;\n}\n\nexport function createIndexer<TFilter, TBlock>({\n streamConfig,\n ...options\n}: IndexerWithStreamConfig<TFilter, TBlock>) {\n const indexer: Indexer<TFilter, TBlock> = {\n options,\n streamConfig,\n hooks: createHooks<IndexerHooks<TFilter, TBlock>>(),\n };\n\n if (indexer.options.debug) {\n createDebugger(indexer.hooks, { tag: \"indexer\" });\n }\n\n indexer.hooks.addHooks(indexer.options.hooks ?? {});\n\n for (const plugin of indexer.options.plugins ?? []) {\n plugin(indexer);\n }\n\n return indexer;\n}\n\nexport interface ReconnectOptions {\n maxRetries?: number;\n retryDelay?: number;\n maxWait?: number;\n}\n\nexport async function runWithReconnect<TFilter, TBlock>(\n client: Client<TFilter, TBlock>,\n indexer: Indexer<TFilter, TBlock>,\n options: ReconnectOptions = {},\n) {\n let retryCount = 0;\n\n const maxRetries = options.maxRetries ?? 10;\n const retryDelay = options.retryDelay ?? 1_000;\n const maxWait = options.maxWait ?? 30_000;\n\n while (true) {\n const abortController = new AbortController();\n\n const runOptions: RunOptions = {\n onConnect() {\n retryCount = 0;\n },\n abortSignal: abortController.signal,\n };\n\n try {\n await run(client, indexer, runOptions);\n abortController.abort();\n return;\n } catch (error) {\n // Only reconnect on internal/server errors.\n // All other errors should be rethrown.\n\n retryCount++;\n\n abortController.abort();\n\n if (error instanceof ClientError || error instanceof ServerError) {\n const isServerError = error instanceof ServerError;\n\n if (error.code === Status.INTERNAL) {\n if (retryCount < maxRetries) {\n consola.error(\n `Internal ${isServerError ? \"server\" : \"client\"} error: ${\n error.message\n }`,\n );\n consola.start(\"Reconnecting...\");\n console.log();\n\n // Add jitter to the retry delay to avoid all clients retrying at the same time.\n const delay = Math.random() * (retryDelay * 0.2) + retryDelay;\n await new Promise((resolve) =>\n setTimeout(resolve, Math.min(retryCount * delay, maxWait)),\n );\n\n continue;\n }\n }\n }\n throw error;\n }\n }\n}\n\nexport interface RunOptions {\n onConnect?: () => void | Promise<void>;\n abortSignal?: AbortSignal;\n}\n\nexport async function run<TFilter, TBlock>(\n client: Client<TFilter, TBlock>,\n indexer: Indexer<TFilter, TBlock>,\n runOptions: RunOptions = {},\n) {\n await indexerAsyncContext.callAsync({}, async () => {\n const context = useIndexerContext();\n\n if (indexer.options.debug) {\n context.debug = true;\n }\n\n const { abortSignal } = runOptions;\n\n await indexer.hooks.callHook(\"plugins:init\", { abortSignal });\n\n const middleware = await registerMiddleware(indexer, abortSignal);\n\n const indexerMetrics = createIndexerMetrics();\n const tracer = createTracer();\n\n await indexer.hooks.callHook(\"run:before\", { abortSignal });\n\n const { indexerName: indexerId } = useInternalContext();\n\n const isFactoryMode = indexer.options.factory !== undefined;\n\n // Give priority to startingCursor over startingBlock.\n let startingCursor: Cursor | undefined;\n if (indexer.options.startingCursor) {\n startingCursor = indexer.options.startingCursor;\n } else if (indexer.options.startingBlock !== undefined) {\n if (indexer.options.startingBlock === 0n) {\n startingCursor = undefined;\n } else if (indexer.options.startingBlock > 0n) {\n startingCursor = {\n orderKey: indexer.options.startingBlock - 1n,\n };\n }\n }\n\n // if factory mode we add a empty filter at the end of the filter array.\n const request = {\n filter: isFactoryMode\n ? [indexer.options.filter, {} as TFilter]\n : [indexer.options.filter],\n finality: indexer.options.finality,\n startingCursor,\n } as StreamDataRequest<TFilter>;\n\n const options: StreamDataOptions = {};\n\n await indexer.hooks.callHook(\"connect:before\", {\n request,\n options,\n abortSignal,\n });\n\n // store main filter, so later it can be merged\n let mainFilter: TFilter;\n if (isFactoryMode) {\n mainFilter = request.filter[1];\n }\n\n let stream: AsyncIterator<\n StreamDataResponse<TBlock>,\n StreamDataResponse<TBlock>\n > = client.streamData(request, options)[Symbol.asyncIterator]();\n\n await indexer.hooks.callHook(\"connect:after\", { request, abortSignal });\n\n let onConnectCalled = false;\n\n while (true) {\n const { value: message, done } = await stream.next();\n\n if (done) {\n break;\n }\n\n if (!onConnectCalled) {\n onConnectCalled = true;\n if (runOptions.onConnect) {\n await runOptions.onConnect();\n }\n }\n\n await indexer.hooks.callHook(\"message\", { message, abortSignal });\n\n switch (message._tag) {\n case \"data\": {\n await tracer.startActiveSpan(\"message data\", async (span) => {\n const blocks = message.data.data;\n const { cursor, endCursor, finality, production } = message.data;\n\n context.cursor = cursor;\n context.endCursor = endCursor;\n context.finality = finality;\n\n // Record current block number being processed\n indexerMetrics.currentBlockGauge.record(\n Number(endCursor?.orderKey),\n {\n indexer_id: indexerId,\n },\n );\n\n reloadIfNeeded();\n\n await middleware(context, async () => {\n let block: TBlock | null;\n\n // when factory mode\n if (isFactoryMode && finality !== \"pending\") {\n assert(indexer.options.factory !== undefined);\n\n const [factoryBlock, mainBlock] = blocks;\n\n block = mainBlock;\n\n if (factoryBlock !== null) {\n const { filter } = await indexer.options.factory({\n block: factoryBlock,\n cursor,\n endCursor,\n finality,\n production,\n context,\n abortSignal,\n });\n\n // write returned data from factory function if filter is not defined\n if (filter) {\n // when filter is defined\n // merge old and new filters\n mainFilter = indexer.streamConfig.mergeFilter(\n mainFilter,\n filter,\n );\n\n // create request with new filters\n const request = {\n filter: [indexer.options.filter, mainFilter],\n finality: indexer.options.finality,\n startingCursor: cursor,\n } as StreamDataRequest<TFilter>;\n\n await indexer.hooks.callHook(\"connect:factory\", {\n request,\n endCursor,\n abortSignal,\n });\n\n // create new stream with new request\n stream = client\n .streamData(request, options)\n [Symbol.asyncIterator]();\n\n const { value: message } = await stream.next();\n\n assert(message._tag === \"data\");\n\n const [_factoryBlock, _block] = message.data.data;\n\n block = _block;\n }\n }\n } else {\n // when not in factory mode\n block = blocks[0];\n }\n\n // if block is not null\n if (block) {\n await tracer.startActiveSpan(\"handler\", async (span) => {\n await indexer.options.transform({\n block,\n cursor,\n endCursor,\n finality,\n production,\n context,\n abortSignal,\n });\n\n span.end();\n });\n }\n });\n\n reloadIfNeeded();\n\n span.end();\n });\n\n // Record processed block metric\n indexerMetrics.processedBlockCounter.add(1, {\n indexer_id: indexerId,\n });\n\n context.cursor = undefined;\n context.endCursor = undefined;\n context.finality = undefined;\n\n break;\n }\n case \"invalidate\": {\n await tracer.startActiveSpan(\"message invalidate\", async (span) => {\n // Record reorg metric\n indexerMetrics.reorgCounter.add(1, {\n indexer_id: indexerId,\n });\n await indexer.hooks.callHook(\"message:invalidate\", {\n message: message.invalidate,\n abortSignal,\n });\n span.end();\n });\n break;\n }\n case \"finalize\": {\n await tracer.startActiveSpan(\"message finalize\", async (span) => {\n await indexer.hooks.callHook(\"message:finalize\", {\n message: message.finalize,\n abortSignal,\n });\n span.end();\n });\n break;\n }\n case \"heartbeat\": {\n await tracer.startActiveSpan(\"message heartbeat\", async (span) => {\n reloadIfNeeded();\n\n await indexer.hooks.callHook(\"message:heartbeat\", { abortSignal });\n reloadIfNeeded();\n\n span.end();\n });\n break;\n }\n case \"systemMessage\": {\n await tracer.startActiveSpan(\n \"message systemMessage\",\n async (span) => {\n switch (message.systemMessage.output?._tag) {\n case \"stderr\": {\n consola.warn(message.systemMessage.output.stderr);\n break;\n }\n case \"stdout\": {\n consola.info(message.systemMessage.output.stdout);\n break;\n }\n default: {\n }\n }\n\n await indexer.hooks.callHook(\"message:systemMessage\", {\n message: message.systemMessage,\n abortSignal,\n });\n span.end();\n },\n );\n break;\n }\n default: {\n consola.warn(\"unexpected message\", message);\n throw new Error(\"not implemented\");\n }\n }\n }\n\n await indexer.hooks.callHook(\"run:after\", { abortSignal });\n });\n}\n\nasync function registerMiddleware<TFilter, TBlock>(\n indexer: Indexer<TFilter, TBlock>,\n abortSignal?: AbortSignal,\n): Promise<MiddlewareFunction<IndexerContext>> {\n const middleware: MiddlewareFunction<IndexerContext>[] = [];\n const use = (fn: MiddlewareFunction<IndexerContext>) => {\n middleware.push(fn);\n };\n\n await indexer.hooks.callHook(\"handler:middleware\", { use, abortSignal });\n\n const composed = compose(middleware);\n\n // Return a named function to help debugging\n return async function _composedIndexerMiddleware(\n context: IndexerContext,\n next?: NextFunction,\n ) {\n await composed(context, next);\n };\n}\n"],"names":["request","message","span"],"mappings":"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"}
1
+ {"version":3,"file":"index.mjs","sources":["../src/compose.ts","../src/otel.ts","../src/utils/index.ts","../src/indexer.ts"],"sourcesContent":["/*\n * MIT License\n *\n * Copyright (c) 2021 - present, Yusuke Wada and Hono contributors\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in all\n * copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n * SOFTWARE.\n */\n\nimport type { IndexerContext } from \"./context\";\n\nexport type NextFunction = () => Promise<void>;\nexport type MiddlewareFunction<C> = (\n context: C,\n next: NextFunction,\n) => Promise<void>;\n\nexport function compose<C extends IndexerContext>(\n middleware: MiddlewareFunction<C>[],\n): (context: C, next?: NextFunction) => Promise<void> {\n return (context, next) => {\n let index = -1;\n\n return dispatch(0);\n\n /// Dispatch the middleware functions.\n async function dispatch(i: number): Promise<void> {\n if (i <= index) {\n throw new Error(\"next() called multiple times\");\n }\n index = i;\n\n let handler: MiddlewareFunction<C> | undefined;\n\n if (i >= middleware.length) {\n if (next) {\n await next();\n }\n\n return;\n }\n\n if (middleware[i]) {\n handler = middleware[i];\n } else {\n handler = i === middleware.length ? next : undefined;\n }\n\n if (!handler) {\n throw new Error(\"Handler not found\");\n }\n\n await handler(context, () => dispatch(i + 1));\n }\n };\n}\n","import { metrics, trace } from \"@opentelemetry/api\";\n\nexport function createTracer() {\n return trace.getTracer(\"@apibara/indexer\");\n}\n\nexport function createIndexerMetrics() {\n const meter = metrics.getMeter(\"@apibara/indexer\");\n\n const currentBlockGauge = meter.createGauge(\"current_block\", {\n description: \"Current block number being processed\",\n unit: \"{block}\",\n });\n\n const processedBlockCounter = meter.createCounter(\"processed_blocks\", {\n description: \"Number of blocks processed\",\n unit: \"{blocks}\",\n });\n\n const reorgCounter = meter.createCounter(\"reorgs\", {\n description: \"Number of reorgs (invalidate messages) received\",\n unit: \"{reorgs}\",\n });\n\n return {\n currentBlockGauge,\n processedBlockCounter,\n reorgCounter,\n };\n}\n","import { useIndexerContext } from \"../context\";\n\nexport function reloadIndexer() {\n const context = useIndexerContext();\n context._reload = true;\n}\n\nexport function reloadIfNeeded() {\n const context = useIndexerContext();\n if (context._reload) {\n context._reload = false;\n throw new ReloadIndexerRequest();\n }\n}\n\nexport class ReloadIndexerRequest extends Error {\n constructor(message?: string) {\n super(message);\n this.name = \"ReloadIndexerRequest\";\n }\n}\n","import {\n type Client,\n ClientError,\n type CreateClientOptions,\n type Cursor,\n type DataFinality,\n type DataProduction,\n type Finalize,\n type Invalidate,\n ServerError,\n Status,\n type StreamConfig,\n type StreamDataOptions,\n type StreamDataRequest,\n type StreamDataResponse,\n type SystemMessage,\n} from \"@apibara/protocol\";\nimport consola from \"consola\";\nimport {\n type Hookable,\n type NestedHooks,\n createDebugger,\n createHooks,\n} from \"hookable\";\n\nimport assert from \"node:assert\";\nimport { type MiddlewareFunction, type NextFunction, compose } from \"./compose\";\nimport {\n type IndexerContext,\n indexerAsyncContext,\n useIndexerContext,\n} from \"./context\";\nimport { createIndexerMetrics, createTracer } from \"./otel\";\nimport type { IndexerPlugin } from \"./plugins\";\nimport { useInternalContext } from \"./plugins/context\";\nimport { reloadIfNeeded } from \"./utils\";\n\nexport type UseMiddlewareFunction = (\n fn: MiddlewareFunction<IndexerContext>,\n) => void;\n\nexport interface IndexerHooks<TFilter, TBlock> {\n \"plugins:init\": ({ abortSignal }: { abortSignal?: AbortSignal }) => void;\n \"run:before\": ({ abortSignal }: { abortSignal?: AbortSignal }) => void;\n \"run:after\": ({ abortSignal }: { abortSignal?: AbortSignal }) => void;\n \"connect:before\": ({\n request,\n options,\n }: {\n request: StreamDataRequest<TFilter>;\n options: StreamDataOptions;\n abortSignal?: AbortSignal;\n }) => void;\n \"connect:after\": ({\n request,\n }: {\n request: StreamDataRequest<TFilter>;\n abortSignal?: AbortSignal;\n }) => void;\n \"connect:factory\": ({\n request,\n endCursor,\n abortSignal,\n }: {\n request: StreamDataRequest<TFilter>;\n endCursor?: Cursor;\n abortSignal?: AbortSignal;\n }) => void;\n \"handler:middleware\": ({\n use,\n abortSignal,\n }: { use: UseMiddlewareFunction; abortSignal?: AbortSignal }) => void;\n message: ({\n message,\n abortSignal,\n }: {\n message: StreamDataResponse<TBlock>;\n abortSignal?: AbortSignal;\n }) => void;\n \"message:invalidate\": ({\n message,\n abortSignal,\n }: { message: Invalidate; abortSignal?: AbortSignal }) => void;\n \"message:finalize\": ({\n message,\n abortSignal,\n }: { message: Finalize; abortSignal?: AbortSignal }) => void;\n \"message:heartbeat\": ({ abortSignal }: { abortSignal?: AbortSignal }) => void;\n \"message:systemMessage\": ({\n message,\n abortSignal,\n }: { message: SystemMessage; abortSignal?: AbortSignal }) => void;\n}\n\nexport type IndexerStartingCursor =\n | {\n startingCursor?: never;\n startingBlock: bigint;\n }\n | {\n startingCursor: Cursor;\n startingBlock?: never;\n }\n | {\n startingCursor?: never;\n startingBlock?: never;\n };\n\nexport type HandlerArgs<TBlock> = {\n block: TBlock;\n cursor?: Cursor | undefined;\n endCursor?: Cursor | undefined;\n finality: DataFinality;\n production: DataProduction;\n context: IndexerContext;\n abortSignal?: AbortSignal;\n};\n\nexport type IndexerConfig<TFilter, TBlock> = {\n streamUrl: string;\n filter: TFilter;\n finality?: DataFinality;\n clientOptions?: CreateClientOptions;\n factory?: (args: HandlerArgs<TBlock>) => Promise<{\n filter?: TFilter;\n }>;\n transform: (args: HandlerArgs<TBlock>) => Promise<void>;\n hooks?: NestedHooks<IndexerHooks<TFilter, TBlock>>;\n plugins?: ReadonlyArray<IndexerPlugin<TFilter, TBlock>>;\n debug?: boolean;\n} & IndexerStartingCursor;\n\nexport type IndexerWithStreamConfig<TFilter, TBlock> = IndexerConfig<\n TFilter,\n TBlock\n> & {\n streamConfig: StreamConfig<TFilter, TBlock>;\n};\n\nexport function defineIndexer<TFilter, TBlock>(\n streamConfig: StreamConfig<TFilter, TBlock>,\n) {\n return (\n config: IndexerConfig<TFilter, TBlock>,\n ): IndexerWithStreamConfig<TFilter, TBlock> => ({\n streamConfig,\n ...config,\n });\n}\n\nexport interface Indexer<TFilter, TBlock> {\n streamConfig: StreamConfig<TFilter, TBlock>;\n options: IndexerConfig<TFilter, TBlock>;\n hooks: Hookable<IndexerHooks<TFilter, TBlock>>;\n}\n\nexport function createIndexer<TFilter, TBlock>({\n streamConfig,\n ...options\n}: IndexerWithStreamConfig<TFilter, TBlock>) {\n const indexer: Indexer<TFilter, TBlock> = {\n options,\n streamConfig,\n hooks: createHooks<IndexerHooks<TFilter, TBlock>>(),\n };\n\n if (indexer.options.debug) {\n createDebugger(indexer.hooks, { tag: \"indexer\" });\n }\n\n indexer.hooks.addHooks(indexer.options.hooks ?? {});\n\n for (const plugin of indexer.options.plugins ?? []) {\n plugin(indexer);\n }\n\n return indexer;\n}\n\nexport interface ReconnectOptions {\n maxRetries?: number;\n retryDelay?: number;\n maxWait?: number;\n signal?: AbortSignal;\n}\n\nexport async function runWithReconnect<TFilter, TBlock>(\n client: Client<TFilter, TBlock>,\n indexer: Indexer<TFilter, TBlock>,\n options: ReconnectOptions = {},\n) {\n let retryCount = 0;\n\n const maxRetries = options.maxRetries ?? 10;\n const retryDelay = options.retryDelay ?? 1_000;\n const maxWait = options.maxWait ?? 30_000;\n const { signal } = options;\n\n while (true) {\n if (signal?.aborted) return;\n\n const abortController = new AbortController();\n\n // Forward external abort into the per-run internal controller so that\n // run() sees the abort signal and can break its loop cleanly.\n const forwardAbort = () => abortController.abort(signal?.reason);\n signal?.addEventListener(\"abort\", forwardAbort, { once: true });\n\n const runOptions: RunOptions = {\n onConnect() {\n retryCount = 0;\n },\n abortSignal: abortController.signal,\n };\n\n try {\n await run(client, indexer, runOptions);\n return;\n } catch (error) {\n // Only reconnect on internal/server errors.\n // All other errors should be rethrown.\n\n retryCount++;\n\n if (signal?.aborted) return;\n\n if (error instanceof ClientError || error instanceof ServerError) {\n const isServerError = error instanceof ServerError;\n\n if (error.code === Status.INTERNAL) {\n if (retryCount < maxRetries) {\n consola.error(\n `Internal ${isServerError ? \"server\" : \"client\"} error: ${\n error.message\n }`,\n );\n consola.start(\"Reconnecting...\");\n console.log();\n\n // Add jitter to the retry delay to avoid all clients retrying at the same time.\n const delay = Math.random() * (retryDelay * 0.2) + retryDelay;\n await new Promise<void>((resolve) => {\n const t = setTimeout(\n resolve,\n Math.min(retryCount * delay, maxWait),\n );\n // wake up immediately if externally aborted during the delay.\n signal?.addEventListener(\n \"abort\",\n () => {\n clearTimeout(t);\n resolve();\n },\n { once: true },\n );\n });\n\n continue;\n }\n }\n }\n throw error;\n } finally {\n signal?.removeEventListener(\"abort\", forwardAbort);\n }\n }\n}\n\nexport interface RunOptions {\n onConnect?: () => void | Promise<void>;\n abortSignal?: AbortSignal;\n}\n\nexport async function run<TFilter, TBlock>(\n client: Client<TFilter, TBlock>,\n indexer: Indexer<TFilter, TBlock>,\n runOptions: RunOptions = {},\n) {\n await indexerAsyncContext.callAsync({}, async () => {\n const context = useIndexerContext();\n\n if (indexer.options.debug) {\n context.debug = true;\n }\n\n const { abortSignal } = runOptions;\n\n await indexer.hooks.callHook(\"plugins:init\", { abortSignal });\n\n const middleware = await registerMiddleware(indexer, abortSignal);\n\n const indexerMetrics = createIndexerMetrics();\n const tracer = createTracer();\n\n await indexer.hooks.callHook(\"run:before\", { abortSignal });\n\n const { indexerName: indexerId } = useInternalContext();\n\n const isFactoryMode = indexer.options.factory !== undefined;\n\n // Give priority to startingCursor over startingBlock.\n let startingCursor: Cursor | undefined;\n if (indexer.options.startingCursor) {\n startingCursor = indexer.options.startingCursor;\n } else if (indexer.options.startingBlock !== undefined) {\n if (indexer.options.startingBlock === 0n) {\n startingCursor = undefined;\n } else if (indexer.options.startingBlock > 0n) {\n startingCursor = {\n orderKey: indexer.options.startingBlock - 1n,\n };\n }\n }\n\n // if factory mode we add a empty filter at the end of the filter array.\n const request = {\n filter: isFactoryMode\n ? [indexer.options.filter, {} as TFilter]\n : [indexer.options.filter],\n finality: indexer.options.finality,\n startingCursor,\n } as StreamDataRequest<TFilter>;\n\n const options: StreamDataOptions = {};\n\n await indexer.hooks.callHook(\"connect:before\", {\n request,\n options,\n abortSignal,\n });\n\n // store main filter, so later it can be merged\n let mainFilter: TFilter;\n if (isFactoryMode) {\n mainFilter = request.filter[1];\n }\n\n let stream: AsyncIterator<\n StreamDataResponse<TBlock>,\n StreamDataResponse<TBlock>\n > = client.streamData(request, options)[Symbol.asyncIterator]();\n\n await indexer.hooks.callHook(\"connect:after\", { request, abortSignal });\n\n let onConnectCalled = false;\n\n const abortPromise = abortSignal ? waitForAbort(abortSignal) : null;\n\n while (true) {\n let result: IteratorResult<\n StreamDataResponse<TBlock>,\n StreamDataResponse<TBlock>\n >;\n\n try {\n result = abortPromise\n ? await Promise.race([stream.next(), abortPromise])\n : await stream.next();\n } catch (e) {\n if (abortSignal?.aborted) {\n // cancel the underlying gRPC stream and exit the loop cleanly so\n // that run:after hooks are still called below.\n await stream.return?.();\n break;\n }\n throw e;\n }\n\n const { value: message, done } = result;\n\n if (done) {\n break;\n }\n\n if (!onConnectCalled) {\n onConnectCalled = true;\n if (runOptions.onConnect) {\n await runOptions.onConnect();\n }\n }\n\n await indexer.hooks.callHook(\"message\", { message, abortSignal });\n\n switch (message._tag) {\n case \"data\": {\n await tracer.startActiveSpan(\"message data\", async (span) => {\n const blocks = message.data.data;\n const { cursor, endCursor, finality, production } = message.data;\n\n context.cursor = cursor;\n context.endCursor = endCursor;\n context.finality = finality;\n\n // Record current block number being processed\n indexerMetrics.currentBlockGauge.record(\n Number(endCursor?.orderKey),\n {\n indexer_id: indexerId,\n },\n );\n\n reloadIfNeeded();\n\n await middleware(context, async () => {\n let block: TBlock | null;\n\n // when factory mode\n if (isFactoryMode && finality !== \"pending\") {\n assert(indexer.options.factory !== undefined);\n\n const [factoryBlock, mainBlock] = blocks;\n\n block = mainBlock;\n\n if (factoryBlock !== null) {\n const { filter } = await indexer.options.factory({\n block: factoryBlock,\n cursor,\n endCursor,\n finality,\n production,\n context,\n abortSignal,\n });\n\n // write returned data from factory function if filter is not defined\n if (filter) {\n // when filter is defined\n // merge old and new filters\n mainFilter = indexer.streamConfig.mergeFilter(\n mainFilter,\n filter,\n );\n\n // create request with new filters\n const request = {\n filter: [indexer.options.filter, mainFilter],\n finality: indexer.options.finality,\n startingCursor: cursor,\n } as StreamDataRequest<TFilter>;\n\n await indexer.hooks.callHook(\"connect:factory\", {\n request,\n endCursor,\n abortSignal,\n });\n\n // create new stream with new request\n stream = client\n .streamData(request, options)\n [Symbol.asyncIterator]();\n\n const { value: message } = await stream.next();\n\n assert(message._tag === \"data\");\n\n const [_factoryBlock, _block] = message.data.data;\n\n block = _block;\n }\n }\n } else {\n // when not in factory mode\n block = blocks[0];\n }\n\n // if block is not null\n if (block) {\n await tracer.startActiveSpan(\"handler\", async (span) => {\n await indexer.options.transform({\n block,\n cursor,\n endCursor,\n finality,\n production,\n context,\n abortSignal,\n });\n\n span.end();\n });\n }\n });\n\n reloadIfNeeded();\n\n span.end();\n });\n\n // Record processed block metric\n indexerMetrics.processedBlockCounter.add(1, {\n indexer_id: indexerId,\n });\n\n context.cursor = undefined;\n context.endCursor = undefined;\n context.finality = undefined;\n\n break;\n }\n case \"invalidate\": {\n await tracer.startActiveSpan(\"message invalidate\", async (span) => {\n // Record reorg metric\n indexerMetrics.reorgCounter.add(1, {\n indexer_id: indexerId,\n });\n await indexer.hooks.callHook(\"message:invalidate\", {\n message: message.invalidate,\n abortSignal,\n });\n span.end();\n });\n break;\n }\n case \"finalize\": {\n await tracer.startActiveSpan(\"message finalize\", async (span) => {\n await indexer.hooks.callHook(\"message:finalize\", {\n message: message.finalize,\n abortSignal,\n });\n span.end();\n });\n break;\n }\n case \"heartbeat\": {\n await tracer.startActiveSpan(\"message heartbeat\", async (span) => {\n reloadIfNeeded();\n\n await indexer.hooks.callHook(\"message:heartbeat\", { abortSignal });\n reloadIfNeeded();\n\n span.end();\n });\n break;\n }\n case \"systemMessage\": {\n await tracer.startActiveSpan(\n \"message systemMessage\",\n async (span) => {\n switch (message.systemMessage.output?._tag) {\n case \"stderr\": {\n consola.warn(message.systemMessage.output.stderr);\n break;\n }\n case \"stdout\": {\n consola.info(message.systemMessage.output.stdout);\n break;\n }\n default: {\n }\n }\n\n await indexer.hooks.callHook(\"message:systemMessage\", {\n message: message.systemMessage,\n abortSignal,\n });\n span.end();\n },\n );\n break;\n }\n default: {\n consola.warn(\"unexpected message\", message);\n throw new Error(\"not implemented\");\n }\n }\n }\n\n await indexer.hooks.callHook(\"run:after\", { abortSignal });\n });\n}\n\n/**\n * Returns a promise that rejects as soon as the given AbortSignal fires.\n * Used to race against stream.next() so the loop can break on abort.\n */\nfunction waitForAbort(signal: AbortSignal): Promise<never> {\n return new Promise<never>((_, reject) => {\n if (signal.aborted) {\n reject(signal.reason);\n return;\n }\n signal.addEventListener(\"abort\", () => reject(signal.reason), {\n once: true,\n });\n });\n}\n\nasync function registerMiddleware<TFilter, TBlock>(\n indexer: Indexer<TFilter, TBlock>,\n abortSignal?: AbortSignal,\n): Promise<MiddlewareFunction<IndexerContext>> {\n const middleware: MiddlewareFunction<IndexerContext>[] = [];\n const use = (fn: MiddlewareFunction<IndexerContext>) => {\n middleware.push(fn);\n };\n\n await indexer.hooks.callHook(\"handler:middleware\", { use, abortSignal });\n\n const composed = compose(middleware);\n\n // Return a named function to help debugging\n return async function _composedIndexerMiddleware(\n context: IndexerContext,\n next?: NextFunction,\n ) {\n await composed(context, next);\n };\n}\n"],"names":["request","message","span"],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- import { i as IndexerPlugin } from '../shared/indexer.4ef52548.cjs';
1
+ import { i as IndexerPlugin } from '../shared/indexer.576be164.cjs';
2
2
  import '@apibara/protocol';
3
3
  import 'hookable';
4
4
 
@@ -1,4 +1,4 @@
1
- import { i as IndexerPlugin } from '../shared/indexer.4ef52548.mjs';
1
+ import { i as IndexerPlugin } from '../shared/indexer.576be164.mjs';
2
2
  import '@apibara/protocol';
3
3
  import 'hookable';
4
4
 
@@ -1,4 +1,4 @@
1
- import { i as IndexerPlugin } from '../shared/indexer.4ef52548.js';
1
+ import { i as IndexerPlugin } from '../shared/indexer.576be164.js';
2
2
  import '@apibara/protocol';
3
3
  import 'hookable';
4
4
 
@@ -1,4 +1,4 @@
1
- import { e as Indexer, i as IndexerPlugin, b as IndexerConfig } from '../shared/indexer.4ef52548.cjs';
1
+ import { e as Indexer, i as IndexerPlugin, b as IndexerConfig } from '../shared/indexer.576be164.cjs';
2
2
  import { MockStreamResponse, MockFilter, MockBlock } from '@apibara/protocol/testing';
3
3
  import { InternalContext } from './plugins.cjs';
4
4
  import '@apibara/protocol';
@@ -1,4 +1,4 @@
1
- import { e as Indexer, i as IndexerPlugin, b as IndexerConfig } from '../shared/indexer.4ef52548.mjs';
1
+ import { e as Indexer, i as IndexerPlugin, b as IndexerConfig } from '../shared/indexer.576be164.mjs';
2
2
  import { MockStreamResponse, MockFilter, MockBlock } from '@apibara/protocol/testing';
3
3
  import { InternalContext } from './plugins.mjs';
4
4
  import '@apibara/protocol';
@@ -1,4 +1,4 @@
1
- import { e as Indexer, i as IndexerPlugin, b as IndexerConfig } from '../shared/indexer.4ef52548.js';
1
+ import { e as Indexer, i as IndexerPlugin, b as IndexerConfig } from '../shared/indexer.576be164.js';
2
2
  import { MockStreamResponse, MockFilter, MockBlock } from '@apibara/protocol/testing';
3
3
  import { InternalContext } from './plugins.js';
4
4
  import '@apibara/protocol';
@@ -1,5 +1,5 @@
1
- import { i as IndexerPlugin } from '../shared/indexer.4ef52548.cjs';
2
- export { j as defineIndexerPlugin } from '../shared/indexer.4ef52548.cjs';
1
+ import { i as IndexerPlugin } from '../shared/indexer.576be164.cjs';
2
+ export { j as defineIndexerPlugin } from '../shared/indexer.576be164.cjs';
3
3
  import { ConsolaReporter, ConsolaInstance } from 'consola';
4
4
  export { ConsolaInstance, ConsolaReporter } from 'consola';
5
5
  import '@apibara/protocol';
@@ -1,5 +1,5 @@
1
- import { i as IndexerPlugin } from '../shared/indexer.4ef52548.mjs';
2
- export { j as defineIndexerPlugin } from '../shared/indexer.4ef52548.mjs';
1
+ import { i as IndexerPlugin } from '../shared/indexer.576be164.mjs';
2
+ export { j as defineIndexerPlugin } from '../shared/indexer.576be164.mjs';
3
3
  import { ConsolaReporter, ConsolaInstance } from 'consola';
4
4
  export { ConsolaInstance, ConsolaReporter } from 'consola';
5
5
  import '@apibara/protocol';
@@ -1,5 +1,5 @@
1
- import { i as IndexerPlugin } from '../shared/indexer.4ef52548.js';
2
- export { j as defineIndexerPlugin } from '../shared/indexer.4ef52548.js';
1
+ import { i as IndexerPlugin } from '../shared/indexer.576be164.js';
2
+ export { j as defineIndexerPlugin } from '../shared/indexer.576be164.js';
3
3
  import { ConsolaReporter, ConsolaInstance } from 'consola';
4
4
  export { ConsolaInstance, ConsolaReporter } from 'consola';
5
5
  import '@apibara/protocol';
@@ -106,6 +106,7 @@ interface ReconnectOptions {
106
106
  maxRetries?: number;
107
107
  retryDelay?: number;
108
108
  maxWait?: number;
109
+ signal?: AbortSignal;
109
110
  }
110
111
  declare function runWithReconnect<TFilter, TBlock>(client: Client<TFilter, TBlock>, indexer: Indexer<TFilter, TBlock>, options?: ReconnectOptions): Promise<void>;
111
112
  interface RunOptions {
@@ -106,6 +106,7 @@ interface ReconnectOptions {
106
106
  maxRetries?: number;
107
107
  retryDelay?: number;
108
108
  maxWait?: number;
109
+ signal?: AbortSignal;
109
110
  }
110
111
  declare function runWithReconnect<TFilter, TBlock>(client: Client<TFilter, TBlock>, indexer: Indexer<TFilter, TBlock>, options?: ReconnectOptions): Promise<void>;
111
112
  interface RunOptions {
@@ -106,6 +106,7 @@ interface ReconnectOptions {
106
106
  maxRetries?: number;
107
107
  retryDelay?: number;
108
108
  maxWait?: number;
109
+ signal?: AbortSignal;
109
110
  }
110
111
  declare function runWithReconnect<TFilter, TBlock>(client: Client<TFilter, TBlock>, indexer: Indexer<TFilter, TBlock>, options?: ReconnectOptions): Promise<void>;
111
112
  interface RunOptions {
@@ -1,5 +1,5 @@
1
1
  import { NestedHooks } from 'hookable';
2
- import { c as IndexerWithStreamConfig, I as IndexerHooks } from '../shared/indexer.4ef52548.cjs';
2
+ import { c as IndexerWithStreamConfig, I as IndexerHooks } from '../shared/indexer.576be164.cjs';
3
3
  import '@apibara/protocol';
4
4
 
5
5
  type VcrResult = Record<string, unknown>;
@@ -1,5 +1,5 @@
1
1
  import { NestedHooks } from 'hookable';
2
- import { c as IndexerWithStreamConfig, I as IndexerHooks } from '../shared/indexer.4ef52548.mjs';
2
+ import { c as IndexerWithStreamConfig, I as IndexerHooks } from '../shared/indexer.576be164.mjs';
3
3
  import '@apibara/protocol';
4
4
 
5
5
  type VcrResult = Record<string, unknown>;
@@ -1,5 +1,5 @@
1
1
  import { NestedHooks } from 'hookable';
2
- import { c as IndexerWithStreamConfig, I as IndexerHooks } from '../shared/indexer.4ef52548.js';
2
+ import { c as IndexerWithStreamConfig, I as IndexerHooks } from '../shared/indexer.576be164.js';
3
3
  import '@apibara/protocol';
4
4
 
5
5
  type VcrResult = Record<string, unknown>;
@@ -1,5 +1,5 @@
1
1
  import { Cursor, StreamDataResponse, Client } from '@apibara/protocol';
2
- import { e as Indexer } from '../shared/indexer.4ef52548.cjs';
2
+ import { e as Indexer } from '../shared/indexer.576be164.cjs';
3
3
  import 'hookable';
4
4
 
5
5
  type VcrConfig = {
@@ -1,5 +1,5 @@
1
1
  import { Cursor, StreamDataResponse, Client } from '@apibara/protocol';
2
- import { e as Indexer } from '../shared/indexer.4ef52548.mjs';
2
+ import { e as Indexer } from '../shared/indexer.576be164.mjs';
3
3
  import 'hookable';
4
4
 
5
5
  type VcrConfig = {
@@ -1,5 +1,5 @@
1
1
  import { Cursor, StreamDataResponse, Client } from '@apibara/protocol';
2
- import { e as Indexer } from '../shared/indexer.4ef52548.js';
2
+ import { e as Indexer } from '../shared/indexer.576be164.js';
3
3
  import 'hookable';
4
4
 
5
5
  type VcrConfig = {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@apibara/indexer",
3
- "version": "2.1.0-beta.57",
3
+ "version": "2.1.0-beta.59",
4
4
  "type": "module",
5
5
  "files": [
6
6
  "dist",
@@ -70,7 +70,7 @@
70
70
  "vitest": "^1.6.0"
71
71
  },
72
72
  "dependencies": {
73
- "@apibara/protocol": "2.1.0-beta.57",
73
+ "@apibara/protocol": "2.1.0-beta.59",
74
74
  "@opentelemetry/api": "^1.9.0",
75
75
  "ci-info": "^4.1.0",
76
76
  "consola": "^3.4.2",
package/src/indexer.ts CHANGED
@@ -181,6 +181,7 @@ export interface ReconnectOptions {
181
181
  maxRetries?: number;
182
182
  retryDelay?: number;
183
183
  maxWait?: number;
184
+ signal?: AbortSignal;
184
185
  }
185
186
 
186
187
  export async function runWithReconnect<TFilter, TBlock>(
@@ -193,10 +194,18 @@ export async function runWithReconnect<TFilter, TBlock>(
193
194
  const maxRetries = options.maxRetries ?? 10;
194
195
  const retryDelay = options.retryDelay ?? 1_000;
195
196
  const maxWait = options.maxWait ?? 30_000;
197
+ const { signal } = options;
196
198
 
197
199
  while (true) {
200
+ if (signal?.aborted) return;
201
+
198
202
  const abortController = new AbortController();
199
203
 
204
+ // Forward external abort into the per-run internal controller so that
205
+ // run() sees the abort signal and can break its loop cleanly.
206
+ const forwardAbort = () => abortController.abort(signal?.reason);
207
+ signal?.addEventListener("abort", forwardAbort, { once: true });
208
+
200
209
  const runOptions: RunOptions = {
201
210
  onConnect() {
202
211
  retryCount = 0;
@@ -206,7 +215,6 @@ export async function runWithReconnect<TFilter, TBlock>(
206
215
 
207
216
  try {
208
217
  await run(client, indexer, runOptions);
209
- abortController.abort();
210
218
  return;
211
219
  } catch (error) {
212
220
  // Only reconnect on internal/server errors.
@@ -214,7 +222,7 @@ export async function runWithReconnect<TFilter, TBlock>(
214
222
 
215
223
  retryCount++;
216
224
 
217
- abortController.abort();
225
+ if (signal?.aborted) return;
218
226
 
219
227
  if (error instanceof ClientError || error instanceof ServerError) {
220
228
  const isServerError = error instanceof ServerError;
@@ -231,15 +239,29 @@ export async function runWithReconnect<TFilter, TBlock>(
231
239
 
232
240
  // Add jitter to the retry delay to avoid all clients retrying at the same time.
233
241
  const delay = Math.random() * (retryDelay * 0.2) + retryDelay;
234
- await new Promise((resolve) =>
235
- setTimeout(resolve, Math.min(retryCount * delay, maxWait)),
236
- );
242
+ await new Promise<void>((resolve) => {
243
+ const t = setTimeout(
244
+ resolve,
245
+ Math.min(retryCount * delay, maxWait),
246
+ );
247
+ // wake up immediately if externally aborted during the delay.
248
+ signal?.addEventListener(
249
+ "abort",
250
+ () => {
251
+ clearTimeout(t);
252
+ resolve();
253
+ },
254
+ { once: true },
255
+ );
256
+ });
237
257
 
238
258
  continue;
239
259
  }
240
260
  }
241
261
  }
242
262
  throw error;
263
+ } finally {
264
+ signal?.removeEventListener("abort", forwardAbort);
243
265
  }
244
266
  }
245
267
  }
@@ -322,8 +344,29 @@ export async function run<TFilter, TBlock>(
322
344
 
323
345
  let onConnectCalled = false;
324
346
 
347
+ const abortPromise = abortSignal ? waitForAbort(abortSignal) : null;
348
+
325
349
  while (true) {
326
- const { value: message, done } = await stream.next();
350
+ let result: IteratorResult<
351
+ StreamDataResponse<TBlock>,
352
+ StreamDataResponse<TBlock>
353
+ >;
354
+
355
+ try {
356
+ result = abortPromise
357
+ ? await Promise.race([stream.next(), abortPromise])
358
+ : await stream.next();
359
+ } catch (e) {
360
+ if (abortSignal?.aborted) {
361
+ // cancel the underlying gRPC stream and exit the loop cleanly so
362
+ // that run:after hooks are still called below.
363
+ await stream.return?.();
364
+ break;
365
+ }
366
+ throw e;
367
+ }
368
+
369
+ const { value: message, done } = result;
327
370
 
328
371
  if (done) {
329
372
  break;
@@ -527,6 +570,22 @@ export async function run<TFilter, TBlock>(
527
570
  });
528
571
  }
529
572
 
573
+ /**
574
+ * Returns a promise that rejects as soon as the given AbortSignal fires.
575
+ * Used to race against stream.next() so the loop can break on abort.
576
+ */
577
+ function waitForAbort(signal: AbortSignal): Promise<never> {
578
+ return new Promise<never>((_, reject) => {
579
+ if (signal.aborted) {
580
+ reject(signal.reason);
581
+ return;
582
+ }
583
+ signal.addEventListener("abort", () => reject(signal.reason), {
584
+ once: true,
585
+ });
586
+ });
587
+ }
588
+
530
589
  async function registerMiddleware<TFilter, TBlock>(
531
590
  indexer: Indexer<TFilter, TBlock>,
532
591
  abortSignal?: AbortSignal,