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

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 (90) hide show
  1. package/dist/chunks/add.mjs +49 -0
  2. package/dist/chunks/build.mjs +3 -3
  3. package/dist/chunks/dev.mjs +41 -19
  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 +127 -134
  11. package/dist/create/index.d.mts +18 -0
  12. package/dist/create/index.d.ts +18 -0
  13. package/dist/create/index.mjs +1025 -0
  14. package/dist/rolldown/index.d.mts +7 -0
  15. package/dist/rolldown/index.d.ts +7 -0
  16. package/dist/rolldown/index.mjs +90 -0
  17. package/dist/runtime/dev.d.ts +3 -0
  18. package/dist/runtime/dev.mjs +58 -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 +64 -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 +46 -0
  27. package/dist/types/index.d.mts +35 -29
  28. package/dist/types/index.d.ts +35 -29
  29. package/package.json +40 -22
  30. package/runtime-meta.d.ts +2 -0
  31. package/runtime-meta.mjs +7 -0
  32. package/src/cli/commands/add.ts +50 -0
  33. package/src/cli/commands/build.ts +5 -3
  34. package/src/cli/commands/dev.ts +50 -19
  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 +15 -5
  42. package/src/core/build/dev.ts +44 -22
  43. package/src/core/build/error.ts +9 -15
  44. package/src/core/build/prepare.ts +5 -2
  45. package/src/core/build/prod.ts +24 -15
  46. package/src/core/build/types.ts +12 -95
  47. package/src/core/config/defaults.ts +4 -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 +3 -4
  51. package/src/core/path.ts +11 -0
  52. package/src/core/scan.ts +40 -0
  53. package/src/create/add.ts +239 -0
  54. package/src/create/colors.ts +15 -0
  55. package/src/create/constants.ts +97 -0
  56. package/src/create/index.ts +2 -0
  57. package/src/create/init.ts +178 -0
  58. package/src/create/templates.ts +501 -0
  59. package/src/create/types.ts +34 -0
  60. package/src/create/utils.ts +422 -0
  61. package/src/rolldown/config.ts +83 -0
  62. package/src/rolldown/index.ts +2 -0
  63. package/src/rolldown/plugins/config.ts +13 -0
  64. package/src/rolldown/plugins/indexers.ts +17 -0
  65. package/src/runtime/dev.ts +67 -0
  66. package/src/runtime/index.ts +2 -0
  67. package/src/runtime/internal/app.ts +86 -0
  68. package/src/runtime/internal/logger.ts +70 -0
  69. package/src/runtime/start.ts +53 -0
  70. package/src/types/apibara.ts +8 -0
  71. package/src/types/config.ts +37 -31
  72. package/src/types/hooks.ts +8 -4
  73. package/src/types/index.ts +1 -1
  74. package/src/types/rolldown.ts +5 -0
  75. package/src/types/virtual/config.d.ts +3 -0
  76. package/src/types/virtual/indexers.d.ts +13 -0
  77. package/dist/internal/citty/index.d.mts +0 -1
  78. package/dist/internal/citty/index.d.ts +0 -1
  79. package/dist/internal/citty/index.mjs +0 -1
  80. package/dist/internal/consola/index.d.mts +0 -2
  81. package/dist/internal/consola/index.d.ts +0 -2
  82. package/dist/internal/consola/index.mjs +0 -1
  83. package/dist/rollup/index.d.mts +0 -5
  84. package/dist/rollup/index.d.ts +0 -5
  85. package/dist/rollup/index.mjs +0 -187
  86. package/src/internal/citty/index.ts +0 -1
  87. package/src/internal/consola/index.ts +0 -1
  88. package/src/rollup/config.ts +0 -209
  89. package/src/rollup/index.ts +0 -1
  90. package/src/types/rollup.ts +0 -8
@@ -1,31 +1,31 @@
1
- import consola__default from 'consola';
1
+ import consola from 'consola';
2
2
  import { createHooks } from 'hookable';
3
3
  import { watchConfig, loadConfig } from 'c12';
4
4
  import { klona } from 'klona/full';
5
- import { resolve, isAbsolute, relative, join, dirname } from 'pathe';
5
+ import { resolve, join, basename, isAbsolute, relative, dirname } from 'pathe';
6
6
  import defu from 'defu';
7
- import { getRollupConfig } from 'apibara/rollup';
7
+ import fse from 'fs-extra';
8
+ import { getRolldownConfig } from 'apibara/rolldown';
9
+ import { colors } from 'consola/utils';
8
10
  import { watch } from 'chokidar';
9
11
  import { debounce } from 'perfect-debounce';
10
- import * as rollup from 'rollup';
11
- import { rollup as rollup$1 } from 'rollup';
12
+ import * as rolldown from 'rolldown';
12
13
  import fsp from 'node:fs/promises';
13
- import fse from 'fs-extra';
14
14
  import { generateTypes, resolveSchema } from 'untyped';
15
15
 
16
16
  const ApibaraDefaults = {
17
17
  rootDir: ".",
18
+ indexersDir: "indexers",
18
19
  runtimeConfig: {},
19
20
  hooks: {},
20
21
  buildDir: ".apibara",
21
22
  typescript: {
22
23
  strict: false,
23
- generateTsConfig: true,
24
24
  generateRuntimeConfigTypes: true,
25
- tsconfigPath: "types/tsconfig.json",
26
- internalPaths: false,
27
- tsConfig: {}
28
- }
25
+ internalPaths: false
26
+ },
27
+ node: true,
28
+ exportConditions: ["node"]
29
29
  };
30
30
 
31
31
  async function resolvePathOptions(options) {
@@ -46,7 +46,7 @@ async function presetResolver(options) {
46
46
  }
47
47
 
48
48
  async function resolveRuntimeConfigOptions(options) {
49
- options.runtimeConfig = { ...options.runtimeConfig, default: "value" };
49
+ options.runtimeConfig = { ...options.runtimeConfig };
50
50
  process.env.APIBARA_RUNTIME_CONFIG = JSON.stringify(options.runtimeConfig);
51
51
  }
52
52
 
@@ -83,41 +83,72 @@ async function _loadUserConfig(configOverrides = {}, opts = {}, dev = false) {
83
83
  return options;
84
84
  }
85
85
 
86
- async function updateApibaraConfig(apibara, config) {
87
- await apibara.hooks.callHook("rollup:reload");
88
- consola__default.success("Apibara config hot reloaded!");
86
+ async function updateApibaraConfig(apibara, _config) {
87
+ await apibara.hooks.callHook("rolldown:reload");
88
+ apibara.logger.success("Apibara config hot reloaded!");
89
+ }
90
+
91
+ const INDEXER_EXTENSIONS = [".indexer.ts", ".indexer.js"];
92
+ async function scanIndexers(apibara) {
93
+ apibara.logger.debug("Scanning indexers");
94
+ const indexersDir = join(
95
+ apibara.options.rootDir,
96
+ apibara.options.indexersDir
97
+ );
98
+ if (!fse.existsSync(indexersDir)) {
99
+ throw new Error(`Indexers directory not found: ${indexersDir}`);
100
+ }
101
+ apibara.indexers = [];
102
+ for (const file of fse.readdirSync(indexersDir)) {
103
+ const indexerName = indexerNameFromFile(file);
104
+ if (indexerName) {
105
+ apibara.indexers.push({
106
+ name: indexerName,
107
+ indexer: join(indexersDir, file)
108
+ });
109
+ }
110
+ }
111
+ apibara.logger.debug(`Found ${apibara.indexers.length} indexers`);
112
+ }
113
+ function indexerNameFromFile(file) {
114
+ for (const extension of INDEXER_EXTENSIONS) {
115
+ if (file.endsWith(extension)) {
116
+ return basename(file, extension);
117
+ }
118
+ }
89
119
  }
90
120
 
91
121
  async function createApibara(config = {}, opts = {}, dev = false) {
92
122
  const options = await loadOptions(config, opts, dev);
93
123
  const apibara = {
94
124
  options,
125
+ indexers: [],
95
126
  hooks: createHooks(),
96
127
  close: () => apibara.hooks.callHook("close"),
97
- logger: consola__default.withTag("apibara"),
128
+ logger: consola.withTag("apibara"),
98
129
  async updateConfig(config2) {
99
130
  updateApibaraConfig(apibara);
100
131
  }
101
132
  };
102
133
  apibara.hooks.addHooks(apibara.options.hooks);
134
+ await scanIndexers(apibara);
103
135
  return apibara;
104
136
  }
105
137
 
106
- function formatRollupError(_error) {
138
+ function formatRolldownError(_error) {
107
139
  try {
108
140
  const logs = [_error.toString()];
109
141
  const errors = _error?.errors || [_error];
110
142
  for (const error of errors) {
111
143
  const id = error.path || error.id || _error.id;
112
144
  let path = isAbsolute(id) ? relative(process.cwd(), id) : id;
113
- const location = error.loc || error.location;
145
+ const location = error.loc;
114
146
  if (location) {
115
147
  path += `:${location.line}:${location.column}`;
116
148
  }
117
- const text = error.text || error.frame;
149
+ const text = error.frame;
118
150
  logs.push(
119
- // biome-ignore lint/style/useTemplate: <explanation>
120
- `Rollup error while processing \`${path}\`` + text ? "\n\n" + text : ""
151
+ `Rolldown error while processing \`${path}\`` + text ? "\n\n" + text : ""
121
152
  );
122
153
  }
123
154
  return logs.join("\n");
@@ -126,44 +157,48 @@ function formatRollupError(_error) {
126
157
  }
127
158
  }
128
159
 
129
- async function watchDev(apibara, rollupConfig) {
130
- let rollupWatcher;
160
+ async function watchDev(apibara, rolldownConfig) {
161
+ let rolldownWatcher;
131
162
  async function load() {
132
- if (rollupWatcher) {
133
- await rollupWatcher.close();
163
+ apibara.logger.start("Setting up a dev server");
164
+ if (rolldownWatcher) {
165
+ await rolldownWatcher.close();
134
166
  }
135
- rollupWatcher = startRollupWatcher(apibara, rollupConfig);
167
+ rolldownWatcher = startRolldownWatcher(apibara, rolldownConfig);
136
168
  }
137
- const reload = debounce(load);
138
- const watchPatterns = [join(apibara.options.rootDir, "indexers")];
169
+ const reload = debounce(async () => await load());
170
+ const watchPatterns = getWatchPatterns(apibara);
139
171
  const watchReloadEvents = /* @__PURE__ */ new Set(["add", "addDir", "unlink", "unlinkDir"]);
140
172
  const reloadWatcher = watch(watchPatterns, { ignoreInitial: true }).on(
141
173
  "all",
142
- (event) => {
174
+ async (event) => {
143
175
  if (watchReloadEvents.has(event)) {
144
- reload();
176
+ await reload();
145
177
  }
146
178
  }
147
179
  );
148
180
  apibara.hooks.hook("close", () => {
149
- rollupWatcher.close();
181
+ rolldownWatcher.close();
150
182
  reloadWatcher.close();
151
183
  });
152
- apibara.hooks.hook("rollup:reload", () => reload());
184
+ apibara.hooks.hook("rolldown:reload", async () => await reload());
153
185
  await load();
154
186
  }
155
- function startRollupWatcher(apibara, rollupConfig) {
156
- const watcher = rollup.watch(
157
- defu(rollupConfig, {
187
+ function startRolldownWatcher(apibara, rolldownConfig) {
188
+ const ignorePatterns = getIgnorePatterns();
189
+ const watcher = rolldown.watch(
190
+ defu(rolldownConfig, {
158
191
  watch: {
159
- chokidar: apibara.options.watchOptions
192
+ exclude: ignorePatterns,
193
+ ...apibara.options.watchOptions ?? {}
160
194
  }
161
195
  })
162
196
  );
163
197
  let start;
164
- watcher.on("event", (event) => {
198
+ watcher.on("event", async (event) => {
165
199
  switch (event.code) {
166
200
  case "START": {
201
+ await apibara.hooks.callHook("dev:restart");
167
202
  return;
168
203
  }
169
204
  case "BUNDLE_START": {
@@ -176,47 +211,81 @@ function startRollupWatcher(apibara, rollupConfig) {
176
211
  "Indexers built",
177
212
  start ? `in ${Date.now() - start} ms` : ""
178
213
  );
179
- apibara.hooks.callHook("dev:reload");
214
+ await apibara.hooks.callHook("dev:reload");
180
215
  return;
181
216
  }
182
217
  case "ERROR": {
183
- apibara.logger.error(formatRollupError(event.error));
218
+ apibara.logger.error(formatRolldownError(event.error));
184
219
  }
185
220
  }
186
221
  });
187
222
  return watcher;
188
223
  }
224
+ const getWatchPatterns = (apibara) => [
225
+ join(apibara.options.rootDir, "indexers")
226
+ ];
227
+ const getIgnorePatterns = (apibara) => [
228
+ "**/.apibara/**",
229
+ "**/.git/**",
230
+ "**/.DS_Store",
231
+ "**/node_modules/**",
232
+ "**/dist/**",
233
+ "**/.turbo/**"
234
+ ];
189
235
 
190
- async function buildProduction(apibara, rollupConfig) {
236
+ async function buildProduction(apibara, rolldownConfig) {
237
+ apibara.logger.start(
238
+ `Building ${colors.cyan(apibara.indexers.length)} indexers`
239
+ );
240
+ const startTime = Date.now();
191
241
  try {
192
- const bundle = await rollup$1(rollupConfig);
193
- if (Array.isArray(rollupConfig.output)) {
194
- for (const outputOptions of rollupConfig.output) {
242
+ const bundle = await rolldown.rolldown(rolldownConfig);
243
+ if (Array.isArray(rolldownConfig.output)) {
244
+ for (const outputOptions of rolldownConfig.output) {
195
245
  await bundle.write(outputOptions);
196
246
  }
197
- } else if (rollupConfig.output) {
198
- await bundle.write(rollupConfig.output);
247
+ } else if (rolldownConfig.output) {
248
+ await bundle.write(rolldownConfig.output);
199
249
  } else {
200
- throw new Error("No output options specified in Rollup config");
250
+ throw new Error("No output options specified in Rolldown config");
201
251
  }
202
252
  await bundle.close();
203
- consola__default.success("Build completed successfully!");
253
+ const endTime = Date.now();
254
+ const duration = endTime - startTime;
255
+ apibara.logger.success(`Build succeeded in ${duration}ms`);
256
+ apibara.logger.info(
257
+ `You can start the indexers with ${colors.cyan("apibara start")}`
258
+ );
204
259
  } catch (error) {
205
- console.error("Build failed:", error);
260
+ apibara.logger.error("Build failed", error);
206
261
  throw error;
207
262
  }
208
263
  }
209
264
 
210
265
  async function build(apibara) {
211
- const rollupConfig = getRollupConfig(apibara);
212
- await apibara.hooks.callHook("rollup:before", apibara, rollupConfig);
213
- return apibara.options.dev ? await watchDev(apibara, rollupConfig) : await buildProduction(apibara, rollupConfig);
266
+ const rolldownConfig = getRolldownConfig(apibara);
267
+ await apibara.hooks.callHook("rolldown:before", apibara, rolldownConfig);
268
+ if (apibara.options.rollupConfig) {
269
+ apibara.logger.error(
270
+ `
271
+ ${colors.cyan("apibara.config:")} rollupConfig is deprecated. Use rolldownConfig instead`
272
+ );
273
+ process.exit(1);
274
+ }
275
+ return apibara.options.dev ? await watchDev(apibara, rolldownConfig) : await buildProduction(apibara, rolldownConfig);
276
+ }
277
+
278
+ function prettyPath(path, highlight = true) {
279
+ const rel = relative(process.cwd(), path);
280
+ return highlight ? colors.cyan(rel) : rel;
214
281
  }
215
282
 
216
283
  async function prepare(apibara) {
217
284
  await prepareDir(apibara.options.buildDir);
218
285
  await prepareDir(apibara.options.outputDir);
219
- consola__default.success("Output directory cleaned");
286
+ apibara.logger.success(
287
+ `Output directory ${prettyPath(apibara.options.outputDir)} cleaned`
288
+ );
220
289
  }
221
290
  async function prepareDir(dir) {
222
291
  await fsp.mkdir(dir, { recursive: true });
@@ -224,6 +293,10 @@ async function prepareDir(dir) {
224
293
  }
225
294
 
226
295
  async function writeTypes(apibara) {
296
+ const isTypeScript = apibara.options._c12.configFile?.endsWith(".ts");
297
+ if (!isTypeScript) {
298
+ return;
299
+ }
227
300
  const typesDir = resolve(apibara.options.buildDir, "types");
228
301
  const config = [
229
302
  "// Generated by apibara",
@@ -245,88 +318,13 @@ declare module "apibara/types" {`,
245
318
  ) : "",
246
319
  "}",
247
320
  // Makes this a module for augmentation purposes
248
- "export type {}"
249
- ];
250
- const declarations = [
251
- // local apibara augmentations
252
- '/// <reference path="./apibara-config.d.ts" />'
321
+ "export type {};"
253
322
  ];
254
323
  const buildFiles = [];
255
324
  buildFiles.push({
256
325
  path: join(typesDir, "apibara-config.d.ts"),
257
326
  contents: config.join("\n")
258
327
  });
259
- buildFiles.push({
260
- path: join(typesDir, "apibara.d.ts"),
261
- contents: declarations.join("\n")
262
- });
263
- if (apibara.options.typescript.generateTsConfig) {
264
- const tsConfigPath = resolve(
265
- apibara.options.buildDir,
266
- apibara.options.typescript.tsconfigPath
267
- );
268
- const tsconfigDir = dirname(tsConfigPath);
269
- const tsConfig = defu(apibara.options.typescript.tsConfig, {
270
- compilerOptions: {
271
- forceConsistentCasingInFileNames: true,
272
- strict: apibara.options.typescript.strict,
273
- noEmit: true,
274
- target: "ESNext",
275
- module: "ESNext",
276
- moduleResolution: "Bundler",
277
- allowJs: true,
278
- resolveJsonModule: true,
279
- jsx: "preserve",
280
- allowSyntheticDefaultImports: true,
281
- jsxFactory: "h",
282
- jsxFragmentFactory: "Fragment"
283
- },
284
- include: [
285
- relativeWithDot(tsconfigDir, join(typesDir, "apibara.d.ts")).replace(
286
- /^(?=[^.])/,
287
- "./"
288
- )
289
- ]
290
- });
291
- for (const alias in tsConfig.compilerOptions.paths) {
292
- const paths = tsConfig.compilerOptions.paths[alias];
293
- tsConfig.compilerOptions.paths[alias] = await Promise.all(
294
- paths.map(async (path) => {
295
- if (!isAbsolute(path)) {
296
- return path;
297
- }
298
- const stats = await fsp.stat(path).catch(
299
- () => null
300
- /* file does not exist */
301
- );
302
- return relativeWithDot(
303
- tsconfigDir,
304
- stats?.isFile() ? path.replace(/(?<=\w)\.\w+$/g, "") : path
305
- );
306
- })
307
- );
308
- }
309
- tsConfig.include = [
310
- ...new Set(
311
- tsConfig.include.map(
312
- (p) => isAbsolute(p) ? relativeWithDot(tsconfigDir, p) : p
313
- )
314
- )
315
- ];
316
- if (tsConfig.exclude) {
317
- tsConfig.exclude = [
318
- ...new Set(
319
- tsConfig.exclude.map(
320
- (p) => isAbsolute(p) ? relativeWithDot(tsconfigDir, p) : p
321
- )
322
- )
323
- ];
324
- }
325
- buildFiles.push({
326
- path: tsConfigPath,
327
- contents: JSON.stringify(tsConfig, null, 2)
328
- });
329
- }
330
328
  await Promise.all(
331
329
  buildFiles.map(async (file) => {
332
330
  const _file = resolve(apibara.options.buildDir, file.path);
@@ -334,12 +332,7 @@ declare module "apibara/types" {`,
334
332
  await fsp.writeFile(_file, file.contents);
335
333
  })
336
334
  );
337
- consola__default.success("Types generated");
338
- }
339
- const RELATIVE_RE = /^\.{1,2}\//;
340
- function relativeWithDot(from, to) {
341
- const rel = relative(from, to);
342
- return RELATIVE_RE.test(rel) ? rel : `./${rel}`;
335
+ apibara.logger.success(`Types written to ${prettyPath(typesDir)}`);
343
336
  }
344
337
 
345
338
  export { build, createApibara, prepare, writeTypes };
@@ -0,0 +1,18 @@
1
+ type Options$1 = {
2
+ argIndexerId?: string;
3
+ argChain?: string;
4
+ argNetwork?: string;
5
+ argStorage?: string;
6
+ argDnaUrl?: string;
7
+ argRootDir?: string;
8
+ };
9
+ declare function addIndexer({ argIndexerId, argChain, argNetwork, argStorage, argDnaUrl, argRootDir, }: Options$1): Promise<void>;
10
+
11
+ type Options = {
12
+ argTargetDir: string;
13
+ argLanguage?: string;
14
+ argNoCreateIndexer?: boolean;
15
+ };
16
+ declare function initializeProject({ argTargetDir, argLanguage, argNoCreateIndexer, }: Options): Promise<void>;
17
+
18
+ export { addIndexer, initializeProject };
@@ -0,0 +1,18 @@
1
+ type Options$1 = {
2
+ argIndexerId?: string;
3
+ argChain?: string;
4
+ argNetwork?: string;
5
+ argStorage?: string;
6
+ argDnaUrl?: string;
7
+ argRootDir?: string;
8
+ };
9
+ declare function addIndexer({ argIndexerId, argChain, argNetwork, argStorage, argDnaUrl, argRootDir, }: Options$1): Promise<void>;
10
+
11
+ type Options = {
12
+ argTargetDir: string;
13
+ argLanguage?: string;
14
+ argNoCreateIndexer?: boolean;
15
+ };
16
+ declare function initializeProject({ argTargetDir, argLanguage, argNoCreateIndexer, }: Options): Promise<void>;
17
+
18
+ export { addIndexer, initializeProject };