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

event-modeling-language

v1.0.0

Published

Event Modeling text DSL language

Readme

Event Modeling

Domain Specific Language (DSL) for writing Event Modeling models. The DSL in textual format can be translated to various outputs, mainly to a diagram.

Event Modeling model is defined in a text with prefered .evml file extension.

Discord channel

What is Event Modeling?

Event Modeling (EM) is a method of describing systems using an example of how information has changed within them over time. Event Modeling specifically omits transient details and looks at what the information flow is and what the user sees at any particular point in time.

You can read more at Event Modeling web page.

Event Modeling diagram is composed of a few main entities:

  • Trigger - Screen and Processor
  • Command
  • View / Read Model
  • Event

Entities are organized in swimlanes forming a timeline usually based on the following patterns:

  • State View
  • State Change
  • Translation
  • Automation

You can find more details in the cheat sheet.

The purpose of the Domain Specific Language (DSL) supporting the drawing of the Event Modeling diagram is the rapid creation. Relations among the entities are inferred by default, so the distraction while you design is limited. Further detail to the entities can be added gradually.

Basic Syntax

The DSL supports two types of syntaxes - compact and relaxed one. Both will be mentioned in the examples and both can be used interchangeably.

Timeline

The timeline is the key part of the diagram and it is composed of Time Frame definitions. Speedy Time Frame typing is the key of the compact notation. For compact notation you type the tf token. For the relaxed notation you type timeframe token.

eventmodeling

tf 01 scn CartScreen
tf 02 cmd AddItem
tf 03 evt ItemAdded

Each Time Frame is referenced by a unique number in order to distinguish one from another and also to be able to reference it when needed. Depending on the complexity of the diagram it should be enough to have just two digit number or more. Imagine you are typing a BASIC program on your ZX Spectrum always starting with a two digit number, but the order of the numbers does not matter, just the uniqueness in the whole timeline.

The Time Frame also contains an Entity Identifier, e.g. in case of 01 Time Frame it is CartScreen. One Entity Identifier can be used multiple times in the timeline for example when you want to express invocations of the same event in different points in time.

Relaxed notation would look like this:

eventmodeling

timeframe 01 screen CartScreen
timeframe 02 command AddItem
timeframe 03 event ItemAdded

Inline data

It is possible to provide data examples for individual Time Frames. An Inline Data is wrapped in curly brackets on the same line as the Time Frame.

Compact version:

eventmodeling

tf 01 scn CartScreen
tf 02 cmd AddItem { description: string }
tf 03 evt ItemAdded { description: string }

Relaxed version:

eventmodeling

timeframe 01 screen CartScreen
timeframe 02 command AddItem { description: string }
timeframe 03 event ItemAdded { description: string }

Data block

If you need to provide more complex data description, you can define the Data Block separately. Data Block is referenced from a Time Frame by providing the identifier inside of double-square brackets [[identifier]], similar to wiki links convention in Markdown.

In case the same entity is repeated you need to uniquely identify the data blocks, therefore the Data Block identifier is suffixed with a number.

Compact version:

eventmodeling

tf 01 scn CartScreen
tf 02 cmd AddItem [[AddItem01]]
tf 03 evt ItemAdded [[ItemAdded]]
tf 04 cmd AddItem [[AddItem02]]
tf 05 evt ItemAdded [[ItemAdded]]

data AddItem01 {
  description: 'john'
  image: 'avatar_john'
  price: 20.4
}

data AddItem02 {
  description: 'jack'
  image: 'avatar_jack'
  price: 12.5
}

data ItemAdded {
  description: string
  image: string
  price: number
}

Relaxed version:

eventmodeling

timeframe 01 screen CartScreen
timeframe 02 command AddItem [[AddItem01]]
timeframe 03 event ItemAdded [[ItemAdded]]
timeframe 04 command AddItem [[AddItem02]]
timeframe 05 event ItemAdded [[ItemAdded]]

data AddItem01 {
  description: 'john'
  image: 'avatar_john'
  price: 20.4
}

data AddItem02 {
  description: 'jack'
  image: 'avatar_jack'
  price: 12.5
}

data ItemAdded {
  description: string
  image: string
  price: number
}

Resetting the flow

By default the diagram builds the relations based on the inference. But modeling a more complex business flow requires to break such inference from time to time. For that you can use a different type of Time Frame called Reset Frame. It is represented by a rf / resetframe token.

Compact version:

eventmodeling

tf 01 scn CartScreen
tf 02 cmd AddItem
tf 03 evt ItemAdded

rf 04 evt External.InventoryChanged
tf 05 pcr InventoryProcessor
tf 06 cmd ChangeInventory
tf 07 evt Cart.InventoryChanged

Relaxed version:

eventmodeling

timeframe 01 screen CartScreen
timeframe 02 command AddItem
timeframe 03 event ItemAdded

resetframe 04 event External.InventoryChanged
timeframe 05 processor InventoryProcessor
timeframe 06 command ChangeInventory
timeframe 07 event Cart.InventoryChanged

Multiple relations

There are situations where you need to specify multiple relations for an entity. For example when a Read Model is built of multiple Events. You can use ->> token for that.

eventmodeling

rf 02 evt CartCreated
rf 03 evt ItemAdded
rf 04 evt ItemRemoved
rf 05 evt CartCleared
tf 01 rmo CartScreen ->> 02 ->> 03 ->> 04 ->> 05

Event Modeling patterns

This chapter briefly summarizes each Event Modeling pattern.

State Change

eventmodeling

tf 01 scn CartScreen
tf 02 cmd AddItem
tf 03 evt ItemAdded

State View

eventmodeling

tf 03 evt ItemAdded
tf 02 rmo CartItems
tf 04 scn CartScreen

Translation

eventmodeling

tf 03 evt External.InventoryChanged
tf 02 pcr InventoryProcessor
tf 04 cmd ChangeInventory
tf 05 evt Cart.InventoryChanged

Details of the Syntax

Entity types

Entity type is determined by the third column in the Time Frame grammar.

Compact version:

tf 01 pcr InventoryProcessor

Relaxed version:

timeframe 01 processor InventoryProcessor

Entities are assigned to default swimlanes unless a Namespace is specified in the Entity Identifier.

There are the following types available:

  • scn / screen: Screen - belongs to UI/Automation swimlane
  • pcr / processor: Processor - belongs to UI/Automation swimlane
  • cmd / command: Command - belongs to Command/Read Model swimlane
  • rmo / readmodel: Read Model - belongs to Command/Read Model swimlane
  • evt / event: Event - belongs to Events swimlane

Swimlanes and Namespaces

There are three basic Swimlanes inferred from the Entity Type.

  • UI/Automation
  • Command/Read Model
  • Events

As your diagram grows and you explore the depths of a particular software system, you want to categorize your Entities as well. In order to do that, you can use Namespace identifier as part of the Entity Identifier.

Inventory.InventoryChanged

Namespace is the first part before the . of the Entity Identifier. Each combination of the Namespace and Entity type forms new Swimlane. The order how they are specified in the text definition specifies the order of the Swimlanes in the diagram.

eventmodeling

rf 01 evt Inventory.InventoryChanged
rf 02 evt External.InventoryChanged

Data block data types

A Data is always wrapped in curly brackets. It can be prepended by a data type in backticks. The pattern applies for Inline Data as well as for Data Block.

tf 01 rmo UserAdded `json`{ "name": "foo" }

or for Data Block

data UserAdded01 `json`{
"name": "foo"
}
There is no special treatment in the diagram renderer at the moment for a specific data type.

Supported types are:

  • json
  • jsobj
  • figma
  • salt
  • uri
  • md
  • html
  • text

Related Resources

There is an attempt to integrate the DSL into Mermaid.