AppSpring Docs

Effects (EffectDecl)

Generated from the doc schema (CatalogDocSchema, @canonify/kernel-catalog/doc): each field’s type, default and description are the schema’s own, and each example is a bundle file that readBundle decodes. A field’s Example is its value in one of those examples.

EffectDecl

An effect: one write, delivery, name or call, in order.

One of, told apart by op:

EffectDecl.create

Create a row.

Field Type Required Default Example Description
op "create" yes — "create" Create a row.
when Expr no — "input.amount > 0" The effect runs only while this CX condition holds; absent = always. Unknown refuses the call.
type TypeId yes — "ty_9d4r7t1x5b" The type of the new row.
set Record<PropId, Expr> yes — {"pr_0q2s4v6x8z":"this","pr_7e9g1j3m5p":"input.amount"} The CX value of each property it sets, by property id.
as Ident no — "line" The name later effects and outputs read the new row by.

An item of effects in an action file (or in an effects function’s body).

{
  "op": "create",
  "type": "ty_9d4r7t1x5b",
  "set": { "pr_0q2s4v6x8z": "this", "pr_7e9g1j3m5p": "input.amount" },
  "as": "line"
}

An item of effects in an action file (or in an effects function’s body).

{
  "op": "create",
  "type": "ty_9d4r7t1x5b",
  "when": "input.amount > 0",
  "set": { "pr_0q2s4v6x8z": "this", "pr_7e9g1j3m5p": "input.amount" }
}

EffectDecl.update

Update a row.

Field Type Required Default Example Description
op "update" yes — "update" Update a row.
when Expr no — "input.note != ''" The effect runs only while this CX condition holds; absent = always. Unknown refuses the call.
target Expr yes — "this" The row it updates: a CX ref.
set Record<PropId, Expr> yes — {"pr_4p6r8t0v2x":"input.note"} The CX value of each property it sets, by property id.
omitAbsent true no — true A property whose value is absent is left as it is, not cleared.

An item of effects in an action file (or in an effects function’s body).

{
  "op": "update",
  "target": "this",
  "when": "input.note != ''",
  "set": { "pr_4p6r8t0v2x": "input.note" },
  "omitAbsent": true
}

EffectDecl.delete

Delete a row.

Field Type Required Default Example Description
op "delete" yes — "delete" Delete a row.
when Expr no — "isSet(input.line)" The effect runs only while this CX condition holds; absent = always. Unknown refuses the call.
target Expr yes — "input.line" The row it deletes: a CX ref.

An item of effects in an action file (or in an effects function’s body).

{ "op": "delete", "target": "input.line", "when": "isSet(input.line)" }

EffectDecl.transition

Move a row along its lifecycle.

Field Type Required Default Example Description
op "transition" yes — "transition" Move a row along its lifecycle.
when Expr no — "input.cancel" The effect runs only while this CX condition holds; absent = always. Unknown refuses the call.
target Expr yes — "this" The row it moves: a CX ref.
lifecycle FsmId yes — "lc_2k4m6p8r0t" The lifecycle.
transition TransitionId yes — "tn_4g6j8m0p2r" The transition of that lifecycle.

An item of effects in an action file (or in an effects function’s body).

{
  "op": "transition",
  "target": "this",
  "when": "input.cancel",
  "lifecycle": "lc_2k4m6p8r0t",
  "transition": "tn_6s8v0x2z4b"
}

EffectDecl.emit

Send a delivery after the commit.

Field Type Required Default Example Description
op "emit" yes — "emit" Send a delivery after the commit: the only I/O.
when Expr no — "isSet(input.notify)" The effect runs only while this CX condition holds; absent = always. Unknown refuses the call.
to string (matching ^[a-z][a-z0-9_]*(\.[a-z][a-z0-9_]*)*$) yes — "webhook.post" A delivery operation: the only I/O, sent after commit (e.g. webhook.post).
input Record<string, Expr> yes — {"url":"'https://example.com/hooks/orders'","body":"id"} The CX value of each input of the delivery operation.
maps Record<string, Record<string (matching ^[A-Za-z][A-Za-z0-9_]*$), Expr>> no — {"params":{"order_no":"number","total":"total"}} The inputs that hold an object (e.g. params, or a webhook body): each field name with its CX value.

An item of effects in an action file (or in an effects function’s body).

{
  "op": "emit",
  "to": "webhook.post",
  "when": "isSet(input.notify)",
  "input": { "url": "'https://example.com/hooks/orders'", "body": "id" }
}

An item of effects in an action file (or in an effects function’s body).

{
  "op": "emit",
  "to": "email.send_template",
  "input": { "recipient": "customer.email", "template_id": "'order_sent'" },
  "maps": { "params": { "order_no": "number", "total": "total" } }
}

EffectDecl.let

Name a value for the effects after it.

Field Type Required Default Example Description
op "let" yes — "let" Name a value.
name Ident yes — "net" The name later effects read it by.
value Expr yes — "total * 0.8" The CX value.
rights Elevated no — (see the example) A widened read: the value is one aggregate over rows the invoker may not read.

An item of effects in an action file (or in an effects function’s body).

{ "op": "let", "name": "net", "value": "total * 0.8" }

An item of effects in an action file (or in an effects function’s body).

{
  "op": "let",
  "name": "open_orders",
  "value": "count(customer.orders)",
  "rights": {
    "discloses": "count",
    "reason": { "text": "The order count is shown to every clerk." }
  }
}

EffectDecl.allocate

Place an amount over rows in order.

Field Type Required Default Example Description
op "allocate" yes — "allocate" Place an amount over rows in order, each row up to its cap.
when Expr no — "input.amount > 0" The effect runs only while this CX condition holds; absent = always. Unknown refuses the call.
amount Expr yes — "input.amount" The amount it places: a CX number, quantity or money. Blank refuses the call; zero places nothing.
over Expr yes — "customer.orders" The rows it places the amount over: a CX collection of rows.
each Ident yes — "o" The name the cap and the order keys read each row by.
cap Expr yes — "o.total" The most a row takes: a CX value of the amount’s type over the row. Blank or zero takes nothing.
order SortKey[] (at least one) yes — [{"by":"o.created_at","desc":true}] The order the rows take their shares in: the first key decides, then the next; ties by the row.
remainder "refuse" | "keep" yes — "keep" refuse: an amount the rows cannot hold refuses the call; keep: what is left stays unplaced.
as Ident yes — "paid" The name later effects and outputs read the shares by: the rows that took a share, each with its share.
message MsgRef no — (see the example) What the refusal says when the rows cannot hold the amount (remainder refuse only).

An item of effects in an action file (or in an effects function’s body).

{
  "op": "allocate",
  "when": "input.amount > 0",
  "amount": "input.amount",
  "over": "customer.orders.where(o => o.status == 'placed')",
  "each": "o",
  "cap": "o.total",
  "order": [{ "by": "o.created_at" }, { "by": "o.total", "desc": true }],
  "remainder": "refuse",
  "as": "paid",
  "message": {
    "text": "The open orders take only {placed} of the payment.",
    "params": { "placed": "paid.sum(s => s.share)" }
  }
}

EffectDecl.call

Run a shared effects function.

Field Type Required Default Example Description
op "call" yes — "call" Run an effects function.
when Expr no — "input.close" The effect runs only while this CX condition holds; absent = always. Unknown refuses the call.
fn FnId yes — "fn_5j7m9p1r3t" The effects function.
with Record<Ident, Expr> yes — {"order":"this"} The CX value of each parameter.

An item of effects in an action file (or in an effects function’s body).

{
  "op": "call",
  "fn": "fn_5j7m9p1r3t",
  "when": "input.close",
  "with": { "order": "this" }
}

EffectDecl.forEach

Run effects once per item of a bounded collection.

Field Type Required Default Example Description
op "forEach" yes — "forEach" Run the body once per item of a collection.
over Expr yes — "input.lines" The collection: a CX collection, at most limit items.
as Ident yes — "item" The name the body reads the item by.
limit integer (greater than 0) yes — 50 The most items it runs over; more is invoke.foreach_limit. Required: every write has a static bound (P7).
preconditions ItemPreconditionDecl[] no — (see the example) The conditions each item needs, checked before the body runs for it.
body EffectDecl[] yes — (see the example) The effects run for each item.

An item of effects in an action file (or in an effects function’s body).

{
  "op": "forEach",
  "over": "input.lines",
  "as": "item",
  "limit": 50,
  "preconditions": [
    {
      "id": "positive_amount",
      "holds": "item.amount > 0",
      "severity": "refuse",
      "message": { "text": "Each line needs an amount above zero." }
    }
  ],
  "body": [
    {
      "op": "create",
      "type": "ty_9d4r7t1x5b",
      "set": { "pr_0q2s4v6x8z": "this", "pr_7e9g1j3m5p": "item.amount" }
    }
  ]
}

SortKey

One key of the order.

Field Type Required Default Example Description
by Expr yes — "o.created_at" The CX key over the row; a blank key sorts first ascending, last descending.
desc true no — true Descending; absent = ascending.

An item of order in an allocate effect of an action file.

{ "by": "o.created_at", "desc": true }

This page as Markdown