apibara 2.0.0-beta.9 → 2.1.0-beta.3

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 (83) hide show
  1. package/dist/chunks/add.mjs +44 -0
  2. package/dist/chunks/build.mjs +3 -3
  3. package/dist/chunks/dev.mjs +22 -18
  4. package/dist/chunks/init.mjs +37 -0
  5. package/dist/chunks/prepare.mjs +0 -2
  6. package/dist/chunks/start.mjs +56 -0
  7. package/dist/cli/index.mjs +5 -1
  8. package/dist/config/index.d.mts +1 -1
  9. package/dist/config/index.d.ts +1 -1
  10. package/dist/core/index.mjs +61 -97
  11. package/dist/create/index.d.mts +17 -0
  12. package/dist/create/index.d.ts +17 -0
  13. package/dist/create/index.mjs +981 -0
  14. package/dist/rollup/index.d.mts +2 -1
  15. package/dist/rollup/index.d.ts +2 -1
  16. package/dist/rollup/index.mjs +130 -167
  17. package/dist/runtime/dev.d.ts +3 -0
  18. package/dist/runtime/dev.mjs +55 -0
  19. package/dist/runtime/index.d.ts +2 -0
  20. package/dist/runtime/index.mjs +2 -0
  21. package/dist/runtime/internal/app.d.ts +2 -0
  22. package/dist/runtime/internal/app.mjs +56 -0
  23. package/dist/runtime/internal/logger.d.ts +14 -0
  24. package/dist/runtime/internal/logger.mjs +45 -0
  25. package/dist/runtime/start.d.ts +3 -0
  26. package/dist/runtime/start.mjs +41 -0
  27. package/dist/types/index.d.mts +22 -19
  28. package/dist/types/index.d.ts +22 -19
  29. package/package.json +35 -13
  30. package/runtime-meta.d.ts +2 -0
  31. package/runtime-meta.mjs +7 -0
  32. package/src/cli/commands/add.ts +44 -0
  33. package/src/cli/commands/build.ts +5 -3
  34. package/src/cli/commands/dev.ts +28 -18
  35. package/src/cli/commands/init.ts +36 -0
  36. package/src/cli/commands/prepare.ts +0 -2
  37. package/src/cli/commands/start.ts +61 -0
  38. package/src/cli/index.ts +3 -0
  39. package/src/config/index.ts +5 -4
  40. package/src/core/apibara.ts +4 -2
  41. package/src/core/build/build.ts +2 -0
  42. package/src/core/build/dev.ts +1 -0
  43. package/src/core/build/error.ts +0 -1
  44. package/src/core/build/prepare.ts +5 -2
  45. package/src/core/build/prod.ts +10 -6
  46. package/src/core/build/types.ts +4 -95
  47. package/src/core/config/defaults.ts +1 -4
  48. package/src/core/config/loader.ts +1 -0
  49. package/src/core/config/resolvers/runtime-config.resolver.ts +1 -1
  50. package/src/core/config/update.ts +2 -3
  51. package/src/core/path.ts +11 -0
  52. package/src/core/scan.ts +40 -0
  53. package/src/create/add.ts +238 -0
  54. package/src/create/colors.ts +15 -0
  55. package/src/create/constants.ts +98 -0
  56. package/src/create/index.ts +2 -0
  57. package/src/create/init.ts +175 -0
  58. package/src/create/templates.ts +468 -0
  59. package/src/create/types.ts +34 -0
  60. package/src/create/utils.ts +422 -0
  61. package/src/rollup/config.ts +67 -189
  62. package/src/rollup/index.ts +1 -0
  63. package/src/rollup/plugins/config.ts +12 -0
  64. package/src/rollup/plugins/esm-shim.ts +69 -0
  65. package/src/rollup/plugins/indexers.ts +17 -0
  66. package/src/runtime/dev.ts +64 -0
  67. package/src/runtime/index.ts +2 -0
  68. package/src/runtime/internal/app.ts +78 -0
  69. package/src/runtime/internal/logger.ts +70 -0
  70. package/src/runtime/start.ts +48 -0
  71. package/src/types/apibara.ts +8 -0
  72. package/src/types/config.ts +28 -27
  73. package/src/types/hooks.ts +1 -0
  74. package/src/types/virtual/config.d.ts +3 -0
  75. package/src/types/virtual/indexers.d.ts +10 -0
  76. package/dist/internal/citty/index.d.mts +0 -1
  77. package/dist/internal/citty/index.d.ts +0 -1
  78. package/dist/internal/citty/index.mjs +0 -1
  79. package/dist/internal/consola/index.d.mts +0 -2
  80. package/dist/internal/consola/index.d.ts +0 -2
  81. package/dist/internal/consola/index.mjs +0 -1
  82. package/src/internal/citty/index.ts +0 -1
  83. package/src/internal/consola/index.ts +0 -1
@@ -1,9 +1,9 @@
1
1
  import { ConsolaInstance } from 'consola';
2
2
  import { NestedHooks, Hookable } from 'hookable';
3
- import { Sink } from '@apibara/indexer';
3
+ import { ConsolaReporter } from '@apibara/indexer/plugins';
4
+ import { RollupCommonJSOptions } from '@rollup/plugin-commonjs';
4
5
  import { C12InputConfig, WatchConfigOptions, ResolvedConfig, ConfigWatcher } from 'c12';
5
6
  import { WatchOptions } from 'chokidar';
6
- import { TSConfig } from 'pkg-types';
7
7
  import { InputOptions, OutputOptions } from 'rollup';
8
8
 
9
9
  type DeepPartial<T> = T extends Record<string, any> ? {
@@ -17,23 +17,26 @@ type RollupConfig = InputOptions & {
17
17
  interface ApibaraHooks {
18
18
  "rollup:before": (apibara: Apibara, rollupConfig: RollupConfig) => void;
19
19
  compiled: (apibara: Apibara) => void;
20
+ "dev:restart": () => void;
20
21
  "dev:reload": () => void;
21
22
  "rollup:reload": () => void;
22
23
  restart: () => void;
23
24
  close: () => void;
24
25
  }
25
26
 
27
+ type LoggerFactory = ({ indexer, preset, }: {
28
+ indexer: string;
29
+ indexers: string[];
30
+ preset?: string;
31
+ }) => ConsolaReporter;
26
32
  /**
27
33
  * Apibara Config type (apibara.config)
28
34
  */
29
- interface ApibaraConfig<T extends Record<string, DeepPartial<ApibaraConfig<T, R>>> = {}, R extends Record<string, unknown> = {}> extends DeepPartial<Omit<ApibaraOptions<T, R>, "preset" | "presets" | "dev">>, C12InputConfig<ApibaraConfig<T, R>> {
30
- sink?: {
31
- default: () => Sink;
32
- [key: string]: () => Sink;
33
- };
35
+ interface ApibaraConfig<T extends Record<string, DeepPartial<Pick<ApibaraConfig<T, R>, "runtimeConfig">>> = Record<string, never>, R extends Record<string, unknown> = Record<string, never>> extends Partial<Omit<ApibaraOptions<T, R>, "preset" | "presets" | "dev">>, C12InputConfig<ApibaraConfig<T, R>> {
34
36
  runtimeConfig?: R;
35
37
  presets?: T;
36
38
  preset?: keyof T;
39
+ logger?: LoggerFactory;
37
40
  }
38
41
  type ApibaraDynamicConfig = Pick<ApibaraConfig, "runtimeConfig">;
39
42
  /**
@@ -43,13 +46,9 @@ interface LoadConfigOptions {
43
46
  watch?: boolean;
44
47
  c12?: WatchConfigOptions;
45
48
  }
46
- interface ApibaraOptions<T extends Record<string, DeepPartial<ApibaraConfig<T, R>>> = {}, R extends Record<string, unknown> = {}> {
49
+ interface ApibaraOptions<T extends Record<string, DeepPartial<Pick<ApibaraConfig<T, R>, "runtimeConfig">>> = Record<string, never>, R extends Record<string, unknown> = Record<string, never>> {
47
50
  _config: ApibaraConfig<T, R>;
48
51
  _c12: ResolvedConfig<ApibaraConfig<T, R>> | ConfigWatcher<ApibaraConfig<T, R>>;
49
- sink: {
50
- default: () => Sink;
51
- [key: string]: () => Sink;
52
- };
53
52
  presets?: T;
54
53
  preset?: keyof T;
55
54
  debug: boolean;
@@ -57,26 +56,30 @@ interface ApibaraOptions<T extends Record<string, DeepPartial<ApibaraConfig<T, R
57
56
  rootDir: string;
58
57
  buildDir: string;
59
58
  outputDir: string;
59
+ indexersDir: string;
60
60
  dev: boolean;
61
61
  watchOptions: WatchOptions;
62
62
  hooks: NestedHooks<ApibaraHooks>;
63
- rollupConfig?: RollupConfig;
63
+ logger?: LoggerFactory;
64
+ rollupConfig?: Partial<RollupConfig>;
65
+ sourceMap?: boolean;
64
66
  entry: string;
65
- minify: boolean;
67
+ commonJS?: RollupCommonJSOptions;
66
68
  typescript: {
67
69
  strict?: boolean;
68
70
  internalPaths?: boolean;
69
71
  generateRuntimeConfigTypes?: boolean;
70
- generateTsConfig?: boolean;
71
- /** the path of the generated `tsconfig.json`, relative to buildDir */
72
- tsconfigPath: string;
73
- tsConfig?: Partial<TSConfig>;
74
72
  };
75
73
  }
76
74
 
75
+ type IndexerDefinition = {
76
+ name: string;
77
+ indexer: string;
78
+ };
77
79
  interface Apibara {
78
80
  options: ApibaraOptions;
79
81
  hooks: Hookable<ApibaraHooks>;
82
+ indexers: IndexerDefinition[];
80
83
  logger: ConsolaInstance;
81
84
  close: () => Promise<void>;
82
85
  updateConfig: (config: ApibaraDynamicConfig) => void | Promise<void>;
@@ -84,4 +87,4 @@ interface Apibara {
84
87
 
85
88
  type ApibaraRuntimeConfig = Record<string, unknown>;
86
89
 
87
- export type { Apibara, ApibaraConfig, ApibaraDynamicConfig, ApibaraHooks, ApibaraOptions, ApibaraRuntimeConfig, DeepPartial, LoadConfigOptions, RollupConfig };
90
+ export type { Apibara, ApibaraConfig, ApibaraDynamicConfig, ApibaraHooks, ApibaraOptions, ApibaraRuntimeConfig, DeepPartial, IndexerDefinition, LoadConfigOptions, LoggerFactory, RollupConfig };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "apibara",
3
- "version": "2.0.0-beta.9",
3
+ "version": "2.1.0-beta.3",
4
4
  "type": "module",
5
5
  "main": "./dist/core/index.mjs",
6
6
  "exports": {
@@ -32,13 +32,25 @@
32
32
  "types": "./dist/hooks/index.d.ts",
33
33
  "import": "./dist/hooks/index.mjs"
34
34
  },
35
- "./internal/consola": {
36
- "import": "./dist/internal/consola/index.mjs",
37
- "types": "./dist/internal/consola/index.d.ts"
35
+ "./runtime": {
36
+ "types": "./dist/runtime/index.d.ts",
37
+ "import": "./dist/runtime/index.mjs"
38
38
  },
39
- "./internal/citty": {
40
- "import": "./dist/internal/citty/index.mjs",
41
- "types": "./dist/internal/citty/index.d.ts"
39
+ "./create": {
40
+ "types": "./dist/create/index.d.ts",
41
+ "import": "./dist/create/index.mjs"
42
+ },
43
+ "./runtime/meta": {
44
+ "types": "./runtime-meta.d.ts",
45
+ "import": "./runtime-meta.mjs"
46
+ },
47
+ "./runtime/*": {
48
+ "types": "./dist/runtime/*.d.ts",
49
+ "import": "./dist/runtime/*.mjs"
50
+ },
51
+ "./dist/runtime/*": {
52
+ "types": "./dist/runtime/*.d.ts",
53
+ "import": "./dist/runtime/*.mjs"
42
54
  }
43
55
  },
44
56
  "bin": {
@@ -47,6 +59,8 @@
47
59
  "files": [
48
60
  "dist",
49
61
  "src",
62
+ "runtime-meta.d.ts",
63
+ "runtime-meta.mjs",
50
64
  "README.md"
51
65
  ],
52
66
  "scripts": {
@@ -55,15 +69,17 @@
55
69
  "typecheck": "tsc --noEmit",
56
70
  "lint:fix": "pnpm lint --write",
57
71
  "format": "biome format . --write",
58
- "playground": "JITI_ESM_RESOLVE=1 NODE_OPTIONS=\"--enable-source-maps\" jiti ./src/cli/index.ts",
72
+ "playground": "JITI_ESM_RESOLVE=1 CONSOLA_LEVEL=debug NODE_OPTIONS=\"--enable-source-maps\" jiti ./src/cli/index.ts",
59
73
  "playground:prepare": "pnpm playground prepare --dir playground",
60
74
  "playground:dev": "pnpm playground dev --dir playground",
61
75
  "playground:build": "pnpm playground build --dir playground",
62
- "playground:start": "JITI_ESM_RESOLVE=1 NODE_OPTIONS=\"--enable-source-maps\" jiti ./playground/.apibara/build/main.mjs"
76
+ "playground:start": "pnpm playground start --dir playground --indexer starknet"
63
77
  },
64
78
  "devDependencies": {
79
+ "@apibara/starknet": "2.1.0-beta.3",
65
80
  "@types/fs-extra": "^11.0.4",
66
81
  "@types/node": "^20.14.0",
82
+ "@types/prompts": "^2.4.9",
67
83
  "jiti": "^1.21.0",
68
84
  "starknet": "^6.11.0",
69
85
  "unbuild": "^2.0.0",
@@ -71,14 +87,13 @@
71
87
  "vitest": "^1.6.0"
72
88
  },
73
89
  "dependencies": {
74
- "@apibara/evm": "2.0.1-beta.1",
75
- "@apibara/indexer": "2.0.0-beta.9",
76
- "@apibara/protocol": "2.0.0-beta.9",
77
- "@apibara/starknet": "2.0.0-beta.9",
90
+ "@apibara/indexer": "2.1.0-beta.3",
91
+ "@apibara/protocol": "2.1.0-beta.3",
78
92
  "@rollup/plugin-commonjs": "^26.0.1",
79
93
  "@rollup/plugin-json": "^6.1.0",
80
94
  "@rollup/plugin-node-resolve": "^15.2.3",
81
95
  "@rollup/plugin-typescript": "^11.1.6",
96
+ "@rollup/plugin-virtual": "^3.0.2",
82
97
  "c12": "^1.11.1",
83
98
  "chokidar": "^3.6.0",
84
99
  "citty": "^0.1.6",
@@ -88,10 +103,17 @@
88
103
  "fs-extra": "^11.2.0",
89
104
  "hookable": "^5.5.3",
90
105
  "klona": "^2.0.6",
106
+ "magic-string": "^0.30.12",
107
+ "ohash": "^1.1.4",
91
108
  "pathe": "^1.1.2",
92
109
  "perfect-debounce": "^1.0.0",
110
+ "picocolors": "^1.1.1",
93
111
  "pkg-types": "^1.1.3",
112
+ "prettier": "^3.5.2",
113
+ "prompts": "^2.4.2",
94
114
  "rollup": "^4.18.1",
115
+ "rollup-plugin-esbuild": "^6.1.1",
116
+ "ts-morph": "^25.0.1",
95
117
  "tslib": "^2.6.3",
96
118
  "untyped": "^1.4.2"
97
119
  }
@@ -0,0 +1,2 @@
1
+ export declare const pkgDir: string;
2
+ export declare const runtimeDir: string;
@@ -0,0 +1,7 @@
1
+ import { fileURLToPath } from "node:url";
2
+
3
+ export const pkgDir = fileURLToPath(new URL(".", import.meta.url));
4
+
5
+ export const runtimeDir = fileURLToPath(
6
+ new URL("dist/runtime/", import.meta.url),
7
+ );
@@ -0,0 +1,44 @@
1
+ import { addIndexer } from "apibara/create";
2
+ import { defineCommand } from "citty";
3
+
4
+ export default defineCommand({
5
+ meta: {
6
+ name: "add",
7
+ description:
8
+ "apibara add helps you add a new indexer to your project with sensible defaults.",
9
+ },
10
+ args: {
11
+ indexerId: {
12
+ type: "positional",
13
+ description: "Indexer ID",
14
+ required: false,
15
+ },
16
+ chain: {
17
+ type: "string",
18
+ description: "Chain",
19
+ },
20
+ network: {
21
+ type: "string",
22
+ description: "Network",
23
+ },
24
+ storage: {
25
+ type: "string",
26
+ description: "Storage",
27
+ },
28
+ dnaUrl: {
29
+ type: "string",
30
+ description: "DNA URL",
31
+ },
32
+ },
33
+ async run({ args }) {
34
+ const { indexerId, chain, network, storage, dnaUrl } = args;
35
+
36
+ await addIndexer({
37
+ argIndexerId: indexerId,
38
+ argChain: chain,
39
+ argNetwork: network,
40
+ argStorage: storage,
41
+ argDnaUrl: dnaUrl,
42
+ });
43
+ },
44
+ });
@@ -1,7 +1,7 @@
1
1
  import { build, createApibara, prepare, writeTypes } from "apibara/core";
2
+ import { runtimeDir } from "apibara/runtime/meta";
2
3
  import { defineCommand } from "citty";
3
- import consola from "consola";
4
- import { resolve } from "pathe";
4
+ import { join, resolve } from "pathe";
5
5
  import { commonArgs } from "../common";
6
6
 
7
7
  export default defineCommand({
@@ -13,11 +13,13 @@ export default defineCommand({
13
13
  ...commonArgs,
14
14
  },
15
15
  async run({ args }) {
16
- consola.start("Building");
17
16
  const rootDir = resolve((args.dir || args._dir || ".") as string);
18
17
  const apibara = await createApibara({
19
18
  rootDir,
20
19
  });
20
+
21
+ apibara.options.entry = join(runtimeDir, "start.mjs");
22
+
21
23
  await prepare(apibara);
22
24
  await writeTypes(apibara);
23
25
  await build(apibara);
@@ -1,17 +1,16 @@
1
1
  import { type ChildProcess, spawn } from "node:child_process";
2
2
  import { build, createApibara, prepare, writeTypes } from "apibara/core";
3
+ import { runtimeDir } from "apibara/runtime/meta";
3
4
  import type { Apibara } from "apibara/types";
4
5
  import { defineCommand } from "citty";
5
- import consola from "consola";
6
- import { resolve } from "pathe";
6
+ import { colors } from "consola/utils";
7
+ import { join, resolve } from "pathe";
7
8
  import { commonArgs } from "../common";
8
9
 
9
10
  // Hot module reloading key regex
10
11
  // for only runtimeConfig.* keys
11
12
  const hmrKeyRe = /^runtimeConfig\./;
12
13
 
13
- let childProcess: ChildProcess | undefined;
14
-
15
14
  export default defineCommand({
16
15
  meta: {
17
16
  name: "dev",
@@ -27,24 +26,23 @@ export default defineCommand({
27
26
  type: "string",
28
27
  description: "Preset to use",
29
28
  },
30
- sink: {
31
- type: "string",
32
- description: "Sink to use",
33
- },
34
29
  },
35
30
  async run({ args }) {
36
- consola.start("Starting dev server");
37
31
  const rootDir = resolve((args.dir || args._dir || ".") as string);
32
+
38
33
  let apibara: Apibara;
34
+ let childProcess: ChildProcess | undefined;
39
35
 
40
36
  const reload = async () => {
41
37
  if (apibara) {
42
- consola.info("Restarting dev server");
38
+ apibara.logger.info("Restarting dev server");
43
39
  if ("unwatch" in apibara.options._c12) {
44
40
  await apibara.options._c12.unwatch();
45
41
  }
42
+
46
43
  await apibara.close();
47
44
  }
45
+
48
46
  apibara = await createApibara(
49
47
  {
50
48
  rootDir,
@@ -59,10 +57,11 @@ export default defineCommand({
59
57
  return; // No changes
60
58
  }
61
59
 
62
- consola.info(
63
- `Nitro config updated:
60
+ apibara.logger.info(
61
+ `Config updated:
64
62
  ${diff.map((entry) => ` ${entry.toString()}`).join("\n")}`,
65
63
  );
64
+
66
65
  await (diff.every((e) => hmrKeyRe.test(e.key))
67
66
  ? apibara.updateConfig(newConfig.config || {}) // Hot reload
68
67
  : reload()); // Full reload
@@ -71,26 +70,35 @@ export default defineCommand({
71
70
  },
72
71
  true,
73
72
  );
73
+
74
74
  apibara.hooks.hookOnce("restart", reload);
75
75
 
76
+ apibara.options.entry = join(runtimeDir, "dev.mjs");
77
+
76
78
  await prepare(apibara);
77
79
  await writeTypes(apibara);
78
80
  await build(apibara);
79
81
 
82
+ apibara.hooks.hook("dev:restart", () => {
83
+ if (childProcess) {
84
+ apibara.logger.info("Change detected, stopping indexers to restart");
85
+ childProcess.kill();
86
+ childProcess = undefined;
87
+ }
88
+ });
89
+
80
90
  apibara.hooks.hook("dev:reload", () => {
81
91
  if (childProcess) {
82
- consola.start("Restarting indexers");
83
92
  childProcess.kill();
84
93
  } else {
85
- consola.success("Dev server started");
86
- consola.success("Starting indexers");
94
+ apibara.logger.success("Restarting indexers");
87
95
  }
88
96
 
89
97
  const childArgs = [
90
- resolve(apibara.options.outputDir || "./.apibara/build", "main.mjs"),
98
+ resolve(apibara.options.outputDir || "./.apibara/build", "dev.mjs"),
99
+ "start",
91
100
  ...(args.indexers ? ["--indexers", args.indexers] : []),
92
101
  ...(args.preset ? ["--preset", args.preset] : []),
93
- ...(args.sink ? ["--sink", args.sink] : []),
94
102
  ];
95
103
 
96
104
  childProcess = spawn("node", childArgs, {
@@ -99,7 +107,9 @@ export default defineCommand({
99
107
 
100
108
  childProcess.on("close", (code) => {
101
109
  if (code !== null) {
102
- consola.log(`Indexers process exited with code ${code}`);
110
+ apibara.logger.log(
111
+ `Indexers process exited with code ${colors.red(code)}`,
112
+ );
103
113
  }
104
114
  });
105
115
  });
@@ -0,0 +1,36 @@
1
+ import { initializeProject } from "apibara/create";
2
+ import { defineCommand } from "citty";
3
+
4
+ export default defineCommand({
5
+ meta: {
6
+ name: "init",
7
+ description: "Initialize a new Apibara project",
8
+ },
9
+ args: {
10
+ dir: {
11
+ type: "positional",
12
+ description: "Target path to initialize the project",
13
+ required: true,
14
+ },
15
+ language: {
16
+ type: "string",
17
+ description: "Language to use: typescript, ts or javascript, js",
18
+ default: "ts",
19
+ alias: "l",
20
+ },
21
+ noIndexer: {
22
+ type: "boolean",
23
+ description: "Do not create an indexer after initialization",
24
+ default: false,
25
+ },
26
+ },
27
+ async run({ args }) {
28
+ const { dir: targetDir, noIndexer, language } = args;
29
+
30
+ await initializeProject({
31
+ argTargetDir: targetDir,
32
+ argLanguage: language,
33
+ argNoCreateIndexer: noIndexer,
34
+ });
35
+ },
36
+ });
@@ -1,7 +1,6 @@
1
1
  import { createApibara, writeTypes } from "apibara/core";
2
2
  import {} from "apibara/types";
3
3
  import { defineCommand } from "citty";
4
- import consola from "consola";
5
4
  import { resolve } from "pathe";
6
5
  import { commonArgs } from "../common";
7
6
 
@@ -14,7 +13,6 @@ export default defineCommand({
14
13
  ...commonArgs,
15
14
  },
16
15
  async run({ args }) {
17
- consola.start("Preparing Types");
18
16
  const rootDir = resolve((args.dir || ".") as string);
19
17
  const apibara = await createApibara({ rootDir });
20
18
  await writeTypes(apibara);
@@ -0,0 +1,61 @@
1
+ import { spawn } from "node:child_process";
2
+ import { createApibara } from "apibara/core";
3
+ import { defineCommand } from "citty";
4
+ import fse from "fs-extra";
5
+ import { resolve } from "pathe";
6
+ import { commonArgs } from "../common";
7
+
8
+ export default defineCommand({
9
+ meta: {
10
+ name: "start",
11
+ description: "Start one indexer",
12
+ },
13
+ args: {
14
+ ...commonArgs,
15
+ indexer: {
16
+ type: "string",
17
+ description: "The indexer to start",
18
+ required: true,
19
+ },
20
+ preset: {
21
+ type: "string",
22
+ description: "The preset to use",
23
+ },
24
+ },
25
+ async run({ args }) {
26
+ const { indexer, preset } = args;
27
+ const rootDir = resolve((args.dir || args._dir || ".") as string);
28
+
29
+ const apibara = await createApibara({
30
+ rootDir,
31
+ });
32
+
33
+ apibara.logger.start(
34
+ `Starting indexer ${indexer}${preset ? ` with preset ${preset}` : ""}`,
35
+ );
36
+
37
+ const outputDir = apibara.options.outputDir || "./.apibara/build";
38
+ const entry = resolve(outputDir, "start.mjs");
39
+
40
+ if (!fse.existsSync(entry)) {
41
+ apibara.logger.error(
42
+ `Output directory ${outputDir} does not exist. Try building the indexer with "apibara build" first.`,
43
+ );
44
+ return process.exit(1);
45
+ }
46
+
47
+ await apibara.close();
48
+
49
+ const childArgs = [
50
+ entry,
51
+ "start",
52
+ "--indexer",
53
+ indexer,
54
+ ...(preset ? ["--preset", preset] : []),
55
+ ];
56
+
57
+ spawn("node", childArgs, {
58
+ stdio: "inherit",
59
+ });
60
+ },
61
+ });
package/src/cli/index.ts CHANGED
@@ -9,7 +9,10 @@ export const mainCli = defineCommand({
9
9
  subCommands: {
10
10
  dev: () => import("./commands/dev").then((r) => r.default),
11
11
  build: () => import("./commands/build").then((r) => r.default),
12
+ start: () => import("./commands/start").then((r) => r.default),
12
13
  prepare: () => import("./commands/prepare").then((r) => r.default),
14
+ init: () => import("./commands/init").then((r) => r.default),
15
+ add: () => import("./commands/add").then((r) => r.default),
13
16
  },
14
17
  });
15
18
 
@@ -1,10 +1,11 @@
1
1
  import type { ApibaraConfig, DeepPartial } from "apibara/types";
2
2
 
3
3
  export function defineConfig<
4
- // biome-ignore lint/complexity/noBannedTypes: <explanation>
5
- T extends Record<string, DeepPartial<ApibaraConfig<T, R>>> = {},
6
- // biome-ignore lint/complexity/noBannedTypes: <explanation>
7
- R extends Record<string, unknown> = {},
4
+ T extends Record<
5
+ string,
6
+ DeepPartial<Pick<ApibaraConfig<T, R>, "runtimeConfig">>
7
+ > = Record<string, never>,
8
+ R extends Record<string, unknown> = Record<string, never>,
8
9
  >(config: ApibaraConfig<T, R>): ApibaraConfig<T, R> {
9
10
  return config;
10
11
  }
@@ -8,18 +8,18 @@ import consola from "consola";
8
8
  import { createHooks } from "hookable";
9
9
  import { loadOptions } from "./config/loader";
10
10
  import { updateApibaraConfig } from "./config/update";
11
+ import { scanIndexers } from "./scan";
11
12
 
12
13
  export async function createApibara(
13
14
  config: ApibaraConfig = {},
14
15
  opts: LoadConfigOptions = {},
15
16
  dev = false,
16
17
  ): Promise<Apibara> {
17
- // load options
18
18
  const options = await loadOptions(config, opts, dev);
19
19
 
20
- // create apibara context
21
20
  const apibara: Apibara = {
22
21
  options,
22
+ indexers: [],
23
23
  hooks: createHooks(),
24
24
  close: () => apibara.hooks.callHook("close"),
25
25
  logger: consola.withTag("apibara"),
@@ -30,5 +30,7 @@ export async function createApibara(
30
30
 
31
31
  apibara.hooks.addHooks(apibara.options.hooks);
32
32
 
33
+ await scanIndexers(apibara);
34
+
33
35
  return apibara;
34
36
  }
@@ -5,7 +5,9 @@ import { buildProduction } from "./prod";
5
5
 
6
6
  export async function build(apibara: Apibara) {
7
7
  const rollupConfig = getRollupConfig(apibara);
8
+
8
9
  await apibara.hooks.callHook("rollup:before", apibara, rollupConfig);
10
+
9
11
  return apibara.options.dev
10
12
  ? await watchDev(apibara, rollupConfig)
11
13
  : await buildProduction(apibara, rollupConfig);
@@ -53,6 +53,7 @@ function startRollupWatcher(apibara: Apibara, rollupConfig: RollupConfig) {
53
53
  switch (event.code) {
54
54
  // The watcher is (re)starting
55
55
  case "START": {
56
+ apibara.hooks.callHook("dev:restart");
56
57
  return;
57
58
  }
58
59
 
@@ -23,7 +23,6 @@ export function formatRollupError(
23
23
  (error as rollup.RollupError).frame;
24
24
 
25
25
  logs.push(
26
- // biome-ignore lint/style/useTemplate: <explanation>
27
26
  `Rollup error while processing \`${path}\`` + text ? "\n\n" + text : "",
28
27
  );
29
28
  }
@@ -1,12 +1,15 @@
1
1
  import fsp from "node:fs/promises";
2
2
  import type { Apibara } from "apibara/types";
3
- import consola from "consola";
4
3
  import fse from "fs-extra";
4
+ import { prettyPath } from "../path";
5
5
 
6
6
  export async function prepare(apibara: Apibara) {
7
7
  await prepareDir(apibara.options.buildDir);
8
8
  await prepareDir(apibara.options.outputDir);
9
- consola.success("Output directory cleaned");
9
+
10
+ apibara.logger.success(
11
+ `Output directory ${prettyPath(apibara.options.outputDir)} cleaned`,
12
+ );
10
13
  }
11
14
 
12
15
  async function prepareDir(dir: string) {
@@ -1,16 +1,18 @@
1
1
  import type { Apibara, RollupConfig } from "apibara/types";
2
- import consola from "consola";
2
+ import { colors } from "consola/utils";
3
3
  import { type OutputOptions, rollup } from "rollup";
4
4
 
5
5
  export async function buildProduction(
6
6
  apibara: Apibara,
7
7
  rollupConfig: RollupConfig,
8
8
  ) {
9
+ apibara.logger.start(
10
+ `Building ${colors.cyan(apibara.indexers.length)} indexers`,
11
+ );
12
+
9
13
  try {
10
- // Create a bundle
11
14
  const bundle = await rollup(rollupConfig);
12
15
 
13
- // Generate output
14
16
  if (Array.isArray(rollupConfig.output)) {
15
17
  for (const outputOptions of rollupConfig.output) {
16
18
  await bundle.write(outputOptions);
@@ -21,12 +23,14 @@ export async function buildProduction(
21
23
  throw new Error("No output options specified in Rollup config");
22
24
  }
23
25
 
24
- // Close the bundle
25
26
  await bundle.close();
26
27
 
27
- consola.success("Build completed successfully!");
28
+ apibara.logger.success("Build succeeded!");
29
+ apibara.logger.info(
30
+ `You can start the indexers with ${colors.cyan("apibara start")}`,
31
+ );
28
32
  } catch (error) {
29
- console.error("Build failed:", error);
33
+ apibara.logger.error("Build failed", error);
30
34
  throw error;
31
35
  }
32
36
  }