@gravito/flux 3.0.2 → 3.0.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.
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["/Users/carl/Dev/Carl/gravito-core/packages/flux/dist/chunk-ZE2RDS47.cjs","../src/storage/BunSQLiteStorage.ts"],"names":[],"mappings":"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","file":"/Users/carl/Dev/Carl/gravito-core/packages/flux/dist/chunk-ZE2RDS47.cjs","sourcesContent":[null,"import { Database } from 'bun:sqlite'\nimport type { WorkflowFilter, WorkflowState, WorkflowStorage } from '../types'\n\n/**\n * Configuration options for the Bun SQLite storage adapter.\n */\nexport interface BunSQLiteStorageOptions {\n /**\n * Path to the SQLite database file.\n * Use ':memory:' for an ephemeral in-memory database.\n */\n path?: string\n /**\n * Name of the table used to store workflow states.\n */\n tableName?: string\n}\n\n/**\n * BunSQLiteStorage provides a persistent storage backend for Flux workflows using Bun's native SQLite module.\n *\n * It handles automatic table creation, indexing for performance, and serialization of workflow state\n * into a relational format.\n *\n * @example\n * ```typescript\n * const storage = new BunSQLiteStorage({\n * path: './workflows.db',\n * tableName: 'my_workflows'\n * });\n * await storage.init();\n * ```\n */\nexport class BunSQLiteStorage implements WorkflowStorage {\n private db: Database\n private tableName: string\n private initialized = false\n\n /**\n * Creates a new instance of BunSQLiteStorage.\n *\n * @param options - Configuration for the database connection and table naming.\n */\n constructor(options: BunSQLiteStorageOptions = {}) {\n this.db = new Database(options.path ?? ':memory:')\n this.tableName = validateSqlIdentifier(options.tableName ?? 'flux_workflows', 'tableName')\n }\n\n /**\n * Initializes the database schema and required indexes.\n *\n * This method is idempotent and will be called automatically by other operations if not invoked manually.\n *\n * @throws {Error} If the database schema cannot be created or indexes fail to initialize.\n */\n async init(): Promise<void> {\n if (this.initialized) {\n return\n }\n\n this.db.run(`\n CREATE TABLE IF NOT EXISTS ${this.tableName} (\n id TEXT PRIMARY KEY,\n name TEXT NOT NULL,\n status TEXT NOT NULL,\n input TEXT NOT NULL,\n data TEXT NOT NULL,\n current_step INTEGER NOT NULL,\n history TEXT NOT NULL,\n error TEXT,\n created_at TEXT NOT NULL,\n updated_at TEXT NOT NULL,\n completed_at TEXT,\n version INTEGER NOT NULL DEFAULT 1,\n definition_version TEXT\n )\n `)\n\n this.db.run(`\n CREATE INDEX IF NOT EXISTS idx_${this.tableName}_name \n ON ${this.tableName}(name)\n `)\n this.db.run(`\n CREATE INDEX IF NOT EXISTS idx_${this.tableName}_status \n ON ${this.tableName}(status)\n `)\n this.db.run(`\n CREATE INDEX IF NOT EXISTS idx_${this.tableName}_created \n ON ${this.tableName}(created_at DESC)\n `)\n\n this.initialized = true\n }\n\n /**\n * Persists or updates a workflow state in the database.\n *\n * Uses an \"INSERT OR REPLACE\" strategy to ensure the latest state is always stored for a given ID.\n *\n * @param state - The current state of the workflow to be saved.\n * @throws {Error} If the database write operation fails or serialization errors occur.\n */\n async save(state: WorkflowState): Promise<void> {\n await this.init()\n\n const stmt = this.db.prepare(`\n INSERT OR REPLACE INTO ${this.tableName} \n (id, name, status, input, data, current_step, history, error, created_at, updated_at, completed_at, version, definition_version)\n VALUES ($id, $name, $status, $input, $data, $currentStep, $history, $error, $createdAt, $updatedAt, $completedAt, $version, $definitionVersion)\n `)\n\n stmt.run({\n $id: state.id,\n $name: state.name,\n $status: state.status,\n $input: JSON.stringify(state.input),\n $data: JSON.stringify(state.data),\n $currentStep: state.currentStep,\n $history: JSON.stringify(state.history),\n $error: state.error ?? null,\n $createdAt: state.createdAt.toISOString(),\n $updatedAt: state.updatedAt.toISOString(),\n $completedAt: state.completedAt?.toISOString() ?? null,\n $version: state.version,\n $definitionVersion: state.definitionVersion ?? null,\n })\n }\n\n /**\n * Retrieves a workflow state by its unique identifier.\n *\n * @param id - The unique ID of the workflow to load.\n * @returns The reconstructed workflow state, or null if no record is found.\n * @throws {Error} If the database query fails or deserialization of stored JSON fails.\n */\n async load(id: string): Promise<WorkflowState | null> {\n await this.init()\n\n const stmt = this.db.prepare(`\n SELECT * FROM ${this.tableName} WHERE id = $id\n `)\n\n const row = stmt.get({ $id: id }) as SQLiteRow | null\n\n if (!row) {\n return null\n }\n\n return this.rowToState(row)\n }\n\n /**\n * Lists workflow states based on the provided filtering criteria.\n *\n * Results are returned in descending order of creation time.\n *\n * @param filter - Criteria for filtering and paginating the results.\n * @returns An array of workflow states matching the filter.\n * @throws {Error} If the database query fails.\n */\n async list(filter?: WorkflowFilter): Promise<WorkflowState[]> {\n await this.init()\n\n let query = `SELECT * FROM ${this.tableName} WHERE 1=1`\n const params: Record<string, unknown> = {}\n\n if (filter?.name) {\n query += ' AND name = $name'\n params.$name = filter.name\n }\n\n if (filter?.status) {\n if (Array.isArray(filter.status)) {\n const placeholders = filter.status.map((_, i) => `$status${i}`).join(', ')\n query += ` AND status IN (${placeholders})`\n filter.status.forEach((s, i) => {\n params[`$status${i}`] = s\n })\n } else {\n query += ' AND status = $status'\n params.$status = filter.status\n }\n }\n\n if (filter?.version) {\n query += ' AND definition_version = $version'\n params.$version = filter.version\n }\n\n query += ' ORDER BY created_at DESC'\n\n if (filter?.limit) {\n query += ' LIMIT $limit'\n params.$limit = filter.limit\n }\n\n if (filter?.offset) {\n query += ' OFFSET $offset'\n params.$offset = filter.offset\n }\n\n const stmt = this.db.prepare(query)\n const rows = stmt.all(params as Record<string, any>) as SQLiteRow[]\n\n return rows.map((row) => this.rowToState(row))\n }\n\n /**\n * Deletes a workflow state from the database.\n *\n * @param id - The unique ID of the workflow to delete.\n * @throws {Error} If the database deletion fails.\n */\n async delete(id: string): Promise<void> {\n await this.init()\n\n const stmt = this.db.prepare(`\n DELETE FROM ${this.tableName} WHERE id = $id\n `)\n\n stmt.run({ $id: id })\n }\n\n /**\n * Closes the database connection and resets the initialization state.\n *\n * @throws {Error} If the database connection cannot be closed cleanly.\n */\n async close(): Promise<void> {\n this.db.close()\n this.initialized = false\n }\n\n /**\n * Converts a raw database row into a structured WorkflowState object.\n *\n * @param row - The raw SQLite row data.\n * @returns The parsed workflow state.\n * @private\n */\n private rowToState(row: SQLiteRow): WorkflowState {\n return {\n id: row.id,\n name: row.name,\n status: row.status as WorkflowState['status'],\n input: JSON.parse(row.input),\n data: JSON.parse(row.data),\n currentStep: row.current_step,\n history: JSON.parse(row.history),\n error: row.error ?? undefined,\n createdAt: new Date(row.created_at),\n updatedAt: new Date(row.updated_at),\n completedAt: row.completed_at ? new Date(row.completed_at) : undefined,\n version: row.version,\n definitionVersion: row.definition_version ?? undefined,\n }\n }\n\n /**\n * Provides direct access to the underlying Bun SQLite Database instance.\n *\n * Useful for performing custom queries or maintenance tasks.\n *\n * @returns The raw Database instance.\n */\n getDatabase(): Database {\n return this.db\n }\n\n /**\n * Performs a VACUUM operation to reclaim unused space and defragment the database.\n *\n * @throws {Error} If the VACUUM operation fails.\n */\n vacuum(): void {\n this.db.run('VACUUM')\n }\n}\n\nfunction validateSqlIdentifier(value: string, field: string): string {\n if (!/^[A-Za-z_][A-Za-z0-9_]*$/.test(value)) {\n throw new Error(\n `Invalid ${field}: \"${value}\". Only letters, numbers, and underscores are allowed.`\n )\n }\n return value\n}\n\n/**\n * Internal representation of a workflow record in the SQLite database.\n */\ninterface SQLiteRow {\n id: string\n name: string\n status: string\n input: string\n data: string\n current_step: number\n history: string\n error: string | null\n created_at: string\n updated_at: string\n completed_at: string | null\n version: number\n definition_version: string | null\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"sources":["/Users/carl/Dev/Carl/gravito-core-ci-fix/packages/flux/dist/cli/flux-visualize.cjs","../../src/cli/flux-visualize.ts"],"names":[],"mappings":"AAAA;AACA;AACE;AACF,yDAA8B;AAC9B;AACA;ACHA,wBAAyC;AACzC,4BAAwB;AACxB,4BAA0B;AAI1B,IAAM,UAAA,EAAY,CAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAAA;AA4ClB,MAAA,SAAe,IAAA,CAAA,EAAO;AACpB,EAAA,IAAI;AACF,IAAA,MAAM,EAAE,OAAO,EAAA,EAAI,6BAAA;AAAU,MAC3B,IAAA,EAAM,OAAA,CAAQ,IAAA,CAAK,KAAA,CAAM,CAAC,CAAA;AAAA,MAC1B,OAAA,EAAS;AAAA,QACP,UAAA,EAAY,EAAE,IAAA,EAAM,SAAS,CAAA;AAAA,QAC7B,KAAA,EAAO,EAAE,IAAA,EAAM,SAAS,CAAA;AAAA,QACxB,KAAA,EAAO,EAAE,IAAA,EAAM,SAAS,CAAA;AAAA,QACxB,OAAA,EAAS,EAAE,IAAA,EAAM,SAAA,EAAW,OAAA,EAAS,MAAM,CAAA;AAAA,QAC3C,oBAAA,EAAsB,EAAE,IAAA,EAAM,SAAA,EAAW,OAAA,EAAS,MAAM,CAAA;AAAA,QACxD,MAAA,EAAQ,EAAE,IAAA,EAAM,SAAS,CAAA;AAAA,QACzB,IAAA,EAAM,EAAE,IAAA,EAAM,SAAA,EAAW,KAAA,EAAO,GAAA,EAAK,OAAA,EAAS,MAAM;AAAA,MACtD;AAAA,IACF,CAAC,CAAA;AAED,IAAA,MAAM,QAAA,EAAU,MAAA;AAEhB,IAAA,GAAA,CAAI,OAAA,CAAQ,KAAA,GAAQ,CAAC,OAAA,CAAQ,UAAA,EAAY;AACvC,MAAA,OAAA,CAAQ,GAAA,CAAI,SAAS,CAAA;AACrB,MAAA,OAAA,CAAQ,IAAA,CAAK,OAAA,CAAQ,KAAA,EAAO,EAAA,EAAI,CAAC,CAAA;AAAA,IACnC;AAEA,IAAA,MAAM,eAAA,EAAiB,2BAAA,OAAQ,CAAQ,UAAU,CAAA;AACjD,IAAA,GAAA,CAAI,CAAC,4BAAA,cAAyB,CAAA,EAAG;AAC/B,MAAA,OAAA,CAAQ,KAAA,CAAM,CAAA,kCAAA,EAAqC,cAAc,CAAA,CAAA;AACnD,MAAA;AAChB,IAAA;AAE2D,IAAA;AACK,IAAA;AAE5D,IAAA;AACe,IAAA;AACsB,MAAA;AACX,MAAA;AAC+B,QAAA;AAC3C,QAAA;AAChB,MAAA;AACiD,MAAA;AACrB,MAAA;AAC9B,IAAA;AAEuC,IAAA;AAEK,IAAA;AACd,MAAA;AACH,MAAA;AACT,MAAA;AACqC,MAAA;AAEN,IAAA;AACnB,MAAA;AACH,MAAA;AAC4B,MAAA;AAClD,IAAA;AAEe,IAAA;AAC8B,MAAA;AACP,MAAA;AACC,MAAA;AACK,MAAA;AACnC,MAAA;AAAoC,uCAAA;AAC3C,IAAA;AACc,MAAA;AACP,MAAA;AAAqD,wDAAA;AACnE,IAAA;AACc,EAAA;AACmD,IAAA;AACnD,IAAA;AAChB,EAAA;AACF;AAEK","file":"/Users/carl/Dev/Carl/gravito-core-ci-fix/packages/flux/dist/cli/flux-visualize.cjs","sourcesContent":[null,"#!/usr/bin/env bun\n\nimport { existsSync, readFileSync } from 'node:fs'\nimport { resolve } from 'node:path'\nimport { parseArgs } from 'node:util'\nimport type { WorkflowDefinition, WorkflowState } from '../types'\nimport { MermaidGenerator } from '../visualization/MermaidGenerator'\n\nconst HELP_TEXT = `\n@gravito/flux - Workflow Visualization CLI\n\nUSAGE:\n flux-visualize [OPTIONS]\n\nOPTIONS:\n --definition <path> Path to workflow definition JSON file\n --state <path> Path to workflow state JSON file (optional)\n --theme <name> Mermaid theme: default, dark, forest, neutral (default: default)\n --details Show detailed step metadata (retries, timeout, etc.)\n --no-parallel-groups Disable parallel group visualization\n --output <path> Output file path (default: stdout)\n --help, -h Show this help message\n\nEXAMPLES:\n # Visualize workflow definition\n flux-visualize --definition ./workflow.json\n\n # Visualize workflow with execution state\n flux-visualize --definition ./workflow.json --state ./state.json\n\n # Generate dark theme diagram with details\n flux-visualize --definition ./workflow.json --theme dark --details\n\n # Save to file\n flux-visualize --definition ./workflow.json --output diagram.mmd\n\nNOTES:\n - Definition file should export a WorkflowDefinition object as JSON\n - State file should export a WorkflowState object as JSON\n - Generated diagrams use Mermaid syntax and can be rendered at https://mermaid.live\n`\n\ninterface CliOptions {\n definition?: string\n state?: string\n theme?: 'default' | 'dark' | 'forest' | 'neutral'\n details?: boolean\n 'no-parallel-groups'?: boolean\n output?: string\n help?: boolean\n}\n\nasync function main() {\n try {\n const { values } = parseArgs({\n args: process.argv.slice(2),\n options: {\n definition: { type: 'string' },\n state: { type: 'string' },\n theme: { type: 'string' },\n details: { type: 'boolean', default: false },\n 'no-parallel-groups': { type: 'boolean', default: false },\n output: { type: 'string' },\n help: { type: 'boolean', short: 'h', default: false },\n },\n })\n\n const options = values as CliOptions\n\n if (options.help || !options.definition) {\n console.log(HELP_TEXT)\n process.exit(options.help ? 0 : 1)\n }\n\n const definitionPath = resolve(options.definition)\n if (!existsSync(definitionPath)) {\n console.error(`Error: Definition file not found: ${definitionPath}`)\n process.exit(1)\n }\n\n const definitionJson = readFileSync(definitionPath, 'utf-8')\n const definition: WorkflowDefinition = JSON.parse(definitionJson)\n\n let state: WorkflowState | undefined\n if (options.state) {\n const statePath = resolve(options.state)\n if (!existsSync(statePath)) {\n console.error(`Error: State file not found: ${statePath}`)\n process.exit(1)\n }\n const stateJson = readFileSync(statePath, 'utf-8')\n state = JSON.parse(stateJson)\n }\n\n const generator = new MermaidGenerator()\n const diagram = state\n ? generator.generateFromState(definition, state, {\n theme: options.theme || 'default',\n showDetails: options.details,\n showStatus: true,\n showParallelGroups: !options['no-parallel-groups'],\n })\n : generator.generateFromDefinition(definition, {\n theme: options.theme || 'default',\n showDetails: options.details,\n showParallelGroups: !options['no-parallel-groups'],\n })\n\n if (options.output) {\n const { writeFileSync } = await import('node:fs')\n const outputPath = resolve(options.output)\n writeFileSync(outputPath, diagram, 'utf-8')\n console.log(`✅ Diagram saved to: ${outputPath}`)\n console.log(`\\n📊 View at: https://mermaid.live`)\n } else {\n console.log(diagram)\n console.log(`\\n📊 Copy the output above to: https://mermaid.live`)\n }\n } catch (error) {\n console.error('Error:', error instanceof Error ? error.message : String(error))\n process.exit(1)\n }\n}\n\nmain()\n"]}
1
+ {"version":3,"sources":["/Users/carl/Dev/Carl/gravito-core/packages/flux/dist/cli/flux-visualize.cjs","../../src/cli/flux-visualize.ts"],"names":[],"mappings":"AAAA;AACA;AACE;AACF,yDAA8B;AAC9B;AACA;ACHA,wBAAyC;AACzC,4BAAwB;AACxB,4BAA0B;AAI1B,IAAM,UAAA,EAAY,CAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAAA;AA4ClB,MAAA,SAAe,IAAA,CAAA,EAAO;AACpB,EAAA,IAAI;AACF,IAAA,MAAM,EAAE,OAAO,EAAA,EAAI,6BAAA;AAAU,MAC3B,IAAA,EAAM,OAAA,CAAQ,IAAA,CAAK,KAAA,CAAM,CAAC,CAAA;AAAA,MAC1B,OAAA,EAAS;AAAA,QACP,UAAA,EAAY,EAAE,IAAA,EAAM,SAAS,CAAA;AAAA,QAC7B,KAAA,EAAO,EAAE,IAAA,EAAM,SAAS,CAAA;AAAA,QACxB,KAAA,EAAO,EAAE,IAAA,EAAM,SAAS,CAAA;AAAA,QACxB,OAAA,EAAS,EAAE,IAAA,EAAM,SAAA,EAAW,OAAA,EAAS,MAAM,CAAA;AAAA,QAC3C,oBAAA,EAAsB,EAAE,IAAA,EAAM,SAAA,EAAW,OAAA,EAAS,MAAM,CAAA;AAAA,QACxD,MAAA,EAAQ,EAAE,IAAA,EAAM,SAAS,CAAA;AAAA,QACzB,IAAA,EAAM,EAAE,IAAA,EAAM,SAAA,EAAW,KAAA,EAAO,GAAA,EAAK,OAAA,EAAS,MAAM;AAAA,MACtD;AAAA,IACF,CAAC,CAAA;AAED,IAAA,MAAM,QAAA,EAAU,MAAA;AAEhB,IAAA,GAAA,CAAI,OAAA,CAAQ,KAAA,GAAQ,CAAC,OAAA,CAAQ,UAAA,EAAY;AACvC,MAAA,OAAA,CAAQ,GAAA,CAAI,SAAS,CAAA;AACrB,MAAA,OAAA,CAAQ,IAAA,CAAK,OAAA,CAAQ,KAAA,EAAO,EAAA,EAAI,CAAC,CAAA;AAAA,IACnC;AAEA,IAAA,MAAM,eAAA,EAAiB,2BAAA,OAAQ,CAAQ,UAAU,CAAA;AACjD,IAAA,GAAA,CAAI,CAAC,4BAAA,cAAyB,CAAA,EAAG;AAC/B,MAAA,OAAA,CAAQ,KAAA,CAAM,CAAA,kCAAA,EAAqC,cAAc,CAAA,CAAA;AACnD,MAAA;AAChB,IAAA;AAE2D,IAAA;AACK,IAAA;AAE5D,IAAA;AACe,IAAA;AACsB,MAAA;AACX,MAAA;AAC+B,QAAA;AAC3C,QAAA;AAChB,MAAA;AACiD,MAAA;AACrB,MAAA;AAC9B,IAAA;AAEuC,IAAA;AAEK,IAAA;AACd,MAAA;AACH,MAAA;AACT,MAAA;AACqC,MAAA;AAEN,IAAA;AACnB,MAAA;AACH,MAAA;AAC4B,MAAA;AAClD,IAAA;AAEe,IAAA;AAC8B,MAAA;AACP,MAAA;AACC,MAAA;AACK,MAAA;AACnC,MAAA;AAAoC,uCAAA;AAC3C,IAAA;AACc,MAAA;AACP,MAAA;AAAqD,wDAAA;AACnE,IAAA;AACc,EAAA;AACmD,IAAA;AACnD,IAAA;AAChB,EAAA;AACF;AAEK","file":"/Users/carl/Dev/Carl/gravito-core/packages/flux/dist/cli/flux-visualize.cjs","sourcesContent":[null,"#!/usr/bin/env bun\n\nimport { existsSync, readFileSync } from 'node:fs'\nimport { resolve } from 'node:path'\nimport { parseArgs } from 'node:util'\nimport type { WorkflowDefinition, WorkflowState } from '../types'\nimport { MermaidGenerator } from '../visualization/MermaidGenerator'\n\nconst HELP_TEXT = `\n@gravito/flux - Workflow Visualization CLI\n\nUSAGE:\n flux-visualize [OPTIONS]\n\nOPTIONS:\n --definition <path> Path to workflow definition JSON file\n --state <path> Path to workflow state JSON file (optional)\n --theme <name> Mermaid theme: default, dark, forest, neutral (default: default)\n --details Show detailed step metadata (retries, timeout, etc.)\n --no-parallel-groups Disable parallel group visualization\n --output <path> Output file path (default: stdout)\n --help, -h Show this help message\n\nEXAMPLES:\n # Visualize workflow definition\n flux-visualize --definition ./workflow.json\n\n # Visualize workflow with execution state\n flux-visualize --definition ./workflow.json --state ./state.json\n\n # Generate dark theme diagram with details\n flux-visualize --definition ./workflow.json --theme dark --details\n\n # Save to file\n flux-visualize --definition ./workflow.json --output diagram.mmd\n\nNOTES:\n - Definition file should export a WorkflowDefinition object as JSON\n - State file should export a WorkflowState object as JSON\n - Generated diagrams use Mermaid syntax and can be rendered at https://mermaid.live\n`\n\ninterface CliOptions {\n definition?: string\n state?: string\n theme?: 'default' | 'dark' | 'forest' | 'neutral'\n details?: boolean\n 'no-parallel-groups'?: boolean\n output?: string\n help?: boolean\n}\n\nasync function main() {\n try {\n const { values } = parseArgs({\n args: process.argv.slice(2),\n options: {\n definition: { type: 'string' },\n state: { type: 'string' },\n theme: { type: 'string' },\n details: { type: 'boolean', default: false },\n 'no-parallel-groups': { type: 'boolean', default: false },\n output: { type: 'string' },\n help: { type: 'boolean', short: 'h', default: false },\n },\n })\n\n const options = values as CliOptions\n\n if (options.help || !options.definition) {\n console.log(HELP_TEXT)\n process.exit(options.help ? 0 : 1)\n }\n\n const definitionPath = resolve(options.definition)\n if (!existsSync(definitionPath)) {\n console.error(`Error: Definition file not found: ${definitionPath}`)\n process.exit(1)\n }\n\n const definitionJson = readFileSync(definitionPath, 'utf-8')\n const definition: WorkflowDefinition = JSON.parse(definitionJson)\n\n let state: WorkflowState | undefined\n if (options.state) {\n const statePath = resolve(options.state)\n if (!existsSync(statePath)) {\n console.error(`Error: State file not found: ${statePath}`)\n process.exit(1)\n }\n const stateJson = readFileSync(statePath, 'utf-8')\n state = JSON.parse(stateJson)\n }\n\n const generator = new MermaidGenerator()\n const diagram = state\n ? generator.generateFromState(definition, state, {\n theme: options.theme || 'default',\n showDetails: options.details,\n showStatus: true,\n showParallelGroups: !options['no-parallel-groups'],\n })\n : generator.generateFromDefinition(definition, {\n theme: options.theme || 'default',\n showDetails: options.details,\n showParallelGroups: !options['no-parallel-groups'],\n })\n\n if (options.output) {\n const { writeFileSync } = await import('node:fs')\n const outputPath = resolve(options.output)\n writeFileSync(outputPath, diagram, 'utf-8')\n console.log(`✅ Diagram saved to: ${outputPath}`)\n console.log(`\\n📊 View at: https://mermaid.live`)\n } else {\n console.log(diagram)\n console.log(`\\n📊 Copy the output above to: https://mermaid.live`)\n }\n } catch (error) {\n console.error('Error:', error instanceof Error ? error.message : String(error))\n process.exit(1)\n }\n}\n\nmain()\n"]}
package/dist/index.cjs CHANGED
@@ -31,10 +31,10 @@
31
31
 
32
32
 
33
33
 
34
- var _chunkWAPZDXSXcjs = require('./chunk-WAPZDXSX.cjs');
34
+ var _chunkDN7SIQ34cjs = require('./chunk-DN7SIQ34.cjs');
35
35
 
36
36
 
37
- var _chunkYXBEYVGYcjs = require('./chunk-YXBEYVGY.cjs');
37
+ var _chunkZE2RDS47cjs = require('./chunk-ZE2RDS47.cjs');
38
38
 
39
39
 
40
40
  var _chunk6AZNHVEOcjs = require('./chunk-6AZNHVEO.cjs');
@@ -50,8 +50,8 @@ var WorkflowProfiler = class {
50
50
  constructor(engine) {
51
51
  this.engine = engine;
52
52
  if (!this.engine) {
53
- this.engine = new (0, _chunkWAPZDXSXcjs.FluxEngine)({
54
- logger: new (0, _chunkWAPZDXSXcjs.FluxSilentLogger)()
53
+ this.engine = new (0, _chunkDN7SIQ34cjs.FluxEngine)({
54
+ logger: new (0, _chunkDN7SIQ34cjs.FluxSilentLogger)()
55
55
  });
56
56
  }
57
57
  }
@@ -219,5 +219,5 @@ var Flux = {
219
219
 
220
220
 
221
221
 
222
- exports.BatchExecutor = _chunkWAPZDXSXcjs.BatchExecutor; exports.BunSQLiteStorage = _chunkYXBEYVGYcjs.BunSQLiteStorage; exports.ContextManager = _chunkWAPZDXSXcjs.ContextManager; exports.CronTrigger = _chunkWAPZDXSXcjs.CronTrigger; exports.Flux = Flux; exports.FluxConsoleLogger = _chunkWAPZDXSXcjs.FluxConsoleLogger; exports.FluxEngine = _chunkWAPZDXSXcjs.FluxEngine; exports.FluxError = _chunkWAPZDXSXcjs.FluxError; exports.FluxErrorCode = _chunkWAPZDXSXcjs.FluxErrorCode; exports.FluxSilentLogger = _chunkWAPZDXSXcjs.FluxSilentLogger; exports.JsonFileTraceSink = _chunkWAPZDXSXcjs.JsonFileTraceSink; exports.MemoryLockProvider = _chunkWAPZDXSXcjs.MemoryLockProvider; exports.MemoryStorage = _chunkWAPZDXSXcjs.MemoryStorage; exports.MermaidGenerator = _chunk6AZNHVEOcjs.MermaidGenerator; exports.OrbitFlux = _chunkWAPZDXSXcjs.OrbitFlux; exports.PostgreSQLStorage = _chunkWAPZDXSXcjs.PostgreSQLStorage; exports.RedisLockProvider = _chunkWAPZDXSXcjs.RedisLockProvider; exports.StateMachine = _chunkWAPZDXSXcjs.StateMachine; exports.StepExecutor = _chunkWAPZDXSXcjs.StepExecutor; exports.WorkflowBuilder = _chunkWAPZDXSXcjs.WorkflowBuilder; exports.WorkflowProfiler = WorkflowProfiler; exports.cannotRemoveRoot = _chunkWAPZDXSXcjs.cannotRemoveRoot; exports.cannotReplaceRoot = _chunkWAPZDXSXcjs.cannotReplaceRoot; exports.createWorkflow = _chunkWAPZDXSXcjs.createWorkflow; exports.emptyWorkflow = _chunkWAPZDXSXcjs.emptyWorkflow; exports.invalidInput = _chunkWAPZDXSXcjs.invalidInput; exports.invalidJsonPointer = _chunkWAPZDXSXcjs.invalidJsonPointer; exports.invalidPathTraversal = _chunkWAPZDXSXcjs.invalidPathTraversal; exports.invalidStateTransition = _chunkWAPZDXSXcjs.invalidStateTransition; exports.invalidStepIndex = _chunkWAPZDXSXcjs.invalidStepIndex; exports.noRecoveryAction = _chunkWAPZDXSXcjs.noRecoveryAction; exports.stepNotFound = _chunkWAPZDXSXcjs.stepNotFound; exports.workflowDefinitionChanged = _chunkWAPZDXSXcjs.workflowDefinitionChanged; exports.workflowNameMismatch = _chunkWAPZDXSXcjs.workflowNameMismatch; exports.workflowNotFound = _chunkWAPZDXSXcjs.workflowNotFound; exports.workflowNotSuspended = _chunkWAPZDXSXcjs.workflowNotSuspended;
222
+ exports.BatchExecutor = _chunkDN7SIQ34cjs.BatchExecutor; exports.BunSQLiteStorage = _chunkZE2RDS47cjs.BunSQLiteStorage; exports.ContextManager = _chunkDN7SIQ34cjs.ContextManager; exports.CronTrigger = _chunkDN7SIQ34cjs.CronTrigger; exports.Flux = Flux; exports.FluxConsoleLogger = _chunkDN7SIQ34cjs.FluxConsoleLogger; exports.FluxEngine = _chunkDN7SIQ34cjs.FluxEngine; exports.FluxError = _chunkDN7SIQ34cjs.FluxError; exports.FluxErrorCode = _chunkDN7SIQ34cjs.FluxErrorCode; exports.FluxSilentLogger = _chunkDN7SIQ34cjs.FluxSilentLogger; exports.JsonFileTraceSink = _chunkDN7SIQ34cjs.JsonFileTraceSink; exports.MemoryLockProvider = _chunkDN7SIQ34cjs.MemoryLockProvider; exports.MemoryStorage = _chunkDN7SIQ34cjs.MemoryStorage; exports.MermaidGenerator = _chunk6AZNHVEOcjs.MermaidGenerator; exports.OrbitFlux = _chunkDN7SIQ34cjs.OrbitFlux; exports.PostgreSQLStorage = _chunkDN7SIQ34cjs.PostgreSQLStorage; exports.RedisLockProvider = _chunkDN7SIQ34cjs.RedisLockProvider; exports.StateMachine = _chunkDN7SIQ34cjs.StateMachine; exports.StepExecutor = _chunkDN7SIQ34cjs.StepExecutor; exports.WorkflowBuilder = _chunkDN7SIQ34cjs.WorkflowBuilder; exports.WorkflowProfiler = WorkflowProfiler; exports.cannotRemoveRoot = _chunkDN7SIQ34cjs.cannotRemoveRoot; exports.cannotReplaceRoot = _chunkDN7SIQ34cjs.cannotReplaceRoot; exports.createWorkflow = _chunkDN7SIQ34cjs.createWorkflow; exports.emptyWorkflow = _chunkDN7SIQ34cjs.emptyWorkflow; exports.invalidInput = _chunkDN7SIQ34cjs.invalidInput; exports.invalidJsonPointer = _chunkDN7SIQ34cjs.invalidJsonPointer; exports.invalidPathTraversal = _chunkDN7SIQ34cjs.invalidPathTraversal; exports.invalidStateTransition = _chunkDN7SIQ34cjs.invalidStateTransition; exports.invalidStepIndex = _chunkDN7SIQ34cjs.invalidStepIndex; exports.noRecoveryAction = _chunkDN7SIQ34cjs.noRecoveryAction; exports.stepNotFound = _chunkDN7SIQ34cjs.stepNotFound; exports.workflowDefinitionChanged = _chunkDN7SIQ34cjs.workflowDefinitionChanged; exports.workflowNameMismatch = _chunkDN7SIQ34cjs.workflowNameMismatch; exports.workflowNotFound = _chunkDN7SIQ34cjs.workflowNotFound; exports.workflowNotSuspended = _chunkDN7SIQ34cjs.workflowNotSuspended;
223
223
  //# sourceMappingURL=index.cjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["/Users/carl/Dev/Carl/gravito-core-ci-fix/packages/flux/dist/index.cjs","../src/profiler/WorkflowProfiler.ts","../src/index.ts"],"names":["cpus"],"mappings":"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","file":"/Users/carl/Dev/Carl/gravito-core-ci-fix/packages/flux/dist/index.cjs","sourcesContent":[null,"import * as os from 'node:os'\nimport { FluxEngine } from '../engine/FluxEngine'\nimport { FluxSilentLogger } from '../logger/FluxLogger'\nimport type { WorkflowDefinition } from '../types'\n\n/**\n * Performance metrics captured during a workflow profiling session.\n *\n * Used to quantify the resource footprint of a workflow execution, enabling\n * data-driven decisions for infrastructure scaling and concurrency tuning.\n *\n * @public\n */\nexport interface ProfileMetrics {\n /** Total wall-clock duration of the workflow execution in milliseconds. */\n durationMs: number\n /** Amount of time spent in user-space CPU operations in milliseconds. */\n cpuUserMs: number\n /** Amount of time spent in system-space CPU operations in milliseconds. */\n cpuSysMs: number\n /** Estimated heap memory increase during execution in bytes. */\n memDeltaBytes: number\n /** Ratio of CPU time to wall-clock time (0.0 to 1.0+). Higher values indicate CPU-bound tasks. */\n cpuRatio: number\n}\n\n/**\n * Concurrency recommendations generated by the profiler.\n *\n * Provides actionable insights into how many instances of a workflow can safely\n * and efficiently run in parallel on the current hardware.\n *\n * @public\n */\nexport interface ProfileRecommendation {\n /** The identified primary bottleneck type. */\n type: 'IO_BOUND' | 'CPU_BOUND' | 'MEMORY_BOUND'\n /** Maximum safe concurrency considering memory and system stability. */\n safeConcurrency: number\n /** Most efficient concurrency level considering CPU utilization. */\n efficientConcurrency: number\n /** A suggested range for worker concurrency configuration. */\n suggestedConcurrency: string\n /** Detailed explanation for the recommendation. */\n reason: string\n}\n\n/**\n * WorkflowProfiler analyzes workflow performance characteristics.\n *\n * It measures CPU usage, memory consumption, and execution duration to recommend\n * optimal concurrency settings for Gravito Quasar workers or high-throughput consumers.\n *\n * @example\n * ```typescript\n * const profiler = new WorkflowProfiler();\n * const metrics = await profiler.profile(myWorkflow, { input: 'data' });\n * const advice = profiler.recommend(metrics);\n * console.log(`Suggested concurrency: ${advice.suggestedConcurrency}`);\n * ```\n *\n * @public\n */\nexport class WorkflowProfiler {\n /**\n * Initializes the profiler with an optional engine.\n *\n * @param engine - The FluxEngine instance to use for execution. If omitted, a silent engine is created.\n */\n constructor(private engine?: FluxEngine) {\n if (!this.engine) {\n // Default minimal engine for profiling (Silent)\n this.engine = new FluxEngine({\n logger: new FluxSilentLogger(),\n })\n }\n }\n\n /**\n * Executes a workflow and captures its resource consumption metrics.\n *\n * Performs a warmup run to ensure JIT optimization before measurement.\n *\n * @param workflow - The workflow definition to profile.\n * @param input - The input data for the workflow execution.\n * @returns A promise resolving to the captured performance metrics.\n *\n * @example\n * ```typescript\n * const metrics = await profiler.profile(orderWorkflow, { id: '123' });\n * console.log(`Duration: ${metrics.durationMs}ms`);\n * ```\n */\n async profile<TInput>(\n workflow: WorkflowDefinition<TInput, any>,\n input: TInput\n ): Promise<ProfileMetrics> {\n // 1. Warmup (JIT)\n try {\n await this.engine?.execute(workflow, input)\n } catch {}\n\n // 2. Measure\n if (global.gc) {\n global.gc()\n }\n\n const startCpu = process.cpuUsage()\n const startMem = process.memoryUsage().heapUsed\n const startTime = process.hrtime.bigint()\n\n await this.engine?.execute(workflow, input)\n\n const endTime = process.hrtime.bigint()\n const endCpu = process.cpuUsage(startCpu)\n const endMem = process.memoryUsage().heapUsed\n\n // 3. Calculate\n const durationNs = Number(endTime - startTime)\n const durationMs = durationNs / 1_000_000\n const cpuUserMs = endCpu.user / 1000\n const cpuSysMs = endCpu.system / 1000\n const totalCpuMs = cpuUserMs + cpuSysMs\n const memDeltaBytes = Math.max(0, endMem - startMem) // Clamp to 0\n\n // CPU Ratio: How much % of the time was spent on CPU vs Waiting\n const cpuRatio = totalCpuMs / durationMs\n\n return {\n durationMs,\n cpuUserMs,\n cpuSysMs,\n memDeltaBytes,\n cpuRatio,\n }\n }\n\n /**\n * Analyzes metrics to generate concurrency recommendations.\n *\n * Considers system CPU cores and total memory to calculate safe and efficient limits.\n *\n * @param metrics - The metrics captured during a profiling session.\n * @param config - Optional current configuration to check against recommendations.\n * @returns A recommendation object containing bottleneck analysis and concurrency limits.\n *\n * @example\n * ```typescript\n * const advice = profiler.recommend(metrics, { configuredConcurrency: 10 });\n * if (advice.type === 'CPU_BOUND') {\n * console.warn('Workflow is CPU bound, consider reducing concurrency');\n * }\n * ```\n */\n recommend(\n metrics: ProfileMetrics,\n config?: { configuredConcurrency?: number }\n ): ProfileRecommendation {\n const totalMem = os.totalmem()\n const cpus = os.cpus().length\n\n // 1. Analyze Bottleneck Type\n let type: ProfileRecommendation['type'] = 'IO_BOUND'\n if (metrics.cpuRatio > 0.5) {\n type = 'CPU_BOUND'\n } else if (metrics.memDeltaBytes > 50 * 1024 * 1024) {\n // > 50MB per run\n type = 'MEMORY_BOUND'\n }\n\n // 2. Calculate Limits\n\n // Memory Limit: Keep 30% buffer for system, divide rest by per-workflow memory\n const safeMem = totalMem * 0.7\n // Use at least 1MB as baseline to avoid division by zero or huge numbers\n const perInstanceMem = Math.max(metrics.memDeltaBytes, 1024 * 1024)\n const maxMemConcurrency = Math.floor(safeMem / perInstanceMem)\n\n // CPU Limit:\n // If IO Bound (0.2% cpu), we can run many. 100% / 0.2% = 500 tasks per core.\n // We cap efficiency at a reasonable number to avoid Event Loop Lag density.\n const cpuEfficiencyFactor = 1 / Math.max(metrics.cpuRatio, 0.001) // Avoid div by 0\n const maxCpuConcurrency = Math.floor(cpus * cpuEfficiencyFactor)\n\n // 3. Synthesize Recommendation\n const safe = Math.min(maxMemConcurrency, 200) // Hard cap at 200 for sanity\n let efficient = Math.min(maxCpuConcurrency, 200)\n\n // If CPU bound, strict limit based on cores\n if (type === 'CPU_BOUND') {\n efficient = cpus // 1:1 mapping is best for CPU bound\n }\n\n const recommended = Math.min(safe, efficient)\n\n let reason = ''\n if (type === 'IO_BOUND') {\n reason = `Workflow is I/O intensive (CPU usage ${(metrics.cpuRatio * 100).toFixed(1)}%). It is safe to run high concurrency up to ${recommended}.`\n } else if (type === 'CPU_BOUND') {\n reason = `Workflow is CPU intensive. Limiting concurrency to match CPU cores (${cpus}) is recommended to prevent blocking.`\n } else {\n reason = `Workflow consumes significant memory (${(metrics.memDeltaBytes / 1024 / 1024).toFixed(1)}MB). Concurrency limited by available RAM.`\n }\n\n if (config?.configuredConcurrency && config.configuredConcurrency > recommended) {\n reason += ` \\n⚠️ Warning: Your current setting (${config.configuredConcurrency}) exceeds the recommended limit (${recommended}).`\n }\n\n return {\n type,\n safeConcurrency: safe,\n efficientConcurrency: efficient,\n suggestedConcurrency: `${Math.max(1, Math.floor(recommended * 0.5))} - ${recommended}`,\n reason,\n }\n }\n}\n","/**\n * @fileoverview @gravito/flux - Platform-agnostic Workflow Engine\n *\n * High-performance, type-safe workflow engine with Bun optimizations.\n *\n * @example Basic Usage\n * ```typescript\n * import { FluxEngine, createWorkflow } from '@gravito/flux'\n *\n * const workflow = createWorkflow('order-process')\n * .input<{ orderId: string }>()\n * .step('validate', async (ctx) => {\n * ctx.data.order = await fetchOrder(ctx.input.orderId)\n * })\n * .step('process', async (ctx) => {\n * await processPayment(ctx.data.order)\n * })\n * .commit('notify', async (ctx) => {\n * await sendEmail(ctx.data.order.email)\n * })\n *\n * const engine = new FluxEngine()\n * const result = await engine.execute(workflow, { orderId: '123' })\n * ```\n *\n * @module @gravito/flux\n */\n\n// Builder\nexport { createWorkflow, WorkflowBuilder } from './builder/WorkflowBuilder'\nexport { ContextManager } from './core/ContextManager'\nexport { type Lock, type LockProvider, MemoryLockProvider } from './core/LockProvider'\nexport {\n type RedisClient,\n RedisLockProvider,\n type RedisLockProviderOptions,\n} from './core/RedisLockProvider'\n// Core (for advanced usage)\nexport { StateMachine } from './core/StateMachine'\nexport { StepExecutor } from './core/StepExecutor'\nexport {\n type BatchExecutionOptions,\n BatchExecutor,\n type BatchItemResult,\n type BatchResult,\n} from './engine/BatchExecutor'\n// Core\nexport { FluxEngine } from './engine/FluxEngine'\n// Errors\nexport {\n cannotRemoveRoot,\n cannotReplaceRoot,\n emptyWorkflow,\n FluxError,\n FluxErrorCode,\n invalidInput,\n invalidJsonPointer,\n invalidPathTraversal,\n invalidStateTransition,\n invalidStepIndex,\n noRecoveryAction,\n stepNotFound,\n workflowDefinitionChanged,\n workflowNameMismatch,\n workflowNotFound,\n workflowNotSuspended,\n} from './errors'\n// Logger\nexport { FluxConsoleLogger, FluxSilentLogger } from './logger/FluxLogger'\nexport { CronTrigger } from './orbit/CronTrigger'\n// Gravito Integration\nexport { OrbitFlux, type OrbitFluxOptions } from './orbit/OrbitFlux'\n// Profiler\nexport {\n type ProfileMetrics,\n type ProfileRecommendation,\n WorkflowProfiler,\n} from './profiler/WorkflowProfiler'\nexport { BunSQLiteStorage, type BunSQLiteStorageOptions } from './storage/BunSQLiteStorage'\n// Storage\nexport { MemoryStorage } from './storage/MemoryStorage'\nexport { PostgreSQLStorage, type PostgreSQLStorageOptions } from './storage/PostgreSQLStorage'\n// Trace\nexport { JsonFileTraceSink } from './trace/JsonFileTraceSink'\n// Types\nexport type {\n CronScheduleOptions,\n // Config\n FluxConfig,\n // Logger\n FluxLogger,\n FluxResult,\n // Trace\n FluxTraceEvent,\n FluxTraceEventType,\n FluxTraceSink,\n // Helper\n FluxWaitResult,\n // Step types\n StepDefinition,\n StepDescriptor,\n StepExecution,\n StepResult,\n WorkflowContext,\n WorkflowDefinition,\n WorkflowDescriptor,\n WorkflowFilter,\n WorkflowState,\n // Core types\n WorkflowStatus,\n // Storage\n WorkflowStorage,\n} from './types'\n// Visualization\nexport { MermaidGenerator, type MermaidOptions } from './visualization/MermaidGenerator'\n\n/**\n * Flux helper utilities for workflow control flow.\n *\n * Provides methods to interact with the workflow engine's special behaviors,\n * such as suspending execution to wait for external signals.\n */\nexport const Flux = {\n /**\n * Suspends workflow execution until a specific signal is received.\n *\n * When a handler returns this result, the engine saves the current state\n * and stops execution. The workflow can be resumed later using `engine.signal()`.\n *\n * @param signal - The unique identifier for the signal to wait for.\n * @returns A special result object that instructs the engine to suspend.\n *\n * @example\n * ```typescript\n * .step('wait-for-approval', async (ctx) => {\n * return Flux.wait('manager-approval');\n * })\n * ```\n */\n wait: (signal: string): import('./types').FluxWaitResult => ({\n __kind: 'flux_wait',\n signal,\n }),\n}\n"]}
1
+ {"version":3,"sources":["/Users/carl/Dev/Carl/gravito-core/packages/flux/dist/index.cjs","../src/profiler/WorkflowProfiler.ts","../src/index.ts"],"names":["cpus"],"mappings":"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","file":"/Users/carl/Dev/Carl/gravito-core/packages/flux/dist/index.cjs","sourcesContent":[null,"import * as os from 'node:os'\nimport { FluxEngine } from '../engine/FluxEngine'\nimport { FluxSilentLogger } from '../logger/FluxLogger'\nimport type { WorkflowDefinition } from '../types'\n\n/**\n * Performance metrics captured during a workflow profiling session.\n *\n * Used to quantify the resource footprint of a workflow execution, enabling\n * data-driven decisions for infrastructure scaling and concurrency tuning.\n *\n * @public\n */\nexport interface ProfileMetrics {\n /** Total wall-clock duration of the workflow execution in milliseconds. */\n durationMs: number\n /** Amount of time spent in user-space CPU operations in milliseconds. */\n cpuUserMs: number\n /** Amount of time spent in system-space CPU operations in milliseconds. */\n cpuSysMs: number\n /** Estimated heap memory increase during execution in bytes. */\n memDeltaBytes: number\n /** Ratio of CPU time to wall-clock time (0.0 to 1.0+). Higher values indicate CPU-bound tasks. */\n cpuRatio: number\n}\n\n/**\n * Concurrency recommendations generated by the profiler.\n *\n * Provides actionable insights into how many instances of a workflow can safely\n * and efficiently run in parallel on the current hardware.\n *\n * @public\n */\nexport interface ProfileRecommendation {\n /** The identified primary bottleneck type. */\n type: 'IO_BOUND' | 'CPU_BOUND' | 'MEMORY_BOUND'\n /** Maximum safe concurrency considering memory and system stability. */\n safeConcurrency: number\n /** Most efficient concurrency level considering CPU utilization. */\n efficientConcurrency: number\n /** A suggested range for worker concurrency configuration. */\n suggestedConcurrency: string\n /** Detailed explanation for the recommendation. */\n reason: string\n}\n\n/**\n * WorkflowProfiler analyzes workflow performance characteristics.\n *\n * It measures CPU usage, memory consumption, and execution duration to recommend\n * optimal concurrency settings for Gravito Quasar workers or high-throughput consumers.\n *\n * @example\n * ```typescript\n * const profiler = new WorkflowProfiler();\n * const metrics = await profiler.profile(myWorkflow, { input: 'data' });\n * const advice = profiler.recommend(metrics);\n * console.log(`Suggested concurrency: ${advice.suggestedConcurrency}`);\n * ```\n *\n * @public\n */\nexport class WorkflowProfiler {\n /**\n * Initializes the profiler with an optional engine.\n *\n * @param engine - The FluxEngine instance to use for execution. If omitted, a silent engine is created.\n */\n constructor(private engine?: FluxEngine) {\n if (!this.engine) {\n // Default minimal engine for profiling (Silent)\n this.engine = new FluxEngine({\n logger: new FluxSilentLogger(),\n })\n }\n }\n\n /**\n * Executes a workflow and captures its resource consumption metrics.\n *\n * Performs a warmup run to ensure JIT optimization before measurement.\n *\n * @param workflow - The workflow definition to profile.\n * @param input - The input data for the workflow execution.\n * @returns A promise resolving to the captured performance metrics.\n *\n * @example\n * ```typescript\n * const metrics = await profiler.profile(orderWorkflow, { id: '123' });\n * console.log(`Duration: ${metrics.durationMs}ms`);\n * ```\n */\n async profile<TInput>(\n workflow: WorkflowDefinition<TInput, any>,\n input: TInput\n ): Promise<ProfileMetrics> {\n // 1. Warmup (JIT)\n try {\n await this.engine?.execute(workflow, input)\n } catch {}\n\n // 2. Measure\n if (global.gc) {\n global.gc()\n }\n\n const startCpu = process.cpuUsage()\n const startMem = process.memoryUsage().heapUsed\n const startTime = process.hrtime.bigint()\n\n await this.engine?.execute(workflow, input)\n\n const endTime = process.hrtime.bigint()\n const endCpu = process.cpuUsage(startCpu)\n const endMem = process.memoryUsage().heapUsed\n\n // 3. Calculate\n const durationNs = Number(endTime - startTime)\n const durationMs = durationNs / 1_000_000\n const cpuUserMs = endCpu.user / 1000\n const cpuSysMs = endCpu.system / 1000\n const totalCpuMs = cpuUserMs + cpuSysMs\n const memDeltaBytes = Math.max(0, endMem - startMem) // Clamp to 0\n\n // CPU Ratio: How much % of the time was spent on CPU vs Waiting\n const cpuRatio = totalCpuMs / durationMs\n\n return {\n durationMs,\n cpuUserMs,\n cpuSysMs,\n memDeltaBytes,\n cpuRatio,\n }\n }\n\n /**\n * Analyzes metrics to generate concurrency recommendations.\n *\n * Considers system CPU cores and total memory to calculate safe and efficient limits.\n *\n * @param metrics - The metrics captured during a profiling session.\n * @param config - Optional current configuration to check against recommendations.\n * @returns A recommendation object containing bottleneck analysis and concurrency limits.\n *\n * @example\n * ```typescript\n * const advice = profiler.recommend(metrics, { configuredConcurrency: 10 });\n * if (advice.type === 'CPU_BOUND') {\n * console.warn('Workflow is CPU bound, consider reducing concurrency');\n * }\n * ```\n */\n recommend(\n metrics: ProfileMetrics,\n config?: { configuredConcurrency?: number }\n ): ProfileRecommendation {\n const totalMem = os.totalmem()\n const cpus = os.cpus().length\n\n // 1. Analyze Bottleneck Type\n let type: ProfileRecommendation['type'] = 'IO_BOUND'\n if (metrics.cpuRatio > 0.5) {\n type = 'CPU_BOUND'\n } else if (metrics.memDeltaBytes > 50 * 1024 * 1024) {\n // > 50MB per run\n type = 'MEMORY_BOUND'\n }\n\n // 2. Calculate Limits\n\n // Memory Limit: Keep 30% buffer for system, divide rest by per-workflow memory\n const safeMem = totalMem * 0.7\n // Use at least 1MB as baseline to avoid division by zero or huge numbers\n const perInstanceMem = Math.max(metrics.memDeltaBytes, 1024 * 1024)\n const maxMemConcurrency = Math.floor(safeMem / perInstanceMem)\n\n // CPU Limit:\n // If IO Bound (0.2% cpu), we can run many. 100% / 0.2% = 500 tasks per core.\n // We cap efficiency at a reasonable number to avoid Event Loop Lag density.\n const cpuEfficiencyFactor = 1 / Math.max(metrics.cpuRatio, 0.001) // Avoid div by 0\n const maxCpuConcurrency = Math.floor(cpus * cpuEfficiencyFactor)\n\n // 3. Synthesize Recommendation\n const safe = Math.min(maxMemConcurrency, 200) // Hard cap at 200 for sanity\n let efficient = Math.min(maxCpuConcurrency, 200)\n\n // If CPU bound, strict limit based on cores\n if (type === 'CPU_BOUND') {\n efficient = cpus // 1:1 mapping is best for CPU bound\n }\n\n const recommended = Math.min(safe, efficient)\n\n let reason = ''\n if (type === 'IO_BOUND') {\n reason = `Workflow is I/O intensive (CPU usage ${(metrics.cpuRatio * 100).toFixed(1)}%). It is safe to run high concurrency up to ${recommended}.`\n } else if (type === 'CPU_BOUND') {\n reason = `Workflow is CPU intensive. Limiting concurrency to match CPU cores (${cpus}) is recommended to prevent blocking.`\n } else {\n reason = `Workflow consumes significant memory (${(metrics.memDeltaBytes / 1024 / 1024).toFixed(1)}MB). Concurrency limited by available RAM.`\n }\n\n if (config?.configuredConcurrency && config.configuredConcurrency > recommended) {\n reason += ` \\n⚠️ Warning: Your current setting (${config.configuredConcurrency}) exceeds the recommended limit (${recommended}).`\n }\n\n return {\n type,\n safeConcurrency: safe,\n efficientConcurrency: efficient,\n suggestedConcurrency: `${Math.max(1, Math.floor(recommended * 0.5))} - ${recommended}`,\n reason,\n }\n }\n}\n","/**\n * @fileoverview @gravito/flux - Platform-agnostic Workflow Engine\n *\n * High-performance, type-safe workflow engine with Bun optimizations.\n *\n * @example Basic Usage\n * ```typescript\n * import { FluxEngine, createWorkflow } from '@gravito/flux'\n *\n * const workflow = createWorkflow('order-process')\n * .input<{ orderId: string }>()\n * .step('validate', async (ctx) => {\n * ctx.data.order = await fetchOrder(ctx.input.orderId)\n * })\n * .step('process', async (ctx) => {\n * await processPayment(ctx.data.order)\n * })\n * .commit('notify', async (ctx) => {\n * await sendEmail(ctx.data.order.email)\n * })\n *\n * const engine = new FluxEngine()\n * const result = await engine.execute(workflow, { orderId: '123' })\n * ```\n *\n * @module @gravito/flux\n */\n\n// Builder\nexport { createWorkflow, WorkflowBuilder } from './builder/WorkflowBuilder'\nexport { ContextManager } from './core/ContextManager'\nexport { type Lock, type LockProvider, MemoryLockProvider } from './core/LockProvider'\nexport {\n type RedisClient,\n RedisLockProvider,\n type RedisLockProviderOptions,\n} from './core/RedisLockProvider'\n// Core (for advanced usage)\nexport { StateMachine } from './core/StateMachine'\nexport { StepExecutor } from './core/StepExecutor'\nexport {\n type BatchExecutionOptions,\n BatchExecutor,\n type BatchItemResult,\n type BatchResult,\n} from './engine/BatchExecutor'\n// Core\nexport { FluxEngine } from './engine/FluxEngine'\n// Errors\nexport {\n cannotRemoveRoot,\n cannotReplaceRoot,\n emptyWorkflow,\n FluxError,\n FluxErrorCode,\n invalidInput,\n invalidJsonPointer,\n invalidPathTraversal,\n invalidStateTransition,\n invalidStepIndex,\n noRecoveryAction,\n stepNotFound,\n workflowDefinitionChanged,\n workflowNameMismatch,\n workflowNotFound,\n workflowNotSuspended,\n} from './errors'\n// Logger\nexport { FluxConsoleLogger, FluxSilentLogger } from './logger/FluxLogger'\nexport { CronTrigger } from './orbit/CronTrigger'\n// Gravito Integration\nexport { OrbitFlux, type OrbitFluxOptions } from './orbit/OrbitFlux'\n// Profiler\nexport {\n type ProfileMetrics,\n type ProfileRecommendation,\n WorkflowProfiler,\n} from './profiler/WorkflowProfiler'\nexport { BunSQLiteStorage, type BunSQLiteStorageOptions } from './storage/BunSQLiteStorage'\n// Storage\nexport { MemoryStorage } from './storage/MemoryStorage'\nexport { PostgreSQLStorage, type PostgreSQLStorageOptions } from './storage/PostgreSQLStorage'\n// Trace\nexport { JsonFileTraceSink } from './trace/JsonFileTraceSink'\n// Types\nexport type {\n CronScheduleOptions,\n // Config\n FluxConfig,\n // Logger\n FluxLogger,\n FluxResult,\n // Trace\n FluxTraceEvent,\n FluxTraceEventType,\n FluxTraceSink,\n // Helper\n FluxWaitResult,\n // Step types\n StepDefinition,\n StepDescriptor,\n StepExecution,\n StepResult,\n WorkflowContext,\n WorkflowDefinition,\n WorkflowDescriptor,\n WorkflowFilter,\n WorkflowState,\n // Core types\n WorkflowStatus,\n // Storage\n WorkflowStorage,\n} from './types'\n// Visualization\nexport { MermaidGenerator, type MermaidOptions } from './visualization/MermaidGenerator'\n\n/**\n * Flux helper utilities for workflow control flow.\n *\n * Provides methods to interact with the workflow engine's special behaviors,\n * such as suspending execution to wait for external signals.\n */\nexport const Flux = {\n /**\n * Suspends workflow execution until a specific signal is received.\n *\n * When a handler returns this result, the engine saves the current state\n * and stops execution. The workflow can be resumed later using `engine.signal()`.\n *\n * @param signal - The unique identifier for the signal to wait for.\n * @returns A special result object that instructs the engine to suspend.\n *\n * @example\n * ```typescript\n * .step('wait-for-approval', async (ctx) => {\n * return Flux.wait('manager-approval');\n * })\n * ```\n */\n wait: (signal: string): import('./types').FluxWaitResult => ({\n __kind: 'flux_wait',\n signal,\n }),\n}\n"]}
package/dist/index.d.cts CHANGED
@@ -1,5 +1,5 @@
1
- import { C as CronScheduleOptions, W as WorkflowDefinition, a as WorkflowState, F as FluxWaitResult } from './types-CRz5XdLd.cjs';
2
- export { b as FluxConfig, c as FluxLogger, d as FluxResult, e as FluxTraceEvent, f as FluxTraceEventType, g as FluxTraceSink, L as Lock, h as LockProvider, M as MemoryLockProvider, S as StepDefinition, i as StepDescriptor, j as StepExecution, k as StepResult, l as WorkflowContext, m as WorkflowDescriptor, n as WorkflowFilter, o as WorkflowStatus, p as WorkflowStorage } from './types-CRz5XdLd.cjs';
1
+ import { C as CronScheduleOptions, W as WorkflowDefinition, a as WorkflowState, F as FluxWaitResult } from './types-CGIEQPFv.cjs';
2
+ export { b as FluxConfig, c as FluxLogger, d as FluxResult, e as FluxTraceEvent, f as FluxTraceEventType, g as FluxTraceSink, L as Lock, h as LockProvider, M as MemoryLockProvider, S as StepDefinition, i as StepDescriptor, j as StepExecution, k as StepResult, l as WorkflowContext, m as WorkflowDescriptor, n as WorkflowFilter, o as WorkflowStatus, p as WorkflowStorage } from './types-CGIEQPFv.cjs';
3
3
  import { FluxEngine } from './index.node.cjs';
4
4
  export { BatchExecutionOptions, BatchExecutor, BatchItemResult, BatchResult, ContextManager, FluxConsoleLogger, FluxSilentLogger, JsonFileTraceSink, MemoryStorage, OrbitFlux, OrbitFluxOptions, PostgreSQLStorage, PostgreSQLStorageOptions, RedisClient, RedisLockProvider, RedisLockProviderOptions, StateMachine, StepExecutor, WorkflowBuilder, createWorkflow } from './index.node.cjs';
5
5
  export { BunSQLiteStorage, BunSQLiteStorageOptions } from './bun.cjs';
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { C as CronScheduleOptions, W as WorkflowDefinition, a as WorkflowState, F as FluxWaitResult } from './types-CRz5XdLd.js';
2
- export { b as FluxConfig, c as FluxLogger, d as FluxResult, e as FluxTraceEvent, f as FluxTraceEventType, g as FluxTraceSink, L as Lock, h as LockProvider, M as MemoryLockProvider, S as StepDefinition, i as StepDescriptor, j as StepExecution, k as StepResult, l as WorkflowContext, m as WorkflowDescriptor, n as WorkflowFilter, o as WorkflowStatus, p as WorkflowStorage } from './types-CRz5XdLd.js';
1
+ import { C as CronScheduleOptions, W as WorkflowDefinition, a as WorkflowState, F as FluxWaitResult } from './types-CGIEQPFv.js';
2
+ export { b as FluxConfig, c as FluxLogger, d as FluxResult, e as FluxTraceEvent, f as FluxTraceEventType, g as FluxTraceSink, L as Lock, h as LockProvider, M as MemoryLockProvider, S as StepDefinition, i as StepDescriptor, j as StepExecution, k as StepResult, l as WorkflowContext, m as WorkflowDescriptor, n as WorkflowFilter, o as WorkflowStatus, p as WorkflowStorage } from './types-CGIEQPFv.js';
3
3
  import { FluxEngine } from './index.node.js';
4
4
  export { BatchExecutionOptions, BatchExecutor, BatchItemResult, BatchResult, ContextManager, FluxConsoleLogger, FluxSilentLogger, JsonFileTraceSink, MemoryStorage, OrbitFlux, OrbitFluxOptions, PostgreSQLStorage, PostgreSQLStorageOptions, RedisClient, RedisLockProvider, RedisLockProviderOptions, StateMachine, StepExecutor, WorkflowBuilder, createWorkflow } from './index.node.js';
5
5
  export { BunSQLiteStorage, BunSQLiteStorageOptions } from './bun.js';
package/dist/index.js CHANGED
@@ -31,10 +31,10 @@ import {
31
31
  workflowNameMismatch,
32
32
  workflowNotFound,
33
33
  workflowNotSuspended
34
- } from "./chunk-4DXCQ6CL.js";
34
+ } from "./chunk-M2ZRQRF4.js";
35
35
  import {
36
36
  BunSQLiteStorage
37
- } from "./chunk-NAIVO7RR.js";
37
+ } from "./chunk-EZGSU6AW.js";
38
38
  import {
39
39
  MermaidGenerator
40
40
  } from "./chunk-WGDTB6OC.js";
@@ -14,8 +14,8 @@
14
14
 
15
15
 
16
16
 
17
- var _chunkWAPZDXSXcjs = require('./chunk-WAPZDXSX.cjs');
18
- require('./chunk-YXBEYVGY.cjs');
17
+ var _chunkDN7SIQ34cjs = require('./chunk-DN7SIQ34.cjs');
18
+ require('./chunk-ZE2RDS47.cjs');
19
19
 
20
20
 
21
21
 
@@ -32,5 +32,5 @@ require('./chunk-YXBEYVGY.cjs');
32
32
 
33
33
 
34
34
 
35
- exports.BatchExecutor = _chunkWAPZDXSXcjs.BatchExecutor; exports.ContextManager = _chunkWAPZDXSXcjs.ContextManager; exports.FluxConsoleLogger = _chunkWAPZDXSXcjs.FluxConsoleLogger; exports.FluxEngine = _chunkWAPZDXSXcjs.FluxEngine; exports.FluxSilentLogger = _chunkWAPZDXSXcjs.FluxSilentLogger; exports.JsonFileTraceSink = _chunkWAPZDXSXcjs.JsonFileTraceSink; exports.MemoryLockProvider = _chunkWAPZDXSXcjs.MemoryLockProvider; exports.MemoryStorage = _chunkWAPZDXSXcjs.MemoryStorage; exports.OrbitFlux = _chunkWAPZDXSXcjs.OrbitFlux; exports.PostgreSQLStorage = _chunkWAPZDXSXcjs.PostgreSQLStorage; exports.RedisLockProvider = _chunkWAPZDXSXcjs.RedisLockProvider; exports.StateMachine = _chunkWAPZDXSXcjs.StateMachine; exports.StepExecutor = _chunkWAPZDXSXcjs.StepExecutor; exports.WorkflowBuilder = _chunkWAPZDXSXcjs.WorkflowBuilder; exports.createWorkflow = _chunkWAPZDXSXcjs.createWorkflow;
35
+ exports.BatchExecutor = _chunkDN7SIQ34cjs.BatchExecutor; exports.ContextManager = _chunkDN7SIQ34cjs.ContextManager; exports.FluxConsoleLogger = _chunkDN7SIQ34cjs.FluxConsoleLogger; exports.FluxEngine = _chunkDN7SIQ34cjs.FluxEngine; exports.FluxSilentLogger = _chunkDN7SIQ34cjs.FluxSilentLogger; exports.JsonFileTraceSink = _chunkDN7SIQ34cjs.JsonFileTraceSink; exports.MemoryLockProvider = _chunkDN7SIQ34cjs.MemoryLockProvider; exports.MemoryStorage = _chunkDN7SIQ34cjs.MemoryStorage; exports.OrbitFlux = _chunkDN7SIQ34cjs.OrbitFlux; exports.PostgreSQLStorage = _chunkDN7SIQ34cjs.PostgreSQLStorage; exports.RedisLockProvider = _chunkDN7SIQ34cjs.RedisLockProvider; exports.StateMachine = _chunkDN7SIQ34cjs.StateMachine; exports.StepExecutor = _chunkDN7SIQ34cjs.StepExecutor; exports.WorkflowBuilder = _chunkDN7SIQ34cjs.WorkflowBuilder; exports.createWorkflow = _chunkDN7SIQ34cjs.createWorkflow;
36
36
  //# sourceMappingURL=index.node.cjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["/Users/carl/Dev/Carl/gravito-core-ci-fix/packages/flux/dist/index.node.cjs"],"names":[],"mappings":"AAAA;AACE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACF,wDAA6B;AAC7B,gCAA6B;AAC7B;AACE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACF,43BAAC","file":"/Users/carl/Dev/Carl/gravito-core-ci-fix/packages/flux/dist/index.node.cjs"}
1
+ {"version":3,"sources":["/Users/carl/Dev/Carl/gravito-core/packages/flux/dist/index.node.cjs"],"names":[],"mappings":"AAAA;AACE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACF,wDAA6B;AAC7B,gCAA6B;AAC7B;AACE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACF,43BAAC","file":"/Users/carl/Dev/Carl/gravito-core/packages/flux/dist/index.node.cjs"}
@@ -1,5 +1,5 @@
1
- import { l as WorkflowContext, q as StepHandlerResult, W as WorkflowDefinition, m as WorkflowDescriptor, a as WorkflowState, o as WorkflowStatus, h as LockProvider, L as Lock, S as StepDefinition, j as StepExecution, k as StepResult, c as FluxLogger, p as WorkflowStorage, n as WorkflowFilter, g as FluxTraceSink, e as FluxTraceEvent, b as FluxConfig, d as FluxResult, C as CronScheduleOptions } from './types-CRz5XdLd.cjs';
2
- export { f as FluxTraceEventType, M as MemoryLockProvider, i as StepDescriptor } from './types-CRz5XdLd.cjs';
1
+ import { l as WorkflowContext, q as StepHandlerResult, W as WorkflowDefinition, m as WorkflowDescriptor, a as WorkflowState, o as WorkflowStatus, h as LockProvider, L as Lock, S as StepDefinition, j as StepExecution, k as StepResult, c as FluxLogger, p as WorkflowStorage, n as WorkflowFilter, g as FluxTraceSink, e as FluxTraceEvent, b as FluxConfig, d as FluxResult, C as CronScheduleOptions } from './types-CGIEQPFv.cjs';
2
+ export { f as FluxTraceEventType, M as MemoryLockProvider, i as StepDescriptor } from './types-CGIEQPFv.cjs';
3
3
  import { GravitoOrbit, PlanetCore } from '@gravito/core';
4
4
 
5
5
  /**
@@ -971,7 +971,8 @@ declare class PostgreSQLStorage implements WorkflowStorage {
971
971
  /**
972
972
  * @fileoverview JSON file trace sink (NDJSON)
973
973
  *
974
- * Writes trace events to a newline-delimited JSON file.
974
+ * Writes trace events to a newline-delimited JSON file with buffering support.
975
+ * Uses RuntimeAdapter's FileSink for efficient batch writes instead of individual syscalls.
975
976
  */
976
977
 
977
978
  /**
@@ -984,6 +985,8 @@ interface JsonFileTraceSinkOptions {
984
985
  path: string;
985
986
  /** Whether to reset (clear) the file on initialization. @default true */
986
987
  reset?: boolean;
988
+ /** Buffer size for batch writes. Events are flushed when buffer reaches this size. @default 50 */
989
+ bufferSize?: number;
987
990
  }
988
991
  /**
989
992
  * A trace sink that writes events to a newline-delimited JSON (NDJSON) file.
@@ -991,11 +994,17 @@ interface JsonFileTraceSinkOptions {
991
994
  * This sink is ideal for local development and debugging as it produces
992
995
  * a human-readable and easily machine-parsable log of workflow events.
993
996
  *
997
+ * Optimizations:
998
+ * - Uses RuntimeAdapter's FileSink for buffered writes (reduces syscalls)
999
+ * - Automatic flush on buffer overflow
1000
+ * - Batch write support for better I/O efficiency
1001
+ *
994
1002
  * @example
995
1003
  * ```typescript
996
1004
  * const sink = new JsonFileTraceSink({
997
1005
  * path: './traces/workflow.jsonl',
998
- * reset: true
1006
+ * reset: true,
1007
+ * bufferSize: 100 // Flush every 100 events
999
1008
  * });
1000
1009
  * ```
1001
1010
  *
@@ -1004,8 +1013,12 @@ interface JsonFileTraceSinkOptions {
1004
1013
  declare class JsonFileTraceSink implements FluxTraceSink {
1005
1014
  private path;
1006
1015
  private ready;
1016
+ private fileSink;
1017
+ private buffer;
1018
+ private bufferSize;
1019
+ private adapter;
1007
1020
  /**
1008
- * Creates a new JSON file trace sink.
1021
+ * Creates a new JSON file trace sink with buffering support.
1009
1022
  *
1010
1023
  * @param options - Configuration options for the sink.
1011
1024
  */
@@ -1020,7 +1033,8 @@ declare class JsonFileTraceSink implements FluxTraceSink {
1020
1033
  /**
1021
1034
  * Appends a trace event to the file in NDJSON format.
1022
1035
  *
1023
- * Waits for initialization to complete before writing.
1036
+ * Events are buffered and written in batches using FileSink
1037
+ * for improved I/O efficiency. Waits for initialization to complete before writing.
1024
1038
  *
1025
1039
  * @param event - The trace event to record.
1026
1040
  * @throws {Error} If writing to the file fails.
@@ -1036,6 +1050,23 @@ declare class JsonFileTraceSink implements FluxTraceSink {
1036
1050
  * ```
1037
1051
  */
1038
1052
  emit(event: FluxTraceEvent): Promise<void>;
1053
+ /**
1054
+ * Flushes buffered events to disk.
1055
+ *
1056
+ * This is called automatically when the buffer reaches the configured size.
1057
+ * Can also be called manually to ensure all events are written.
1058
+ *
1059
+ * @throws {Error} If flushing fails.
1060
+ */
1061
+ flushBuffer(): Promise<void>;
1062
+ /**
1063
+ * Closes the sink and flushes any remaining buffered events.
1064
+ *
1065
+ * Should be called before process exit to ensure all events are persisted.
1066
+ *
1067
+ * @throws {Error} If closing or flushing fails.
1068
+ */
1069
+ close(): Promise<void>;
1039
1070
  }
1040
1071
 
1041
1072
  /**
@@ -1,5 +1,5 @@
1
- import { l as WorkflowContext, q as StepHandlerResult, W as WorkflowDefinition, m as WorkflowDescriptor, a as WorkflowState, o as WorkflowStatus, h as LockProvider, L as Lock, S as StepDefinition, j as StepExecution, k as StepResult, c as FluxLogger, p as WorkflowStorage, n as WorkflowFilter, g as FluxTraceSink, e as FluxTraceEvent, b as FluxConfig, d as FluxResult, C as CronScheduleOptions } from './types-CRz5XdLd.js';
2
- export { f as FluxTraceEventType, M as MemoryLockProvider, i as StepDescriptor } from './types-CRz5XdLd.js';
1
+ import { l as WorkflowContext, q as StepHandlerResult, W as WorkflowDefinition, m as WorkflowDescriptor, a as WorkflowState, o as WorkflowStatus, h as LockProvider, L as Lock, S as StepDefinition, j as StepExecution, k as StepResult, c as FluxLogger, p as WorkflowStorage, n as WorkflowFilter, g as FluxTraceSink, e as FluxTraceEvent, b as FluxConfig, d as FluxResult, C as CronScheduleOptions } from './types-CGIEQPFv.js';
2
+ export { f as FluxTraceEventType, M as MemoryLockProvider, i as StepDescriptor } from './types-CGIEQPFv.js';
3
3
  import { GravitoOrbit, PlanetCore } from '@gravito/core';
4
4
 
5
5
  /**
@@ -971,7 +971,8 @@ declare class PostgreSQLStorage implements WorkflowStorage {
971
971
  /**
972
972
  * @fileoverview JSON file trace sink (NDJSON)
973
973
  *
974
- * Writes trace events to a newline-delimited JSON file.
974
+ * Writes trace events to a newline-delimited JSON file with buffering support.
975
+ * Uses RuntimeAdapter's FileSink for efficient batch writes instead of individual syscalls.
975
976
  */
976
977
 
977
978
  /**
@@ -984,6 +985,8 @@ interface JsonFileTraceSinkOptions {
984
985
  path: string;
985
986
  /** Whether to reset (clear) the file on initialization. @default true */
986
987
  reset?: boolean;
988
+ /** Buffer size for batch writes. Events are flushed when buffer reaches this size. @default 50 */
989
+ bufferSize?: number;
987
990
  }
988
991
  /**
989
992
  * A trace sink that writes events to a newline-delimited JSON (NDJSON) file.
@@ -991,11 +994,17 @@ interface JsonFileTraceSinkOptions {
991
994
  * This sink is ideal for local development and debugging as it produces
992
995
  * a human-readable and easily machine-parsable log of workflow events.
993
996
  *
997
+ * Optimizations:
998
+ * - Uses RuntimeAdapter's FileSink for buffered writes (reduces syscalls)
999
+ * - Automatic flush on buffer overflow
1000
+ * - Batch write support for better I/O efficiency
1001
+ *
994
1002
  * @example
995
1003
  * ```typescript
996
1004
  * const sink = new JsonFileTraceSink({
997
1005
  * path: './traces/workflow.jsonl',
998
- * reset: true
1006
+ * reset: true,
1007
+ * bufferSize: 100 // Flush every 100 events
999
1008
  * });
1000
1009
  * ```
1001
1010
  *
@@ -1004,8 +1013,12 @@ interface JsonFileTraceSinkOptions {
1004
1013
  declare class JsonFileTraceSink implements FluxTraceSink {
1005
1014
  private path;
1006
1015
  private ready;
1016
+ private fileSink;
1017
+ private buffer;
1018
+ private bufferSize;
1019
+ private adapter;
1007
1020
  /**
1008
- * Creates a new JSON file trace sink.
1021
+ * Creates a new JSON file trace sink with buffering support.
1009
1022
  *
1010
1023
  * @param options - Configuration options for the sink.
1011
1024
  */
@@ -1020,7 +1033,8 @@ declare class JsonFileTraceSink implements FluxTraceSink {
1020
1033
  /**
1021
1034
  * Appends a trace event to the file in NDJSON format.
1022
1035
  *
1023
- * Waits for initialization to complete before writing.
1036
+ * Events are buffered and written in batches using FileSink
1037
+ * for improved I/O efficiency. Waits for initialization to complete before writing.
1024
1038
  *
1025
1039
  * @param event - The trace event to record.
1026
1040
  * @throws {Error} If writing to the file fails.
@@ -1036,6 +1050,23 @@ declare class JsonFileTraceSink implements FluxTraceSink {
1036
1050
  * ```
1037
1051
  */
1038
1052
  emit(event: FluxTraceEvent): Promise<void>;
1053
+ /**
1054
+ * Flushes buffered events to disk.
1055
+ *
1056
+ * This is called automatically when the buffer reaches the configured size.
1057
+ * Can also be called manually to ensure all events are written.
1058
+ *
1059
+ * @throws {Error} If flushing fails.
1060
+ */
1061
+ flushBuffer(): Promise<void>;
1062
+ /**
1063
+ * Closes the sink and flushes any remaining buffered events.
1064
+ *
1065
+ * Should be called before process exit to ensure all events are persisted.
1066
+ *
1067
+ * @throws {Error} If closing or flushing fails.
1068
+ */
1069
+ close(): Promise<void>;
1039
1070
  }
1040
1071
 
1041
1072
  /**
@@ -14,8 +14,8 @@ import {
14
14
  StepExecutor,
15
15
  WorkflowBuilder,
16
16
  createWorkflow
17
- } from "./chunk-4DXCQ6CL.js";
18
- import "./chunk-NAIVO7RR.js";
17
+ } from "./chunk-M2ZRQRF4.js";
18
+ import "./chunk-EZGSU6AW.js";
19
19
  export {
20
20
  BatchExecutor,
21
21
  ContextManager,
@@ -359,6 +359,16 @@ interface FluxTraceSink {
359
359
  * @param event - The event to record.
360
360
  */
361
361
  emit(event: FluxTraceEvent): void | Promise<void>;
362
+ /**
363
+ * Optional method to flush any buffered events.
364
+ * Called to ensure all events are persisted before shutdown.
365
+ */
366
+ flush?(): Promise<void>;
367
+ /**
368
+ * Optional method to close the sink and release resources.
369
+ * Should be called before process exit.
370
+ */
371
+ close?(): Promise<void>;
362
372
  }
363
373
  /**
364
374
  * Global configuration for the Flux engine instance.
@@ -359,6 +359,16 @@ interface FluxTraceSink {
359
359
  * @param event - The event to record.
360
360
  */
361
361
  emit(event: FluxTraceEvent): void | Promise<void>;
362
+ /**
363
+ * Optional method to flush any buffered events.
364
+ * Called to ensure all events are persisted before shutdown.
365
+ */
366
+ flush?(): Promise<void>;
367
+ /**
368
+ * Optional method to close the sink and release resources.
369
+ * Should be called before process exit.
370
+ */
371
+ close?(): Promise<void>;
362
372
  }
363
373
  /**
364
374
  * Global configuration for the Flux engine instance.
package/package.json CHANGED
@@ -1,6 +1,7 @@
1
1
  {
2
2
  "name": "@gravito/flux",
3
- "version": "3.0.2",
3
+ "sideEffects": false,
4
+ "version": "3.0.3",
4
5
  "description": "Platform-agnostic workflow engine for Gravito",
5
6
  "type": "module",
6
7
  "main": "./dist/index.node.cjs",
@@ -39,6 +40,7 @@
39
40
  ],
40
41
  "scripts": {
41
42
  "build": "tsup",
43
+ "build:dts": "tsup --dts --dts-only",
42
44
  "dev:viewer": "node ./bin/flux.js dev --trace ./.flux/trace.ndjson --port 4280",
43
45
  "typecheck": "bun tsc -p tsconfig.json --noEmit --skipLibCheck",
44
46
  "test": "bun test --timeout=10000",
@@ -48,7 +50,7 @@
48
50
  "test:integration": "test $(find tests -name '*.integration.test.ts' 2>/dev/null | wc -l) -gt 0 && find tests -name '*.integration.test.ts' -print0 | xargs -0 bun test --timeout=10000 || echo 'No integration tests found'"
49
51
  },
50
52
  "peerDependencies": {
51
- "@gravito/core": "^1.6.1",
53
+ "@gravito/core": "^2.0.0",
52
54
  "pg": "^8.18.0"
53
55
  },
54
56
  "peerDependenciesMeta": {
@@ -60,7 +62,7 @@
60
62
  }
61
63
  },
62
64
  "devDependencies": {
63
- "@gravito/core": "^1.6.1",
65
+ "@gravito/core": "workspace:*",
64
66
  "@types/pg": "^8.16.0",
65
67
  "bun-types": "latest",
66
68
  "pg": "^8.18.0",