Invect

Next.js

Use Invect with Next.js App Router via server actions and API routes.

Installation

npm install @invect/core @invect/nextjs

Setup

API Routes

Create a catch-all API route for Invect:

app/api/invect/[...route]/route.ts
import { createInvectHandler } from '@invect/nextjs';

const handler = createInvectHandler({
  baseDatabaseConfig: {
    type: 'sqlite',
    connectionString: process.env.DATABASE_URL || 'file:./dev.db',
    id: 'main',
  },
});

export const GET = handler;
export const POST = handler;
export const PUT = handler;
export const DELETE = handler;

Frontend Component

In a client page or layout, mount the Invect component:

app/workflows/page.tsx
'use client';

import { Invect } from '@invect/frontend';
import '@invect/frontend/styles';

export default function WorkflowsPage() {
  return <Invect apiBaseUrl="/api/invect" />;
}

Server Actions

You can also use the core directly in server actions:

app/actions/workflows.ts
'use server';

import { Invect } from '@invect/core';

let core: Invect | null = null;

function getCore() {
  if (!core) {
    core = new Invect({
      baseDatabaseConfig: {
        type: 'sqlite',
        connectionString: process.env.DATABASE_URL || 'file:./dev.db',
        id: 'main',
      },
    });
    core.initialize();
  }
  return core;
}

export async function executeWorkflow(flowId: string, inputs: any) {
  const result = await getCore().startFlowRun(flowId, inputs);
  return result;
}

export async function listWorkflows() {
  return getCore().listFlows();
}

Triggering Flows from Server Components

app/dashboard/page.tsx
import { executeWorkflow, listWorkflows } from '@/app/actions/workflows';

export default async function Dashboard() {
  const flows = await listWorkflows();

  return (
    <div>
      <h1>Workflows</h1>
      {flows.map(flow => (
        <div key={flow.id}>
          <h2>{flow.name}</h2>
          <form action={async () => {
            'use server';
            await executeWorkflow(flow.id, {});
          }}>
            <button type="submit">Run</button>
          </form>
        </div>
      ))}
    </div>
  );
}