Module: lib/compiler/rewind/writeSet

What an atomic action writes, and whether that answer is complete.

The journal does not need this. It observes the reactive proxies, so it sees every write an action makes whether or not anything predicted it. What needs this is the report: the developer asking "if this rolls back, what comes back with it?" — and, more sharply, "what does not?"

The walk is over the model Atlas already built. An action's own writes edges are the first hop; every invokes edge to another action contributes that action's write set in turn, which is how a component action that calls cart.addQty() is credited with the bridge state that call touches.

The completeness rule

A write set is bounded only when nothing in its closure was left unresolved for a reason that could be hiding a write. That flag is not decoration: AVX_W44 compares two write sets, and comparing an incomplete one would produce a warning that is a false positive and a false negative at the same time. Anything unbounded is excluded from that comparison and reported under AVX_W42 instead.

Source:

Members

(static, constant) MAX_INVOKE_DEPTH :number

How many invokes hops the closure follows.

Deep enough for a component action calling a bridge action that calls another, which is as far as an Avenx application usually reaches, and bounded so a pathological graph cannot make a build slow. Running out of depth makes the write set unbounded rather than silently short.

Type:
  • number
Source:

(inner, constant) BLOCKING_REASONS :Set:.<string:>

Unresolved reasons that could be concealing a write.

Deliberately the same list atlas/diagnostics.js blocks on, for the same reason: a dynamic member could be the write, a shadowed identifier means a body was not followed, a spread could carry a value out, and an unknown identifier could be the missing link. None can be ruled out.

Type:
  • Set:.<string:>
Source:

Methods

(static) collectAtomicActions(model) → {Array:.<{node:: object:, label:: string:, writes:: Array:.<string:>, bounded:: boolean:, reasons:: Array:.<object:>, depthExceeded:: boolean:}>}

Finds every atomic action in the model, with its write set.

Parameters:
Name Type Description
model object

The finished AppModel.

Source:
Returns:

One entry per atomic action, ordered by node id.

Type
Array:.<{node:: object:, label:: string:, writes:: Array:.<string:>, bounded:: boolean:, reasons:: Array:.<object:>, depthExceeded:: boolean:}>

(static) computeWriteSet(model, actionId) → {Object}

Computes what one action writes, following the actions it invokes.

Parameters:
Name Type Description
model object

The finished AppModel.

actionId string

The action's node id.

Source:
Returns:

The write set, whether it is complete, and why it is not when it is not.

Type
Object

(static) invokes(model, fromId, toId) → {boolean}

Whether one action can reach another by invoking it.

Used to keep AVX_W44 off a caller and its callee. Their write sets overlap by construction — the caller's set contains the callee's — and they cannot interleave harmfully, because a nested transaction joins the enclosing frame rather than opening a second one. Warning about that pair would report the feature working as designed.

Parameters:
Name Type Description
model object

The finished AppModel.

fromId string

The possible caller.

toId string

The possible callee.

Source:
Returns:

True when fromId reaches toId.

Type
boolean

(inner) writeTarget(model, edge) → {string}

Renders one write as the string the reports and the overlap check compare.

Parameters:
Name Type Description
model object

The model.

edge object

A writes edge.

Source:
Returns:

A readable target, e.g. cart.items[].qty.

Type
string