Overview
action wraps a synchronous function and adds observability: subscribers that fire on every call, before/after interceptors for validation and result enrichment, and a consistent callable interface.
The result is still returned synchronously — wrapping a function in action does not change its calling behavior. What you gain is a centralized execution point with hooks for analytics, logging, and side-channel effects without coupling them at the call site.
Subscribe with .__subscribe(fn) (not .subscribe — that name belongs to asyncAction).
action — intercept, subscribe, and set()
Empty input is blocked by interceptBefore (not a custom guard at the click handler). interceptAfter stamps char count. __subscribe logs every success. save.set() swaps the implementation without dropping interceptors or subscribers.
interceptBefore / interceptAfter
Before interceptor trims + uppercases; empty input throws. After interceptor tags the result. Subscriber sees the enriched value.