Version v2.0.0 Size 1.4 KB gzip Dependencies Zero dependencies
Why Sentinel?
Browser environment APIs use different events, observer callbacks, initial states, and cleanup methods. Sentinel gives them one explicit handle shape and exposes current values as Ripple Readable<T> signals.
ts
// Before
{
const panel = document.querySelector<HTMLElement>('[data-panel]');
if (!panel) throw new Error('Panel not found');
const observer = new ResizeObserver(([entry]) => {
console.log(entry?.contentRect.width);
});
observer.observe(panel);
// Later
observer.disconnect();
}
// After
import { createElementSize } from '@vielzeug/sentinel';
{
const panel = document.querySelector<HTMLElement>('[data-panel]');
if (!panel) throw new Error('Panel not found');
const size = createElementSize(panel);
const unsubscribe = size.subscribe(() => {
console.log(size.value?.width);
});
// Later
unsubscribe();
size.dispose();
}| Feature | Sentinel | Native observer APIs | Ad hoc event listeners |
|---|---|---|---|
| Bundle size | 1.4 KB | Built in | Application-defined |
| Zero dependencies | |||
| Reactive current state | |||
| Consistent disposable handle | |||
| Shared abort ownership | |||
| Ripple composition |
Use Sentinel when browser or DOM observations need reactive state, consistent ownership, and composition with Ripple.
Consider native APIs when one isolated observer is sufficient and adding Ripple as a peer dependency is not justified.
Installation
sh
pnpm add @vielzeug/sentinel @vielzeug/ripplesh
npm install @vielzeug/sentinel @vielzeug/ripplesh
yarn add @vielzeug/sentinel @vielzeug/rippleQuick Start
Create a viewport Sentinel, render its initial state, then react to changes until the page lifetime ends.
ts
import { createViewport } from '@vielzeug/sentinel';
function observeViewport(): () => void {
const viewport = createViewport();
const render = () => {
const { dpr, height, width } = viewport.value;
console.log(`${width}×${height} at ${dpr}dpr`);
};
render();
const unsubscribe = viewport.subscribe(render);
return () => {
unsubscribe();
viewport.dispose();
};
}
const stopObserving = observeViewport();
// Call stopObserving() when the owning view unmounts.Features
createViewport()— Observe viewport dimensions and device pixel ratio.createNetwork()— Track online status and optional connection details.createMediaQuery()— Observe one media query.createElementSize()— Read content-box dimensions fromResizeObserver.createIntersection()— Track normalized intersection state.dispose()— Release owned browser observers and listeners.SentinelOptions.signal— Abort several Sentinels through one external lifetime.
Documentation
See Also
- @vielzeug/ripple — Derive and watch values from Sentinel state.
- @vielzeug/ore — Bind Sentinels to web-component mount and cleanup lifecycles.
- @vielzeug/focus — Manage keyboard focus alongside observed UI state.
- @vielzeug/gesture — Handle pointer gestures alongside environmental observations.