npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@model-ts/eventbridge

v7.6.0

Published

Publish @model-ts/core models as EventBridge events, built on Effect.

Readme

@model-ts/eventbridge

Publish @model-ts/core models as Amazon EventBridge events. Publishing is an Effect that needs an EventBridge service, so the bus is chosen with a layer: the real one in production, an in-memory one in tests. This page is the API reference; the main README explains the concepts.

[!NOTE] Version 7 is built on Effect v4. The io-ts version is @model-ts/eventbridge 3.x.

npm install @model-ts/core @model-ts/eventbridge effect @aws-sdk/client-eventbridge

Event models

An event is a model with EventBridge.provider and source and detailType getters (or fields). Its encoded form, _tag included, becomes the event's detail.

import { Model } from "@model-ts/core"
import { EventBridge } from "@model-ts/eventbridge"
import { Schema } from "effect"

class OrderPlaced extends Model.Class<OrderPlaced>()(
  "OrderPlaced",
  EventBridge.provider,
  { orderId: OrderId, total: Schema.Number },
) {
  get source() {
    return "shop"
  }
  get detailType() {
    return "shop.order.placed"
  }
}

EventBridge.provider adds event.publish(), an Effect<ReadonlyArray<ResultEntry>, PublishErrors, EventBridge>. It needs source and detailType on the model; without them, calling it is a type error.

Publishing

import { EventBridge } from "@model-ts/eventbridge"

const program = Effect.gen(function* () {
  yield* new OrderPlaced({ orderId, total: 42 }).publish()

  // Several events at once, in PutEvents calls of up to 10.
  yield* EventBridge.publish(orderPlaced, invoiceCreated, stockReserved)
})

EventBridge.publish encodes every event before it sends anything, so an event that cannot be encoded fails the whole call without publishing the others. Events go out in order, in PutEvents calls of up to 10 entries. If EventBridge rejects some entries, every call is still made, and the result is a PublishError whose entries has one result per event, in order, so the failed ones can be retried.

Provide the bus with a layer:

| Layer | Bus | | ---------------------------------------------- | --------------------------------------------------------------- | | EventBridge.layer({ eventBusName, client? }) | EventBridge; client is passed to new EventBridgeClient(...) | | EventBridge.layerMemory | In memory; also provides PublishedEvents |

// The bus name from Config, read when the layer is built
const EventBridgeLive = Layer.unwrap(
  Effect.gen(function* () {
    return EventBridge.layer({
      eventBusName: yield* Config.String("EVENT_BUS_NAME"),
    })
  }),
)

The client is created when the layer is built and destroyed when its scope closes. Anything with source, detailType and encode() can be published, models or not: that shape is PublishableEvent.

Errors

| Error | Fields | Raised when | | ------------------ | ----------------------------- | ------------------------------------------------------------ | | EventEncodeError | detailType, cause | An event could not be encoded. Nothing was sent. | | PublishError | failedEntryCount, entries | EventBridge rejected some entries. | | EventBridgeError | cause | The PutEvents call failed: network, permissions, throttling. |

Their union is PublishErrors.

Tracing

| Span | Kind | Attributes | | ----------------------- | -------- | --------------------------------------------------------------------------------------------------------------------------------------------------------- | | EventBridge.publish | internal | messaging.batch.message_count | | EventBridge.PutEvents | producer | messaging.system, messaging.operation.name, messaging.destination.name (the bus), messaging.batch.message_count, rpc.*, model_ts.detail_types |

One EventBridge.PutEvents span is created per call, inside the EventBridge.publish span. A call whose entries were rejected ends its span with the PublishError for that call.

Testing

Provide the in-memory bus and read what was published:

import { expect, layer } from "@effect/vitest"
import { EventBridge, PublishedEvents } from "@model-ts/eventbridge"

layer(EventBridge.layerMemory)((it) => {
  it.effect("announces the order", () =>
    Effect.gen(function* () {
      yield* placeOrder(order)

      const published = yield* PublishedEvents.use((events) => events.all)
      expect(published.map((event) => event.detailType)).toEqual([
        "shop.order.placed",
      ])
    }),
  )
})

EventBridge.layerMemory encodes and batches events exactly like the real bus, so encoding failures show up in tests. Each recorded event has eventBusName: "memory" and the decoded detail, which you can turn back into a model with OrderPlaced.from(event.detail).