bdchauvette / icw Goto Github PK
View Code? Open in Web Editor NEW:boat: Async iteration utility library for JavaScript
License: BSD Zero Clause License
:boat: Async iteration utility library for JavaScript
License: BSD Zero Clause License
e.g. mapSync
, filterSync
.
Need to figure out how to integrate this with the ICW
class.
cf. Array#flat
TODO:
src
This is a bundling-only step for better interop with unpkg
, and should not involve transpiling or polyfills.
For comparing whether the items in each iterable are Object.is
equal
isEqual([1, 2, 3], [1, 2, 3]) // true
isEqual([1, 2, 3], [4, 5, 6]) // false
For functions like nth
, indexOf
and last
, it would be nice to have a fast path that just accesses the value at the underlying index (if available), instead of iterating through the entire iterable.
cf. Array#join
cf. Array#findIndex
[head, ...tail]
[first, /* ... */, last]
head
and first
can just be aliases.
cf. array.splice
Instead of only accepting AsyncIterable<T>
and Iterable<T>
, functions should accept a type of:
type IterableLike<T> = AsyncIterable<T> | Iterable<T> | ArrayLike<T> | Promise<T> | PromiseLike<T>
This accomplishes two things:
from
Regarding #1, from
currently accepts a range of inputs that are converted to an AsyncIterable
. If we implicitly accept these inputs in each method, then
We can accomplish this without too much overhead by adding an (internal?) method that avoids casting AsyncIterable
and Iterable
to an AsyncIterable
, e.g.
function toIterable(iterableLike: IterableLike<T>) {
if (isAsyncIterable(iterableLike) || isIterable(iterableLike)) return iterableLike;
// ...
}
Then inside each function, instead of just doing:
for await (let value of iterable) {}
we can do
for await (let value of toIterable(iterable)) {}
This doesn't replace from
, which converts its input to an AsyncIterable
, but it does make the overall API more (IMO) intuitive.
When trying to implement methods that return single values (e.g. reduce
, indexOf
, etc), there's a bit of tension between wanting to make an API that's super chainable and one that behaves more like native JS.
Currently, these methods return AsyncIterables
that contain a single item. This lets us pass the result of these items into any of the other functions that expect an iterable
, e.g.
// Weird, but illustrative?
compose(
_ => map(_, double),
_ => reduce(_, sum),
_ => map(_, (n => [n, n, n]),
_ => reduce(_, sum),
)
However, this is less intuitive if we really just want a single value:
// Doesn't work :(
let summedValues = await reduce([1, 2, 3], sum)
If we make reduce
& friends return a Promise
, and make all of the functions accept an IterableLike
, we get the best of both worlds.
This makes it harder to know which methods will be eager, and which will be lazy, which adds overall complexity to the library.
We could fix this by making everything eager, but that's even less appealing to me.
We could also have a rule like "any method that returns a single value returns a Promise instead of an iterable", but I'm not sure if that's ideal, either?
Returning Promises from chainable methods (e.g. ICW.of(1, 2, 3).reduce(sum)
) breaks the chainability, and leads to a disconnect between the standalone methods and the chainable interface. That is, it's kind of weird if we can compose
or flow
all of the standalone methods together, but we can't do that with the chainable ones.
To be fair, the chainable API (i.e. the ICW
class) is kind of a second-class citizen because it's not tree-shakeable, and is more complex to implement than the standalone functions.
We could also get around this by having the chainable methods return a subclass of Promise
that contains all of the chainable methods, e.g.
class ICW<T> {
// ...
reduce(fn): ICWPromise<T> {}
}
But I'm not sure (1) how to do that without circular dependencies, and (2) if it's worth the complexity.
It might be better to just punt on making these particular methods chainable for now.
e.g. fromDOMEvent
for converting events from a DOM EventTarget
, and fromNodeEvent
for EventEmitter
events.
cf. Array#flatMap
TODO:
tsc
with @babel/preset-typescript
tsc
for emitting declarationsThis will hopefully simplify the testing setup, and will allow us to use babel plugins to e.g. add file extensions to import statements, so the script can work in the browser.
This is pretty important ๐
i.e. a chainable class that extends ICW, but also includes Node-only methods for Streams or whatever.
Should probably use Symbol.species
somehow.
cf. #21
cf. Array#lastIndexOf
cf. Array#includes
cf. Array#slice
cf. Array#indexOf
cf. Array#find
Since adding plop
, we can now add new methods much easier by running:
npm run plop
or
yarn plop
Answer the questions, then plop will scaffold out the files, imports, and tests ๐
cf. Array#every
cf. Array#reduce
cf. Array#concat
Options object? Higher order function? ๐ต
This will be kind of gross, because it will require buffering all of the values before sorting them ๐ฟ
cf. Array#some
TODO:
To convert to a node style callback, e.g.
ICW
.from([1, 2, 3])
.map(double)
.toCallback((err, result) => console.log(result));
// 2
// 4
// 6
i.e. a function that creates an iterable containing numbers in the range provided by the arguments:
for await (let n of range(0, 3)) {
console.log(n)
}
// 0
// 1
// 2
// 3
Not sure if this really needs to async, but might be good for consistency?
i.e. a chainable class that extends ICW
, but also includes DOM-only methods.
Should probably use Symbol.species
somehow.
cf. #22
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.