Refactor event bus and queue system; detect cycles in DI realization and make
Some checks failed
continuous-integration/drone/push Build is failing
Some checks failed
continuous-integration/drone/push Build is failing
This commit is contained in:
@@ -8,6 +8,7 @@ import {
|
||||
import {Iterable, StopIteration} from './Iterable'
|
||||
import {applyWhere, WhereOperator} from './where'
|
||||
import {AsyncPipe, Pipeline} from '../support/Pipe'
|
||||
import {Awaitable} from '../support/types'
|
||||
type AsyncCollectionComparable<T> = CollectionItem<T>[] | Collection<T> | AsyncCollection<T>
|
||||
type AsyncKeyFunction<T, T2> = (item: CollectionItem<T>, index: number) => CollectionItem<T2> | Promise<CollectionItem<T2>>
|
||||
type AsyncCollectionFunction<T, T2> = (items: AsyncCollection<T>) => T2
|
||||
@@ -39,14 +40,26 @@ export class AsyncCollection<T> {
|
||||
|
||||
private async inChunksAll<T2>(key: KeyOperator<T, T2>, callback: (items: Collection<T2>) => any): Promise<void> {
|
||||
await this.storedItems.chunk(this.iteratorChunkSize, async items => {
|
||||
await callback(items.pluck(key))
|
||||
if ( typeof key !== 'function' ) {
|
||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||
// @ts-ignore
|
||||
key = x => x[key]
|
||||
}
|
||||
|
||||
await callback(items.map(key))
|
||||
})
|
||||
await this.storedItems.reset()
|
||||
}
|
||||
|
||||
private async inChunksAllNumbers<T2>(key: KeyOperator<T, T2>, callback: (items: number[]) => any): Promise<void> {
|
||||
await this.storedItems.chunk(this.iteratorChunkSize, async items => {
|
||||
await callback(items.pluck(key).map(x => Number(x))
|
||||
if ( typeof key !== 'function' ) {
|
||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||
// @ts-ignore
|
||||
key = x => x[key]
|
||||
}
|
||||
|
||||
await callback(items.map(key).map(x => Number(x))
|
||||
.all())
|
||||
})
|
||||
await this.storedItems.reset()
|
||||
@@ -275,12 +288,12 @@ export class AsyncCollection<T> {
|
||||
* @param {function} operator - item => boolean
|
||||
* @return Promise<boolean>
|
||||
*/
|
||||
async some(operator: (item: T) => boolean): Promise<boolean> {
|
||||
async some(operator: (item: T) => Awaitable<boolean|undefined|void>): Promise<boolean> {
|
||||
let contains = false
|
||||
|
||||
await this.inChunks(items => {
|
||||
await this.inChunks(async items => {
|
||||
for ( const item of items.all() ) {
|
||||
if ( operator(item) ) {
|
||||
if ( await operator(item) ) {
|
||||
contains = true
|
||||
throw new StopIteration()
|
||||
}
|
||||
@@ -394,6 +407,14 @@ export class AsyncCollection<T> {
|
||||
return new Collection<T>(newItems)
|
||||
}
|
||||
|
||||
/**
|
||||
* Like filter, but inverted. That is, filters out items that DO match the criterion.
|
||||
* @param func
|
||||
*/
|
||||
async filterOut<T2>(func: KeyFunction<T, T2>): Promise<Collection<T>> {
|
||||
return this.filter(async (...args) => !(await func(...args)))
|
||||
}
|
||||
|
||||
/**
|
||||
* Calls the passed in function if the boolean condition is true. Allows for functional syntax.
|
||||
* @param {boolean} bool
|
||||
@@ -677,14 +698,16 @@ export class AsyncCollection<T> {
|
||||
* @param {KeyOperator} key
|
||||
* @return Promise<Collection>
|
||||
*/
|
||||
async pluck<T2>(key: KeyOperator<T, T2>): Promise<Collection<T2>> {
|
||||
let newItems: CollectionItem<T2>[] = []
|
||||
async pluck<T2 extends keyof T>(key: T2): Promise<Collection<T[T2]>> {
|
||||
let newItems: CollectionItem<T[T2]>[] = []
|
||||
|
||||
await this.inChunksAll(key, async items => {
|
||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||
// @ts-ignore
|
||||
newItems = newItems.concat(items.all())
|
||||
})
|
||||
|
||||
return new Collection<T2>(newItems)
|
||||
return new Collection<T[T2]>(newItems)
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -14,7 +14,9 @@ type MaybeCollectionIndex = CollectionIndex | undefined
|
||||
type ComparisonFunction<T> = (item: CollectionItem<T>, otherItem: CollectionItem<T>) => number
|
||||
|
||||
import { WhereOperator, applyWhere, whereMatch } from './where'
|
||||
import {Awaitable, Either, isLeft, Maybe, MethodsOf, right, unright} from '../support/types'
|
||||
import {Awaitable, Awaited, Either, isLeft, Maybe, MethodsOf, right, unright} from '../support/types'
|
||||
import {AsyncCollection} from './AsyncCollection'
|
||||
import {ArrayIterable} from './ArrayIterable'
|
||||
|
||||
const collect = <T>(items: CollectionItem<T>[]): Collection<T> => Collection.collect(items)
|
||||
const toString = (item: unknown): string => String(item)
|
||||
@@ -265,6 +267,16 @@ class Collection<T> {
|
||||
return new Collection(matches)
|
||||
}
|
||||
|
||||
/**
|
||||
* Like diff, but mutates the current collection.
|
||||
* @param items
|
||||
*/
|
||||
diffInPlace<T2>(items: CollectionComparable<T|T2>): this {
|
||||
const exclude = items instanceof Collection ? items.all() : items
|
||||
this.storedItems = this.storedItems.filter(item => !exclude.includes(item))
|
||||
return this
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a collection of items that ARE in this collection, but NOT In the `items` collection
|
||||
* using a helper function to determine whether two items are equal.
|
||||
@@ -355,6 +367,14 @@ class Collection<T> {
|
||||
return right(new Collection<TRight>(newItems))
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the collection as an AsyncCollection.
|
||||
*/
|
||||
toAsync(): AsyncCollection<T> {
|
||||
const iter = new ArrayIterable([...this.storedItems])
|
||||
return new AsyncCollection<T>(iter)
|
||||
}
|
||||
|
||||
/**
|
||||
* Map a method on the underlying type, passing it any required parameters.
|
||||
* This is delightfully type-safe.
|
||||
@@ -365,6 +385,22 @@ class Collection<T> {
|
||||
return this.map(x => x[method](...params))
|
||||
}
|
||||
|
||||
/**
|
||||
* Shortcut for .mapCall(...).awaitAll().
|
||||
* @param method
|
||||
* @param params
|
||||
*/
|
||||
async awaitMapCall<T2 extends MethodsOf<T>>(method: T2, ...params: Parameters<T[T2]>): Promise<Collection<Awaited<ReturnType<T[T2]>>>> {
|
||||
return this.mapCall(method, ...params).awaitAll()
|
||||
}
|
||||
|
||||
/**
|
||||
* Await all values in the collection.
|
||||
*/
|
||||
async awaitAll(): Promise<Collection<Awaited<T>>> {
|
||||
return this.promiseMap(async x => x as Awaited<T>)
|
||||
}
|
||||
|
||||
/**
|
||||
* Map each element in the collection to a string.
|
||||
*/
|
||||
@@ -462,6 +498,14 @@ class Collection<T> {
|
||||
return new Collection(this.storedItems.filter(func ?? Boolean))
|
||||
}
|
||||
|
||||
/**
|
||||
* Like filter, but inverted. That is, removes items that DO match the criterion.
|
||||
* @param func
|
||||
*/
|
||||
filterOut<T2>(func?: KeyFunction<T, T2>): Collection<T> {
|
||||
return this.filter((...args) => !(func ?? Boolean)(...args))
|
||||
}
|
||||
|
||||
whereDefined(): Collection<NonNullable<T>> {
|
||||
return this.filter() as unknown as Collection<NonNullable<T>>
|
||||
}
|
||||
@@ -793,8 +837,8 @@ class Collection<T> {
|
||||
*
|
||||
* @param key
|
||||
*/
|
||||
pluck<T2>(key: KeyOperator<T, T2>): Collection<T2> {
|
||||
return new Collection<T2>(this.allOperator(key))
|
||||
pluck<T2 extends keyof T>(key: T2): Collection<T[T2]> {
|
||||
return new Collection<T[T2]>(this.allOperator(key))
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1188,7 +1232,7 @@ class Collection<T> {
|
||||
*
|
||||
* @param func
|
||||
*/
|
||||
tap<T2>(func: CollectionFunction<T, T2>): Collection<T> {
|
||||
tap<T2>(func: CollectionFunction<T, T2>): this {
|
||||
func(this)
|
||||
return this
|
||||
}
|
||||
|
||||
@@ -72,3 +72,5 @@ export type TypeArraySignature<TArr extends unknown[], TReturn> = (...params: TA
|
||||
export type MethodsOf<T, TMethod = (...args: any[]) => any> = {
|
||||
[K in keyof T]: T[K] extends TMethod ? K : never
|
||||
}[keyof T]
|
||||
|
||||
export type Awaited<T> = T extends PromiseLike<infer U> ? U : T
|
||||
|
||||
Reference in New Issue
Block a user