2.1.8 • Published 3 years ago

@paychex/collector-batch v2.1.8

Weekly downloads
-
License
Apache-2.0
Repository
github
Last release
3 years ago

@paychex/collector-batch

Provides a customizable batching collector for use with a @paychex/core Tracker.

Installation

npm install @paychex/collector-batch

Importing

esm

import { batch } from '@paychex/collector-batch';

cjs

const { batch } = require('@paychex/collector-batch');

amd

define(['@paychex/collector-batch'], function(collectors) { ... });
define(['@paychex/collector-batch'], function({ batch }) { ... });
require(['@paychex/collector-batch'], function(collectors) { ... });
require(['@paychex/collector-batch'], function({ batch }) { ... });

iife (browser)

const { batch } = window['@paychex/collector-batch'];

Usage

Construct your batch collector by passing a send function and optional coalesce function to the factory method:

import { batch } from '@paychex/collector-batch';

async function send(payload) {
    // logic to persist tracking entries here;
    // payload will be array of TrackingInfo instances
}

const collector = batch(send);
// using a custom coalesce function

import { batch, utils } from '@paychex/collector-batch';

async function send(payload) {
    // payload will contain JSON-Patch entries
}

const collector = batch(send, utils.toPatch);

When usign toPatch, your send method's payload will be an Array whose first item is a complete TrackingInfo object and whose subsequent items will be Arrays of JSON-Patch items describing any differences from the previous item.

For example, if you sent the following events:

tracker.event('click', { category: 'ux' });
tracker.event('click', { category: 'menu', text: 'log out' });

Then the toPatch payload passed to your send method would look like this:

[
  {
    "id": "a0ed9697-1e38-4bca-b17b-5c79b9f028e2",
    "type": "event",
    "label": "click",
    "start": 1611604974339,
    "stop": 1611604974339,
    "duration": 0,
    "count": 1,
    "data": {
      "category": "ux"
    }
  },
  [
    {
      "op": "replace",
      "path": "/data/category",
      "value": "menu"
    },
    {
      "op": "add",
      "path": "/data/text",
      "value": "log out"
    },
    {
      "op": "replace",
      "path": "/stop",
      "value": 1611604974340
    },
    {
      "op": "replace",
      "path": "/start",
      "value": 1611604974340
    },
    {
      "op": "replace",
      "path": "/id",
      "value": "b387d125-1910-45ff-a346-cd17e35c9e94"
    }
  ]
]

Although the above payload seems larger than just sending the TrackingInfo instances directly, if you modify your data pipeline to enable compression (e.g. using a library like pako), the overall size can be reduced dramatically.

Examples

// sending JSON-Patch entries to an endpoint

import { trackers } from '@paychex/core';
import { batch, utils } from '@paychex/collector-batch';

import { createRequest, fetch } from '~/path/to/data/layer.js';

const operation = {
  method: 'PATCH',
  base: 'my-endpoint',
  path: '/analytics/tracking',
  ignore: {
    tracking: true,
    traceability: true,
  }
};

async function send(payload) {
  await fetch(createRequest(operation, null, payload));
}

const collector = batch(send, utils.toPatch);
export const tracker = trackers.create(collector);

You can combine your collector with other utility methods, such as buffer, to provide "debounce" logic:

// collect all items received within 5-second intervals

import { batch } from '@paychex/collector-batch';
import { functions, signals, trackers } from '@paychex/core';

async function send(payload) { ... }

const signal = signals.autoReset(false);
const collector = functions.buffer(batch(send), [signal]);

setInterval(signal.set, 5000);

export const tracker = trackers.create(collector);