Creates a React context + hook pair bound to a specific ObserverEngine instance.
Returns a [Provider, useHook] tuple — rename to whatever fits your domain.
function UserStatus() {
const { on, once, oncePromise, emit, emitFactory } = useApiObserver();
// Subscribe — re-subscribes if callback identity changes,
// so wrap handlers with useCallback to keep them stable
const handler = useCallback((data) => {
console.log('logged in:', data.userId);
}, []);
on('user.login', handler);
// One-shot listener with a callback
const initHandler = useCallback((data) => {
console.log('init:', data);
}, []);
once('app.init', initHandler);
// One-shot listener as a reactive tuple (no callback needed)
const [waiting, data, cancel] = oncePromise('notification');
// waiting: true until the event fires, then false
// data: null until resolved, then the event payload
// cancel: call to stop listening early
// Fire events — emit is already stable (bound to engine)
emit('user.logout', { userId: '123' });
// Or get a memoized emitter for a specific event
const logout = emitFactory('user.logout');
// <button onClick={() => logout({ userId: '123' })} />
return <div>{waiting ? 'Waiting...' : data?.message}</div>;
}
Rules:on, once, oncePromise, and emitFactory call React hooks
internally, so they follow the same rules as hooks — call them at the
top level of your component, never conditionally or in loops.
Creates a React context + hook pair bound to a specific ObserverEngine instance. Returns a
[Provider, useHook]tuple — rename to whatever fits your domain.Setup (run once, e.g. in a
setup.tsfile):Wrap your app (providers need no props — instance is captured):
Use in components:
Rules:
on,once,oncePromise, andemitFactorycall React hooks internally, so they follow the same rules as hooks — call them at the top level of your component, never conditionally or in loops.