Skip to content

Natural Language Syntax

EventFlow uses natural language patterns that read like English. This page covers all syntax patterns.

Actors (@)

Actors are referenced with @ inline, always lowercase:

flow
@customer clicks checkout
@sales_manager approves the order
@system sends notification
@payment_gateway processes the card

Events (:)

Events are referenced with : inline:

flow
on> :checkout from @customer
on :payment_success from @payment
emit :order_confirmed to @customer

States (#)

States are referenced with # inline:

flow
order moves to #checkout
payment enters #processing
document transitions to #approved
ticket becomes #closed

State Transition Keywords

All of these are equivalent - use what reads best:

KeywordExample
moves toorder moves to #paid
transitions toorder transitions to #approved
enterspayment enters #processing
becomesticket becomes #closed
changes tostatus changes to #active

Guards (?)

Guards are conditions that start with ? at the beginning of the line:

flow
? cart is not empty
  proceed to checkout

Multiple Guards (AND)

Multiple ? lines require ALL conditions to pass:

flow
? payment is authorized
? shipping is valid
? inventory is available
  complete the order

OR Guards

Use ?? for OR conditions:

flow
? user is admin
?? user has manager role
  show admin panel

Combined Logic

flow
? cart is valid
? user is logged in
?? user is guest with email
  allow checkout

Reads as: (cart is valid AND user is logged in) OR user is guest with email

Default Case

Use otherwise or empty ?:

flow
? status is pending
  process request
? status is approved
  send notification
otherwise
  log error

Or with empty ?:

flow
? status is pending
  process request
?
  handle other cases

Assertions (=)

Assertions start with = and appear in expect: blocks:

flow
expect:
  = order is in #processing
  = $total equals 1250
  = @customer received confirmation
  = payment was processed

Data Tables

Use tables for structured data:

flow
cart contains:
  | product     | quantity | price |
  | Laptop      | 1        | 1200  |
  | Mouse       | 2        | 25    |
  | Keyboard    | 1        | 75    |
flow
@customer enters shipping:
  | field   | value           |
  | street  | "123 Main St"   |
  | city    | "Springfield"   |
  | zip     | "62701"         |

Comments

flow
// single line comment

/*
  multi-line
  comment
*/

@customer clicks checkout  // inline comment

Event Patterns

Receiving Events

flow
// Public API endpoint
on> :checkout from @customer
  ...

// Internal event
on :payment_success from @payment
  ...

// From any sender
on :status_update
  ...

Sending Events

flow
// Basic emit
emit :payment_request to @payment

// With data
emit :payment_request to @payment
  with $order_id, $total

// With structured data
emit :order_details to @warehouse
  with:
    | field     | value       |
    | order_id  | $order_id   |
    | items     | $items      |
    | priority  | "high"      |

Context Patterns

Setting Values

flow
$total becomes 100
$name becomes "John"
$is_active becomes true
$items becomes empty

With Type Annotations

flow
$total: number becomes 100
$name: string becomes "John"
$is_active: boolean becomes true
$items: array becomes empty

Arithmetic

flow
$total increases by 25
$total decreases by 10
$count increases by 1

Collections

flow
$items adds "Laptop"
$items adds $new_item
$items removes "Mouse"
$items clears

Reading Values

flow
? $total is greater than 100
? $items contains "Laptop"
? $count equals 0
? $name is not empty

Comparison Operators

PatternMeaning
equalsEqual to
isEqual to
is notNot equal to
is greater thanGreater than
is less thanLess than
is at leastGreater than or equal
is at mostLess than or equal
containsArray/string contains
is emptyEmpty array/string
is not emptyNon-empty

State Checks

flow
? order is in #pending
? order is not in #cancelled
? payment has entered #processing

Time-Based Patterns

flow
? created more than 24 hours ago
? updated within last 1 hour
? days since purchase < 7

Natural Language Flexibility

EventFlow is designed to be flexible. These are equivalent:

flow
// All valid for state transitions
order moves to #paid
order transitions to #paid
order enters #paid
order becomes #paid

// All valid for comparisons
? $total equals 100
? $total is 100
? $total is equal to 100

The goal is readability - use what sounds most natural for your context.

Released under the MIT License.