useBloc connects a bloc to a React component. But state often needs to reach code that has no component to render: a logger, an analytics pipeline, a localStorage sync, a <canvas> driven by an imperative library, or a test assertion. watch is the escape hatch for those cases — it observes one or more blocs outside of React and runs a callback whenever their state changes.
Runs once immediately with the current instance(s), then on every subsequent state change. Return watch.STOP to tear down the subscription from inside the callback.
Returns: a stop() function. Calling it unsubscribes and is idempotent — calling it more than once is safe.
Behavior.watchacquires each input from the registry with a counted ref — creating the instance if it does not exist yet. That ref keeps an otherwise-unused bloc alive for as long as the watch is active, and is dropped when you call stop() or return watch.STOP. If the instance is disposed elsewhere anyway (e.g. by clearAll()), watch re-acquires and resubscribes on the next microtask, then runs the callback again. Subscriptions are coalesced per microtask flush — several synchronous mutations produce a single callback run — so callbacks land asynchronously after emit(). The callback fires once immediately on setup with the current state, then again after every subsequent change.
Cubit<S> is a StateContainer<S> with emit / patch exposed as
public mutation surface. Today it adds nothing structurally beyond
StateContainer — both are inherited from the underlying
StructuralContainer<S>. Kept as a real class (not a type alias) because
downstream code does instance instanceof Cubit checks.
The class body is intentionally empty: a no-op emit override would
still go through applyState, and patch is inherited from
StructuralContainer (path-diffed, microtask-flushed). A caller that
wants "skip if no real change" patch semantics can wrap patch
themselves or call emit after a manual equality check.
Cubit<S> is a StateContainer<S> with emit / patch exposed as
public mutation surface. Today it adds nothing structurally beyond
StateContainer — both are inherited from the underlying
StructuralContainer<S>. Kept as a real class (not a type alias) because
downstream code does instance instanceof Cubit checks.
The class body is intentionally empty: a no-op emit override would
still go through applyState, and patch is inherited from
StructuralContainer (path-diffed, microtask-flushed). A caller that
wants "skip if no real change" patch semantics can wrap patch
themselves or call emit after a manual equality check.
Cubit<S> is a StateContainer<S> with emit / patch exposed as
public mutation surface. Today it adds nothing structurally beyond
StateContainer — both are inherited from the underlying
StructuralContainer<S>. Kept as a real class (not a type alias) because
downstream code does instance instanceof Cubit checks.
The class body is intentionally empty: a no-op emit override would
still go through applyState, and patch is inherited from
StructuralContainer (path-diffed, microtask-flushed). A caller that
wants "skip if no real change" patch semantics can wrap patch
themselves or call emit after a manual equality check.
Cubit<S> is a StateContainer<S> with emit / patch exposed as
public mutation surface. Today it adds nothing structurally beyond
StateContainer — both are inherited from the underlying
StructuralContainer<S>. Kept as a real class (not a type alias) because
downstream code does instance instanceof Cubit checks.
The class body is intentionally empty: a no-op emit override would
still go through applyState, and patch is inherited from
StructuralContainer (path-diffed, microtask-flushed). A caller that
wants "skip if no real change" patch semantics can wrap patch
themselves or call emit after a manual equality check.
Cubit<S> is a StateContainer<S> with emit / patch exposed as
public mutation surface. Today it adds nothing structurally beyond
StateContainer — both are inherited from the underlying
StructuralContainer<S>. Kept as a real class (not a type alias) because
downstream code does instance instanceof Cubit checks.
The class body is intentionally empty: a no-op emit override would
still go through applyState, and patch is inherited from
StructuralContainer (path-diffed, microtask-flushed). A caller that
wants "skip if no real change" patch semantics can wrap patch
themselves or call emit after a manual equality check.
Cubit<S> is a StateContainer<S> with emit / patch exposed as
public mutation surface. Today it adds nothing structurally beyond
StateContainer — both are inherited from the underlying
StructuralContainer<S>. Kept as a real class (not a type alias) because
downstream code does instance instanceof Cubit checks.
The class body is intentionally empty: a no-op emit override would
still go through applyState, and patch is inherited from
StructuralContainer (path-diffed, microtask-flushed). A caller that
wants "skip if no real change" patch semantics can wrap patch
themselves or call emit after a manual equality check.
Cubit<S> is a StateContainer<S> with emit / patch exposed as
public mutation surface. Today it adds nothing structurally beyond
StateContainer — both are inherited from the underlying
StructuralContainer<S>. Kept as a real class (not a type alias) because
downstream code does instance instanceof Cubit checks.
The class body is intentionally empty: a no-op emit override would
still go through applyState, and patch is inherited from
StructuralContainer (path-diffed, microtask-flushed). A caller that
wants "skip if no real change" patch semantics can wrap patch
themselves or call emit after a manual equality check.
Cubit<S> is a StateContainer<S> with emit / patch exposed as
public mutation surface. Today it adds nothing structurally beyond
StateContainer — both are inherited from the underlying
StructuralContainer<S>. Kept as a real class (not a type alias) because
downstream code does instance instanceof Cubit checks.
The class body is intentionally empty: a no-op emit override would
still go through applyState, and patch is inherited from
StructuralContainer (path-diffed, microtask-flushed). A caller that
wants "skip if no real change" patch semantics can wrap patch
themselves or call emit after a manual equality check.
Cubit<S> is a StateContainer<S> with emit / patch exposed as
public mutation surface. Today it adds nothing structurally beyond
StateContainer — both are inherited from the underlying
StructuralContainer<S>. Kept as a real class (not a type alias) because
downstream code does instance instanceof Cubit checks.
The class body is intentionally empty: a no-op emit override would
still go through applyState, and patch is inherited from
StructuralContainer (path-diffed, microtask-flushed). A caller that
wants "skip if no real change" patch semantics can wrap patch
themselves or call emit after a manual equality check.
Cubit<S> is a StateContainer<S> with emit / patch exposed as
public mutation surface. Today it adds nothing structurally beyond
StateContainer — both are inherited from the underlying
StructuralContainer<S>. Kept as a real class (not a type alias) because
downstream code does instance instanceof Cubit checks.
The class body is intentionally empty: a no-op emit override would
still go through applyState, and patch is inherited from
StructuralContainer (path-diffed, microtask-flushed). A caller that
wants "skip if no real change" patch semantics can wrap patch
themselves or call emit after a manual equality check.
Cubit<S> is a StateContainer<S> with emit / patch exposed as
public mutation surface. Today it adds nothing structurally beyond
StateContainer — both are inherited from the underlying
StructuralContainer<S>. Kept as a real class (not a type alias) because
downstream code does instance instanceof Cubit checks.
The class body is intentionally empty: a no-op emit override would
still go through applyState, and patch is inherited from
StructuralContainer (path-diffed, microtask-flushed). A caller that
wants "skip if no real change" patch semantics can wrap patch
themselves or call emit after a manual equality check.
Cubit<S> is a StateContainer<S> with emit / patch exposed as
public mutation surface. Today it adds nothing structurally beyond
StateContainer — both are inherited from the underlying
StructuralContainer<S>. Kept as a real class (not a type alias) because
downstream code does instance instanceof Cubit checks.
The class body is intentionally empty: a no-op emit override would
still go through applyState, and patch is inherited from
StructuralContainer (path-diffed, microtask-flushed). A caller that
wants "skip if no real change" patch semantics can wrap patch
themselves or call emit after a manual equality check.
Cubit<S> is a StateContainer<S> with emit / patch exposed as
public mutation surface. Today it adds nothing structurally beyond
StateContainer — both are inherited from the underlying
StructuralContainer<S>. Kept as a real class (not a type alias) because
downstream code does instance instanceof Cubit checks.
The class body is intentionally empty: a no-op emit override would
still go through applyState, and patch is inherited from
StructuralContainer (path-diffed, microtask-flushed). A caller that
wants "skip if no real change" patch semantics can wrap patch
themselves or call emit after a manual equality check.
Cubit<{
items:CartItem[]
items:
interfaceCartItem
CartItem[] }>{
constructor(){
super({
items:CartItem[]
items: [] });
}
get
CartCubit.total: number
total(){
returnthis.
StructuralContainer<{items:CartItem[];}>.state: {
items:CartItem[];
}
state.
items:CartItem[]
items.
Array<CartItem>.reduce<number>(callbackfn: (previousValue: number,currentValue: CartItem,currentIndex: number,array: CartItem[])=>number,initialValue: number): number (+2overloads)
Calls the specified callback function for all the elements in an array. The return value of the callback function is the accumulated result, and is provided as an argument in the next call to the callback function.
@param ― callbackfn A function that accepts up to four arguments. The reduce method calls the callbackfn function one time for each element in the array.
@param ― initialValue If initialValue is specified, it is used as the initial value to start the accumulation. The first call to the callbackfn function provides this value as an argument instead of an array value.
Cubit<S> is a StateContainer<S> with emit / patch exposed as
public mutation surface. Today it adds nothing structurally beyond
StateContainer — both are inherited from the underlying
StructuralContainer<S>. Kept as a real class (not a type alias) because
downstream code does instance instanceof Cubit checks.
The class body is intentionally empty: a no-op emit override would
still go through applyState, and patch is inherited from
StructuralContainer (path-diffed, microtask-flushed). A caller that
wants "skip if no real change" patch semantics can wrap patch
themselves or call emit after a manual equality check.
Cubit<S> is a StateContainer<S> with emit / patch exposed as
public mutation surface. Today it adds nothing structurally beyond
StateContainer — both are inherited from the underlying
StructuralContainer<S>. Kept as a real class (not a type alias) because
downstream code does instance instanceof Cubit checks.
The class body is intentionally empty: a no-op emit override would
still go through applyState, and patch is inherited from
StructuralContainer (path-diffed, microtask-flushed). A caller that
wants "skip if no real change" patch semantics can wrap patch
themselves or call emit after a manual equality check.
Cubit<{
series:number[]
series: number[] }>{
constructor(){
super({
series:number[]
series: [] });
}
}
declarefunction
functioncreateChart(el: HTMLElement):{
setData(series: number[]): void;
destroy(): void;
}
createChart(
el:HTMLElement
el:
interfaceHTMLElement
The HTMLElement interface represents any HTML element. Some elements directly implement this interface, while others implement it via an interface that inherits it.
The HTMLElement interface represents any HTML element. Some elements directly implement this interface, while others implement it via an interface that inherits it.
Both observe a single container outside React; both fire once per microtask flush. The differences:
watch gives you the instance (so getters and methods are available), accepts multiple blocs, supports instance() references and the watch.STOP sentinel, and fires once immediately on setup.
channel.subscribe is the lower-level path-scoped surface on a container’s channel. You pass an interest thunk (the paths you care about, or ALL_PATHS for everything) and a callback that fires when a matching path changes. It does not fire on setup and gives you the changed path set rather than the instance — read state off the container yourself. Prefer watch for whole-state observation; reach for channel.subscribe when you need path-scoped interest.
Cubit<S> is a StateContainer<S> with emit / patch exposed as
public mutation surface. Today it adds nothing structurally beyond
StateContainer — both are inherited from the underlying
StructuralContainer<S>. Kept as a real class (not a type alias) because
downstream code does instance instanceof Cubit checks.
The class body is intentionally empty: a no-op emit override would
still go through applyState, and patch is inherited from
StructuralContainer (path-diffed, microtask-flushed). A caller that
wants "skip if no real change" patch semantics can wrap patch
themselves or call emit after a manual equality check.
Cubit<S> is a StateContainer<S> with emit / patch exposed as
public mutation surface. Today it adds nothing structurally beyond
StateContainer — both are inherited from the underlying
StructuralContainer<S>. Kept as a real class (not a type alias) because
downstream code does instance instanceof Cubit checks.
The class body is intentionally empty: a no-op emit override would
still go through applyState, and patch is inherited from
StructuralContainer (path-diffed, microtask-flushed). A caller that
wants "skip if no real change" patch semantics can wrap patch
themselves or call emit after a manual equality check.
channel.subscribe is inherited from StructuralContainer (the structural layer under every Cubit) — watch is a thin wrapper around it (channel.subscribe(() => ALL_PATHS, ...) plus instance resolution, an immediate fire, and watch.STOP).
A thunk returning the region this subscriber cares about, re-evaluated lazily, once per flush. Return ALL_PATHS to be woken by everything.
cb
(dirty: PathSet) => void
Runs when dirty intersects interest(). container.state already reflects the new value when this fires.
returns
() => void
Idempotent unsubscribe.
ALL_PATHS (value) and the PathSet type are public, re-exported from @blac/core specifically so plugins can compose channel subscriptions. Minting a specificSet<PathId> requires the per-class PathInterner, which is @internal and not re-exported — so the only portable interest you can build from outside the framework is ALL_PATHS. The fine-grained Set<PathId> form is what useBloc’s render tracker assembles for itself; see Tracking.
Errors from a subscriber’s cb or interest thunk are collected, not swallowed: after all subscribers for a flush have run, a single error rethrows as-is, and multiple throw together as an AggregateError.
Reach for channel.subscribe only when composing directly on the channel (plugins, devtools, infra):
Both take a callback that runs on state change. They differ in setup semantics:
watch resolves the instance itself via acquire (creating it if needed), fires the callback once immediately with the current state, and holds a counted registry ref until you stop it — so it keeps the instance alive.
observe takes a live instance you already hold, does not fire on subscribe, and adds no registry ref — so it never keeps the instance alive. It is for hand-managed subscriptions against an instance whose lifecycle you’re not driving through watch.
The ref is the difference that bites: an observed instance can be disposed under you at refcount 0 (the subscription then tears itself down), whereas a watched one cannot go away while the watch is active.
Both are microtask-coalesced: several synchronous emits in one tick deliver a single callback call with the latest state.
Subscribe to every state change of a LIVE container instance, without the
immediate first call and without taking a registry ref.
Contrast with watch: watch fires once on subscribe AND holds a ref that
keeps the instance alive. observe does neither — it is for hand-managed
subscriptions against an instance you already hold.
Delivery is microtask-coalesced by the container's channel scheduler: several
emits in one tick deliver ONE call carrying the latest state.
Cubit<S> is a StateContainer<S> with emit / patch exposed as
public mutation surface. Today it adds nothing structurally beyond
StateContainer — both are inherited from the underlying
StructuralContainer<S>. Kept as a real class (not a type alias) because
downstream code does instance instanceof Cubit checks.
The class body is intentionally empty: a no-op emit override would
still go through applyState, and patch is inherited from
StructuralContainer (path-diffed, microtask-flushed). A caller that
wants "skip if no real change" patch semantics can wrap patch
themselves or call emit after a manual equality check.
Cubit<S> is a StateContainer<S> with emit / patch exposed as
public mutation surface. Today it adds nothing structurally beyond
StateContainer — both are inherited from the underlying
StructuralContainer<S>. Kept as a real class (not a type alias) because
downstream code does instance instanceof Cubit checks.
The class body is intentionally empty: a no-op emit override would
still go through applyState, and patch is inherited from
StructuralContainer (path-diffed, microtask-flushed). A caller that
wants "skip if no real change" patch semantics can wrap patch
themselves or call emit after a manual equality check.
Ensure an instance exists without taking ownership (no ref added). Instance
identity is derived purely from args, matching acquire.
ensure(
classUserCubit
UserCubit);
// observe: no immediate fire, no ref — for an instance you already hold
const
conststopObserving:()=> void
stopObserving=
observe<{
name: string;
}>(instance: StateContainer<{
name: string;
}, any, any>,listener:(state: Readonly<{
name: string;
}>)=> void):()=>void
Subscribe to every state change of a LIVE container instance, without the
immediate first call and without taking a registry ref.
Contrast with watch: watch fires once on subscribe AND holds a ref that
keeps the instance alive. observe does neither — it is for hand-managed
subscriptions against an instance you already hold.
Delivery is microtask-coalesced by the container's channel scheduler: several
emits in one tick deliver ONE call carrying the latest state.
observe(
constuser: UserCubit
user,(
state:Readonly<{
name: string;
}>
state)=>{
varconsole: Console
console.
Console.log(...data: any[]): void
The console.log() static method outputs a message to the console.