@apibara/plugin-drizzle 2.1.0-beta.1 → 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.
package/dist/index.cjs CHANGED
@@ -4,10 +4,21 @@ const indexer = require('@apibara/indexer');
4
4
  const plugins = require('@apibara/indexer/plugins');
5
5
  const internal = require('@apibara/indexer/internal');
6
6
  const plugins$1 = require('@apibara/indexer/internal/plugins');
7
+ const constants = require('./shared/plugin-drizzle.e884ca32.cjs');
8
+ const pglite$1 = require('@electric-sql/pglite');
9
+ const nodePostgres = require('drizzle-orm/node-postgres');
10
+ const migrator$1 = require('drizzle-orm/node-postgres/migrator');
11
+ const pglite = require('drizzle-orm/pglite');
12
+ const migrator = require('drizzle-orm/pglite/migrator');
13
+ const pg = require('pg');
7
14
  const protocol = require('@apibara/protocol');
8
15
  const drizzleOrm = require('drizzle-orm');
9
16
  const pgCore = require('drizzle-orm/pg-core');
10
17
 
18
+ function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e.default : e; }
19
+
20
+ const pg__default = /*#__PURE__*/_interopDefaultCompat(pg);
21
+
11
22
  class DrizzleStorageError extends Error {
12
23
  constructor(message, options) {
13
24
  super(message, options);
@@ -36,6 +47,50 @@ function sleep(ms) {
36
47
  return new Promise((resolve) => setTimeout(resolve, ms));
37
48
  }
38
49
 
50
+ function drizzle(options) {
51
+ const {
52
+ connectionString = "memory://",
53
+ schema,
54
+ type = "pglite",
55
+ config,
56
+ poolConfig
57
+ } = options ?? {};
58
+ if (connectionString.startsWith("postgres://") || type === "node-postgres") {
59
+ const pool = new pg__default.Pool({
60
+ connectionString,
61
+ ...poolConfig || {}
62
+ });
63
+ return nodePostgres.drizzle(pool, { schema, ...config || {} });
64
+ }
65
+ if (type === "pglite") {
66
+ return pglite.drizzle({
67
+ schema,
68
+ connection: {
69
+ dataDir: connectionString || "memory://pglite"
70
+ },
71
+ ...config || {}
72
+ });
73
+ }
74
+ throw new Error("Invalid database type");
75
+ }
76
+ async function migrate(db, options) {
77
+ const isPglite = !!("$client" in db && db.$client instanceof pglite$1.PGlite);
78
+ try {
79
+ if (isPglite) {
80
+ await migrator.migrate(db, options);
81
+ } else {
82
+ await migrator$1.migrate(db, options);
83
+ }
84
+ } catch (error) {
85
+ throw new DrizzleStorageError(
86
+ "Failed to apply migrations! Please check if you have generated migrations using drizzle:generate",
87
+ {
88
+ cause: error
89
+ }
90
+ );
91
+ }
92
+ }
93
+
39
94
  const CHECKPOINTS_TABLE_NAME = "__indexer_checkpoints";
40
95
  const FILTERS_TABLE_NAME = "__indexer_filters";
41
96
  const SCHEMA_VERSION_TABLE_NAME = "__indexer_schema_version";
@@ -213,6 +268,17 @@ async function finalizeState(props) {
213
268
  });
214
269
  }
215
270
  }
271
+ async function resetPersistence(props) {
272
+ const { tx, indexerId } = props;
273
+ try {
274
+ await tx.delete(checkpoints).where(drizzleOrm.eq(checkpoints.id, indexerId));
275
+ await tx.delete(filters).where(drizzleOrm.eq(filters.id, indexerId));
276
+ } catch (error) {
277
+ throw new DrizzleStorageError("Failed to reset persistence state", {
278
+ cause: error
279
+ });
280
+ }
281
+ }
216
282
 
217
283
  function getReorgTriggerName(table, indexerId) {
218
284
  return `${table}_reorg_${indexerId}`;
@@ -433,28 +499,59 @@ async function finalize(tx, cursor, indexerId) {
433
499
  });
434
500
  }
435
501
  }
502
+ async function cleanupStorage(tx, tables, indexerId) {
503
+ try {
504
+ for (const table of tables) {
505
+ await tx.execute(
506
+ drizzleOrm.sql.raw(
507
+ `DROP TRIGGER IF EXISTS ${getReorgTriggerName(table, indexerId)} ON ${table};`
508
+ )
509
+ );
510
+ }
511
+ await tx.execute(
512
+ drizzleOrm.sql.raw(`
513
+ DELETE FROM __reorg_rollback
514
+ WHERE indexer_id = '${indexerId}'
515
+ `)
516
+ );
517
+ for (const table of tables) {
518
+ try {
519
+ await tx.execute(drizzleOrm.sql.raw(`TRUNCATE TABLE ${table} CASCADE;`));
520
+ } catch (error) {
521
+ throw new DrizzleStorageError(`Failed to truncate table ${table}`, {
522
+ cause: error
523
+ });
524
+ }
525
+ }
526
+ } catch (error) {
527
+ throw new DrizzleStorageError("Failed to clean up storage", {
528
+ cause: error
529
+ });
530
+ }
531
+ }
436
532
 
437
- const DRIZZLE_PROPERTY = "_drizzle";
438
533
  const MAX_RETRIES = 5;
439
534
  function useDrizzleStorage(_db) {
440
535
  const context = indexer.useIndexerContext();
441
- if (!context[DRIZZLE_PROPERTY]) {
536
+ if (!context[constants.DRIZZLE_PROPERTY]) {
442
537
  throw new DrizzleStorageError(
443
538
  "drizzle storage is not available. Did you register the plugin?"
444
539
  );
445
540
  }
446
- return context[DRIZZLE_PROPERTY];
541
+ return context[constants.DRIZZLE_PROPERTY];
447
542
  }
448
543
  function drizzleStorage({
449
544
  db,
450
545
  persistState: enablePersistence = true,
451
546
  indexerName: identifier = "default",
452
547
  schema,
453
- idColumn = "id"
548
+ idColumn = "id",
549
+ migrate: migrateOptions
454
550
  }) {
455
- return plugins.defineIndexerPlugin((indexer) => {
551
+ return plugins.defineIndexerPlugin((indexer$1) => {
456
552
  let tableNames = [];
457
553
  let indexerId = "";
554
+ const alwaysReindex = process.env["APIBARA_ALWAYS_REINDEX"] === "true";
458
555
  try {
459
556
  tableNames = Object.values(schema ?? db._.schema ?? {}).map(
460
557
  (table) => table.dbName
@@ -464,12 +561,34 @@ function drizzleStorage({
464
561
  cause: error
465
562
  });
466
563
  }
467
- indexer.hooks.hook("run:before", async () => {
468
- const { indexerName: indexerFileName, availableIndexers } = plugins$1.useInternalContext();
564
+ indexer$1.hooks.hook("run:before", async () => {
565
+ const internalContext = plugins$1.useInternalContext();
566
+ const context = indexer.useIndexerContext();
567
+ const logger = plugins.useLogger();
568
+ context[constants.DRIZZLE_STORAGE_DB_PROPERTY] = db;
569
+ const { indexerName: indexerFileName, availableIndexers } = internalContext;
469
570
  indexerId = internal.generateIndexerId(indexerFileName, identifier);
571
+ if (alwaysReindex) {
572
+ logger.warn(
573
+ `Reindexing: Deleting all data from tables - ${tableNames.join(", ")}`
574
+ );
575
+ await withTransaction(db, async (tx) => {
576
+ await cleanupStorage(tx, tableNames, indexerId);
577
+ if (enablePersistence) {
578
+ await resetPersistence({ tx, indexerId });
579
+ }
580
+ logger.success("Tables have been cleaned up for reindexing");
581
+ });
582
+ }
470
583
  let retries = 0;
584
+ let migrationsApplied = false;
471
585
  while (retries <= MAX_RETRIES) {
472
586
  try {
587
+ if (migrateOptions && !migrationsApplied) {
588
+ await migrate(db, migrateOptions);
589
+ migrationsApplied = true;
590
+ logger.success("Migrations applied");
591
+ }
473
592
  await withTransaction(db, async (tx) => {
474
593
  await initializeReorgRollbackTable(tx, indexerId);
475
594
  if (enablePersistence) {
@@ -479,6 +598,9 @@ function drizzleStorage({
479
598
  break;
480
599
  } catch (error) {
481
600
  if (retries === MAX_RETRIES) {
601
+ if (error instanceof DrizzleStorageError) {
602
+ throw error;
603
+ }
482
604
  throw new DrizzleStorageError(
483
605
  "Initialization failed after 5 retries",
484
606
  {
@@ -491,7 +613,7 @@ function drizzleStorage({
491
613
  }
492
614
  }
493
615
  });
494
- indexer.hooks.hook("connect:before", async ({ request }) => {
616
+ indexer$1.hooks.hook("connect:before", async ({ request }) => {
495
617
  if (!enablePersistence) {
496
618
  return;
497
619
  }
@@ -508,7 +630,7 @@ function drizzleStorage({
508
630
  }
509
631
  });
510
632
  });
511
- indexer.hooks.hook("connect:after", async ({ request }) => {
633
+ indexer$1.hooks.hook("connect:after", async ({ request }) => {
512
634
  const cursor = request.startingCursor;
513
635
  if (!cursor) {
514
636
  return;
@@ -520,7 +642,7 @@ function drizzleStorage({
520
642
  }
521
643
  });
522
644
  });
523
- indexer.hooks.hook("connect:factory", async ({ request, endCursor }) => {
645
+ indexer$1.hooks.hook("connect:factory", async ({ request, endCursor }) => {
524
646
  if (!enablePersistence) {
525
647
  return;
526
648
  }
@@ -534,7 +656,7 @@ function drizzleStorage({
534
656
  });
535
657
  }
536
658
  });
537
- indexer.hooks.hook("message:finalize", async ({ message }) => {
659
+ indexer$1.hooks.hook("message:finalize", async ({ message }) => {
538
660
  const { cursor } = message.finalize;
539
661
  if (!cursor) {
540
662
  throw new DrizzleStorageError("Finalized Cursor is undefined");
@@ -546,7 +668,7 @@ function drizzleStorage({
546
668
  }
547
669
  });
548
670
  });
549
- indexer.hooks.hook("message:invalidate", async ({ message }) => {
671
+ indexer$1.hooks.hook("message:invalidate", async ({ message }) => {
550
672
  const { cursor } = message.invalidate;
551
673
  if (!cursor) {
552
674
  throw new DrizzleStorageError("Invalidate Cursor is undefined");
@@ -558,7 +680,7 @@ function drizzleStorage({
558
680
  }
559
681
  });
560
682
  });
561
- indexer.hooks.hook("handler:middleware", async ({ use }) => {
683
+ indexer$1.hooks.hook("handler:middleware", async ({ use }) => {
562
684
  use(async (context, next) => {
563
685
  try {
564
686
  const { endCursor, finality } = context;
@@ -566,7 +688,7 @@ function drizzleStorage({
566
688
  throw new DrizzleStorageError("End Cursor is undefined");
567
689
  }
568
690
  await withTransaction(db, async (tx) => {
569
- context[DRIZZLE_PROPERTY] = { db: tx };
691
+ context[constants.DRIZZLE_PROPERTY] = { db: tx };
570
692
  if (finality !== "finalized") {
571
693
  await registerTriggers(
572
694
  tx,
@@ -577,7 +699,7 @@ function drizzleStorage({
577
699
  );
578
700
  }
579
701
  await next();
580
- delete context[DRIZZLE_PROPERTY];
702
+ delete context[constants.DRIZZLE_PROPERTY];
581
703
  if (enablePersistence) {
582
704
  await persistState({
583
705
  tx,
@@ -600,5 +722,7 @@ function drizzleStorage({
600
722
  });
601
723
  }
602
724
 
725
+ exports.drizzle = drizzle;
603
726
  exports.drizzleStorage = drizzleStorage;
727
+ exports.migrate = migrate;
604
728
  exports.useDrizzleStorage = useDrizzleStorage;
package/dist/index.d.cts CHANGED
@@ -1,17 +1,144 @@
1
1
  import * as _apibara_indexer_plugins from '@apibara/indexer/plugins';
2
- import { TablesRelationalConfig, ExtractTablesWithRelations } from 'drizzle-orm';
2
+ import { DrizzleConfig, TablesRelationalConfig, ExtractTablesWithRelations } from 'drizzle-orm';
3
3
  import { PgQueryResultHKT, PgTransaction, PgDatabase } from 'drizzle-orm/pg-core';
4
+ import { PGliteOptions, PGlite } from '@electric-sql/pglite';
5
+ import { MigrationConfig } from 'drizzle-orm/migrator';
6
+ import { NodePgDatabase as NodePgDatabase$1 } from 'drizzle-orm/node-postgres';
7
+ import { PgliteDatabase as PgliteDatabase$1 } from 'drizzle-orm/pglite';
8
+ import pg from 'pg';
9
+
10
+ /**
11
+ * Union type of all possible drizzle database options
12
+ */
13
+ type DrizzleOptions = PgliteDrizzleOptions | NodePgDrizzleOptions;
14
+ /**
15
+ * Configuration options for Node-Postgres database connection
16
+ */
17
+ type NodePgDrizzleOptions = {
18
+ /**
19
+ * Type of database to use -
20
+ * - "pglite" - PGLite database
21
+ * - "node-postgres" - Node-Postgres database
22
+ * @default "pglite"
23
+ */
24
+ type: "node-postgres";
25
+ /**
26
+ * Connection string to use for the database
27
+ * @default ""
28
+ */
29
+ connectionString?: string;
30
+ /**
31
+ * Pool configuration options for Node-Postgres
32
+ */
33
+ poolConfig?: pg.PoolConfig;
34
+ /**
35
+ * Additional drizzle configuration options
36
+ */
37
+ config?: Omit<DrizzleConfig, "schema">;
38
+ };
39
+ /**
40
+ * Configuration options for PGLite database connection
41
+ */
42
+ type PgliteDrizzleOptions = {
43
+ /**
44
+ * Type of database to use -
45
+ * - "pglite" - PGLite database
46
+ * - "node-postgres" - Node-Postgres database
47
+ */
48
+ type?: "pglite";
49
+ /**
50
+ * Connection string to use for the database
51
+ * @default "memory://pglite"
52
+ */
53
+ connectionString?: string;
54
+ /**
55
+ * Pool configuration is not supported for PGLite
56
+ */
57
+ poolConfig?: never;
58
+ /**
59
+ * Additional drizzle configuration options with PGLite specific connection options
60
+ */
61
+ config?: Omit<DrizzleConfig, "schema"> & {
62
+ connection?: (PGliteOptions & {
63
+ dataDir?: string;
64
+ }) | string;
65
+ };
66
+ };
67
+ /**
68
+ * Extended PGLite database type with client information
69
+ */
70
+ type PgliteDatabase<TSchema extends Record<string, unknown>> = PgliteDatabase$1<TSchema> & {
71
+ $client: PGlite;
72
+ };
73
+ /**
74
+ * Extended Node-Postgres database type with client information
75
+ */
76
+ type NodePgDatabase<TSchema extends Record<string, unknown>> = NodePgDatabase$1<TSchema> & {
77
+ $client: pg.Pool;
78
+ };
79
+ type Database<TOptions extends DrizzleOptions, TSchema extends Record<string, unknown>> = TOptions extends PgliteDrizzleOptions ? PgliteDatabase<TSchema> : NodePgDatabase<TSchema>;
80
+ /**
81
+ * Creates a new Drizzle database instance based on the provided options
82
+ * @param options - Configuration options for the database connection
83
+ * @returns A configured Drizzle database instance
84
+ * @throws {Error} If an invalid database type is specified
85
+ */
86
+ declare function drizzle<TSchema extends Record<string, unknown>, TOptions extends DrizzleOptions>(options?: TOptions & {
87
+ /**
88
+ * Schema to use for the database
89
+ * @default {}
90
+ */
91
+ schema?: TSchema;
92
+ }): Database<TOptions, TSchema>;
93
+ /**
94
+ * Options for database migration
95
+ */
96
+ type MigrateOptions = MigrationConfig;
97
+ /**
98
+ * Performs database migration based on the provided configuration
99
+ * @param db - The database instance to migrate
100
+ * @param options - Migration configuration options
101
+ *
102
+ * @important This function runs migrations on the database instance provided to the `drizzleStorage` plugin.
103
+ * It automatically detects the type of database and runs the appropriate migrate function
104
+ * (PGLite or Node-Postgres).
105
+ *
106
+ * @example
107
+ * ```ts
108
+ * await migrate(db, { migrationsFolder: "./drizzle" });
109
+ * ```
110
+ */
111
+ declare function migrate<TSchema extends Record<string, unknown>>(db: PgliteDatabase<TSchema> | NodePgDatabase<TSchema>, options: MigrateOptions): Promise<void>;
4
112
 
5
113
  type DrizzleStorage<TQueryResult extends PgQueryResultHKT, TFullSchema extends Record<string, unknown> = Record<string, never>, TSchema extends TablesRelationalConfig = ExtractTablesWithRelations<TFullSchema>> = {
6
114
  db: PgTransaction<TQueryResult, TFullSchema, TSchema>;
7
115
  };
8
116
  declare function useDrizzleStorage<TQueryResult extends PgQueryResultHKT, TFullSchema extends Record<string, unknown> = Record<string, never>, TSchema extends TablesRelationalConfig = ExtractTablesWithRelations<TFullSchema>>(_db?: PgDatabase<TQueryResult, TFullSchema, TSchema>): DrizzleStorage<TQueryResult, TFullSchema, TSchema>;
9
117
  interface DrizzleStorageOptions<TQueryResult extends PgQueryResultHKT, TFullSchema extends Record<string, unknown> = Record<string, never>, TSchema extends TablesRelationalConfig = ExtractTablesWithRelations<TFullSchema>> {
118
+ /**
119
+ * The Drizzle database instance.
120
+ */
10
121
  db: PgDatabase<TQueryResult, TFullSchema, TSchema>;
122
+ /**
123
+ * Whether to persist the indexer's state. Defaults to true.
124
+ */
11
125
  persistState?: boolean;
126
+ /**
127
+ * The name of the indexer. Default value is 'default'.
128
+ */
12
129
  indexerName?: string;
130
+ /**
131
+ * The schema of the database.
132
+ */
13
133
  schema?: Record<string, unknown>;
134
+ /**
135
+ * The column to use as the id. Defaults to 'id'.
136
+ */
14
137
  idColumn?: string;
138
+ /**
139
+ * The options for the database migration. When provided, the database will automatically run migrations before the indexer runs.
140
+ */
141
+ migrate?: MigrateOptions;
15
142
  }
16
143
  /**
17
144
  * Creates a plugin that uses Drizzle as the storage layer.
@@ -22,7 +149,8 @@ interface DrizzleStorageOptions<TQueryResult extends PgQueryResultHKT, TFullSche
22
149
  * @param options.indexerName - The name of the indexer. Defaults value is 'default'.
23
150
  * @param options.schema - The schema of the database.
24
151
  * @param options.idColumn - The column to use as the id. Defaults to 'id'.
152
+ * @param options.migrate - The options for the database migration. when provided, the database will automatically run migrations before the indexer runs.
25
153
  */
26
- declare function drizzleStorage<TFilter, TBlock, TQueryResult extends PgQueryResultHKT, TFullSchema extends Record<string, unknown> = Record<string, never>, TSchema extends TablesRelationalConfig = ExtractTablesWithRelations<TFullSchema>>({ db, persistState: enablePersistence, indexerName: identifier, schema, idColumn, }: DrizzleStorageOptions<TQueryResult, TFullSchema, TSchema>): _apibara_indexer_plugins.IndexerPlugin<TFilter, TBlock>;
154
+ declare function drizzleStorage<TFilter, TBlock, TQueryResult extends PgQueryResultHKT, TFullSchema extends Record<string, unknown> = Record<string, never>, TSchema extends TablesRelationalConfig = ExtractTablesWithRelations<TFullSchema>>({ db, persistState: enablePersistence, indexerName: identifier, schema, idColumn, migrate: migrateOptions, }: DrizzleStorageOptions<TQueryResult, TFullSchema, TSchema>): _apibara_indexer_plugins.IndexerPlugin<TFilter, TBlock>;
27
155
 
28
- export { type DrizzleStorage, type DrizzleStorageOptions, drizzleStorage, useDrizzleStorage };
156
+ export { type Database, type DrizzleOptions, type DrizzleStorage, type DrizzleStorageOptions, type MigrateOptions, type NodePgDatabase, type NodePgDrizzleOptions, type PgliteDatabase, type PgliteDrizzleOptions, drizzle, drizzleStorage, migrate, useDrizzleStorage };
package/dist/index.d.mts CHANGED
@@ -1,17 +1,144 @@
1
1
  import * as _apibara_indexer_plugins from '@apibara/indexer/plugins';
2
- import { TablesRelationalConfig, ExtractTablesWithRelations } from 'drizzle-orm';
2
+ import { DrizzleConfig, TablesRelationalConfig, ExtractTablesWithRelations } from 'drizzle-orm';
3
3
  import { PgQueryResultHKT, PgTransaction, PgDatabase } from 'drizzle-orm/pg-core';
4
+ import { PGliteOptions, PGlite } from '@electric-sql/pglite';
5
+ import { MigrationConfig } from 'drizzle-orm/migrator';
6
+ import { NodePgDatabase as NodePgDatabase$1 } from 'drizzle-orm/node-postgres';
7
+ import { PgliteDatabase as PgliteDatabase$1 } from 'drizzle-orm/pglite';
8
+ import pg from 'pg';
9
+
10
+ /**
11
+ * Union type of all possible drizzle database options
12
+ */
13
+ type DrizzleOptions = PgliteDrizzleOptions | NodePgDrizzleOptions;
14
+ /**
15
+ * Configuration options for Node-Postgres database connection
16
+ */
17
+ type NodePgDrizzleOptions = {
18
+ /**
19
+ * Type of database to use -
20
+ * - "pglite" - PGLite database
21
+ * - "node-postgres" - Node-Postgres database
22
+ * @default "pglite"
23
+ */
24
+ type: "node-postgres";
25
+ /**
26
+ * Connection string to use for the database
27
+ * @default ""
28
+ */
29
+ connectionString?: string;
30
+ /**
31
+ * Pool configuration options for Node-Postgres
32
+ */
33
+ poolConfig?: pg.PoolConfig;
34
+ /**
35
+ * Additional drizzle configuration options
36
+ */
37
+ config?: Omit<DrizzleConfig, "schema">;
38
+ };
39
+ /**
40
+ * Configuration options for PGLite database connection
41
+ */
42
+ type PgliteDrizzleOptions = {
43
+ /**
44
+ * Type of database to use -
45
+ * - "pglite" - PGLite database
46
+ * - "node-postgres" - Node-Postgres database
47
+ */
48
+ type?: "pglite";
49
+ /**
50
+ * Connection string to use for the database
51
+ * @default "memory://pglite"
52
+ */
53
+ connectionString?: string;
54
+ /**
55
+ * Pool configuration is not supported for PGLite
56
+ */
57
+ poolConfig?: never;
58
+ /**
59
+ * Additional drizzle configuration options with PGLite specific connection options
60
+ */
61
+ config?: Omit<DrizzleConfig, "schema"> & {
62
+ connection?: (PGliteOptions & {
63
+ dataDir?: string;
64
+ }) | string;
65
+ };
66
+ };
67
+ /**
68
+ * Extended PGLite database type with client information
69
+ */
70
+ type PgliteDatabase<TSchema extends Record<string, unknown>> = PgliteDatabase$1<TSchema> & {
71
+ $client: PGlite;
72
+ };
73
+ /**
74
+ * Extended Node-Postgres database type with client information
75
+ */
76
+ type NodePgDatabase<TSchema extends Record<string, unknown>> = NodePgDatabase$1<TSchema> & {
77
+ $client: pg.Pool;
78
+ };
79
+ type Database<TOptions extends DrizzleOptions, TSchema extends Record<string, unknown>> = TOptions extends PgliteDrizzleOptions ? PgliteDatabase<TSchema> : NodePgDatabase<TSchema>;
80
+ /**
81
+ * Creates a new Drizzle database instance based on the provided options
82
+ * @param options - Configuration options for the database connection
83
+ * @returns A configured Drizzle database instance
84
+ * @throws {Error} If an invalid database type is specified
85
+ */
86
+ declare function drizzle<TSchema extends Record<string, unknown>, TOptions extends DrizzleOptions>(options?: TOptions & {
87
+ /**
88
+ * Schema to use for the database
89
+ * @default {}
90
+ */
91
+ schema?: TSchema;
92
+ }): Database<TOptions, TSchema>;
93
+ /**
94
+ * Options for database migration
95
+ */
96
+ type MigrateOptions = MigrationConfig;
97
+ /**
98
+ * Performs database migration based on the provided configuration
99
+ * @param db - The database instance to migrate
100
+ * @param options - Migration configuration options
101
+ *
102
+ * @important This function runs migrations on the database instance provided to the `drizzleStorage` plugin.
103
+ * It automatically detects the type of database and runs the appropriate migrate function
104
+ * (PGLite or Node-Postgres).
105
+ *
106
+ * @example
107
+ * ```ts
108
+ * await migrate(db, { migrationsFolder: "./drizzle" });
109
+ * ```
110
+ */
111
+ declare function migrate<TSchema extends Record<string, unknown>>(db: PgliteDatabase<TSchema> | NodePgDatabase<TSchema>, options: MigrateOptions): Promise<void>;
4
112
 
5
113
  type DrizzleStorage<TQueryResult extends PgQueryResultHKT, TFullSchema extends Record<string, unknown> = Record<string, never>, TSchema extends TablesRelationalConfig = ExtractTablesWithRelations<TFullSchema>> = {
6
114
  db: PgTransaction<TQueryResult, TFullSchema, TSchema>;
7
115
  };
8
116
  declare function useDrizzleStorage<TQueryResult extends PgQueryResultHKT, TFullSchema extends Record<string, unknown> = Record<string, never>, TSchema extends TablesRelationalConfig = ExtractTablesWithRelations<TFullSchema>>(_db?: PgDatabase<TQueryResult, TFullSchema, TSchema>): DrizzleStorage<TQueryResult, TFullSchema, TSchema>;
9
117
  interface DrizzleStorageOptions<TQueryResult extends PgQueryResultHKT, TFullSchema extends Record<string, unknown> = Record<string, never>, TSchema extends TablesRelationalConfig = ExtractTablesWithRelations<TFullSchema>> {
118
+ /**
119
+ * The Drizzle database instance.
120
+ */
10
121
  db: PgDatabase<TQueryResult, TFullSchema, TSchema>;
122
+ /**
123
+ * Whether to persist the indexer's state. Defaults to true.
124
+ */
11
125
  persistState?: boolean;
126
+ /**
127
+ * The name of the indexer. Default value is 'default'.
128
+ */
12
129
  indexerName?: string;
130
+ /**
131
+ * The schema of the database.
132
+ */
13
133
  schema?: Record<string, unknown>;
134
+ /**
135
+ * The column to use as the id. Defaults to 'id'.
136
+ */
14
137
  idColumn?: string;
138
+ /**
139
+ * The options for the database migration. When provided, the database will automatically run migrations before the indexer runs.
140
+ */
141
+ migrate?: MigrateOptions;
15
142
  }
16
143
  /**
17
144
  * Creates a plugin that uses Drizzle as the storage layer.
@@ -22,7 +149,8 @@ interface DrizzleStorageOptions<TQueryResult extends PgQueryResultHKT, TFullSche
22
149
  * @param options.indexerName - The name of the indexer. Defaults value is 'default'.
23
150
  * @param options.schema - The schema of the database.
24
151
  * @param options.idColumn - The column to use as the id. Defaults to 'id'.
152
+ * @param options.migrate - The options for the database migration. when provided, the database will automatically run migrations before the indexer runs.
25
153
  */
26
- declare function drizzleStorage<TFilter, TBlock, TQueryResult extends PgQueryResultHKT, TFullSchema extends Record<string, unknown> = Record<string, never>, TSchema extends TablesRelationalConfig = ExtractTablesWithRelations<TFullSchema>>({ db, persistState: enablePersistence, indexerName: identifier, schema, idColumn, }: DrizzleStorageOptions<TQueryResult, TFullSchema, TSchema>): _apibara_indexer_plugins.IndexerPlugin<TFilter, TBlock>;
154
+ declare function drizzleStorage<TFilter, TBlock, TQueryResult extends PgQueryResultHKT, TFullSchema extends Record<string, unknown> = Record<string, never>, TSchema extends TablesRelationalConfig = ExtractTablesWithRelations<TFullSchema>>({ db, persistState: enablePersistence, indexerName: identifier, schema, idColumn, migrate: migrateOptions, }: DrizzleStorageOptions<TQueryResult, TFullSchema, TSchema>): _apibara_indexer_plugins.IndexerPlugin<TFilter, TBlock>;
27
155
 
28
- export { type DrizzleStorage, type DrizzleStorageOptions, drizzleStorage, useDrizzleStorage };
156
+ export { type Database, type DrizzleOptions, type DrizzleStorage, type DrizzleStorageOptions, type MigrateOptions, type NodePgDatabase, type NodePgDrizzleOptions, type PgliteDatabase, type PgliteDrizzleOptions, drizzle, drizzleStorage, migrate, useDrizzleStorage };