Detailed notes
- There is no separate async API mode: Promise, Observable, and Expression values go through the same observation pipeline as other values.
- Metadata is used at concrete decision points: ValueMetadata.isAsync(...) is checked in indexed observer factories to attach async observers, and ValueMetadata.needsProxy(...) is checked in IdentifierExpression to decide recursive proxying for member paths.
- PENDING is internal runtime state used while async values are unresolved; it is not a user-facing expression value.
- Promise observers cache resolved values and emit property changes when resolution arrives.
- Observable observers cache emissions, dedupe consecutive equal values, and emit through state manager.
- Expression observers forward expression.changed into the same property-change pipeline used by Promise/Observable.
- State manager wraps async updates in startChangeCycle/endChangeCycle, and transaction commit is deferred until cycle depth returns to zero.