diff --git a/change/@apibara-indexer-95c6848e-72aa-429f-bbe9-556a867c123e.json b/change/@apibara-indexer-95c6848e-72aa-429f-bbe9-556a867c123e.json new file mode 100644 index 00000000..a7cd487b --- /dev/null +++ b/change/@apibara-indexer-95c6848e-72aa-429f-bbe9-556a867c123e.json @@ -0,0 +1,7 @@ +{ + "type": "prerelease", + "comment": "Add logger plugin", + "packageName": "@apibara/indexer", + "email": "francesco@ceccon.me", + "dependentChangeType": "patch" +} diff --git a/change/apibara-45ec1e62-bbea-48bc-ac29-b6ea1acc4024.json b/change/apibara-45ec1e62-bbea-48bc-ac29-b6ea1acc4024.json new file mode 100644 index 00000000..989f039c --- /dev/null +++ b/change/apibara-45ec1e62-bbea-48bc-ac29-b6ea1acc4024.json @@ -0,0 +1,7 @@ +{ + "type": "prerelease", + "comment": "Add logger plugin", + "packageName": "apibara", + "email": "francesco@ceccon.me", + "dependentChangeType": "patch" +} diff --git a/examples/cli/indexers/1-evm.indexer.ts b/examples/cli/indexers/1-evm.indexer.ts index 3aace3bf..831fd990 100644 --- a/examples/cli/indexers/1-evm.indexer.ts +++ b/examples/cli/indexers/1-evm.indexer.ts @@ -2,17 +2,16 @@ import { EvmStream } from "@apibara/evm"; import { defineIndexer } from "@apibara/indexer"; export default defineIndexer(EvmStream)({ - streamUrl: "http://localhost:7007", + streamUrl: "https://ethereum.preview.apibara.org", finality: "accepted", + startingCursor: { + orderKey: 10_000_000n, + }, filter: { header: "always", + transactions: [{}], }, - async transform({ cursor, endCursor }) { - console.log({ cursor, endCursor }); - }, - hooks: { - "message:invalidate"({ message }) { - console.warn(message); - }, + async transform({ endCursor }) { + console.log({ endCursor }); }, }); diff --git a/examples/cli/indexers/2-starknet.indexer.ts b/examples/cli/indexers/2-starknet.indexer.ts index 061e784e..4bbbc592 100644 --- a/examples/cli/indexers/2-starknet.indexer.ts +++ b/examples/cli/indexers/2-starknet.indexer.ts @@ -1,4 +1,5 @@ import { defineIndexer, useSink } from "@apibara/indexer"; +import { useLogger } from "@apibara/indexer/plugins/logger"; import { sqlite } from "@apibara/indexer/sinks/sqlite"; import { StarknetStream } from "@apibara/starknet"; import type { ApibaraRuntimeConfig } from "apibara/types"; @@ -31,7 +32,9 @@ export default function (runtimeConfig: ApibaraRuntimeConfig) { }, ], }, - async transform({ block: { header }, context }) { + async transform({ endCursor, block: { header }, context }) { + const logger = useLogger(); + logger.info("Transforming block ", endCursor); const { writer } = useSink({ context }); // writer.insert([{ diff --git a/packages/cli/src/runtime/internal/app.ts b/packages/cli/src/runtime/internal/app.ts index dd841d40..e738b8db 100644 --- a/packages/cli/src/runtime/internal/app.ts +++ b/packages/cli/src/runtime/internal/app.ts @@ -1,4 +1,5 @@ import { createIndexer as _createIndexer } from "@apibara/indexer"; +import { logger } from "@apibara/indexer/plugins/logger"; import { config } from "#apibara-internal-virtual/config"; import { indexers } from "#apibara-internal-virtual/indexers"; @@ -33,7 +34,12 @@ export function createIndexer(indexerName: string, preset?: string) { ); } - return typeof indexerDefinition.indexer === "function" - ? _createIndexer(indexerDefinition.indexer(runtimeConfig)) - : _createIndexer(indexerDefinition.indexer); + const definition = + typeof indexerDefinition.indexer === "function" + ? indexerDefinition.indexer(runtimeConfig) + : indexerDefinition.indexer; + + definition.plugins = [...(definition.plugins ?? []), logger()]; + + return _createIndexer(definition); } diff --git a/packages/indexer/build.config.ts b/packages/indexer/build.config.ts index 9beccbce..ebb537d5 100644 --- a/packages/indexer/build.config.ts +++ b/packages/indexer/build.config.ts @@ -10,6 +10,7 @@ export default defineBuildConfig({ "./src/vcr/index.ts", "./src/plugins/index.ts", "./src/plugins/kv.ts", + "./src/plugins/logger.ts", "./src/plugins/persistence.ts", ], clean: true, diff --git a/packages/indexer/package.json b/packages/indexer/package.json index 4e29a101..e27f991c 100644 --- a/packages/indexer/package.json +++ b/packages/indexer/package.json @@ -52,6 +52,12 @@ "require": "./dist/plugins/index.cjs", "default": "./dist/plugins/index.mjs" }, + "./plugins/logger": { + "types": "./dist/plugins/logger.d.ts", + "import": "./dist/plugins/logger.mjs", + "require": "./dist/plugins/logger.cjs", + "default": "./dist/plugins/logger.mjs" + }, "./plugins/kv": { "types": "./dist/plugins/kv.d.ts", "import": "./dist/plugins/kv.mjs", diff --git a/packages/indexer/src/plugins/logger.ts b/packages/indexer/src/plugins/logger.ts new file mode 100644 index 00000000..c8fe59e7 --- /dev/null +++ b/packages/indexer/src/plugins/logger.ts @@ -0,0 +1,30 @@ +import { type ConsolaInstance, type ConsolaReporter, consola } from "consola"; +import { useIndexerContext } from "../context"; +import { defineIndexerPlugin } from "./config"; + +export type { ConsolaReporter, ConsolaInstance } from "consola"; + +export function logger({ + logger, +}: { logger?: ConsolaReporter } = {}) { + return defineIndexerPlugin((indexer) => { + indexer.hooks.hook("run:before", () => { + const ctx = useIndexerContext(); + + if (logger) { + ctx.logger = consola.create({ reporters: [logger] }); + } else { + ctx.logger = consola.create({}); + } + }); + }); +} + +export function useLogger(): ConsolaInstance { + const ctx = useIndexerContext(); + + if (!ctx?.logger) + throw new Error("Logger plugin is not available in context"); + + return ctx.logger; +}