Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Async sequence, ES module support and operator updates #38

Open
wants to merge 28 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
421cd87
Update project config and dependencies
ACertainCoder Mar 28, 2024
ecf5410
Update target to es2015 and use strict mode
ACertainCoder Mar 28, 2024
f21cecb
Add AsyncSequence and update related code
ACertainCoder Mar 28, 2024
5424f51
Update existing unit tests
ACertainCoder Mar 28, 2024
8ad71fe
Reorganize existing unit tests
ACertainCoder Mar 28, 2024
6418955
Update docs entrypoint
ACertainCoder Mar 28, 2024
dcc58cc
Update existing unit tests
ACertainCoder Mar 28, 2024
e90f17d
Use Reflect api when applying mixins
ACertainCoder Mar 28, 2024
9d0ecc0
Add JSDoc to creation functions
ACertainCoder Mar 28, 2024
b703cce
Fix compatibility with regular iterables
ACertainCoder Mar 30, 2024
abf5f25
Remove irregular promise support
ACertainCoder Mar 30, 2024
b75ab0b
Replace redundant code
ACertainCoder Mar 30, 2024
a49cdc8
Update types to not error on non-void return value
ACertainCoder Mar 30, 2024
a138ed9
Use nullish coalescing operator
ACertainCoder Mar 30, 2024
0f95424
Update jsdoc
ACertainCoder Mar 30, 2024
cc68f2b
Add to(Async)Sequence and onEachIndexed
ACertainCoder Mar 30, 2024
cb27238
Update existing unit tests
ACertainCoder Mar 30, 2024
27ea98b
Add unit tests for async sequence
ACertainCoder Mar 30, 2024
af077bf
Add unit tests for to(Async)Sequence
ACertainCoder Mar 30, 2024
6dd1474
Add unit tests for onEachIndexed
ACertainCoder Mar 30, 2024
068de63
Update entrypoints
ACertainCoder Mar 30, 2024
5976e08
Update imports and exports
ACertainCoder Mar 30, 2024
165ed10
Update API doc
ACertainCoder Mar 30, 2024
346f456
Replace redundant code
ACertainCoder Mar 30, 2024
91795cc
Add ESM support
ACertainCoder Mar 30, 2024
987e223
Remove irregular promise support
ACertainCoder Mar 30, 2024
5b68f1b
Replace Promise.resolve with async
ACertainCoder Mar 30, 2024
737fd17
Add unit tests for filterHolistically
ACertainCoder Mar 30, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
.DS_Store
.idea
.yarn
*.iml

lib
Expand Down
1 change: 1 addition & 0 deletions .yarnrc.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
nodeLinker: node-modules
12 changes: 9 additions & 3 deletions APIDOC.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,16 @@ Download the [latest release](https://github.com/winterbe/sequency/releases) fro
```bash
npm install sequency
```

or

```bash
yarn add sequency
```

### How Sequency works
## How Sequency works

Sequency is centered around the interface [Sequence](https://winterbe.github.io/sequency/interfaces/Sequence.html) to process any kind of iterable data such as arrays, maps and sets.
Sequency is centered around the interface [Sequence](https://winterbe.github.io/sequency/interfaces/Sequence.html) to process any kind of iterable data such as arrays, maps and sets.

The interface `Sequence` provides a fluent functional API consisting of intermediate and terminal operations. Intermediate functions return a new sequence, thus enabling method chaining while terminal functions return an arbitrary result. You can explore all available `Sequence` operations by navigating to the [Sequence](https://winterbe.github.io/sequency/interfaces/Sequence.html) interface.

Expand Down Expand Up @@ -46,6 +48,10 @@ const result = asSequence(numbers)
// result: [5, 4, 3]
```

### License
## Asynchronous sequences

Sequency supports promises via the dedicated interface [AsyncSequence](https://winterbe.github.io/sequency/interfaces/AsyncSequence.html). This requires you to await the result of terminal functions.

## License

MIT © [winterbe](https://twitter.com/winterbe_)
66 changes: 42 additions & 24 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,30 @@
"name": "sequency",
"version": "0.20.0",
"description": "Functional sequences for processing iterable data in JavaScript",
"main": "lib/Sequence.js",
"umd:main": "lib-umd/sequency.js",
"typings": "lib/Sequence.d.ts",
"main": "./lib/cjs/sequency.js",
"module": "./lib/esm/sequency.js",
"umd:main": "./lib/umd/sequency.js",
"types": "./lib/types/sequency.d.ts",
"exports": {
".": {
"default": "./lib/cjs/sequency.js",
"require": "./lib/cjs/sequency.js",
"import": "./lib/esm/sequency.js",
"types": "./lib/types/sequency.d.ts"
}
},
"scripts": {
"test": "jest",
"watch": "jest --watch --notify",
"coverage": "rimraf coverage && jest --coverage",
"travis": "yarn lint && yarn test",
"lint": "node_modules/.bin/tslint -c tslint.json 'src/**/*.ts' 'test/**/*.ts'",
"docs": "rimraf docs && typedoc --name Sequency --readme APIDOC.md -out docs --hideGenerator src/Sequence.ts",
"docs": "rimraf docs && typedoc --name Sequency --readme APIDOC.md -out docs --hideGenerator src/sequency.ts",
"docs-publish": "yarn docs && touch docs/.nojekyll && gh-pages -d docs -t",
"bundle": "webpack --mode production && size-limit",
"bundle-browsertest": "open ./test/browsertest-lib.html",
"clean": "rimraf lib && rimraf lib-umd && rimraf docs && rimraf coverage",
"compile": "tsc",
"clean": "rimraf lib && rimraf docs && rimraf coverage",
"compile": "node_modules/.bin/tsc -b tsconfig.json tsconfig.esm.json tsconfig.cjs.json",
"build": "yarn clean && yarn lint && yarn compile && yarn test && yarn bundle",
"prepublishOnly": "yarn build"
},
Expand All @@ -32,43 +41,52 @@
},
"files": [
"lib",
"lib-umd",
"LICENSE"
],
"engines": {
"node": ">=6.0.0"
},
"packageManager": "[email protected]",
"devDependencies": {
"@size-limit/preset-small-lib": "^7.0.8",
"@types/jest": "^27.4.1",
"gh-pages": "^3.2.3",
"jest": "^27.5.1",
"rimraf": "^3.0.2",
"size-limit": "^7.0.8",
"ts-loader": "^8.2.0",
"tslint": "^5.11.0",
"typedoc": "^0.22.13",
"typescript": "^4.6.2",
"uglifyjs-webpack-plugin": "^2.2.0",
"webpack": "^4.46.0",
"webpack-cli": "^3.3.12"
"@size-limit/preset-small-lib": "^11.1.2",
"@types/jest": "^29.5.12",
"gh-pages": "^6.1.1",
"jest": "^29.7.0",
"rimraf": "^5.0.5",
"size-limit": "^11.1.2",
"terser-webpack-plugin": "^5.3.10",
"ts-jest": "^29.1.2",
"ts-loader": "^9.5.1",
"tslint": "^6.1.3",
"typedoc": "^0.25.12",
"typescript": "^5.4.3",
"webpack": "^5.91.0",
"webpack-cli": "^5.1.4"
},
"jest": {
"moduleFileExtensions": [
"ts",
"js"
],
"transform": {
"^.+\\.ts$": "<rootDir>/preprocessor.js"
"^.+\\.ts$": [
"ts-jest",
{
"tsconfig": "./tsconfig.esm.json",
"useESM": true
}
]
},
"testMatch": [
"**/test/*.ts"
"**/test/**/*.ts"
],
"testURL": "http://localhost/"
"testEnvironmentOptions": {
"url": "http://localhost/"
}
},
"size-limit": [
{
"path": "lib-umd/sequency.min.js",
"path": "lib/umd/sequency.min.js",
"limit": "10 KB"
}
],
Expand Down
11 changes: 0 additions & 11 deletions preprocessor.js

This file was deleted.

105 changes: 105 additions & 0 deletions src/AsyncSequence.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
import {applyMixins} from "./internal";
import {All as AllOp} from "./operators/async/all";
import {Any as AnyOp} from "./operators/async/any";
import {AsIterable as AsIterableOp} from "./operators/async/asIterable";
import {Associate as AssociateOp} from "./operators/async/associate";
import {AssociateBy as AssociateByOp} from "./operators/async/associateBy";
import {Average as AverageOp} from "./operators/async/average";
import {Chunk as ChunkOp} from "./operators/async/chunk";
import {Contains as ContainsOp} from "./operators/async/contains";
import {Count as CountOp} from "./operators/async/count";
import {Distinct as DistinctOp} from "./operators/async/distinct";
import {DistinctBy as DistinctByOp} from "./operators/async/distinctBy";
import {Drop as DropOp} from "./operators/async/drop";
import {DropWhile as DropWhileOp} from "./operators/async/dropWhile";
import {ElementAt as ElementAtOp} from "./operators/async/elementAt";
import {ElementAtOrElse as ElementAtOrElseOp} from "./operators/async/elementAtOrElse";
import {ElementAtOrNull as ElementAtOrNullOp} from "./operators/async/elementAtOrNull";
import {Filter as FilterOp} from "./operators/async/filter";
import {FilterHolistically as FilterHolisticallyOp} from "./operators/async/filterHolistically";
import {FilterIndexed as FilterIndexedOp} from "./operators/async/filterIndexed";
import {FilterNot as FilterNotOp} from "./operators/async/filterNot";
import {FilterNotNull as FilterNotNullOp} from "./operators/async/filterNotNull";
import {First as FirstOp} from "./operators/async/first";
import {FirstOrNull as FirstOrNullOp} from "./operators/async/firstOrNull";
import {FlatMap as FlatMapOp} from "./operators/async/flatMap";
import {Flatten as FlattenOp} from "./operators/async/flatten";
import {Fold as FoldOp} from "./operators/async/fold";
import {FoldIndexed as FoldIndexedOp} from "./operators/async/foldIndexed";
import {ForEach as ForEachOp} from "./operators/async/forEach";
import {ForEachIndexed as ForEachIndexedOp} from "./operators/async/forEachIndexed";
import {GroupBy as GroupByOp} from "./operators/async/groupBy";
import {IndexOf as IndexOfOp} from "./operators/async/indexOf";
import {IndexOfFirst as IndexOfFirstOp} from "./operators/async/indexOfFirst";
import {IndexOfLast as IndexOfLastOp} from "./operators/async/indexOfLast";
import {JoinToString as JoinToStringOp} from "./operators/async/joinToString";
import {Last as LastOp} from "./operators/async/last";
import {LastOrNull as LastOrNullOp} from "./operators/async/lastOrNull";
import {Map as MapOp} from "./operators/async/map";
import {MapIndexed as MapIndexedOp} from "./operators/async/mapIndexed";
import {MapNotNull as MapNotNullOp} from "./operators/async/mapNotNull";
import {Max as MaxOp} from "./operators/async/max";
import {MaxBy as MaxByOp} from "./operators/async/maxBy";
import {MaxWith as MaxWithOp} from "./operators/async/maxWith";
import {Merge as MergeOp} from "./operators/async/merge";
import {Min as MinOp} from "./operators/async/min";
import {MinBy as MinByOp} from "./operators/async/minBy";
import {Minus as MinusOp} from "./operators/async/minus";
import {MinWith as MinWithOp} from "./operators/async/minWith";
import {None as NoneOp} from "./operators/async/none";
import {OnEach as OnEachOp} from "./operators/async/onEach";
import {OnEachIndexed as OnEachIndexedOp} from "./operators/async/onEachIndexed";
import {Partition as PartitionOp} from "./operators/async/partition";
import {Plus as PlusOp} from "./operators/async/plus";
import {Reduce as ReduceOp} from "./operators/async/reduce";
import {ReduceIndexed as ReduceIndexedOp} from "./operators/async/reduceIndexed";
import {Reverse as ReverseOp} from "./operators/async/reverse";
import {Single as SingleOp} from "./operators/async/single";
import {SingleOrNull as SingleOrNullOp} from "./operators/async/singleOrNull";
import {Sorted as SortedOp} from "./operators/async/sorted";
import {SortedBy as SortedByOp} from "./operators/async/sortedBy";
import {SortedByDescending as SortedByDescendingOp} from "./operators/async/sortedByDescending";
import {SortedDescending as SortedDescendingOp} from "./operators/async/sortedDescending";
import {SortedWith as SortedWithOp} from "./operators/async/sortedWith";
import {Sum as SumOp} from "./operators/async/sum";
import {SumBy as SumByOp} from "./operators/async/sumBy";
import {Take as TakeOp} from "./operators/async/take";
import {TakeWhile as TakeWhileOp} from "./operators/async/takeWhile";
import {ToArray as ToArrayOp} from "./operators/async/toArray";
import {ToMap as ToMapOp} from "./operators/async/toMap";
import {ToSequence as ToSequenceOp} from "./operators/async/toSequence";
import {ToSet as ToSetOp} from "./operators/async/toSet";
import {Unzip as UnzipOp} from "./operators/async/unzip";
import {WithIndex as WithIndexOp} from "./operators/async/withIndex";
import {Zip as ZipOp} from "./operators/async/zip";

/**
* A Sequence provides a fluent functional API consisting
* of various intermediate and terminal operations for processing the iterated data.
* The operations are evaluated lazily to avoid examining all the input data
* when it's not necessary. Sequences can be iterated only once.
*/
export interface AsyncSequence<T> extends AsyncSequenceOperators<T> {
readonly iterator: AsyncIterator<T>;
}

/**
* @hidden
*/
export interface AsyncSequenceOperators<T> extends AllOp, AnyOp, AsIterableOp, AssociateOp, AssociateByOp<T>, AverageOp, ChunkOp, ContainsOp, CountOp, DistinctOp, DistinctByOp, DropOp, DropWhileOp,
ElementAtOp, ElementAtOrElseOp, ElementAtOrNullOp, FilterOp, FilterHolisticallyOp, FilterIndexedOp, FilterNotOp, FilterNotNullOp, FirstOp, FirstOrNullOp, FlatMapOp, FlattenOp, FoldOp,
FoldIndexedOp, ForEachOp, ForEachIndexedOp, GroupByOp, IndexOfOp, IndexOfFirstOp, IndexOfLastOp, JoinToStringOp, LastOp, LastOrNullOp, MapOp, MapIndexedOp, MapNotNullOp, MaxOp, MaxByOp,
MaxWithOp, MergeOp, MinOp, MinByOp, MinusOp, MinWithOp, NoneOp, OnEachOp, OnEachIndexedOp, PartitionOp, PlusOp, ReduceOp, ReduceIndexedOp, ReverseOp, SingleOp, SingleOrNullOp, SortedOp,
SortedByOp, SortedByDescendingOp, SortedDescendingOp, SortedWithOp, SumOp, SumByOp, TakeOp, TakeWhileOp, ToArrayOp, ToMapOp, ToSetOp, ToSequenceOp, UnzipOp, WithIndexOp, ZipOp {
}

export class AsyncSequenceImpl<T> {
constructor(readonly iterator: AsyncIterator<T>) {
}
}

applyMixins(AsyncSequenceImpl, [AllOp, AnyOp, AsIterableOp, AssociateOp, AssociateByOp, AverageOp, ChunkOp, ContainsOp, CountOp, DistinctOp, DistinctByOp, DropOp, DropWhileOp,
ElementAtOp, ElementAtOrElseOp, ElementAtOrNullOp, FilterOp, FilterHolisticallyOp, FilterIndexedOp, FilterNotOp, FilterNotNullOp, FirstOp, FirstOrNullOp, FlatMapOp, FlattenOp, FoldOp,
FoldIndexedOp, ForEachOp, ForEachIndexedOp, GroupByOp, IndexOfOp, IndexOfFirstOp, IndexOfLastOp, JoinToStringOp, LastOp, LastOrNullOp, MapOp, MapIndexedOp, MapNotNullOp, MaxOp, MaxByOp,
MaxWithOp, MergeOp, MinOp, MinByOp, MinusOp, MinWithOp, NoneOp, OnEachOp, OnEachIndexedOp, PartitionOp, PlusOp, ReduceOp, ReduceIndexedOp, ReverseOp, SingleOp, SingleOrNullOp, SortedOp,
SortedByOp, SortedByDescendingOp, SortedDescendingOp, SortedWithOp, SumOp, SumByOp, TakeOp, TakeWhileOp, ToArrayOp, ToMapOp, ToSetOp, ToSequenceOp, UnzipOp, WithIndexOp, ZipOp]);
30 changes: 30 additions & 0 deletions src/BaseJoinToStringConfig.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
export interface BaseJoinToStringConfig {
/**
* Value to prepend
*/
value?: string;
/**
* Element separator
*/
separator?: string;
/**
* Element prefix
*/
prefix?: string;
/**
* Element postfix
*/
postfix?: string;
/**
* Element limit
*
* - -1: unlimited
* - 0: truncate immediately
* - 1..n: truncate after the limit is reached
*/
limit?: number;
/**
* Truncation indicator (like "...")
*/
truncated?: string;
}
Loading