Skip to content

Build scalable and durable micro-services with APIs, Messaging and Workflows

License

Notifications You must be signed in to change notification settings

sam-goodwin/eventual

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation


Eventual

A drop-in serverless runtime and SDK for building event-driven systems.

MIT License Discord Twitter

πŸ› Β  Eventual is in pre-release - come chat to us on Discord!


Overview

Website β€’ API Docs β€’ Quick Start

Eventual makes building and operating resilient event-driven applications easy at any scale.

  • πŸ’ͺΒ  Powerful orchestration and choreography - build durable, long-running Workflows, scale APIs, publish and subscribe to Events, and connect to SaaS via Integrations.
  • πŸŒ€Β  Event-driven - build asynchronous systems that are more resilient, scalable and evolvable.
  • πŸ“ˆΒ  Serverless - fully serverless, load-based pricing that scales to $0 and minimal operational complexity.
  • 🧩  Composable and Evolvable - loosely coupled architectures make it easy to add new services and evolve your system over time.
  • πŸ§‘β€πŸ’»Β  Code-first - end-to-end type safety that spans across service boundaries, from APIs to Events to long-running Workflows.
  • 🌩  Your cloud, your security boundaries - runs on your cloud infrastructure, with transparent billing and total control over data and security.
  • πŸ› Β  Distributed as IaC - integrates with your favorite Infrastructure-as-Code (IaC) frameworks such as the AWS CDK and SST.

Quick Start

Start a new project with Eventual or drop-in to an existing AWS CDK or SST application by visiting the Quick Start.

# create a new project
npm create eventual

# enter the new project's directory
cd <project-name>

# deploy to AWS
npx cdk deploy

What is Eventual?

Eventual makes building and operating resilient event-driven applications easy at any scale. Its code-first workflow engine and event-driven primitives simplify and standardize how teams solve complex business orchestration problems and evolve system architectures over time. Leverages Serverless to scale from 0 to any sized workload and your favorite Infrastructure-as-Code framework to drop directly in to your stack without getting in your way.

We highly recommend checking out Werner Vogel's 2022 AWS RE:Invent Keynote.

With our plug-and-play foundation blocks, you can use as much or as little as needed to build your distributed system. These building blocks include:

🌐 Serverless REST APIs

Easily create scalable, event-driven APIs with code-first routes.

import { api } from "@eventual/core";

api.post("/echo", async (request) => {
  return new Response(await request.text());
});

πŸ“£ Publish and subscribe to Events

import { event } from "@eventual/core";

interface MyEvent {
  key: string;
}

export const myEvent = event<MyEvent>("MyEvent");

myEvent.onEvent((e) => {
  console.log(e.key);
});

πŸ€– Turing complete, imperative workflows

Eventual allows you to use the full power of TypeScript to build long-running, durable workflows with unlimited complexity - including operators, for-loops, try-catch, if-else, while, do-while, etc.

export const myWorkflow = workflow("myWorkflow", async (items: string[]) => {
  try {
    await Promise.all(
      items.map(async (item) => {
        if (isConditionTrue(item)) {
          await downStreamService(`hello ${item}`);
        }
      })
    );
  } catch (err) {
    console.error(err);
  }
});

πŸ§ͺ Unit test and simulate distributed systems

Easily unit test your service's business logic, including APIs, workflows, and event handlers, using your preferred testing practices and frameworks. Run tests locally or within your CI/CD pipeline to ensure your service is reliable and maintainable.

import { myWorkflow } from "../src/my-workflow";

const env = new TestEnvironment({
  entry: path.join(__dirname, "..", "src", "my-workflow.ts")
})

test("workflow should be OK", async () => {
  const execution = await env.startExecution(myWorkflow, ({
    hello: "world",
  });

  // advance time
  await env.tick(1);

  expect(await execution.getStatus()).toMatchObject({
    status: ExecutionStatus.SUCCESS
  });
});

🐞 Debug production problems locally in your IDE

Replay problematic workflows in production locally and use your IDE's debugger to discover and fix problems.

Debug Production

eventual replay execution <execution-id> --entry ./src/index.ts

πŸ”Œ Integrate with Cloud Resources and Services

import { Slack, SlackCredentials } from "@eventual/integrations-slack";
import { AWSSecret } from "@eventual/aws-client";

const slack = new Slack("my-slack-connection", {
  credentials: new JsonSecret<SlackCredentials>(
    new AWSSecret({
      secretId: process.env.SLACK_SECRET_ID!,
    })
  ),
});

// register a webhook for a slack command
slack.command("/ack", async (request) => {
  await sendSignal(request.text, "ack");
  request.ack();
});

export const task = workflow("task", async (request) => {
  await expectSignal("ack");

  // publish a message to slack from a workflow
  await slack.client.chat.postMessage({
    channel: request.channel,
    text: `Complete: ${request.task}`,
  });
});