Skip to content
/ leseq Public

Lazy collection(lazy list) with high tree-shaking affinity and easy customization.

License

Notifications You must be signed in to change notification settings

ugaya40/leseq

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

npm version

Lazy list(lazy list) with high tree-shaking affinity and easy customization.

Features

  • 🎁 Lazy Collection: The collections are only enumerated to the minimum necessary. Infinite sequences are supported.
  • 🎄 Tree-Shakeable: Only the features you use will be bundled.
  • 👻 Async Iterator Support: Iterable can also be seamlessly treated as Async Iterator.
  • 📎 Easy-Customization: You can easily create the functions you need by yourself. In this way.
  • 🗂 Rxjs-like Syntax: To achieve tree-shaking, we use an rxjs-like syntax.
  • Simple Equality Strategy: It uses a simple Equality Strategy.
  • 💯 All Typed: The whole thing is written in TypeScript, which also provides completion for type conversion between operators.
  • 💨 No dependencies
import {from, map, take} from 'leseq';

const result1 = from([1,2,3,4,5]).pipe(
  map(i => i * i),
  take(3)
).toArray();

//result1: [1,4,9]

This is the result of bundle visualizer in the example above (1.21KB gzipped).

Resource

Advanced

Getting Started

npm install leseq

If you are using Async Iterable and "target " in tsconfig.json is smaller than "es2018", you must add "ES2018.AsyncGenerator " and "ES2018.AsyncIterable " in tsconfig.json/lib or the type will not display properly.

{
  "compilerOptions": {
    "target": "es6",
    "lib": ["DOM", "ES6", "ES2018.AsyncGenerator", "ES2018.AsyncIterable"]
  }
}

Iterable

import {from, map, take, find, range, reverse, filter} from 'leseq';

const result1 = from([1,2,3,4,5]).pipe(
  map(i => i * i),
  take(3)
)

for (const one of result1) {
  console.log(one)
}

//result: 1
//result: 4
//result: 9

const result2 = from([1,2,3,4,5]).pipe(
  filter(i => i % 2 == 0)
).value(
  find(i => i > 2)
);

//result2: 4

//lazy
const result3 = range(1, 10000000).pipe(
  take(3),
  reverse(),
  map((i) => i * i)
).toArray();

//result3: [9,4,1]

Async Iterable

import {from, mapAsync, filterAsync, fromAsAsync, findAsync, asyncSeq} from 'leseq';

const sleep = (milliseconds: number) => new Promise(resolve => setTimeout(resolve,milliseconds));

//from iterable to async iterable.
const result1 = await from([1,2,3,4,5]).to(asyncSeq()).pipe(
  mapAsync(async i => {
    await sleep(1000);
    return i * i;
  }),
  filterAsync(async i => i % 2 == 0)
).toArrayAsync();

//5 seconds later... result1: [4,16]

const result2 = await fromAsAsync([1,2,3,4,5]).pipe(
  mapAsync(async i => {
    await sleep(1000);
    return i * i;
  }),
  filterAsync(async i => i % 2 == 0)
).valueAsync(findAsync());

//2 seconds later... result2: 4

const result3 = await fromConcatAsAsync([1,2],[3,4]).pipe(
  mapAsync(async i => {
    await sleep(1000);
    return i * i;
  }),
);

for await (const one of result3) {
  console.log(one);
}

//1 seconds later... result: 1
//2 seconds later... result: 4
//3 seconds later... result: 9
//4 seconds later... result: 16

Usage

It is possible to generate sequences (Seq<T>/AsyncSeq<T> object) with Generator, convert them to sequences with different characteristics with To, perform operations such as value conversion and filtering with any number of Operators, and convert them to a single value with Value.

// sync iterator
SyncSource = 
  Generators(ex: from, fromConcat, ..etc) | 
  SyncSource.to(To(ex: share, async))
  SyncSource.pipe(
    ...SyncOperators(ex: map, filter, ...etc)
  );

value = SyncSource.value(SyncValues(ex: find,some, ...etc));

// async iterator
AsyncSource = 
  AsyncGenerators(ex: fromAsAsync, fromConcatAsAsync, ...etc) |
  SyncSource.to(asyncSeq()) | // iterable to async iterable. |
  AsyncSource.to(To(ex: shareAsync)) |
  AsyncSource.pipe(
    ...AsyncOperators(ex: mapAsync, filterAsync, ...etc)
  );

value = await AsyncSource.valueAsync(AsyncValues(ex: findAsync,someAsync, ...etc));

Because it is a lazy list, it does not execute processing when pipe()/to() is called, but only when value(valueAsync), toArray(toArrayAsync)/toMutableArray(toMutableArrayAsync), or forEach(forEachAsync) is called.

Changes from "Iterable" or Seq<T> to "Async Iterable" can be made at any time with .to(asyncSeq()). but Once the chain is changed to "Async Iterable" by .to(asyncSeq()) or other means, only the asynchronous version of Operator/Value can be used in the same chain thereafter. This is because, in principle, it is impossible to change from an "Async Iterable" to "Iterable".

The predefined Generators/Operators/To/Values are as follows. And all of them have asynchronous versions(xxxAsAsync or xxxAsync).

If the function you want to use does not exist, you can also define your own Operator/Value function in this way.

Predefined Generators

Generator Description
defer Generates a sequence that delays the generation of sources until the actual enumeration is performed. (async version: deferAsAsync )
deferFromPromise [Async Only] Generates a sequence whose values are the result of sequential execution of a single Promise or multiple Promises; Promise execution is delayed until the sequence is enumerated.
deferValue Generates a sequence that delays the generation of the source until the actual enumeration is performed. the source in deferValue consists of a single value. (async version: deferValueAsAsync )
from Generates a sequence from an iterable object. (async version: fromAsAsync )
fromConcat Generates a concatenated sequence of multiple iterable objects. (async version: fromConcatAsAsync )
fromValue Generates a sequence from a single value. (async version: fromValueAsAsync )
range Generates a sequential number sequence. (async version: rangeAsAsync )
zip Generates a sequence of arrays made by concatenating the elements of multiple sequences one at a time. (async version: zipAsAsync )

Predefined To

To Description
async Converts the current sequence to AsyncSeq<T> and returns it.
share Converts the current sequence to SharedSeq<T> and returns it; in a SharedSeq<T>, iterator is share until close method is called. (async version: shareAsync )

Predefined Operators

It is used within the pipe method of the Seq<T> object. Any number of operators can be connected.

Operator Description
catchError If the original iterable sequence raises an exception, the specified action is performed, terminating the enumeration or enumerating an alternate sequence. (async version: catchErrorAsync )
chunk Returns a sequence divided into array of the specified size. (async version: chunkAsync )
chunkByAccumulation Returns a sequence divided into arrays based on an accumulation function and a threshold condition. (async version: chunkByAccumulationAsync )
concat Returns a sequence in which the current sequence and the specified sequence are concatenated. (async version: concatAsync )
concatValue Returns the sequence to which the specified value is added. (async version: concatValueAsync )
difference Returns the sequence that is the difference set between the current sequence and the specified sequence. (async version: differenceAsync )
filter Returns a sequence that has been filtered by the specified condition. (async version: filterAsync )
finalize Invokes a specified action after the source iterable sequence terminates normally or exceptionally. (async version: finalizeAsync )
flatten Returns a flattened sequence. (async version: flattenAsync )
groupBy Returns a sequence grouped by a specified key. (async version: groupByAsync )
intersect Returns a sequence that is the product set of the current sequence and the specified sequence. (async version: intersectAsync )
map Returns the sequence in which each element has been transformed by the specified transformation function. (async version: mapAsync )
orderBy Returns a sequence sorted by a specified key. (async version: orderByAsync )
repeat Returns a sequence that repeats the source sequence a specified number of times. (async version: repeatAsync )
reverse Returns a sequence in reverse order of the current sequence. (async version: reverseAsync )
scan Returns the resulting sequence after applying the aggregate function to the elements of the current sequence. (async version: scanAsync )
skip Returns the sequence with the specified number of skips. (async version: skipAsync )
skipWhile Returns the sequence of elements skipped while matching the condition. (async version: skipWhileAsync )
take Returns a sequence that enumerates the specified number of items. (async version: takeAsync )
takeWhile Returns a sequence to be enumerated only while the condition is matched. (async version: takeWhileAsync )
tap Run side effects. (async version: tapAsync )
union Returns a sequence that is the union set of the current sequence and the specified sequence. (async version: unionAsync )
uniq Returns a deduplicated sequence. (async version: uniqAsync )
zipWith Returns a sequence of arrays consisting of the elements of the source array and the elements of the multiple sequences given as arguments, concatenated one by one. (async version: zipWithAsync )

Predefined Values

Generates a value from a sequence. Used in the value method of the Seq<T> object.

Value Description
every Returns whether or not all elements of a sequence meet the specified conditions. (async version: everyAsync )
find Returns the first element that satisfies the condition. If no element satisfying the condition is found, an error is thrown. (async version: findAsync )
findOrDefault Returns the first element that satisfies the condition. If no element is found that satisfies the condition, it returns the specified default value. (async version: findOrDefaultAsync )
reduce Returns the result of applying the aggregate function to the elements of the current sequence. (async version: reduceAsync )
some Returns whether or not any element of the sequence satisfies the specified condition. (async version: someAsync )