Noiseless Praying Mantis

    TypeScript icon, indicating that this package has built-in type declarations

    2.1.10 • Public • Published



    A collection of reactive wrappers for various browser APIs.


    This package provides factory functions which can be used to turn browser APIs into subscribable things. A subscribable thing can either be consumed directly with callback functions or by utilzing one of the popular libraries for reactive programming.


    The subscribable-things package is published on npm and can be installed as usual.

    npm install subscribable-things

    It exports individual functions for each wrapped browser API which are described in greater detail below. They can either be used directly by providing a callback function ...

    import { mediaQueryMatch } from 'subscribable-things';
    const subscribe = mediaQueryMatch('(max-width:600px)');
    const unsubscribe = subscribe((isMatching) => console.log(isMatching));

    ... or by utilizing a library for reactive programming like RxJS ...

    import { from } from 'rxjs';
    import { mediaQueryMatch } from 'subscribable-things';
    const mediaQueryMatch$ = from(mediaQueryMatch('(max-width:600px)'));
    const subscription = mediaQueryMatch$.subscribe((isMatching) => console.log(isMatching));

    ... or Callbags ...

    import fromObs from 'callbag-from-obs';
    import observe from 'callbag-observe';
    import { mediaQueryMatch } from 'subscribable-things';
    const source = fromObs(mediaQueryMatch('(max-width:600px)'));
    observe((isMatching) => console.log(isMatching))(source);

    ... or XStream ...

    import { mediaQueryMatch } from 'subscribable-things';
    import { fromObservable } from 'xstream';
    const stream = fromObservable(mediaQueryMatch('(max-width:600px)'));
    const unsubscribe = stream.subscribe((isMatching) => console.log(isMatching));

    ... or Bacon.js ...

    import { fromESObservable } from 'baconjs';
    import { mediaQueryMatch } from 'subscribable-things';
    const eventStream = fromESObservable(mediaQueryMatch('(max-width:600px)'));
    const unsubscribe = eventStream.onValue((isMatching) => console.log(isMatching));

    ... or Kefir.js.

    import { fromESObservable } from 'kefir';
    import { mediaQueryMatch } from 'subscribable-things';
    const stream = fromESObservable(mediaQueryMatch('(max-width:600px)'));
    const subscription = stream.observe({
        value(isMatching) {

    It is even possible to consume subscribable-things as an async iterable by taking the little detour over RxJS and rxjs-for-await.

    import { eachValueFrom } from 'rxjs-for-await';
    import { from } from 'rxjs';
    import { mediaQueryMatch } from 'subscribable-things';
    const source$ = from(mediaQueryMatch('(max-width:600px)'));
    for await (const isMatching of eachValueFrom(source$)) {

    Also it's possible to output values directly to HTML via hyperf.

    import h from 'hyperf';
    import { mediaQueryMatch } from 'subscribable-things';
    const element = h`<div>is matching: ${mediaQueryMatch('(max-width:600px)')}</div>`;


    function animationFrame(): SubscribableThing<number>;

    This function wraps the requestAnimationFrame() method. It emits the current timestamp of each animation frame.

    attribute(htmlElement, name)

    function attribute(htmlElement: HTMLElement, name: string): TSubscribableThing<null | string>;

    This function uses mutations() on the inside to emit the latest value of the attribute with the given name.


    function geolocation(options?: PositionOptions): SubscribableThing<GeolocationPosition>;

    This is a wrapper for the Geolocation API. It uses watchPosition() to gather the most recent GeolocationPosition whenever it changes.

    intersections(htmlElement, [options])

    function intersections(
        htmlElement: HTMLElement,
        options?: IntersectionObserverInit
    ): SubscribableThing<IntersectionObserverEntry[]>;

    This function is a wrapper for the IntersectionObserver.


    function mediaDevices(): SubscribableThing<MediaDeviceInfo[]>;

    This function is a wrapper for the enumerateDevices() method of the Media Capture and Streams specification. It will also listen for the devicechange event to emit a fresh list of devices whenever they change.


    function mediaQueryMatch(mediaQueryString: string): SubscribableThing<boolean>;

    This function is a wrapper for the matchMedia() method. It will emit a new value whenever the result of matchMedia() changes.


    function midiInputs(midiAccess: IMidiAccess): SubscribableThing<IMidiInput[]>;

    This function returns the currently available MIDI input devices. It accepts a MIDIAccess object of the Web MIDI API.


    function midiOutputs(midiAccess: IMidiAccess): SubscribableThing<IMidiOutput[]>;

    This function returns the currently available MIDI output devices. It accepts a MIDIAccess object of the Web MIDI API.


    function metrics(options: PerformanceObserverInit): SubscribableThing<PerformanceEntry[]>;

    This function is a wrapper for the PerformanceObserver as defined by the Performance Timeline Level 2 specification.

    mutations(htmlElement, options)

    function mutations(
        htmlElement: HTMLElement,
        options: MutationObserverInit
    ): SubscribableThing<MutationRecord[]>;

    This function is a wrapper for the MutationObserver.

    on(target, type, [options])

    function on(
        target: EventTarget,
        type: string,
        options?: boolean | AddEventListenerOptions
    ): SubscribableThing<Event>;

    This function can be used to subscribe to events of a certain type dispatched from an EventTarget.


    function online(): SubscribableThing<boolean>;

    This function wraps the onLine property of the Navigator and listens for the corresponding 'online' and 'offline' events on the Window to emit updates.


    function permissionState(
        permissionDescriptor: PermissionDescriptor
    ): SubscribableThing<PermissionState>;

    This function is a wrapper for the query() method of the Permissions API. It will monitor the permission status to emit a new state whenever it gets updated.


    function reports(options?: IReportingObserverOptions): SubscribableThing<IReport[]>;

    This function is a wrapper for the ReportingObserver of the Reporting API.

    resizes(htmlElement, [options])

    function resizes(
        htmlElement: HTMLElement,
        options?: IResizesObserverOptions
    ): SubscribableThing<IResizeObserverEntry[]>;

    This function is a wrapper for the ResizeObserver of the Resize Observer specification.


    function unhandledRejection(coolingOffPeriod: number): SubscribableThing<any>;

    This function emits unhandled rejections. It will listen for the unhandledrejection event to register possibly unhandled rejections. It will then wait for the cooling-off period to elapse before it emits the reason (aka the error) that caused the unhandled rejection. It is possible that a previously unhandled rejection gets handled later on in which case a rejectionhandled event will be fired. If that happens during the cooling-off period nothing will be emitted by this function.


    function videoFrame(
        videoElement: HTMLVideoElement
    ): SubscribableThing<{ now: number } & IVideoFrameMetadata>;

    This function wraps the requestVideoFrameCallback() method of the given HTMLVideoElement. It emits the current timestamp combined with the VideoFrameMetadata object.


    function wakeLock(type: TWakeLockType): SubscribableThing<boolen>;

    This function simplifies the usage of the Screen Wake Lock API. It emits true when a wake lock could be acquired and emits false once the wake lock gets released by the browser. As long as the subscription is alive it will continuosly try to get a new wake lock if the current one gets released.


    There are two similar packages available which are based directly on RxJS. They are rx-use and rxjs-web.


    npm i subscribable-things

    DownloadsWeekly Downloads






    Unpacked Size

    225 kB

    Total Files


    Last publish


    • chrisguttandin