Jadpo is experimental and not ready for production. These docs follow the compiler's main branch as of 30 Oct 2026. What's built · Install 0.1.0
jadpo
Reference: Jobs and events

Jobs and events

Subscribers

On this page

A subscriber reacts to an event: each time the event is committed, it runs an action. It names one event in on: and the action to run in run:. Inside run:, event is the event delivered.

domains/planning/subscribers/update_statistics.jadpo:

example
// domains/planning/subscribers/update_statistics.jadposubscriber update_statistics {    on: TodoCompleted    run: count_completion(event)}

What a subscriber holds

A subscriber holds three things, and nothing else (subscriber.item_invalid):

  • on:, the event type. Another domain's event must be public and imported.
  • run:, a call of an action in the subscriber's own domain (subscriber.run_invalid). Its arguments are event or fields read through it, such as event.todo_id (subscriber.argument_invalid), and they are type-checked against the action's parameters.
  • retry:, optionally (Retries and giving up).

One event each

A subscriber listens for one event. To react to two events, write two subscribers.

Each subscriber on its own

Every subscriber of an event gets its own delivery. One failing doesn't affect the others. Nothing that happens in a subscriber reaches the action that emitted the event, which has already committed and returned. A subscriber's action may emit further events.

Runs as the system

A subscriber runs as the system (Access.system, Background work), not as the user who caused the event. If it needs to know who, put a field such as by: User.id in the event.

What a subscriber stores from its event

Jadpo checks that a subscriber doesn't store a value from its event where people who may not read the value could see it.

What an event carries is everything any emit of it put there, apart from what a request sent. Along a chain of events, it also includes what a subscriber's action emits from the event it was given. That is because each action's emits, and those of the actions it calls, count as part of what it passes to its callers.

What the subscriber's action stores from what it is passed is checked where the subscriber passes it, as a call is (Policy), and refused with policy.output_field_unproved at the argument. What decided an emit, and any reject in its action, go with every field of the event.

A value from an event has left its record

The record a value came from may change or move between the emit and the delivery. So a value an event carries is checked as though it came from any record of its entity. Of the field's readers, only "anyone signed in" and roles held across the whole app carry over.

The one link kept is the tenant. When the event's tenant field came from the same record as a value, that record was the tenant's, and the subscriber is limited to that tenant. So the value may be stored wherever that tenant's roles may read it.

A subscriber that needs more passes the event's ids and reads the current state, as Declaring an event advises.

Markdown for agents: /docs/subscribers.md.Built from Jadpo main at a707efb.