All Projects → ivan7237d → antiutils

ivan7237d / antiutils

Licence: MIT license
TypeScript/JavaScript utilities for those who don't like utilities

Programming Languages

typescript
32286 projects
javascript
184084 projects - #8 most used programming language

Projects that are alternatives of or similar to antiutils

hlatyping
Precision HLA typing from next-generation sequencing data
Stars: ✭ 28 (-9.68%)
Mutual labels:  pipeline
bat
Battery management utility for Linux laptops.
Stars: ✭ 107 (+245.16%)
Mutual labels:  utilities
MTBseq source
MTBseq is an automated pipeline for mapping, variant calling and detection of resistance mediating and phylogenetic variants from illumina whole genome sequence data of Mycobacterium tuberculosis complex isolates.
Stars: ✭ 26 (-16.13%)
Mutual labels:  pipeline
bacannot
Generic but comprehensive pipeline for prokaryotic genome annotation and interrogation with interactive reports and shiny app.
Stars: ✭ 51 (+64.52%)
Mutual labels:  pipeline
swarmci
Swarm CI - Docker Swarm-based CI system or enhancement to existing systems.
Stars: ✭ 48 (+54.84%)
Mutual labels:  pipeline
katana-skipper
Simple and flexible ML workflow engine
Stars: ✭ 234 (+654.84%)
Mutual labels:  pipeline
iOS-UtiliKit
All the things you're tired of writing.
Stars: ✭ 21 (-32.26%)
Mutual labels:  utilities
sc2-illumina-pipeline
Bioinformatics pipeline for SARS-CoV-2 sequencing at CZ Biohub
Stars: ✭ 18 (-41.94%)
Mutual labels:  pipeline
KoELECTRA-Pipeline
Transformers Pipeline with KoELECTRA
Stars: ✭ 37 (+19.35%)
Mutual labels:  pipeline
proposal-hack-pipes
Old specification for Hack pipes in JavaScript. Please go to the new specification.
Stars: ✭ 87 (+180.65%)
Mutual labels:  pipeline
wareki
Utility function for Japanese calender.
Stars: ✭ 23 (-25.81%)
Mutual labels:  utilities
sparklanes
A lightweight data processing framework for Apache Spark
Stars: ✭ 17 (-45.16%)
Mutual labels:  pipeline
tutti-quanti-shelf
Collection of miscellaneous developer-oriented utilities wrapped into one single app, built with Electron.
Stars: ✭ 30 (-3.23%)
Mutual labels:  utilities
utilities
Collection of small useful functions in Python
Stars: ✭ 30 (-3.23%)
Mutual labels:  utilities
dnaPipeTE
dnaPipeTE (for de-novo assembly & annotation Pipeline for Transposable Elements), is a pipeline designed to find, annotate and quantify Transposable Elements in small samples of NGS datasets. It is very useful to quantify the proportion of TEs in newly sequenced genomes since it does not require genome assembly and works on small datasets (< 1X).
Stars: ✭ 28 (-9.68%)
Mutual labels:  pipeline
vmutils
cross platform library to manipulate and extract information of memory regions
Stars: ✭ 22 (-29.03%)
Mutual labels:  utilities
Wave
Wave is C# library extends the ArcGIS for Desktop and ArcFM Solution APIs in an effort to simplify customizing these products. The library has been designed to use extension methods to expose the features of the library.
Stars: ✭ 13 (-58.06%)
Mutual labels:  utilities
OpenDriver2Tools
Driver 1 and Driver 2 tools
Stars: ✭ 25 (-19.35%)
Mutual labels:  utilities
HexEditor
Hex Editor GUI
Stars: ✭ 16 (-48.39%)
Mutual labels:  utilities
proxyunsetter
Windows tray tool to unset the system proxy.
Stars: ✭ 26 (-16.13%)
Mutual labels:  utilities

Antiutils

npm version gzip size tree shaking types coverage status

TypeScript/JavaScript utilities for those who don't like utilities.

Installing

yarn add antiutils

or

npm install antiutils --save

Minimal API

This library provides a utility only when something can't be easily and readably accomplished with vanilla JavaScript. There are three reasons: first, the code is easier to write and refactor when there is "only one way to do it"; second, we'd all much rather use a universally understood language than a dialect; and third, a large utility library shapes your whole codebase, and we the authors do not want to be telling you how to write your code (let TC39 do it).

pipe function

The library provides a function pipe which takes between 1 and 12 arguments. pipe(x, a, b) is equivalent to b(a(x)), in other words, this function pipes a value through a number of functions in the order that they appear. This article talks about why this function is useful.

💡 TIP

At any point in the pipeline, you can insert the log function from 1log library to log piped values.

Non-mutating functions for working with objects, arrays, maps, and sets

Objects:

💡 TIP

If you use TypeScript 4.1+, you can enable strictly checked indexed access using --noUncheckedIndexedAccess compiler flag.

Arrays:

Maps:

Sets:

Functions for working with native iterables

How-to:

  • Filter an iterable in a way that the type system understands:

    pipe(
      [1, undefined],
      // Equivalent to `filterIterable((value) => value !== undefined)`.
      flatMapIterable((value) => (value !== undefined ? [value] : [])),
    );

    (type will be inferred as IterableIterator<number>, not IterableIterator<number | undefined> as would be the case if you used filterIterable; the same trick works when filtering arrays and observables).

  • Index elements: zipIterables(rangeIterable(), yourIterable) (returns an iterable of [<element index>, <element>]).

  • Get a flag indicating if the element is the first element: zipIterables(firstIterable(), yourIterable) (returns an iterable of [boolean, <element>]).

  • Count elements in an iterable: pipe(yourIterable, reduceIterable(countReducer, 0)).

  • Find the first element matching a predicate: pipe(yourIterable, filter(yourPredicate), firstInIterable).

  • Yield values while a condition holds:

    pipe(
      [1, 2, 3, 2],
      scanIterable((_, value) => (value <= 2 ? value : undefined)),
    );

    (yields 1, 2, see Reducers and scanIterable).

Comparison functions

The library exports types

interface CompareFunction<T> {
  (to: T, from: T): number;
}

interface EqualFunction<T> {
  (from: T, to: T): boolean;
}

It provides implementations of CompareFunction for primitive types:

and a function lexicographicCompare to compose CompareFunctions.

It also provides implementations of EqualFunction for objects, iterables, maps, and sets:

and a function deepEqual that recursively delegates to those functions depending on the object type.

Reducers

The library exports types

interface Reducer<Accumulator, Element> {
  (accumulator: Accumulator, element: Element): Accumulator;
}

interface PartialReducer<Accumulator, Element> {
  (accumulator: Accumulator, element: Element): Accumulator | undefined;
}

Reducer is a regular reducer that can be passed to reduce method of an array. PartialReducer is like a regular reducer, but can return undefined to indicate that the current value of the accumulator should be used as the final result, so functions reduceIterable and scanIterable will stop the iteration short.

The library provides the following implementations of Reducer:

and the following implementations of PartialReducer:

Lenses

In Antiutils the definition of a lens is based on the concept of a view, which is a combination of a getter and a setter:

interface View<S, A> {
  get: () => A;
  set: (value: A) => S;
}

When generic type S is void, the setter only performs a side effect - we call this type of view a state view:

type StateView<A> = View<void, A>;

State views are useful when working with React components - for details, see package antiutils-react which provides glue between Antiutils and React.

The setter can also be a pure function that performs a non-mutating update, as in the following view that lets you access property a in object { a: 1, b: 2 }:

const view: View<{ a: number }, number> = {
  get: () => 1,
  set: (value) => ({ a: value, b: 2 }),
};

A lens is defined as a function that transforms one view into another view:

interface Lens<S, A, B> {
  (source: View<S, A>): View<S, B>;
}

The library provides the following utilities:

  • objectProp: returns a lens that zooms in on an object's property.

  • mapProp: returns a lens that zooms in on a value stored in a Map under a specific key.

  • setProp: returns a lens that zooms in on presence of an element in a Set.

  • rootView: a function that converts a value into a view { get: () => value, set: <identity function> }.

Here is an example using objectProp and rootView:

type State = { a: { b: string; c: string } };

/**
 * A reducer that sets the value of `b` in the state to the value provided
 * as action payload.
 **/
const sampleReducer = (state: State, action: { payload: string }) =>
  pipe(
    // Returns `View<State, State>`.
    rootView(state),
    // Transforms values into `View<State, { b: string; c: string }>`.
    objectProp('a'),
    // Transforms values into `View<State, string>`.
    objectProp('b'),
  )
    // `set` takes a value for `b` and returns a new `State`.
    .set(action.payload);

expect(sampleReducer({ a: { b: '', c: '' } }, { payload: 'x' })).toEqual({
  a: { b: 'x', c: '' },
});

In the code above, TypeScript successfully infers the types, and as we get to a point where we need to type 'a', 'b', or 'c', IntelliSense shows correct suggestions.

A similar example, but with property a optional:

type State = { a?: { b: string; c: string } };

const sampleReducer = (state: State, action: { payload: string }) =>
  pipe(
    rootView(state),
    // Transforms values into `View<State, { b: string; c: string } |
    // undefined>`.
    objectProp('a'),
    // Transforms values into `View<State, { b: string; c: string }>`.
    ({ get, set }) => ({
      get: () => get() ?? { b: '', c: '' },
      set,
    }),
    objectProp('b'),
  ).set(action.payload);

expect(sampleReducer({}, { payload: 'x' })).toEqual({
  a: { b: 'x', c: '' },
});

💡 TIP

You can log views using a plugin from package 1log-antiutils.

Memoization

The library provides utilities memoizeWeak and memoizeStrong to memoize functions that take a single argument. Internally they cache results in respectively a WeakMap and a Map, with arguments as keys and results as values. memoizeWeak has an advantage that retaining a reference to the memoized function will not prevent cached arguments and results from being garbage-collected, but it can only memoize functions that take objects (not primitive values) as arguments, because only objects can be used as keys in a WeakMap.

💡 TIP

You can combine memoizeWeak and memoizeStrong to memoize a function that takes multiple arguments, some of them primitive values, e.g.

const original = (x: { a: number }, y: number) => x.a + y;
const memoized = memoizeWeak((x: { a: number }) =>
  memoizeStrong((y: number) => original(x, y)),
);
const withRestoredSignature = (x: { a: number }, y: number) => memoized(x)(y);

The library also provides a function teach for cases when you need to teach a memoized function to return a result already known from an external source such as persisted storage, and a function knows to check if there is a cached result for a given argument.

Functions for downcasting

The library provides the following identity functions that cast the argument to a type, but unlike TypeScript's as, never make type assertions:

  • asNever: a function which has signature (value: never) => never and which throws if called, used to typecheck that a symbol has type never and therefore the call site is unreachable. For example, if a has type 0 | 1, you could write a === 0 ? 'zero' : a === 1 ? 'one' : asNever(a) to make sure that all possibilities for a have been exhausted. If the type of a changes to say 0 | 1 | 2, the type of the argument passed to asNever will be inferred as 2, and this will cause a typechecking error because the only type assignable to never is never itself.

  • as: an identity function with signature <T>(value: T) => T that can be used to downcast a value to a non-generic type: as<YourType>(yourValue).

  • asContext: an identity function with signature <A, B extends A>(value: B) => A that can be used to infer the type of a value from the context instead of the other way around. As an example, consider the following code that throws if the iterable has more than 1 element:

    pipe(
      <some iterable>,
      reduceIterable(
        asContext(() => {
          throw <some error>;
        }),
      ),
    );

    Without wrapping the reducer in asContext, TypeScript would infer the type of the accumulator as never and the code would not typecheck.

  • asCompareFunction, asEqualFunction, asLens, asReducer, asPartialReducer, asStateView, asView: identity functions that can be used to downcast values to any of the generic types defined by the library.


Contributing guidelines

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].