Skip to main content

@pexip/utils

Generic utility functions.

Install​

npm install @pexip/utils

Table of Content​

Functions​

Wrap or create new functions.

noop​

Placeholder function, useful when we're expecting a function to be set later

import {noop} from '@pexip/utils';

noop(); // returns undefined

let fn: () => void = noop;

onEvent(() => {
fn(); // won't fail even if this is called before onUpdate
});

onUpdate((updatedFn: () => void) => {
fn = updatedFn;
});

pipe​

Pipes the value of an expression into a pipeline of functions.

import {pipe} from '@pexip/utils';

const len = (s: string): number => s.length;
const double = (n: number): number => n * 2;

// Equivalent to `const doubleLen = (s: string) => double(len(s));`
const doubleLen = pipe(len, double);

doubleLen('abc'); // returns 6

throttle​

Creates a throttled function that only invokes func at most once per every wait milliseconds

import {throttle} from '@pexip/utils';

const onMouseMoveCallback = () => {
// do some logic on 🐭 move
};

const throttled = throttle(onMouseMoveCallback, 500);

document.addEventListener('mousemove', throttled); // onMouseMoveCallback will invoke only once within a 500 milliseconds

isDefined​

Test that a value t is set to something and return it, throws on undefined. This is handy when selecting using an index to eliminiate the infered undefined type.

import {isDefined} from '@pexip/utils';

const strs = ['foo', 'bar', 'qux'];
// str infers `string`, or throws if selecting outside range
const str = isDefined(strs[0]);

const objs: {[key: string]: {prop: string}} = {
hello: {prop: 'world'};
}
// obj infers `{prop: string}`, or throws if the key is not set
const obj = isDefined(objs['hello'])

try {
console.log(isDefined('')); // => ''
console.log(isDefined(0)); // => 0
console.log(isDefined(false)); // => false
console.log(isDefined(null)); // => null
console.log(isDefined(undefined)); // will throw
// ...

Array​

nthThrows​

Inspired by lodash nth this will select the given index from an array, but throw if the selected value is undefined. As with the lodash version of nth it will select from the end of the array given a negative index. This version of nth is likely to be most useful in tests.

import {nthThrows} from '@pexip/utils';

const mockData = [{foo: 'bar'}];

describe('test suite', () => {
it('should test something', () => {
// this will be {foo: string} | undefined
const dataOrUndefined = mockData[0]:
// while this will be {foo: string}, or else the test will fail
const data = nthThrows(mockData, 0);
});
})

nthOr​

Inspired by lodash nth this will select the given index from an array, but return the default value if the selected value is undefined. As with the lodash version of nth it will select from the end of the array given a negative index.

import {nthOr} from '@pexip/utils';

const nrs = [10, 20, 30];
console.log(nthOr(nrs, 0, 40)); // => 10
console.log(nthOr(nrs, 1, 40)); // => 20
console.log(nthOr(nrs, 2, 40)); // => 30
console.log(nthOr(nrs, 3, 40)); // => 40
console.log(nthOr(nrs, -1, 40)); // => 30
console.log(nthOr(nrs, -2, 40)); // => 20
console.log(nthOr(nrs, -3, 40)); // => 10
console.log(nthOr(nrs, -4, 40)); // => 40

It is generic and will infer what type it expects as a defaultValue.

const values = [
{foo: 'bar', baz: 10, qux: [10]},
{foo: 'quux', qux: []},
];
const value = nthOr(values, 0, {foo: '', qux: []}); // it should know that `foo` and `qux` are required fields

firstOr and lastOr​

Quite commonly we want either the first or last value from an array, so these wrap nthOr with a default index parameter.

import {firstOr, lastOr} from '@pexip/utils';

const strs = ['foo', 'bar', 'qux'];
console.log(firstOr(strs, '')); // => 'foo';
console.log(lastOr(strs, '')); // => 'qux';

Backoff​

Exponential backoff utility class. Usage as so:

import {Backoff} from '@pexip/utils';

const backoff = new Backoff({
factor: 2,
jitter: 0,
max: 30000,
min: 1000,
});

for (let i = 0; i < MAX_REFRESH_ATTEMPTS; i++) {
const attempt = Boolean(Math.round(Math.random())); //try something

if (attempt) {
backoff.reset();
return;
} else {
await backoff.promise();
}
}
backoff.reset();

endsWithAnyOf​

like String.endsWith but allows passing an array of search strings (instead of just 1), returning true if the 'subject' string matches any of them.

import {endsWithAnyOf} from '@pexip/utils';

const doesEndWith = endsWithAnyOf('Pexip', ['hello', 'ip', '!']); //true
const doesEndWith2 = endsWithAnyOf('Pexip', ['hello', 'world', '!']); //false

getBaseURI​

get the base path of document

<base href="/somepath/" />
import {getBaseURI} from '@pexip/utils';

const base = getBaseURI(); // /somepath/

Classes​

ClassDescription
Backoff-

Interfaces​

InterfaceDescription
AsyncQueueOptions-
QueueA Queue to serve first-in-first-out (FIFO)
SealedTextSegmentA read-only view over a segment which has just been sealed, i.e. it is full and no more lines will ever be written to it.
TextRingBufferOptionsOptions for createTextRingBuffer.
TextRingBufferA bounded, in-memory store of UTF-8 encoded text lines.

Type Aliases​

Type AliasDescription
AsyncJob-
DiffResult-
ProxyLoggerMinimal logger contract required by proxyWithLog. Only the methods the proxy actually calls are listed, so any richer logger (e.g. one with warn, error, redaction, etc.) is structurally assignable.
OnSegmentSealedCalled when a segment is sealed, i.e. when it is full and no more lines will ever be written to it, and when TextRingBuffer.flush is called. This is the extension seam for persisting evicted logs, e.g. to IndexedDB.
Fn-

Variables​

VariableDescription
assert-
QUEUE_THROTTLE_IN_MS-
QUEUE_TIMEOUT_IN_MS-
QUEUE_DELAY_IN_MS-
NO_VALUE-
ASTERISK**************************************************************************** Constants ****************************************************************************
BACKSLASH-
CARET-
CLOSE_BRACE-
CLOSE_BRACKET-
CLOSE_PARENTHESE-
DOLLAR-
DOT-
OPEN_BRACE-
OPEN_BRACKET-
OPEN_PARENTHESE-
PIPE-
PLUS-
QUESTION_MARK-
NUMERIC## Numeric Identifier A single 0, or a non-zero digit followed by zero or more digits.
NUMERICLOSE## Numeric Lose Identifier At least 1 digit.
NONNUMERIC## Non-numeric Identifier Zero or more digits, followed by a letter or hyphen, and then zero or more letters, digits, or hyphens.
BUILD-
optionA Combinator to make the provided pattern's occurrence as optional. i.e. ?
anyA Combinator to make the provided pattern's occurrence as any or more, i.e. *
beginA Combinator for the match start of a string.
endA Combinator for the match end of a string.
QUEUE_SIZE-
QUEUE_DROP_LAST-
scheduleWithTimeoutFallback implementation of Task Scheduling API using setTimeout
scheduleWithSchedulerPrioritized Task Scheduling API

Functions​

FunctionDescription
createAsyncQueue-
cancellablePromiseWrapping provided async callback to allow to resolve the async operation with cleanup when the cancel function is called
createCircularBufferCreates a circular buffer backed by a TypedArray using a "power-of-two size" optimization.
debounceAn higher-order-function that debounce a given function to only invoke after N amount of time passes since its last call.
diffObjectComputes a shallow diff between two plain JS objects. Returns added, removed, and changed keys.
difference-
symmetricDifference-
hasSymmetricDifference-
endsWithAnyOf-
getBaseURI-
getTimeLeft-
hasOwnA type utility function to check if the provided object has the prop, and provide a proper type to workaround Typescript's limitation
identity-
isDefinedTest that a value t is set to something and return it, throws on undefined.
isEmptyVerify if the provided unknown object is empty
memoizeMemoizes a function based on its arguments and dependencies, where the comparison algorithm is a shallow equality check based on Object.is[^1]
noopA no-operation function.
nthThrowsInspired by lodash nth this will select the given index from an array, but throw if the value is undefined. As with the lodash version of nth it will select from the end of the array given a negative index. This is likely to be most useful in tests. You might want nthOr, firstOr, or lastOr instead
nthOrInspired by lodash nth this will select the given index from an array. As with the lodash version of nth it will select from the end of the array given a negative index.
firstOrSelects the first element in a list
lastOrSelects the last element in a list
groupA Combinator to group pattern. When name is provided, it will be one of the keys that returned from
rangeA Combinator to make the provided pattern's occurrence as in specified range. i.e. {min,max}
altA Combinator to make the provided patterns as a combination of alternatives
joinA Combinator to join the provided patterns as a single pattern
createTokenizer-
pipePipes the value of an expression into a pipeline of functions.
prigPseudorandom index generator implemented with Miller Shuffle Algorithm D variant NEW April 2023 aka: MillerShuffleAlgo_d
createLogProxyHandlerBuild a ProxyHandler that logs every interaction with the target: property reads/writes/deletes, descriptor and prototype access, in checks, key enumeration, extensibility changes, and direct calls. Function properties accessed via get are themselves wrapped so each method call is logged with its arguments.
proxyWithLogCurried helper that wraps an object in a logging proxy. Useful when several objects share the same logger and scope and only differ by name.
createQueue-
createScheduler-
subscribeEventSubscribe an EventTarget's event and return a unsubscribe function
createTextRingBufferCreates a bounded store of text lines, backed by a ring of pre-allocated Uint8Array segments which lines are encoded into with TextEncoder.encodeInto.
throttleCreates a throttled function that only invokes func at most once per every wait milliseconds