apibara 2.1.0-beta.3 → 2.1.0-beta.31

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (115) hide show
  1. package/dist/chunks/add.mjs +17 -8
  2. package/dist/chunks/add.mjs.map +1 -0
  3. package/dist/chunks/build.mjs +5 -2
  4. package/dist/chunks/build.mjs.map +1 -0
  5. package/dist/chunks/dev.mjs +56 -21
  6. package/dist/chunks/dev.mjs.map +1 -0
  7. package/dist/chunks/init.mjs +12 -7
  8. package/dist/chunks/init.mjs.map +1 -0
  9. package/dist/chunks/prepare.mjs +5 -2
  10. package/dist/chunks/prepare.mjs.map +1 -0
  11. package/dist/chunks/start.mjs +16 -11
  12. package/dist/chunks/start.mjs.map +1 -0
  13. package/dist/chunks/write-project-info.mjs +51 -0
  14. package/dist/chunks/write-project-info.mjs.map +1 -0
  15. package/dist/cli/index.mjs +3 -1
  16. package/dist/cli/index.mjs.map +1 -0
  17. package/dist/common/index.d.mts +28 -0
  18. package/dist/common/index.d.ts +28 -0
  19. package/dist/common/index.mjs +64 -0
  20. package/dist/common/index.mjs.map +1 -0
  21. package/dist/config/index.mjs +1 -0
  22. package/dist/config/index.mjs.map +1 -0
  23. package/dist/core/index.mjs +133 -68
  24. package/dist/core/index.mjs.map +1 -0
  25. package/dist/create/index.d.mts +2 -1
  26. package/dist/create/index.d.ts +2 -1
  27. package/dist/create/index.mjs +144 -115
  28. package/dist/create/index.mjs.map +1 -0
  29. package/dist/hooks/index.mjs +6 -1
  30. package/dist/hooks/index.mjs.map +1 -0
  31. package/dist/indexer/index.d.ts +1 -0
  32. package/dist/indexer/index.mjs +1 -0
  33. package/dist/indexer/plugins.d.ts +1 -0
  34. package/dist/indexer/plugins.mjs +1 -0
  35. package/dist/indexer/testing.d.ts +1 -0
  36. package/dist/indexer/testing.mjs +1 -0
  37. package/dist/indexer/vcr.d.ts +1 -0
  38. package/dist/indexer/vcr.mjs +1 -0
  39. package/dist/rolldown/index.d.mts +7 -0
  40. package/dist/rolldown/index.d.ts +7 -0
  41. package/dist/rolldown/index.mjs +122 -0
  42. package/dist/rolldown/index.mjs.map +1 -0
  43. package/dist/runtime/dev.mjs +23 -10
  44. package/dist/runtime/internal/app.d.ts +16 -1
  45. package/dist/runtime/internal/app.mjs +51 -21
  46. package/dist/runtime/project-info.d.ts +3 -0
  47. package/dist/runtime/project-info.mjs +67 -0
  48. package/dist/runtime/start.mjs +27 -10
  49. package/dist/shared/apibara.63c9a277.mjs +30 -0
  50. package/dist/shared/apibara.63c9a277.mjs.map +1 -0
  51. package/dist/shared/apibara.730bb1e4.mjs +18 -0
  52. package/dist/shared/apibara.730bb1e4.mjs.map +1 -0
  53. package/dist/types/index.d.mts +24 -20
  54. package/dist/types/index.d.ts +24 -20
  55. package/dist/types/index.mjs +1 -0
  56. package/dist/types/index.mjs.map +1 -0
  57. package/package.json +33 -16
  58. package/src/cli/commands/add.ts +16 -7
  59. package/src/cli/commands/build.ts +5 -2
  60. package/src/cli/commands/dev.ts +64 -20
  61. package/src/cli/commands/init.ts +12 -7
  62. package/src/cli/commands/prepare.ts +4 -2
  63. package/src/cli/commands/start.ts +17 -10
  64. package/src/cli/commands/write-project-info.ts +56 -0
  65. package/src/cli/common.ts +33 -1
  66. package/src/cli/index.ts +2 -0
  67. package/src/common/constants.ts +6 -0
  68. package/src/common/helper.ts +86 -0
  69. package/src/common/index.ts +2 -0
  70. package/src/core/apibara.ts +7 -2
  71. package/src/core/build/build.ts +13 -5
  72. package/src/core/build/dev.ts +46 -23
  73. package/src/core/build/error.ts +9 -14
  74. package/src/core/build/prepare.ts +5 -3
  75. package/src/core/build/prod.ts +25 -16
  76. package/src/core/build/types.ts +11 -1
  77. package/src/core/config/defaults.ts +3 -0
  78. package/src/core/config/loader.ts +15 -7
  79. package/src/core/config/resolvers/runtime.resolver.ts +44 -0
  80. package/src/core/config/update.ts +6 -2
  81. package/src/create/add.ts +10 -9
  82. package/src/create/constants.ts +9 -11
  83. package/src/create/init.ts +8 -5
  84. package/src/create/templates.ts +132 -105
  85. package/src/hooks/useRuntimeConfig.ts +4 -1
  86. package/src/indexer/index.ts +1 -0
  87. package/src/indexer/plugins.ts +1 -0
  88. package/src/indexer/testing.ts +1 -0
  89. package/src/indexer/vcr.ts +1 -0
  90. package/src/rolldown/config.ts +84 -0
  91. package/src/rolldown/index.ts +2 -0
  92. package/src/{rollup → rolldown}/plugins/indexers.ts +3 -3
  93. package/src/rolldown/plugins/instrumentation.ts +68 -0
  94. package/src/runtime/dev.ts +25 -9
  95. package/src/runtime/internal/app.ts +75 -29
  96. package/src/runtime/project-info.ts +90 -0
  97. package/src/runtime/start.ts +30 -9
  98. package/src/types/config.ts +27 -13
  99. package/src/types/hooks.ts +8 -5
  100. package/src/types/index.ts +1 -1
  101. package/src/types/rolldown.ts +5 -0
  102. package/src/types/virtual/indexers.d.ts +4 -1
  103. package/src/types/virtual/instrumentation.d.ts +4 -0
  104. package/dist/rollup/index.d.mts +0 -6
  105. package/dist/rollup/index.d.ts +0 -6
  106. package/dist/rollup/index.mjs +0 -150
  107. package/dist/shared/apibara.1b515d04.mjs +0 -8
  108. package/src/core/config/resolvers/preset.resolver.ts +0 -9
  109. package/src/core/config/resolvers/runtime-config.resolver.ts +0 -6
  110. package/src/rollup/config.ts +0 -87
  111. package/src/rollup/index.ts +0 -2
  112. package/src/rollup/plugins/config.ts +0 -12
  113. package/src/rollup/plugins/esm-shim.ts +0 -69
  114. package/src/types/rollup.ts +0 -8
  115. package/src/types/virtual/config.d.ts +0 -3
@@ -1,6 +1,7 @@
1
1
  import fs from "node:fs";
2
2
  import path from "node:path";
3
3
  import { consola } from "consola";
4
+ import prompts from "prompts";
4
5
  import { type ObjectLiteralExpression, Project, SyntaxKind } from "ts-morph";
5
6
  import { cyan, green, magenta, yellow } from "./colors";
6
7
  import { packageVersions } from "./constants";
@@ -14,21 +15,18 @@ export function generatePackageJson(isTypeScript: boolean) {
14
15
  private: true,
15
16
  type: "module",
16
17
  scripts: {
17
- prepare: "apibara prepare",
18
+ ...(isTypeScript && { prepare: "apibara prepare" }),
18
19
  dev: "apibara dev",
19
20
  start: "apibara start",
20
21
  build: "apibara build",
21
22
  ...(isTypeScript && { typecheck: "tsc --noEmit" }),
22
23
  },
23
24
  dependencies: {
24
- "@apibara/indexer": packageVersions["@apibara/indexer"],
25
25
  "@apibara/protocol": packageVersions["@apibara/protocol"],
26
26
  apibara: packageVersions.apibara,
27
27
  },
28
28
  devDependencies: {
29
29
  ...(isTypeScript && {
30
- "@rollup/plugin-typescript":
31
- packageVersions["@rollup/plugin-typescript"],
32
30
  "@types/node": packageVersions["@types/node"],
33
31
  typescript: packageVersions.typescript,
34
32
  }),
@@ -58,17 +56,10 @@ export function generateTsConfig() {
58
56
  }
59
57
 
60
58
  export function generateApibaraConfig(isTypeScript: boolean) {
61
- return `${isTypeScript ? 'import typescript from "@rollup/plugin-typescript";\nimport type { Plugin } from "apibara/rollup";\n' : ""}import { defineConfig } from "apibara/config";
59
+ return `import { defineConfig } from "apibara/config";
62
60
 
63
61
  export default defineConfig({
64
- runtimeConfig: {},${
65
- isTypeScript
66
- ? `
67
- rollupConfig: {
68
- plugins: [typescript()${isTypeScript ? " as Plugin" : ""}],
69
- },`
70
- : ""
71
- }
62
+ runtimeConfig: {},
72
63
  });\n`;
73
64
  }
74
65
 
@@ -78,9 +69,10 @@ export function generateIndexer({
78
69
  chain,
79
70
  language,
80
71
  }: IndexerOptions) {
81
- return `import { defineIndexer } from "@apibara/indexer";
82
- import { useLogger } from "@apibara/indexer/plugins";
72
+ return `import { defineIndexer } from "apibara/indexer";
73
+ import { useLogger } from "apibara/plugins";
83
74
  ${storage === "postgres" ? `import { drizzleStorage } from "@apibara/plugin-drizzle";` : ""}
75
+ ${storage === "postgres" ? `import { drizzle } from "@apibara/plugin-drizzle";` : ""}
84
76
  ${
85
77
  chain === "ethereum"
86
78
  ? `import { EvmStream } from "@apibara/evm";`
@@ -91,19 +83,17 @@ ${
91
83
  : ""
92
84
  }
93
85
  ${language === "typescript" ? `import type { ApibaraRuntimeConfig } from "apibara/types";` : ""}
94
- ${
95
- storage === "postgres"
96
- ? `import { getDrizzlePgDatabase } from "../lib/db";`
97
- : ""
98
- }
86
+ ${storage === "postgres" ? `import * as schema from "../lib/schema";` : ""}
99
87
 
100
88
 
101
89
  export default function (runtimeConfig${language === "typescript" ? ": ApibaraRuntimeConfig" : ""}) {
102
90
  const indexerId = "${indexerId}";
103
- const { startingBlock, streamUrl${storage === "postgres" ? ", postgresConnectionString" : ""} } = runtimeConfig[indexerId];
91
+ const { startingBlock, streamUrl } = runtimeConfig[indexerId];
104
92
  ${
105
93
  storage === "postgres"
106
- ? "const { db } = getDrizzlePgDatabase(postgresConnectionString);"
94
+ ? `const db = drizzle({
95
+ schema,
96
+ });`
107
97
  : ""
108
98
  }
109
99
 
@@ -122,7 +112,7 @@ export default function (runtimeConfig${language === "typescript" ? ": ApibaraRu
122
112
  filter: {
123
113
  header: "always",
124
114
  },
125
- plugins: [${storage === "postgres" ? "drizzleStorage({ db, persistState: true })" : ""}],
115
+ plugins: [${storage === "postgres" ? "drizzleStorage({ db, migrate: { migrationsFolder: './drizzle' } })" : ""}],
126
116
  async transform({ endCursor, finality }) {
127
117
  const logger = useLogger();
128
118
 
@@ -136,14 +126,12 @@ export default function (runtimeConfig${language === "typescript" ? ": ApibaraRu
136
126
  ${
137
127
  storage === "postgres"
138
128
  ? `// Example snippet to insert data into db using drizzle with postgres
139
- // const { db } = useDrizzleStorage();
140
- // const { logs } = block;
141
- // for (const log of logs) {
142
- // await db.insert(exampleTable).values({
143
- // number: Number(endCursor?.orderKey),
144
- // hash: log.transactionHash,
145
- // });
146
- // }`
129
+ // const { db: database } = useDrizzleStorage();
130
+
131
+ // await database.insert(schema.cursorTable).values({
132
+ // endCursor: Number(endCursor?.orderKey),
133
+ // uniqueKey: \`\${endCursor?.uniqueKey}\`,
134
+ // });`
147
135
  : ""
148
136
  }
149
137
  },
@@ -235,12 +223,8 @@ export async function updateApibaraConfigFile({
235
223
 
236
224
  const runtimeConfigString = `{
237
225
  startingBlock: 0,
238
- streamUrl: "${dnaUrl ?? getDnaUrl(chain, network)}"${
239
- storage === "postgres"
240
- ? `,
241
- postgresConnectionString: process.env["POSTGRES_CONNECTION_STRING"] ?? "memory://${indexerId}"`
242
- : ""
243
- }}`;
226
+ streamUrl: "${dnaUrl ?? getDnaUrl(chain, network)}"
227
+ }`;
244
228
 
245
229
  const project = new Project();
246
230
  const sourceFile = project.addSourceFileAtPath(pathToConfig);
@@ -284,7 +268,7 @@ export async function updateApibaraConfigFile({
284
268
  }
285
269
 
286
270
  export async function createDrizzleStorageFiles(options: IndexerOptions) {
287
- const { cwd, language, storage } = options;
271
+ const { cwd, language, storage, indexerId } = options;
288
272
 
289
273
  if (storage !== "postgres") return;
290
274
 
@@ -312,11 +296,11 @@ export async function createDrizzleStorageFiles(options: IndexerOptions) {
312
296
  const drizzleConfigContent = `${language === "typescript" ? 'import type { Config } from "drizzle-kit";' : ""}
313
297
 
314
298
  export default {
315
- schema: "./lib/schema.ts",
299
+ schema: "./lib/schema.${fileExtension}",
316
300
  out: "./drizzle",
317
301
  dialect: "postgresql",
318
302
  dbCredentials: {
319
- url: process.env["POSTGRES_CONNECTION_STRING"] ?? "",
303
+ url: process.env["POSTGRES_CONNECTION_STRING"] ?? "memory://${indexerId}",
320
304
  },
321
305
  }${language === "typescript" ? " satisfies Config" : ""};`;
322
306
 
@@ -347,14 +331,14 @@ export default {
347
331
  });
348
332
 
349
333
  if (!schemaExists || schemaOverwrite) {
350
- const schemaContent = `// --- Add your pg table schemas here ----
334
+ const schemaContent = `// --- Add your pg table schemas here ----
351
335
 
352
336
  // import { bigint, pgTable, text, uuid } from "drizzle-orm/pg-core";
353
337
 
354
- // export const exampleTable = pgTable("example_table", {
338
+ // export const cursorTable = pgTable("cursor_table", {
355
339
  // id: uuid("id").primaryKey().defaultRandom(),
356
- // number: bigint("number", { mode: "number" }),
357
- // hash: text("hash"),
340
+ // endCursor: bigint("end_cursor", { mode: "number" }),
341
+ // uniqueKey: text("unique_key"),
358
342
  // });
359
343
 
360
344
  export {};
@@ -369,63 +353,6 @@ export {};
369
353
  consola.success(`Created ${cyan("lib/schema.ts")}`);
370
354
  }
371
355
 
372
- /**
373
- *
374
- *
375
- * DB File
376
- *
377
- *
378
- */
379
- const dbFileName = `db.${fileExtension}`;
380
-
381
- const dbPath = path.join(cwd, "lib", dbFileName);
382
-
383
- const { exists: dbExists, overwrite: dbOverwrite } = await checkFileExists(
384
- dbPath,
385
- {
386
- askPrompt: true,
387
- fileName: `lib/${dbFileName}`,
388
- allowIgnore: true,
389
- },
390
- );
391
-
392
- if (!dbExists || dbOverwrite) {
393
- const dbContent = `import * as schema from "./schema";
394
- import { drizzle as nodePgDrizzle } from "drizzle-orm/node-postgres";
395
- import { drizzle as pgLiteDrizzle } from "drizzle-orm/pglite";
396
- import pg from "pg";
397
-
398
-
399
- export function getDrizzlePgDatabase(connectionString${language === "typescript" ? ": string" : ""}) {
400
- // Create pglite instance
401
- if (connectionString.includes("memory")) {
402
- return {
403
- db: pgLiteDrizzle({
404
- schema,
405
- connection: {
406
- dataDir: connectionString,
407
- },
408
- }),
409
- };
410
- }
411
-
412
- // Create node-postgres instance
413
- const pool = new pg.Pool({
414
- connectionString,
415
- });
416
-
417
- return { db: nodePgDrizzle(pool, { schema }) };
418
- }`;
419
-
420
- // create directory if it doesn't exist
421
- fs.mkdirSync(path.dirname(dbPath), { recursive: true });
422
- fs.writeFileSync(dbPath, dbContent);
423
-
424
- await formatFile(dbPath);
425
-
426
- consola.success(`Created ${cyan(`lib/${dbFileName}`)}`);
427
- }
428
-
429
356
  console.log("\n");
430
357
 
431
358
  // If schema file is created, show the example
@@ -445,17 +372,17 @@ ${yellow(`
445
372
 
446
373
  import { bigint, pgTable, text, uuid } from "drizzle-orm/pg-core";
447
374
 
448
- export const exampleTable = pgTable("example_table", {
375
+ export const cursorTable = pgTable("cursor_table", {
449
376
  id: uuid("id").primaryKey().defaultRandom(),
450
- number: bigint("number", { mode: "number" }),
451
- hash: text("hash"),
377
+ endCursor: bigint("end_cursor", { mode: "number" }),
378
+ uniqueKey: text("unique_key"),
452
379
  });`)}`);
453
380
 
454
381
  console.log("\n");
455
382
  }
456
383
 
457
384
  consola.info(
458
- `Run ${green(`${options.packageManager} run drizzle:generate`)} & ${green(`${options.packageManager} run drizzle:migrate`)} to generate and apply migrations.`,
385
+ `Run ${green(`${options.packageManager}${options.packageManager === "npm" ? " run" : ""} drizzle:generate`)} & ${green(`${options.packageManager}${options.packageManager === "npm" ? " run" : ""} drizzle:migrate`)} to generate and apply migrations.`,
459
386
  );
460
387
  }
461
388
 
@@ -466,3 +393,103 @@ export async function createStorageRelatedFiles(options: IndexerOptions) {
466
393
  await createDrizzleStorageFiles(options);
467
394
  }
468
395
  }
396
+
397
+ const gitIgnoreItems: {
398
+ isRecommended: boolean;
399
+ description?: string;
400
+ value: string;
401
+ }[] = [
402
+ {
403
+ isRecommended: false,
404
+ value: "node_modules",
405
+ },
406
+ {
407
+ isRecommended: false,
408
+ value: "dist",
409
+ },
410
+ {
411
+ isRecommended: true,
412
+ description: "build and dev files of apibara",
413
+ value: ".apibara",
414
+ },
415
+ {
416
+ isRecommended: false,
417
+ value: ".env",
418
+ },
419
+ {
420
+ isRecommended: false,
421
+ description: "for mac users",
422
+ value: ".DS_Store",
423
+ },
424
+ ];
425
+
426
+ export async function createGitIgnoreFile(cwd: string) {
427
+ const gitIgnorePath = path.join(cwd, ".gitignore");
428
+
429
+ if (fs.existsSync(gitIgnorePath)) {
430
+ const result = await prompts([
431
+ {
432
+ type: "select",
433
+ name: "overwrite",
434
+ message: `${cyan(".gitignore")} already exists. Please choose how to proceed:`,
435
+ initial: 0,
436
+ choices: [
437
+ {
438
+ title: "Choose items to append in your .gitignore",
439
+ value: "append",
440
+ },
441
+ {
442
+ title: "Keep original",
443
+ value: "ignore",
444
+ },
445
+ {
446
+ title: "Overwrite",
447
+ value: "overwrite",
448
+ },
449
+ ],
450
+ },
451
+ {
452
+ type: (overwrite: "append" | "ignore" | "overwrite") =>
453
+ overwrite === "append" ? "multiselect" : null,
454
+ name: "ignoreItems",
455
+ message: "Choose items to append in your .gitignore",
456
+ choices: gitIgnoreItems.map((item) => ({
457
+ title: `${yellow(item.value)}${
458
+ item.description ? ` - ${item.description}` : ""
459
+ }${item.isRecommended ? ` ${green("(recommended)")}` : ""}`,
460
+ value: item.value,
461
+ })),
462
+ },
463
+ ]);
464
+
465
+ const { overwrite, ignoreItems } = result as {
466
+ overwrite: "append" | "ignore" | "overwrite";
467
+ ignoreItems: string[];
468
+ };
469
+
470
+ if (overwrite === "append" && ignoreItems.length > 0) {
471
+ const gitIgnoreContent = fs.readFileSync(gitIgnorePath, "utf8");
472
+ fs.writeFileSync(
473
+ gitIgnorePath,
474
+ `${gitIgnoreContent}\n${result.ignoreItems.join("\n")}`,
475
+ );
476
+ consola.success(`Updated ${cyan(".gitignore")}`);
477
+ return;
478
+ }
479
+
480
+ if (overwrite === "overwrite") {
481
+ fs.writeFileSync(
482
+ gitIgnorePath,
483
+ gitIgnoreItems.map((item) => item.value).join("\n"),
484
+ );
485
+ consola.success(`Updated ${cyan(".gitignore")}`);
486
+ return;
487
+ }
488
+ }
489
+
490
+ fs.writeFileSync(
491
+ gitIgnorePath,
492
+ gitIgnoreItems.map((item) => item.value).join("\n"),
493
+ );
494
+ consola.success(`Created ${cyan(".gitignore")}`);
495
+ }
@@ -1,5 +1,8 @@
1
+ import { ENV_INTERNAL_APIBARA_PROCESSED_RUNTIME } from "apibara/common";
1
2
  import type { ApibaraRuntimeConfig } from "apibara/types";
2
3
 
3
4
  export function useRuntimeConfig(): ApibaraRuntimeConfig {
4
- return JSON.parse(process.env.APIBARA_RUNTIME_CONFIG || "{}");
5
+ return JSON.parse(
6
+ process.env[ENV_INTERNAL_APIBARA_PROCESSED_RUNTIME] || "{}",
7
+ );
5
8
  }
@@ -0,0 +1 @@
1
+ export * from "@apibara/indexer";
@@ -0,0 +1 @@
1
+ export * from "@apibara/indexer/plugins";
@@ -0,0 +1 @@
1
+ export * from "@apibara/indexer/testing";
@@ -0,0 +1 @@
1
+ export * from "@apibara/indexer/vcr";
@@ -0,0 +1,84 @@
1
+ import { existsSync } from "node:fs";
2
+ import { builtinModules } from "node:module";
3
+ import type { Apibara } from "apibara/types";
4
+ import defu from "defu";
5
+ import { join } from "pathe";
6
+ import type {
7
+ ConfigExport,
8
+ RolldownOptions,
9
+ RolldownPluginOption,
10
+ } from "rolldown";
11
+ import { indexers } from "./plugins/indexers";
12
+ import { instrumentation } from "./plugins/instrumentation";
13
+
14
+ const runtimeDependencies = [
15
+ "better-sqlite3",
16
+ "@electric-sql/pglite",
17
+ "pg",
18
+ // https://socket.io/docs/v4/server-installation/#additional-packages
19
+ "utf-8-validate",
20
+ "bufferutil",
21
+ // was giving unresolved import warnings from `node-fetch` library.
22
+ "encoding",
23
+ ];
24
+
25
+ export function getRolldownConfig(apibara: Apibara): RolldownOptions {
26
+ const extensions: string[] = [
27
+ ".ts",
28
+ ".mjs",
29
+ ".js",
30
+ ".json",
31
+ ".node",
32
+ ".tsx",
33
+ ".jsx",
34
+ ];
35
+
36
+ const tsConfigExists = existsSync(
37
+ join(apibara.options.rootDir, "tsconfig.json"),
38
+ );
39
+
40
+ const rolldownConfig: RolldownOptions & {
41
+ plugins: RolldownPluginOption[];
42
+ } = defu(
43
+ // biome-ignore lint/suspicious/noExplicitAny: apibara.options.rolldownConfig is typed
44
+ apibara.options.rolldownConfig as any,
45
+ <ConfigExport>{
46
+ platform: "node",
47
+ input: apibara.options.entry,
48
+ output: {
49
+ dir: join(apibara.options.outputDir || "./.apibara/build"),
50
+ format: "esm",
51
+ entryFileNames: "[name].mjs",
52
+ chunkFileNames: "chunks/[name]-[hash].mjs",
53
+ sourcemap: true,
54
+ },
55
+ plugins: [],
56
+ onwarn(warning, rolldownWarn) {
57
+ if (
58
+ !["CIRCULAR_DEPENDENCY", "EVAL", "THIS_IS_UNDEFINED"].includes(
59
+ warning.code || "",
60
+ ) &&
61
+ !warning.message.includes("Unsupported source map comment") &&
62
+ !warning.message.includes("@__PURE__") &&
63
+ !warning.message.includes("/*#__PURE__*/")
64
+ ) {
65
+ rolldownWarn(warning);
66
+ }
67
+ },
68
+ resolve: {
69
+ extensions,
70
+ preferBuiltins: !!apibara.options.node,
71
+ mainFields: ["main"],
72
+ exportConditions: apibara.options.exportConditions,
73
+ tsconfigFilename: tsConfigExists ? "tsconfig.json" : undefined,
74
+ },
75
+ treeshake: true,
76
+ external: [...builtinModules, ...runtimeDependencies],
77
+ },
78
+ );
79
+
80
+ rolldownConfig.plugins?.push(instrumentation(apibara));
81
+ rolldownConfig.plugins?.push(indexers(apibara));
82
+
83
+ return rolldownConfig;
84
+ }
@@ -0,0 +1,2 @@
1
+ export * from "./config";
2
+ export type { Plugin } from "rolldown";
@@ -1,17 +1,17 @@
1
1
  import virtual from "@rollup/plugin-virtual";
2
2
  import type { Apibara } from "apibara/types";
3
3
  import { hash } from "ohash";
4
+ import type { RolldownPluginOption } from "rolldown";
4
5
 
5
6
  export function indexers(apibara: Apibara) {
6
7
  const indexers = [...new Set(apibara.indexers)];
7
-
8
8
  return virtual({
9
9
  "#apibara-internal-virtual/indexers": `
10
- ${indexers.map((i) => `import _${hash(i)} from '${i.indexer}';`).join("\n")}
10
+ ${indexers.map((i) => `import * as _${hash(i)} from '${i.indexer}';`).join("\n")}
11
11
 
12
12
  export const indexers = [
13
13
  ${indexers.map((i) => `{ name: "${i.name}", indexer: _${hash(i)} }`).join(",\n")}
14
14
  ];
15
15
  `,
16
- });
16
+ }) as RolldownPluginOption;
17
17
  }
@@ -0,0 +1,68 @@
1
+ import { existsSync } from "node:fs";
2
+ import { join } from "node:path";
3
+ import virtual from "@rollup/plugin-virtual";
4
+ import type { Apibara } from "apibara/types";
5
+ import type { RolldownPluginOption } from "rolldown";
6
+
7
+ export function instrumentation(apibara: Apibara) {
8
+ const instrumentationPath = join(
9
+ apibara.options._c12.cwd!,
10
+ `instrumentation.${apibara.options._c12.configFile?.endsWith(".ts") ? "ts" : "js"}`,
11
+ );
12
+
13
+ if (!existsSync(instrumentationPath)) {
14
+ return virtual({
15
+ "#apibara-internal-virtual/instrumentation": `
16
+ let register = undefined;
17
+ let logger = undefined;
18
+
19
+ export { register, logger };
20
+ `,
21
+ }) as RolldownPluginOption;
22
+ }
23
+
24
+ /**
25
+ * We are importing the instrumentation file inline with "require" instead of "import" at the top of the file to avoid warnings from rolldown
26
+ * when some methods are not defined in the instrumentation file.
27
+ *
28
+ * Example warning:
29
+ *
30
+ * [IMPORT_IS_UNDEFINED] Warning: Import `logger` will always be undefined because there is no matching export in 'instrumentation.ts'
31
+ * ╭─[virtual:#apibara-internal-virtual/instrumentation:11:35]
32
+ * │
33
+ * 11 │ if (instrumentation && typeof instrumentation.logger === "function") {
34
+ * │ ───────────┬──────────
35
+ * │ ╰────────────
36
+ * ────╯
37
+
38
+ * [IMPORT_IS_UNDEFINED] Warning: Import `logger` will always be undefined because there is no matching export in 'instrumentation.ts'
39
+ * ╭─[virtual:#apibara-internal-virtual/instrumentation:12:16]
40
+ * │
41
+ * 12 │ logger = instrumentation.logger;
42
+ * │ ───────────┬──────────
43
+ * │ ╰────────────
44
+ * ────╯
45
+ */
46
+ return virtual({
47
+ "#apibara-internal-virtual/instrumentation": `
48
+ let register = undefined;
49
+ let logger = undefined;
50
+
51
+ try {
52
+ const instrumentation = require('${instrumentationPath}');
53
+
54
+ if (instrumentation?.register && typeof instrumentation.register === "function") {
55
+ register = instrumentation.register;
56
+ }
57
+
58
+ if (instrumentation?.logger && typeof instrumentation.logger === "function") {
59
+ logger = instrumentation.logger;
60
+ }
61
+ } catch {
62
+ // Silently handle any require errors
63
+ }
64
+
65
+ export { register, logger };
66
+ `,
67
+ }) as RolldownPluginOption;
68
+ }
@@ -1,7 +1,12 @@
1
1
  import { runWithReconnect } from "@apibara/indexer";
2
- import { createClient } from "@apibara/protocol";
2
+ import { getRuntimeDataFromEnv } from "apibara/common";
3
3
  import { defineCommand, runMain } from "citty";
4
- import { availableIndexers, createIndexer } from "./internal/app";
4
+ import { blueBright } from "picocolors";
5
+ import {
6
+ availableIndexers,
7
+ createAuthenticatedClient,
8
+ createIndexer,
9
+ } from "./internal/app";
5
10
 
6
11
  const startCommand = defineCommand({
7
12
  meta: {
@@ -13,13 +18,11 @@ const startCommand = defineCommand({
13
18
  type: "string",
14
19
  description: "Which indexers to run",
15
20
  },
16
- preset: {
17
- type: "string",
18
- description: "Preset to use",
19
- },
20
21
  },
21
22
  async run({ args }) {
22
- const { indexers: indexersArgs, preset } = args;
23
+ const { indexers: indexersArgs } = args;
24
+
25
+ const { processedRuntimeConfig, preset } = getRuntimeDataFromEnv();
23
26
 
24
27
  let selectedIndexers = availableIndexers;
25
28
  if (indexersArgs) {
@@ -36,13 +39,26 @@ const startCommand = defineCommand({
36
39
 
37
40
  await Promise.all(
38
41
  selectedIndexers.map(async (indexer) => {
39
- const indexerInstance = createIndexer(indexer, preset);
42
+ const { indexer: indexerInstance, logger } =
43
+ createIndexer({
44
+ indexerName: indexer,
45
+ processedRuntimeConfig,
46
+ preset,
47
+ }) ?? {};
48
+ if (!indexerInstance) {
49
+ return;
50
+ }
40
51
 
41
- const client = createClient(
52
+ const client = createAuthenticatedClient(
42
53
  indexerInstance.streamConfig,
43
54
  indexerInstance.options.streamUrl,
55
+ indexerInstance.options.clientOptions,
44
56
  );
45
57
 
58
+ if (logger) {
59
+ logger.info(`Indexer ${blueBright(indexer)} started`);
60
+ }
61
+
46
62
  await runWithReconnect(client, indexerInstance);
47
63
  }),
48
64
  );