[ICO]NameLast modifiedSizeDescription
[PARENTDIR]Parent Directory  -  
[DIR]build/2023-10-19 15:45 -  
[DIR]src/2023-10-19 15:45 -  
[   ]LICENSE2023-10-19 15:45 1.1Kf0d2fc9 test post-receive hook [كارل مبارك]
[TXT]README.md2023-10-19 15:45 11K15de0e0 styling, texts [كارل مبارك]
[   ]package.json2023-10-19 15:45 3.5K120707f added node version q18.16 to dependincies [كارل مبارك]
![logo](https://repository-images.githubusercontent.com/243833305/16fbe600-64ca-11ea-8f60-736c8d74ec0f)

# subscribable-things

**A collection of reactive wrappers for various browser APIs.**

[![version](https://img.shields.io/npm/v/subscribable-things.svg?style=flat-square)](https://www.npmjs.com/package/subscribable-things)

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.

## Usage

The `subscribable-things` package is published on [npm](https://www.npmjs.com/package/subscribable-things) and can be installed as usual.

```shell
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 ...

```js
import { mediaQueryMatch } from 'subscribable-things';

const subscribe = mediaQueryMatch('(max-width:600px)');

const unsubscribe = subscribe((isMatching) => console.log(isMatching));

unsubscribe();
```

... or by utilizing a library for reactive programming like [RxJS](https://rxjs-dev.firebaseapp.com) ...

```js
import { from } from 'rxjs';
import { mediaQueryMatch } from 'subscribable-things';

const mediaQueryMatch$ = from(mediaQueryMatch('(max-width:600px)'));

const subscription = mediaQueryMatch$.subscribe((isMatching) => console.log(isMatching));

subscription.unsubscribe();
```

... or [Callbags](https://github.com/callbag/callbag) ...

```js
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](https://staltz.github.io/xstream) ...

```js
import { mediaQueryMatch } from 'subscribable-things';
import { fromObservable } from 'xstream';

const stream = fromObservable(mediaQueryMatch('(max-width:600px)'));

const unsubscribe = stream.subscribe((isMatching) => console.log(isMatching));

unsubscribe();
```

... or [Bacon.js](https://baconjs.github.io) ...

```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));

unsubscribe();
```

... or [Kefir.js](https://kefirjs.github.io/kefir).

```js
import { fromESObservable } from 'kefir';
import { mediaQueryMatch } from 'subscribable-things';

const stream = fromESObservable(mediaQueryMatch('(max-width:600px)'));

const subscription = stream.observe({
    value(isMatching) {
        console.log(isMatching);
    }
});

subscription.unsubscribe();
```

It is even possible to consume `subscribable-things` as an async iterable by taking the little detour over RxJS and [rxjs-for-await](https://github.com/benlesh/rxjs-for-await).

```js
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$)) {
    console.log(isMatching);
}
```

Also it's possible to output values directly to HTML via [hyperf](https://github.com/spectjs/hyperf).

```js
import h from 'hyperf';
import { mediaQueryMatch } from 'subscribable-things';

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

document.body.appendChild(element);
```

### animationFrame()

```ts
function animationFrame(): SubscribableThing<number>;
```

This function wraps the [`requestAnimationFrame()`](https://html.spec.whatwg.org/multipage/imagebitmap-and-animations.html#dom-animationframeprovider-requestanimationframe) method. It emits the current timestamp of each animation frame.

### attribute(htmlElement, name)

```ts
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.

### geolocation([options])

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

This is a wrapper for the [Geolocation API](https://w3c.github.io/geolocation-api/). It uses [`watchPosition()`](https://w3c.github.io/geolocation-api/#watchposition-method) to gather the most recent [`GeolocationPosition`](https://w3c.github.io/geolocation-api/#dfn-a-new-geolocationposition) whenever it changes.

### intersections(htmlElement, [options])

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

This function is a wrapper for the [`IntersectionObserver`](https://developer.mozilla.org/docs/Web/API/IntersectionObserver).

### mediaDevices()

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

This function is a wrapper for the [`enumerateDevices()`](https://developer.mozilla.org/docs/Web/API/MediaDevices/enumerateDevices) method of the [Media Capture and Streams specification](https://w3c.github.io/mediacapture-main). It will also listen for the [`devicechange` event](https://developer.mozilla.org/docs/Web/API/MediaDevices/devicechange_event) to emit a fresh list of devices whenever they change.

### mediaQueryMatch(mediaQueryString)

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

This function is a wrapper for the [`matchMedia()`](https://developer.mozilla.org/docs/Web/API/Window/matchMedia) method. It will emit a new value whenever the result of `matchMedia()` changes.

### midiInputs(midiAccess)

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

This function returns the currently available MIDI input devices. It accepts a [`MIDIAccess`](https://developer.mozilla.org/docs/Web/API/MIDIAccess) object of the [Web MIDI API](https://webaudio.github.io/web-midi-api).

### midiOutputs(midiAccess)

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

This function returns the currently available MIDI output devices. It accepts a [`MIDIAccess`](https://developer.mozilla.org/docs/Web/API/MIDIAccess) object of the [Web MIDI API](https://webaudio.github.io/web-midi-api).

### metrics(options)

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

This function is a wrapper for the [`PerformanceObserver`](https://developer.mozilla.org/docs/Web/API/PerformanceObserver) as defined by the [Performance Timeline Level 2 specification](https://w3c.github.io/performance-timeline).

### mutations(htmlElement, options)

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

This function is a wrapper for the [`MutationObserver`](https://developer.mozilla.org/docs/Web/API/MutationObserver).

### on(target, type, [options])

```ts
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`](https://dom.spec.whatwg.org/#interface-eventtarget).

### online()

```ts
function online(): SubscribableThing<boolean>;
```

This function wraps the [`onLine`](https://developer.mozilla.org/docs/Web/API/NavigatorOnLine/onLine) property of the [`Navigator`](https://developer.mozilla.org/docs/Web/API/Navigator) and listens for the corresponding [`'online'`](https://developer.mozilla.org/docs/Web/API/Window/online_event) and [`'offline'`](https://developer.mozilla.org/docs/Web/API/Window/offline_event) events on the [`Window`](https://developer.mozilla.org/docs/Web/API/Window) to emit updates.

### permissionState(permissionDescriptor)

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

This function is a wrapper for the [`query()`](https://developer.mozilla.org/docs/Web/API/Permissions/query) method of the [Permissions API](https://w3c.github.io/permissions). It will monitor the permission status to emit a new state whenever it gets updated.

### reports([options])

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

This function is a wrapper for the [`ReportingObserver`](https://developer.mozilla.org/docs/Web/API/ReportingObserver) of the [Reporting API](https://w3c.github.io/reporting).

### resizes(htmlElement, [options])

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

This function is a wrapper for the [`ResizeObserver`](https://developer.mozilla.org/docs/Web/API/ResizeObserver) of the [Resize Observer specification](https://drafts.csswg.org/resize-observer).

### unhandledRejection(coolingOffPeriod)

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

This function emits unhandled rejections. It will listen for the [`unhandledrejection` event](https://developer.mozilla.org/docs/Web/API/Window/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](https://developer.mozilla.org/docs/Web/API/Window/rejectionhandled_event) will be fired. If that happens during the cooling-off period nothing will be emitted by this function.

### videoFrame(videoElement)

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

This function wraps the [`requestVideoFrameCallback()`](https://wicg.github.io/video-rvfc) method of the given [`HTMLVideoElement`](https://html.spec.whatwg.org/multipage/media.html#htmlvideoelement). It emits the current timestamp combined with the [`VideoFrameMetadata`](https://wicg.github.io/video-rvfc/#video-frame-metadata) object.

### wakeLock(type)

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

This function simplifies the usage of the [Screen Wake Lock API](https://w3c.github.io/screen-wake-lock). 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.

## Alternatives

There are two similar packages available which are based directly on RxJS. They are [rx-use](https://github.com/streamich/rx-use) and [rxjs-web](https://github.com/niklas-wortmann/rxjs-web).