A proof-of-concept implementation showing how to run Inngest with Cloudflare Durable Objects. This is an example repo demonstrating the pattern, not a published package.
This is an example implementation showing how to run Inngest functions in Cloudflare Workers using Durable Objects. It demonstrates patterns for:
- Background job processing in Cloudflare
- Event-driven architectures
- Reliable async processing that doesn't shit the bed
Clone this repo to check it out:
git clone https://github.com/joelhooks/cloudflare-do-inngest.git
cd cloudflare-do-inngest
pnpm installimport { createInngestDO } from '@joelhooks/cloudflare-do-inngest'
import { inngest } from './inngest-client'
import { functions } from './functions'
export class InngestHandler extends DurableObject {
constructor(state: DurableObjectState, env: Env) {
super(state, env)
return createInngestDO({
client: inngest,
functions,
})(state, env)
}
}import { Hono } from "hono"
import { createMiddleware } from 'hono/factory'
import { InngestHandler } from './inngest-handler'
type Bindings = {
INNGEST_HANDLER: DurableObjectNamespace<InngestHandler>
}
const app = new Hono<{ Bindings: Bindings }>()
const inngestMiddleware = createMiddleware(async (c, next) => {
const id = c.env.INNGEST_HANDLER.idFromName("inngest")
const stub = c.env.INNGEST_HANDLER.get(id)
c.set('inngestStub', stub)
await next()
})
app.on(["GET", "PUT", "POST"], "/api/inngest", inngestMiddleware, async (c) => {
return c.var.inngestStub.fetch(c.req.raw)
})
export default appimport { inngest } from "./inngest-client"
export const processOrder = inngest.createFunction(
{ id: "process-order" },
{ event: "order/created" },
async ({ event, step }) => {
// Do your work here
return {
status: "processed",
orderId: event.data.orderId
}
}
)Make sure you've got these in your wrangler.toml:
[[durable_objects.bindings]]
name = "INNGEST_HANDLER"
class_name = "InngestHandler"
[[migrations]]
tag = "v1"
new_classes = ["InngestHandler"]This is written in TypeScript and includes all the type definitions you need. Define your event types like this:
import { EventSchemas } from "inngest"
type OrderEvent = {
name: "order/created"
data: {
orderId: string
amount: number
}
}
export type InngestEvents = OrderEvent
export const schemas = new EventSchemas().fromUnion<InngestEvents>()- Fork it
- Create your feature branch:
git checkout -b my-new-feature - Commit your changes:
git commit -am 'Add some feature' - Push to the branch:
git push origin my-new-feature - Submit a pull request
MIT - Do whatever you want with it.