This package has been deprecated

Author message:

No longer maintained. Moved to https://npm.im/@reallyland/node_mod.

@reallyland/polling-observer
TypeScript icon, indicating that this package has built-in type declarations

0.4.3 • Public • Published

@reallyland/polling-observer

A new way of running polling function with observer pattern


Buy Me A Coffee tippin.me Follow me

Version Node version MIT License

Downloads Total downloads Packagephobia Bundlephobia

CircleCI Dependency Status codecov Coverage Status

codebeat badge Codacy Badge Code of Conduct

Like PerformanceObserver or any other observer APIs you could find in a browser, but this is for polling. Not only does it run polling with defined parameters but also collect polling metrics for each run until timeout or a defined condition fulfills.

Table of contents

Pre-requisites

Node.js

  • Node.js >= 8.16.0
  • NPM >= 6.4.1 (NPM comes with Node.js so there is no need to install separately.)
  • perf_hooks (Added in node@8.5.0 behind experimental flag)

Browser

Setup

Install

# Install via NPM
$ npm install --save @reallyland/polling-observer

Usage

Performance API is strictly required before running any polling. To ensure performance.now is available globally on Node.js, you can do:

/** Node.js */
import { performance } from 'perf_hooks';

global.performance = performance; // or globalThis.performance = performance;

TypeScript or native ES Modules

interface DataType {
  status: 'complete' | 'in-progress';
  items: Record<string, any>[];
}

import { PollingObserver } from '@reallyland/polling-observer';

const obs = new PollingObserver((data/** list, observer */) => {
  const { status, items } = data || {};
  const itemsLen = (items && items.length) || 0;

  /** Stop polling when any of the conditions fulfills */
  return 'complete' === status || itemsLen > 99;
});

obs.observe(
  async () => {
    /** Polling callback - fetch resources */
    const r = await fetch('https://example.com/api?key=123');
    const d = await r.json();

    return d;
  },
  /** Run polling (at least) every 2 seconds and timeout if it exceeds 30 seconds */
  {
    interval: 2e3,
    timeout: 30e3,
  }
);

/**
 * When polling finishes, it will either fulfill or reject depending on the status:
 * 
 * | Status  | Returns   |
 * | ------- | --------- |
 * | finish  | <value>   |
 * | timeout | <value>   |
 * | error   | <reason>  |
 * 
 */
obs.onfinish = (data, records/**, observer */) => {
  const { status, value, reason } = data || {};

  switch (status) {
    case 'error': {
      console.error(`Polling fails due to: `, reason);
      break;
    }
    case 'timeout': {
      console.log(`Polling timeouts after 30 seconds: `, value);
      break;
    }
    case 'finish':
    default: {
      console.log(`Polling finishes: `, value);
    }
  }

  console.log(`Formatted polling records: `, records.map(n => n.toJSON()));
  /**
   * [
   *   {
   *     duration: 100,
   *     entryType: 'polling-measure',
   *     name: 'polling:0',
   *     startTime: 100,
   *   },
   *   ...
   * ]
   */

  obs.disconnect(); /** Disconnect to clean up */
};

Node.js

const { PollingObserver } = require('@reallyland/polling-observer');

const obs = new PollingObserver((data/** entries, observer */) => {
  const { status, items } = data || {};
  const itemsLen = (items && items.length) || 0;

  /** Stop polling when any of the conditions fulfills */
  return 'complete' === status || itemsLen > 99;
});

obs.observe(
  async () => {
    /** Polling callback - fetch resources */
    const r = await fetch('https://example.com/api?key=123');
    const d = await r.json();

    return d;
  },
  /** Run polling (at least) every 2 seconds and timeout if it exceeds 30 seconds */
  {
    interval: 2e3,
    timeout: 30e3,
  }
);

/**
 * When polling finishes, it will either fulfill or reject depending on the status:
 * 
 * | Status  | Returns   |
 * | ------- | --------- |
 * | finish  | <value>   |
 * | timeout | <value>   |
 * | error   | <reason>  |
 * 
 */
obs.onfinish = (data, entries/**, observer */) => {
  const { status, value, reason } = data || {};

  switch (status) {
    case 'error': {
      console.error(`Polling fails due to: `, reason);
      break;
    }
    case 'timeout': {
      console.log(`Polling timeouts after 30 seconds: `, value);
      break;
    }
    case 'finish':
    default: {
      console.log(`Polling finishes: `, value);
    }
  }

  console.log(`Formatted polling entries: `, entries.map(n => n.toJSON()));
  /**
   * [
   *   {
   *     duration: 100,
   *     entryType: 'polling-measure',
   *     name: 'polling:0',
   *     startTime: 100,
   *   },
   *   ...
   * ]
   */

  obs.disconnect(); /** Disconnect to clean up */
};

Browser

ES Modules

<!doctype html>
<html>
  <head>
    <script type="module">
      import { PollingObserver } from 'https://unpkg.com/@reallyland/polling-observer@latest/dist/polling-observer.min.js';

      // --snip
    </script>
  </head>
</html>

UMD

<!doctype html>
<html>
  <head>
    <script src="https://unpkg.com/@reallyland/polling-observer@latest/dist/polling-observer.umd.min.js"></script>
    <script>
      var { PollingObserver } = window.PollingObserver;

      // --snip
    </script>
  </head>
</html>

Demo

Edit PollingObserver

API Reference

OnfinishFulfilled<T>

interface OnfinishFulfilled<T> {
  status: 'finish' | 'timeout';
  value: T;
}

OnfinishRejected

interface OnfinishRejected {
  status: 'error';
  reason: Error;
}

PollingMeasure

interface PollingMeasure {
  duration: number;
  entryType: 'polling-measure';
  name: string;
  startTime: number;
}
  • duration <number> Duration of the polling takes in milliseconds.
  • entryType <string> Entry type, defaults to polling-measure.
  • name <string> Polling name in the format of polling:<index> where <index> starts from 0 and increments on each polling.
  • startTime <string> Relative timestamp (in milliseconds ) indicates when the polling starts at.

Methods

PollingMeasure.toJSON()
  • <Function> Returns a JSON representation of the polling object's properties.

PollingObserver<T>

Methods

PollingObserver.observe(callback[, options])

The method is used to initiate polling with a polling callback and optional configuration.

  • callback <Function> Callback to be executed in each polling and return the result so that it will be passed as the first argument in conditionCallback.
    • returns: <T | Promise<T>> Return polling result in the type of T or Promise<T> in each polling.
  • options <Object> Optional configuration to run the polling.
    • interval <number> Optional interval in milliseconds. This is the minimum delay before starting the next polling.
    • timeout <number> Optional timeout in milliseconds. Polling ends when it reaches the defined timeout even though the condition has not been met yet. As long as timeout is not a number or it has a value that is less than 1, it indicates an infinite polling. The polling needs to be stopped manually by calling PollingObserver.disconnect() method.
PollingObserver.disconnect()

Once a PollingObserver disconnects, the polling stops and all polling metrics will be cleared. Calling PollingObserver.takeRecords() after the disconnection will always return an empty record.

A onfinish event handler can be used to retrieve polling records after a disconnection but it has to be attached before disconnecting the observer.

PollingObserver.takeRecords()

The method returns a list of PollingMeasure object containing the metrics of each polling.

Event handler

PollingObserver.onfinish

Note that no finish event fires when the polling finishes. So observer.addEventListener('finish', ...) will not work.

Event handler for when a polling finishes. When a polling finishes, it can either be fulfilled with a value or rejected with a reason. Any one of which contains a status field to tell the state of the finished polling.

When a polling fulfills, it returns an OnfinishFulfilled<T> object with status set to finish or timeout and a value in the type of T.

When a polling rejects, it returns an OnfinishRejected object with status set to error and a reason in the type of Error.

Status Returns
finish <value>
timeout <value>
error <reason>

deno

Coming soon.

License

MIT License © Rong Sen Ng (motss)

Package Sidebar

Install

npm i @reallyland/polling-observer

Weekly Downloads

13

Version

0.4.3

License

MIT

Unpacked Size

78.4 kB

Total Files

27

Last publish

Collaborators

  • motss