UNPKG

durable-execution-storage-drizzle

Version:

Drizzle ORM storage implementation for durable-execution

833 lines 30.4 kB
import { type TablesRelationalConfig } from 'drizzle-orm'; import { type MySqlDatabase, type MySqlQueryResultHKT, type MySqlQueryResultKind, type PreparedQueryHKTBase } from 'drizzle-orm/mysql-core'; import { type DurableExecutionErrorStorageValue, type TaskExecutionCloseStatus, type TaskExecutionOnChildrenFinishedProcessingStatus, type TaskExecutionsStorage, type TaskExecutionStatus, type TaskExecutionSummary, type TaskRetryOptions } from 'durable-execution'; /** * Creates a MySQL table schema for storing durable task executions. * * This function generates a Drizzle ORM table definition with all necessary columns and indexes * for the durable-execution storage layer. The table includes: * - Task hierarchy tracking (root, parent, child relationships) * - Execution state management (status, retries, timeouts) * - Input/output data storage * - Timestamp tracking for scheduling and expiration * * @example * ```ts * // In your schema file (e.g., schema.ts) * import { createMySqlTaskExecutionsTable } from 'durable-execution-storage-drizzle' * * // Use default table name * export const taskExecutions = createMySqlTaskExecutionsTable() * * // Or specify a custom table name * export const myTasksTable = createMySqlTaskExecutionsTable('my_custom_task_executions') * ``` * * @param tableName - The name of the table to create. Defaults to 'task_executions'. * @returns A Drizzle MySQL table definition ready for migrations. */ export declare function createMySqlTaskExecutionsTable(tableName?: string): import("drizzle-orm/mysql-core").MySqlTableWithColumns<{ name: string; schema: undefined; columns: { id: import("drizzle-orm/mysql-core").MySqlColumn<{ name: "id"; tableName: string; dataType: "number"; columnType: "MySqlSerial"; data: number; driverParam: number; notNull: true; hasDefault: true; isPrimaryKey: true; isAutoincrement: true; hasRuntimeDefault: false; enumValues: undefined; baseColumn: never; identity: undefined; generated: undefined; }, {}, {}>; rootTaskId: import("drizzle-orm/mysql-core").MySqlColumn<{ name: "root_task_id"; tableName: string; dataType: "string"; columnType: "MySqlVarChar"; data: string; driverParam: string | number; notNull: false; hasDefault: false; isPrimaryKey: false; isAutoincrement: false; hasRuntimeDefault: false; enumValues: [string, ...string[]]; baseColumn: never; identity: undefined; generated: undefined; }, {}, {}>; rootExecutionId: import("drizzle-orm/mysql-core").MySqlColumn<{ name: "root_execution_id"; tableName: string; dataType: "string"; columnType: "MySqlVarChar"; data: string; driverParam: string | number; notNull: false; hasDefault: false; isPrimaryKey: false; isAutoincrement: false; hasRuntimeDefault: false; enumValues: [string, ...string[]]; baseColumn: never; identity: undefined; generated: undefined; }, {}, {}>; parentTaskId: import("drizzle-orm/mysql-core").MySqlColumn<{ name: "parent_task_id"; tableName: string; dataType: "string"; columnType: "MySqlVarChar"; data: string; driverParam: string | number; notNull: false; hasDefault: false; isPrimaryKey: false; isAutoincrement: false; hasRuntimeDefault: false; enumValues: [string, ...string[]]; baseColumn: never; identity: undefined; generated: undefined; }, {}, {}>; parentExecutionId: import("drizzle-orm/mysql-core").MySqlColumn<{ name: "parent_execution_id"; tableName: string; dataType: "string"; columnType: "MySqlVarChar"; data: string; driverParam: string | number; notNull: false; hasDefault: false; isPrimaryKey: false; isAutoincrement: false; hasRuntimeDefault: false; enumValues: [string, ...string[]]; baseColumn: never; identity: undefined; generated: undefined; }, {}, {}>; indexInParentChildren: import("drizzle-orm/mysql-core").MySqlColumn<{ name: "index_in_parent_children"; tableName: string; dataType: "number"; columnType: "MySqlInt"; data: number; driverParam: string | number; notNull: false; hasDefault: false; isPrimaryKey: false; isAutoincrement: false; hasRuntimeDefault: false; enumValues: undefined; baseColumn: never; identity: undefined; generated: undefined; }, {}, {}>; isOnlyChildOfParent: import("drizzle-orm/mysql-core").MySqlColumn<{ name: "is_only_child_of_parent"; tableName: string; dataType: "boolean"; columnType: "MySqlBoolean"; data: boolean; driverParam: number | boolean; notNull: false; hasDefault: false; isPrimaryKey: false; isAutoincrement: false; hasRuntimeDefault: false; enumValues: undefined; baseColumn: never; identity: undefined; generated: undefined; }, {}, {}>; isFinalizeOfParent: import("drizzle-orm/mysql-core").MySqlColumn<{ name: "is_finalize_of_parent"; tableName: string; dataType: "boolean"; columnType: "MySqlBoolean"; data: boolean; driverParam: number | boolean; notNull: false; hasDefault: false; isPrimaryKey: false; isAutoincrement: false; hasRuntimeDefault: false; enumValues: undefined; baseColumn: never; identity: undefined; generated: undefined; }, {}, {}>; taskId: import("drizzle-orm/mysql-core").MySqlColumn<{ name: "task_id"; tableName: string; dataType: "string"; columnType: "MySqlVarChar"; data: string; driverParam: string | number; notNull: true; hasDefault: false; isPrimaryKey: false; isAutoincrement: false; hasRuntimeDefault: false; enumValues: [string, ...string[]]; baseColumn: never; identity: undefined; generated: undefined; }, {}, {}>; executionId: import("drizzle-orm/mysql-core").MySqlColumn<{ name: "execution_id"; tableName: string; dataType: "string"; columnType: "MySqlVarChar"; data: string; driverParam: string | number; notNull: true; hasDefault: false; isPrimaryKey: false; isAutoincrement: false; hasRuntimeDefault: false; enumValues: [string, ...string[]]; baseColumn: never; identity: undefined; generated: undefined; }, {}, {}>; isSleepingTask: import("drizzle-orm/mysql-core").MySqlColumn<{ name: "is_sleeping_task"; tableName: string; dataType: "boolean"; columnType: "MySqlBoolean"; data: boolean; driverParam: number | boolean; notNull: true; hasDefault: false; isPrimaryKey: false; isAutoincrement: false; hasRuntimeDefault: false; enumValues: undefined; baseColumn: never; identity: undefined; generated: undefined; }, {}, {}>; sleepingTaskUniqueId: import("drizzle-orm/mysql-core").MySqlColumn<{ name: "sleeping_task_unique_id"; tableName: string; dataType: "string"; columnType: "MySqlVarChar"; data: string; driverParam: string | number; notNull: false; hasDefault: false; isPrimaryKey: false; isAutoincrement: false; hasRuntimeDefault: false; enumValues: [string, ...string[]]; baseColumn: never; identity: undefined; generated: undefined; }, {}, {}>; retryOptions: import("drizzle-orm/mysql-core").MySqlColumn<{ name: "retry_options"; tableName: string; dataType: "json"; columnType: "MySqlJson"; data: TaskRetryOptions; driverParam: string; notNull: true; hasDefault: false; isPrimaryKey: false; isAutoincrement: false; hasRuntimeDefault: false; enumValues: undefined; baseColumn: never; identity: undefined; generated: undefined; }, {}, { $type: TaskRetryOptions; }>; sleepMsBeforeRun: import("drizzle-orm/mysql-core").MySqlColumn<{ name: "sleep_ms_before_run"; tableName: string; dataType: "number"; columnType: "MySqlBigInt53"; data: number; driverParam: string | number; notNull: true; hasDefault: false; isPrimaryKey: false; isAutoincrement: false; hasRuntimeDefault: false; enumValues: undefined; baseColumn: never; identity: undefined; generated: undefined; }, {}, {}>; timeoutMs: import("drizzle-orm/mysql-core").MySqlColumn<{ name: "timeout_ms"; tableName: string; dataType: "number"; columnType: "MySqlBigInt53"; data: number; driverParam: string | number; notNull: true; hasDefault: false; isPrimaryKey: false; isAutoincrement: false; hasRuntimeDefault: false; enumValues: undefined; baseColumn: never; identity: undefined; generated: undefined; }, {}, {}>; areChildrenSequential: import("drizzle-orm/mysql-core").MySqlColumn<{ name: "are_children_sequential"; tableName: string; dataType: "boolean"; columnType: "MySqlBoolean"; data: boolean; driverParam: number | boolean; notNull: true; hasDefault: false; isPrimaryKey: false; isAutoincrement: false; hasRuntimeDefault: false; enumValues: undefined; baseColumn: never; identity: undefined; generated: undefined; }, {}, {}>; input: import("drizzle-orm/mysql-core").MySqlColumn<{ name: "input"; tableName: string; dataType: "string"; columnType: "MySqlText"; data: string; driverParam: string; notNull: true; hasDefault: false; isPrimaryKey: false; isAutoincrement: false; hasRuntimeDefault: false; enumValues: [string, ...string[]]; baseColumn: never; identity: undefined; generated: undefined; }, {}, {}>; executorId: import("drizzle-orm/mysql-core").MySqlColumn<{ name: "executor_id"; tableName: string; dataType: "string"; columnType: "MySqlVarChar"; data: string; driverParam: string | number; notNull: false; hasDefault: false; isPrimaryKey: false; isAutoincrement: false; hasRuntimeDefault: false; enumValues: [string, ...string[]]; baseColumn: never; identity: undefined; generated: undefined; }, {}, {}>; status: import("drizzle-orm/mysql-core").MySqlColumn<{ name: "status"; tableName: string; dataType: "string"; columnType: "MySqlVarChar"; data: TaskExecutionStatus; driverParam: string | number; notNull: true; hasDefault: false; isPrimaryKey: false; isAutoincrement: false; hasRuntimeDefault: false; enumValues: [string, ...string[]]; baseColumn: never; identity: undefined; generated: undefined; }, {}, { $type: TaskExecutionStatus; }>; isFinished: import("drizzle-orm/mysql-core").MySqlColumn<{ name: "is_finished"; tableName: string; dataType: "boolean"; columnType: "MySqlBoolean"; data: boolean; driverParam: number | boolean; notNull: true; hasDefault: false; isPrimaryKey: false; isAutoincrement: false; hasRuntimeDefault: false; enumValues: undefined; baseColumn: never; identity: undefined; generated: undefined; }, {}, {}>; runOutput: import("drizzle-orm/mysql-core").MySqlColumn<{ name: "run_output"; tableName: string; dataType: "string"; columnType: "MySqlText"; data: string; driverParam: string; notNull: false; hasDefault: false; isPrimaryKey: false; isAutoincrement: false; hasRuntimeDefault: false; enumValues: [string, ...string[]]; baseColumn: never; identity: undefined; generated: undefined; }, {}, {}>; output: import("drizzle-orm/mysql-core").MySqlColumn<{ name: "output"; tableName: string; dataType: "string"; columnType: "MySqlText"; data: string; driverParam: string; notNull: false; hasDefault: false; isPrimaryKey: false; isAutoincrement: false; hasRuntimeDefault: false; enumValues: [string, ...string[]]; baseColumn: never; identity: undefined; generated: undefined; }, {}, {}>; error: import("drizzle-orm/mysql-core").MySqlColumn<{ name: "error"; tableName: string; dataType: "json"; columnType: "MySqlJson"; data: DurableExecutionErrorStorageValue; driverParam: string; notNull: false; hasDefault: false; isPrimaryKey: false; isAutoincrement: false; hasRuntimeDefault: false; enumValues: undefined; baseColumn: never; identity: undefined; generated: undefined; }, {}, { $type: DurableExecutionErrorStorageValue; }>; retryAttempts: import("drizzle-orm/mysql-core").MySqlColumn<{ name: "retry_attempts"; tableName: string; dataType: "number"; columnType: "MySqlInt"; data: number; driverParam: string | number; notNull: true; hasDefault: false; isPrimaryKey: false; isAutoincrement: false; hasRuntimeDefault: false; enumValues: undefined; baseColumn: never; identity: undefined; generated: undefined; }, {}, {}>; startAt: import("drizzle-orm/mysql-core").MySqlColumn<{ name: "start_at"; tableName: string; dataType: "number"; columnType: "MySqlBigInt53"; data: number; driverParam: string | number; notNull: true; hasDefault: false; isPrimaryKey: false; isAutoincrement: false; hasRuntimeDefault: false; enumValues: undefined; baseColumn: never; identity: undefined; generated: undefined; }, {}, {}>; startedAt: import("drizzle-orm/mysql-core").MySqlColumn<{ name: "started_at"; tableName: string; dataType: "number"; columnType: "MySqlBigInt53"; data: number; driverParam: string | number; notNull: false; hasDefault: false; isPrimaryKey: false; isAutoincrement: false; hasRuntimeDefault: false; enumValues: undefined; baseColumn: never; identity: undefined; generated: undefined; }, {}, {}>; expiresAt: import("drizzle-orm/mysql-core").MySqlColumn<{ name: "expires_at"; tableName: string; dataType: "number"; columnType: "MySqlBigInt53"; data: number; driverParam: string | number; notNull: false; hasDefault: false; isPrimaryKey: false; isAutoincrement: false; hasRuntimeDefault: false; enumValues: undefined; baseColumn: never; identity: undefined; generated: undefined; }, {}, {}>; waitingForChildrenStartedAt: import("drizzle-orm/mysql-core").MySqlColumn<{ name: "waiting_for_children_started_at"; tableName: string; dataType: "number"; columnType: "MySqlBigInt53"; data: number; driverParam: string | number; notNull: false; hasDefault: false; isPrimaryKey: false; isAutoincrement: false; hasRuntimeDefault: false; enumValues: undefined; baseColumn: never; identity: undefined; generated: undefined; }, {}, {}>; waitingForFinalizeStartedAt: import("drizzle-orm/mysql-core").MySqlColumn<{ name: "waiting_for_finalize_started_at"; tableName: string; dataType: "number"; columnType: "MySqlBigInt53"; data: number; driverParam: string | number; notNull: false; hasDefault: false; isPrimaryKey: false; isAutoincrement: false; hasRuntimeDefault: false; enumValues: undefined; baseColumn: never; identity: undefined; generated: undefined; }, {}, {}>; finishedAt: import("drizzle-orm/mysql-core").MySqlColumn<{ name: "finished_at"; tableName: string; dataType: "number"; columnType: "MySqlBigInt53"; data: number; driverParam: string | number; notNull: false; hasDefault: false; isPrimaryKey: false; isAutoincrement: false; hasRuntimeDefault: false; enumValues: undefined; baseColumn: never; identity: undefined; generated: undefined; }, {}, {}>; children: import("drizzle-orm/mysql-core").MySqlColumn<{ name: "children"; tableName: string; dataType: "json"; columnType: "MySqlJson"; data: TaskExecutionSummary[]; driverParam: string; notNull: false; hasDefault: false; isPrimaryKey: false; isAutoincrement: false; hasRuntimeDefault: false; enumValues: undefined; baseColumn: never; identity: undefined; generated: undefined; }, {}, { $type: TaskExecutionSummary[]; }>; activeChildrenCount: import("drizzle-orm/mysql-core").MySqlColumn<{ name: "active_children_count"; tableName: string; dataType: "number"; columnType: "MySqlInt"; data: number; driverParam: string | number; notNull: true; hasDefault: false; isPrimaryKey: false; isAutoincrement: false; hasRuntimeDefault: false; enumValues: undefined; baseColumn: never; identity: undefined; generated: undefined; }, {}, {}>; onChildrenFinishedProcessingStatus: import("drizzle-orm/mysql-core").MySqlColumn<{ name: "on_children_finished_processing_status"; tableName: string; dataType: "string"; columnType: "MySqlVarChar"; data: TaskExecutionOnChildrenFinishedProcessingStatus; driverParam: string | number; notNull: true; hasDefault: false; isPrimaryKey: false; isAutoincrement: false; hasRuntimeDefault: false; enumValues: [string, ...string[]]; baseColumn: never; identity: undefined; generated: undefined; }, {}, { $type: TaskExecutionOnChildrenFinishedProcessingStatus; }>; onChildrenFinishedProcessingExpiresAt: import("drizzle-orm/mysql-core").MySqlColumn<{ name: "on_children_finished_processing_expires_at"; tableName: string; dataType: "number"; columnType: "MySqlBigInt53"; data: number; driverParam: string | number; notNull: false; hasDefault: false; isPrimaryKey: false; isAutoincrement: false; hasRuntimeDefault: false; enumValues: undefined; baseColumn: never; identity: undefined; generated: undefined; }, {}, {}>; onChildrenFinishedProcessingFinishedAt: import("drizzle-orm/mysql-core").MySqlColumn<{ name: "on_children_finished_processing_finished_at"; tableName: string; dataType: "number"; columnType: "MySqlBigInt53"; data: number; driverParam: string | number; notNull: false; hasDefault: false; isPrimaryKey: false; isAutoincrement: false; hasRuntimeDefault: false; enumValues: undefined; baseColumn: never; identity: undefined; generated: undefined; }, {}, {}>; finalize: import("drizzle-orm/mysql-core").MySqlColumn<{ name: "finalize"; tableName: string; dataType: "json"; columnType: "MySqlJson"; data: TaskExecutionSummary; driverParam: string; notNull: false; hasDefault: false; isPrimaryKey: false; isAutoincrement: false; hasRuntimeDefault: false; enumValues: undefined; baseColumn: never; identity: undefined; generated: undefined; }, {}, { $type: TaskExecutionSummary; }>; closeStatus: import("drizzle-orm/mysql-core").MySqlColumn<{ name: "close_status"; tableName: string; dataType: "string"; columnType: "MySqlVarChar"; data: TaskExecutionCloseStatus; driverParam: string | number; notNull: true; hasDefault: false; isPrimaryKey: false; isAutoincrement: false; hasRuntimeDefault: false; enumValues: [string, ...string[]]; baseColumn: never; identity: undefined; generated: undefined; }, {}, { $type: TaskExecutionCloseStatus; }>; closeExpiresAt: import("drizzle-orm/mysql-core").MySqlColumn<{ name: "close_expires_at"; tableName: string; dataType: "number"; columnType: "MySqlBigInt53"; data: number; driverParam: string | number; notNull: false; hasDefault: false; isPrimaryKey: false; isAutoincrement: false; hasRuntimeDefault: false; enumValues: undefined; baseColumn: never; identity: undefined; generated: undefined; }, {}, {}>; closedAt: import("drizzle-orm/mysql-core").MySqlColumn<{ name: "closed_at"; tableName: string; dataType: "number"; columnType: "MySqlBigInt53"; data: number; driverParam: string | number; notNull: false; hasDefault: false; isPrimaryKey: false; isAutoincrement: false; hasRuntimeDefault: false; enumValues: undefined; baseColumn: never; identity: undefined; generated: undefined; }, {}, {}>; needsPromiseCancellation: import("drizzle-orm/mysql-core").MySqlColumn<{ name: "needs_promise_cancellation"; tableName: string; dataType: "boolean"; columnType: "MySqlBoolean"; data: boolean; driverParam: number | boolean; notNull: true; hasDefault: false; isPrimaryKey: false; isAutoincrement: false; hasRuntimeDefault: false; enumValues: undefined; baseColumn: never; identity: undefined; generated: undefined; }, {}, {}>; createdAt: import("drizzle-orm/mysql-core").MySqlColumn<{ name: "created_at"; tableName: string; dataType: "number"; columnType: "MySqlBigInt53"; data: number; driverParam: string | number; notNull: true; hasDefault: false; isPrimaryKey: false; isAutoincrement: false; hasRuntimeDefault: false; enumValues: undefined; baseColumn: never; identity: undefined; generated: undefined; }, {}, {}>; updatedAt: import("drizzle-orm/mysql-core").MySqlColumn<{ name: "updated_at"; tableName: string; dataType: "number"; columnType: "MySqlBigInt53"; data: number; driverParam: string | number; notNull: true; hasDefault: false; isPrimaryKey: false; isAutoincrement: false; hasRuntimeDefault: false; enumValues: undefined; baseColumn: never; identity: undefined; generated: undefined; }, {}, {}>; }; dialect: "mysql"; }>; /** * Type representing the MySQL table schema for task executions. Use this type when you need to * reference the table structure in your code. */ export type TaskExecutionsMySqlTable = ReturnType<typeof createMySqlTaskExecutionsTable>; /** * Creates a MySQL storage adapter for durable-execution. * * This function creates a storage implementation that uses MySQL as the backend for persisting * task execution state. The storage adapter handles: * - Transactional operations for consistency * - Row-level locking with 'FOR UPDATE SKIP LOCKED' for concurrent access * - Efficient querying with proper indexes * - Parent-child task relationship management * * @example * ```ts * import { drizzle } from 'drizzle-orm/mysql2' * import mysql from 'mysql2/promise' * import { DurableExecutor } from 'durable-execution' * import { createMySqlTaskExecutionsTable, createMySqlTaskExecutionsStorage } from 'durable-execution-storage-drizzle' * * // Setup database connection * const connection = await mysql.createConnection({ * uri: process.env.DATABASE_URL * }) * const db = drizzle(connection) * * // Create table schema and storage * const taskExecutionsTable = createMySqlTaskExecutionsTable() * const storage = createMySqlTaskExecutionsStorage( * db, * taskExecutionsTable, * (result) => result[0].affectedRows // mysql2 driver * ) * * // Use with DurableExecutor * const executor = await DurableExecutor.make(storage) * ``` * * @example * ```ts * // For PlanetScale driver * import { drizzle } from 'drizzle-orm/planetscale-serverless' * import { Client } from '@planetscale/database' * * const client = new Client({ * url: process.env.DATABASE_URL * }) * const db = drizzle(client) * * const storage = createMySqlTaskExecutionsStorage( * db, * taskExecutionsTable, * (result) => result.rowsAffected // PlanetScale driver * ) * ``` * * @param db - A Drizzle MySQL database instance. * @param taskExecutionsTable - The table created by `createMySqlTaskExecutionsTable()`. * @param getAffectedRowsCount - A function to extract affected rows count from MySQL query * results. This varies based on your MySQL driver (mysql2, planetscale, etc.). * @param options - The options for the storage. * @param options.enableTestMode - Whether to enable test mode. Defaults to false. * @returns A TaskExecutionsStorage implementation for use with DurableExecutor. */ export declare function createMySqlTaskExecutionsStorage<TQueryResult extends MySqlQueryResultHKT, TPreparedQueryHKT extends PreparedQueryHKTBase, TFullSchema extends Record<string, unknown>, TSchema extends TablesRelationalConfig>(db: MySqlDatabase<TQueryResult, TPreparedQueryHKT, TFullSchema, TSchema>, taskExecutionsTable: TaskExecutionsMySqlTable, getAffectedRowsCount: (result: MySqlQueryResultKind<TQueryResult, never>) => number, options?: { enableTestMode?: boolean; }): TaskExecutionsStorage; //# sourceMappingURL=mysql.d.ts.map