@bluejay/collection
TypeScript icon, indicating that this package has built-in type declarations

5.0.0 • Public • Published

Collection

npm npm npm

Async ready, chainable, highly convenient array subclass. Supports all array methods, plus a bunch of async iterations and some common Lodash methods out of the box.

Requirements

  • node >= 8.6, tested with:
    • node@8.6.0
    • node@12.8.1
  • typescript >= 4.0, tested with:
    • typescript@4.0.2

Installation

npm i @bluejay/collection [--save]

Usage

Array inheritance

A Collection IS an Array. Collections are fully compatible with the ES6 array specification.

In practice:

const collection = new Collection([1, 2, 3]);

Array.isArray(collection); // true

function foo(bar: number[]) {
  // Do stuff
}

foo([1, 2, 3]); // Compiles
foo(collection); // Compiles too!

JSON.stringify(collection); // [1,2,3]

Array.from(collection); // [1,2,3]

If you wish to check if an object is a collection, use Collection.isCollection():

const collection = new Collection([1, 2, 3]);

Collection.isCollection(collection); // true

Available methods

  • All array methods are supported
  • Some Lodash methods such as omit() or pick() are built-in as instance methods
  • A few async methods allow you to perform async operations directly from the collection itself
import { Collection } from '@bluejay/collection';

const collection = new Collection([{ foo: 1 }, { foo: 2 }, { foo: 3 }]); // Initialize with an array

collection.size(); // 3
collection.getAt(1); // { foo: 2 }
collection.setAt(1, 5);

// Array style elements access
collection[1] = { foo: 18 };
collection[1]; // { foo: 18 }

// Regular array methods
collection.forEach(el => console.log(el.foo)); // 1, 2, 3
collection.map(el => console.log(el.foo)); // 1, 2, 3

// Async array methods
await collection.mapSeries(async el => el.foo * 2); // Collection<[2, 4, 6]>
await collection.mapParallel(async el => el.foo * 2); // Collection<[2, 4, 6]>

// Lodash methods
collection.findByProperties({ foo: 1 }); // { foo: 1 }
collection.mapByProperty('foo'); // Collection<[1, 2, 3]>

// Iterate
for (const object of collection) {
  // Do something
}

Collections and inheritance

To create a Collection subclass, just do what you do best:

class MyCollection<T> extends Collection<T> {
  private persistent:

  public constructor(objects: T[], options: { persistent: boolean }) {
    super(objects);
    this.persistent = options.persistent;
  }

  public isPersistent() {
    return this.persistent;
  }
}

const instance = new MyCollection([1, 2, 3], { persistent: true });

instance.size(); // 3
instance.isPersistent(); // true

You will, however, soon notice that methods that return a collection return an instance of Collection, not MyCollection.

const filtered = instance.filter(value => value >= 2);
filtered.toArray(); // [2, 3]
filtered.isPersistent(); // Compilation error! `isPersistent()` does not exist on type `Collection`

This is because Bluejay has no way to know which arguments your implementation requires. In order to solve this issue, we need to override the factory() method which Bluejay calls each time it needs to create a new Collection.

class MyCollection<T> extends Collection<T> {
  private persistent:

  public constructor(objects: T[], options: { persistent: boolean }) {
    super(objects);
    this.persistent = options.persistent;
  }

  protected factory<Y>(objects: Y[]) { // We don't know which type exactly we're getting here since `map()` and other methods might create collections of a different type than T
    return new MyCollection<Y>(objects, { persistent: this.persistent });
  }

  public isPersistent() {
    return this.persistent;
  }
}

const instance = new MyCollection([1, 2, 3], { persistent: true });

instance.isPersistent(); // true

const filtered = instance.filter(value => value >= 2);

filtered.isPersistent(); // true - Not compilation error anymore

instance.forEach((value, index, currentObj: MyCollection<number>) => { // Note that we need to explicitly set the type here as TS doesn't manage to infer it from the implementation
  currentObj.isPersistent(); // true
});

Note: While we made sure to provide a way for you to override the instances created by Bluejay, most implementations will not need such a complex setup. It is absolutely NOT necessary to override this method if you don't explicitly need to.

Package Sidebar

Install

npm i @bluejay/collection

Weekly Downloads

1,017

Version

5.0.0

License

MIT

Unpacked Size

43.2 kB

Total Files

11

Last publish

Collaborators

  • asifarran
  • bluebirds