sflow
Version:
sflow is a powerful and highly-extensible library designed for processing and manipulating streams of data effortlessly. Inspired by the functional programming paradigm, it provides a rich set of utilities for transforming streams, including chunking, fil
829 lines (828 loc) • 37.6 kB
TypeScript
import { ReadableLike } from "web-streams-extensions";
//#region src/andIgnoreError.d.ts
declare function andIgnoreError(regex: RegExp | string): (error: unknown) => null;
//#endregion
//#region src/utils.d.ts
/** Comparable type for ordering (replaces rambda's Ord) */
type Ord = string | number;
//#endregion
//#region src/FieldPath.d.ts
/**
* Lightweight replacements for react-hook-form's FieldPathByValue / FieldPathValue.
* Only the subset needed by sflow (top-level keys) is implemented here.
*/
/**
* All top-level keys of T whose value is assignable to V.
*/
type FieldPathByValue<T, V> = { [K in keyof T & string]: T[K] extends V ? K : never }[keyof T & string];
/**
* The value type at key K in T.
*/
type FieldPathValue<T, K extends string> = K extends keyof T ? T[K] : never;
//#endregion
//#region node_modules/ts-essentials/dist/async-or-sync/index.d.ts
type AsyncOrSync<Type> = PromiseLike<Type> | Type;
//#endregion
//#region src/Awaitable.d.ts
type Awaitable<T> = Promise<T> | T;
//#endregion
//#region src/cacheLists.d.ts
/**
* 1. cache whole list once upstream flushed
* 2. Replace the stream with cached list if exist
*
* Set ttl in your store settings
*
* This step should place at near the output end.
* @deprecated use cacheSkips to reduce cache size
*/
declare function cacheLists<T>(store: {
has?: (key: string) => Awaitable<boolean>;
get: (key: string) => Awaitable<T[] | undefined>;
set: (key: string, chunks: T[]) => Awaitable<void>;
}, _options?: string | {
/**
* Key could step name,
* or defaults to `new Error().stack` if you r lazy enough
*/
key?: string;
}): TransformStream<any, any>;
//#endregion
//#region src/cacheSkips.d.ts
/**
* Assume Stream content is ordered plain json object, (class is not supported)
* And new element always insert into head
*
* Only emit unmet contents
*
* Once flow done, cache latest contents in windowSize, and skip from cached content next time
*
*
*/
declare function cacheSkips<T>(store: {
has?: (key: string) => Awaitable<boolean>;
get: (key: string) => Awaitable<T[] | undefined>;
set: (key: string, chunks: T[]) => Awaitable<void>;
}, _options?: string | {
/**
* Key could step name,
* or defaults to `new Error().stack` if you r lazy enough
*/
key?: string; /** defaults to 1, incase first n header may modify by others you could set it as 2 */
windowSize?: number;
}): TransformStream<any, any>;
//#endregion
//#region src/cacheTails.d.ts
/**
* Assume Stream content is ordered plain json object, (class is not supported)
* And new element always insert into head
*
* Set ttl in your store settings
*
* 1. cache whole list once upstream flushed
* 2. Stop upstream and Continue with cached list once head matched
*
* This step should place at near the output end.
*/
declare function cacheTails<T>(store: {
has?: (key: string) => Awaitable<boolean>;
get: (key: string) => Awaitable<T[] | undefined>;
set: (key: string, chunks: T[]) => Awaitable<void>;
}, _options?: string | {
/**
* Key could step name,
* or defaults to `new Error().stack` if you r lazy enough
*/
key?: string;
}): {
writable: WritableStream<any>;
readable: ReadableStream<any>;
};
//#endregion
//#region src/chunkBys.d.ts
/** chunk items by compareFn, group items with same Ord */
declare function chunkBys<T>(compareFn: (x: T) => Awaitable<Ord>): TransformStream<T, T[]>;
//#endregion
//#region src/chunkIfs.d.ts
/** chunk items if condition is true */
declare function chunkIfs<T>(predicate: (x: T, i: number, chunks: T[]) => Awaitable<boolean>, {
inclusive
}?: {
inclusive?: boolean | undefined;
}): TransformStream<T, T[]>;
//#endregion
//#region src/chunkIntervals.d.ts
/**
* Collect items into lists, but collect item[] in interval (ms)
* Note: will emit all
*/
declare function chunkIntervals<T>(interval?: number): TransformStream<T, T[]>;
//#endregion
//#region src/chunks.d.ts
declare function chunks<T>(n?: number): TransformStream<T, T[]>;
//#endregion
//#region src/chunkTransforms.d.ts
type ChunkTransformer<T> = (chunks: T[], ctrl: TransformStreamDefaultController<T>) => Awaitable<T[]>;
/**
* Creates a TransformStream that processes chunks using provided transformers.
*
* @template T - The type of chunk that the TransformStream will process.
*
* @param {Object} options - The options object containing transformer functions.
* @param {ChunkTransformer<T>} [options.start] - The transformer function to run when the stream is started.
* @param {ChunkTransformer<T>} [options.transform] - The transformer function to run for each chunk, current chunk will be the last element.
* @param {ChunkTransformer<T>} [options.flush] - The transformer function to run when the stream is flushed.
*
* @returns A new TransformStream that applies the provided transformers.
*/
declare function chunkTransforms<T>(options: {
start?: ChunkTransformer<T>;
transform?: ChunkTransformer<T>;
flush?: ChunkTransformer<T>;
}): TransformStream<T, T>;
//#endregion
//#region src/confluences.d.ts
/** Confluence of multiple flow sources by breadth first */
/** @deprecated use confluencesBy */
declare const confluences: <T>({
order
}?: {
order?: "breadth" | "deepth" | "faster";
}) => TransformStream<ReadableStream<T>, T>;
//#endregion
//#region src/convolves.d.ts
/**
* @example
* convolves(2)
* [1,2,3,4] => [[1,2],[2,3],[3,4]]
* convolves(3)
* [1,2,3,4] => [[1,2,3],[2,3,4]]
*/
declare function convolves<T>(n: number): TransformStream<T, T[]>;
//#endregion
//#region src/debounces.d.ts
declare function debounces<T>(t: number): TransformStream<T, T>;
//#endregion
//#region src/FlowSource.d.ts
type FlowSource<T> = Promise<T> | Iterable<T> | AsyncIterable<T> | (() => Iterable<T>) | (() => AsyncIterable<T>) | ReadableLike<T> | ReadableStream<T>;
//#endregion
//#region src/flatMaps.d.ts
declare function flatMaps<T, R>(fn: (x: T, i: number) => Awaitable<R[]>): TransformStream<T, R>;
//#endregion
//#region src/flats.d.ts
/**
* Flattens an array of arrays into a stream of values.
* If the input is an empty array, it will throw an error.
* To avoid this error, you can add a `.filter(array => array.length)` stage before
*
* @returns A TransformStream that flattens an array of arrays into a stream of values.
*/
declare function flats<T>(): TransformStream<T[], T> & {
by: <Z>(stream: TransformStream<T, Z>) => TransformStream<T[], Z> & {
by: <Z_1>(stream: TransformStream<Z, Z_1>) => TransformStream<T[], Z_1> & {
by: <Z_2>(stream: TransformStream<Z_1, Z_2>) => TransformStream<T[], Z_2> & {
by: <Z_3>(stream: TransformStream<Z_2, Z_3>) => TransformStream<T[], Z_3> & {
by: <Z_4>(stream: TransformStream<Z_3, Z_4>) => TransformStream<T[], Z_4> & {
by: <Z_5>(stream: TransformStream<Z_4, Z_5>) => TransformStream<T[], Z_5> & {
by: <Z_6>(stream: TransformStream<Z_5, Z_6>) => TransformStream<T[], Z_6> & {
by: <Z_7>(stream: TransformStream<Z_6, Z_7>) => TransformStream<T[], Z_7> & {
by: <Z_8>(stream: TransformStream<Z_7, Z_8>) => TransformStream<T[], Z_8> & {
by: <Z_9>(stream: TransformStream<Z_8, Z_9>) => TransformStream<T[], Z_9> & {
by: <Z_10>(stream: TransformStream<Z_9, Z_10>) => TransformStream<T[], Z_10> & /*elided*/any;
};
};
};
};
};
};
};
};
};
};
};
//#endregion
//#region src/heads.d.ts
declare function heads<T>(n?: number): TransformStream<T, T>;
//#endregion
//#region src/limits.d.ts
/** Currently will not pipe down more items after count satisfied */
declare function limits<T>(n: number, {
terminate
}?: {
terminate?: boolean | undefined;
}): TransformStream<T, T>;
//#endregion
//#region src/lines.d.ts
type LinesOptions = {
EOL?: "KEEP" | "LF" | "CRLF" | "NONE";
};
/** split string stream into lines stream, handy to concat LLM's tokens stream into line by line stream or split a long string by lines */
declare const lines: (opts?: LinesOptions) => TransformStream<string, string>;
//#endregion
//#region src/logs.d.ts
type MapFnIndexed<T> = (x: T, i?: number) => Awaitable<any>;
/**
* log the value and index and return as original stream, handy to debug.
* Note: stream won't await the log function.
*/
declare function logs<T>(mapFn?: MapFnIndexed<T>): TransformStream<T, T>;
//#endregion
//#region src/mapAddFields.d.ts
declare function mapAddFields<K extends string, T extends Record<string, any>, R>(key: K, fn: (x: T, i: number) => Awaitable<R>): TransformStream<T, Omit<T, K> & { [key in K]: R }>;
//#endregion
//#region src/peeks.d.ts
/** Note: peeks will not await peek fn, use forEachs if you want downstream tobe awaited */
declare function peeks<T>(fn: (x: T, i: number) => Awaitable<void>): TransformStream<T, T>;
//#endregion
//#region src/riffles.d.ts
declare function riffles<T>(sep: T): TransformStream<T, T>;
//#endregion
//#region src/SourcesType.d.ts
type SourcesType<SRCS extends FlowSource<unknown>[]> = SRCS extends FlowSource<infer T>[] ? T : never;
//#endregion
//#region src/skips.d.ts
declare function skips<T>(n?: number): TransformStream<T, T>;
//#endregion
//#region src/slices.d.ts
declare function slices<T>(start?: number, end?: number): {
writable: WritableStream<T>;
readable: ReadableStream<T>;
};
//#endregion
//#region src/strings.d.ts
declare const matchs: (matcher: {
[Symbol.match](string: string): RegExpMatchArray | null;
}) => TransformStream<string, RegExpMatchArray | null>;
declare const matchAlls: (regexp: RegExp) => TransformStream<string, IterableIterator<RegExpExecArray>>;
declare const replaces: {
/**
* Replaces text in a string, using a regular expression or search string.
* @param searchValue A string or regular expression to search for.
* @param replaceValue A string containing the text to replace. When the {@linkcode searchValue} is a `RegExp`, all matches are replaced if the `g` flag is set (or only those matches at the beginning, if the `y` flag is also present). Otherwise, only the first match of {@linkcode searchValue} is replaced.
*/
(searchValue: string | RegExp, replaceValue: string): TransformStream<string, string>;
/**
* Replaces text in a string, using a regular expression or search string.
* @param searchValue A string to search for.
* @param replacer A function that returns the replacement text.
*/
(searchValue: string | RegExp, replacer: (substring: string, ...args: any[]) => Awaitable<string>): TransformStream<string, string>;
/**
* Passes a string and {@linkcode replaceValue} to the `[Symbol.replace]` method on {@linkcode searchValue}. This method is expected to implement its own replacement algorithm.
* @param searchValue An object that supports searching for and replacing matches within a string.
* @param replaceValue The replacement text.
*/
(searchValue: string | RegExp | {
[Symbol.replace](string: string, replaceValue: string): string;
}, replaceValue: string): TransformStream<string, string>;
/**
* Replaces text in a string, using an object that supports replacement within a string.
* @param searchValue A object can search for and replace matches within a string.
* @param replacer A function that returns the replacement text.
*/
(searchValue: string | RegExp | {
[Symbol.replace](string: string, replacer: (substring: string, ...args: any[]) => string): string;
}, replacer: (substring: string, ...args: any[]) => Awaitable<string>): TransformStream<string, string>;
};
declare const replaceAlls: {
/**
* Replace all instances of a substring in a string, using a regular expression or search string.
* @param searchValue A string to search for.
* @param replaceValue A string containing the text to replace for every successful match of searchValue in this string.
*/
(searchValue: string | RegExp, replaceValue: string): TransformStream<string, string>;
/**
* Replace all instances of a substring in a string, using a regular expression or search string.
* @param searchValue A string to search for.
* @param replacer A function that returns the replacement text.
*/
(searchValue: string | RegExp, replacer: (substring: string, ...args: any[]) => Promise<string> | string): TransformStream<string, string>;
};
//#endregion
//#region src/tails.d.ts
declare function tails<T>(n?: number): TransformStream<T, T>;
//#endregion
//#region src/takeWhiles.d.ts
/**
* Takes elements from the stream while the predicate returns true.
* Stops and terminates the stream when the predicate returns false.
*
* @param fn Predicate function that determines whether to continue taking elements
* @returns A TransformStream that takes elements while the predicate is true
* @template T The type of the input/output stream
* @example
* sflow([1, 2, 3, 4, 5])
* .takeWhile(x => x < 4)
* .toArray() // [1, 2, 3]
*/
declare function takeWhiles<T>(fn: (x: T, i: number) => Awaitable<unknown>, {
terminate
}?: {
terminate?: boolean | undefined;
}): TransformStream<T, T>;
//#endregion
//#region src/terminates.d.ts
declare function terminates<_T>(signal: AbortSignal): TransformStream<unknown, any>;
//#endregion
//#region src/throttles.d.ts
type ThrottleOption = {
/** drop=true: Drop chunks by interval, will ensure last item emit by default. set keepLast=false to drop last */drop?: boolean;
/**
* drop=true: Drop chunks by interval, will ensure last item emit by default. set keepLast=false to drop last
* has no effect when drop=false
*/
keepLast?: boolean;
};
/**
* ```ts
* drop=true: Drop chunks by interval, will ensure last item emit by default.
* set keepLast=false to drop last
*
* @example
* if you dont want item drops, please use forEach to limit speed
* sth like:
* sflow().forEach(sleep(1000)).forEach(sleep(1000)).log().done()
*/
declare function throttles<T>(interval: number, {
drop,
keepLast
}?: ThrottleOption): TransformStream<T, T>;
//#endregion
//#region src/toLatest.d.ts
/**
* Convert a readable stream to it's latest value
*
* the return object is dynamic updated
*/
declare function toLatests<T>(r: ReadableStream<T>): {
latest: Promise<T>;
next: Promise<T>;
};
//#endregion
//#region src/Unwinded.d.ts
type Unwinded<T, K> = T extends Record<string, unknown> ? K extends FieldPathByValue<T, ReadonlyArray<unknown>> ? { [key in K]: FieldPathValue<T, K> extends ReadonlyArray<infer U> ? U : never } & Omit<T, K> : never : never;
//#endregion
//#region src/uniqs.d.ts
/** uniq by a new Set(), note: use === to compare */
declare const uniqs: <T>() => TransformStream<T, T>;
/** uniq by a new Map(), Note: use === to compare keys */
declare const uniqBys: <T, K>(keyFn: (x: T) => Awaitable<K>) => TransformStream<T, T>;
//#endregion
//#region src/sflow.d.ts
type Reducer$1<S, T> = (state: S, x: T, i: number) => Awaitable<S>;
type EmitReducer<S, T, R> = (state: S, x: T, i: number) => Awaitable<{
next: S;
emit: R;
}>;
interface BaseFlow<T> {
_type: T;
readable: ReadableStream<T>;
writable: WritableStream<T>;
/** @deprecated use chunk */
buffer(...args: Parameters<typeof chunks<T>>): sflow<T[]>;
cacheSkip(...args: Parameters<typeof cacheSkips<T>>): sflow<T>;
cacheList(...args: Parameters<typeof cacheLists<T>>): sflow<T>;
cacheTail(...args: Parameters<typeof cacheTails<T>>): sflow<T>;
chunk(...args: Parameters<typeof chunks<T>>): sflow<T[]>;
/** inverse of flat, chunk all items */
chunk(): sflow<T[]>;
/** inverse of flat, chunk or buffer a length as array */
chunk(...args: Parameters<typeof chunks<T>>): sflow<T[]>;
/** group by (only affect on concat items)*/
chunkBy(...args: Parameters<typeof chunkBys<T>>): sflow<T[]>;
/** @see {@link chunkIfs} */
chunkIf(...args: Parameters<typeof chunkIfs<T>>): sflow<T[]>;
chunkTransforms<T>(options: {
start?: ChunkTransformer<T>;
transform?: ChunkTransformer<T>;
flush?: ChunkTransformer<T>;
}): sflow<T>;
/** @see convolves */
convolve(...args: Parameters<typeof convolves<T>>): sflow<T[]>;
/** act as pipeThrough<T,T> */
portal: {
(): sflow<T>;
(stream: TransformStream<T, T>): sflow<T>;
(fn: (s: sflow<T>) => FlowSource<T>): sflow<T>;
};
/** act as pipeThrough, alias of by */
through: {
(): sflow<T>;
(stream: TransformStream<T, T>): sflow<T>;
<R>(fn: (s: sflow<T>) => FlowSource<R>): sflow<R>;
<R>(stream: TransformStream<T, R>): sflow<R>;
};
/** act as pipeThrough, alias of through */
by: {
(): sflow<T>;
(stream: TransformStream<T, T>): sflow<T>;
<R>(fn: (s: sflow<T>) => AsyncOrSync<FlowSource<R>>): sflow<R>;
<R>(stream: TransformStream<T, R>): sflow<R>;
};
/** act as pipeThrough, but lazy, only pull upstream when downstream pull */
byLazy: {
(stream: TransformStream<T, T>): sflow<T>;
<R>(stream: TransformStream<T, R>): sflow<R>;
};
/** @deprecated use chunkInterval */
interval(...args: Parameters<typeof chunkIntervals<T>>): sflow<T[]>;
chunkInterval(...args: Parameters<typeof chunkIntervals<T>>): sflow<T[]>;
debounce(...args: Parameters<typeof debounces<T>>): sflow<T>;
filter(fn: (x: T, i: number) => Awaitable<any>): sflow<T>;
filter(): sflow<NonNullable<T>>;
find(fn: (x: T, i: number) => Awaitable<any>): sflow<T>;
flatMap<R>(...args: Parameters<typeof flatMaps<T, R>>): sflow<R>;
/** interleave a separator between items (alias for riffle) */
join(...args: Parameters<typeof riffles<T>>): sflow<T>;
merge(...args: FlowSource<T>[]): sflow<T>;
concat(srcs?: FlowSource<FlowSource<T>>): sflow<T>;
limit(...args: Parameters<typeof limits<T>>): sflow<T>;
head(...args: Parameters<typeof heads<T>>): sflow<T>;
map<R>(fn: (x: T, i: number) => Awaitable<R>): sflow<R>;
map<R>(fn: (x: T, i: number) => Awaitable<R>, options?: {
concurrency?: number;
}): sflow<R>;
log(...args: Parameters<typeof logs<T>>): sflow<T>;
peek(...args: Parameters<typeof peeks<T>>): sflow<T>;
riffle(...args: Parameters<typeof riffles<T>>): sflow<T>;
forEach(fn: (x: T, i: number) => Awaitable<undefined | any>): sflow<T>;
forEach(fn: (x: T, i: number) => Awaitable<undefined | any>, options?: {
concurrency?: number;
}): sflow<T>;
pMap<R>(fn: (x: T, i: number) => Awaitable<R>): sflow<R>;
pMap<R>(fn: (x: T, i: number) => Awaitable<R>, options?: {
concurrency?: number;
}): sflow<R>;
asyncMap<R>(fn: (x: T, i: number) => Awaitable<R>): sflow<R>;
asyncMap<R>(fn: (x: T, i: number) => Awaitable<R>, options?: {
concurrency?: number;
}): sflow<R>;
reduce(fn: (state: T | undefined, x: T, i: number) => Awaitable<T>): sflow<T>;
reduce(fn: Reducer$1<T, T>, initialState: T): sflow<T>;
reduce<S>(fn: (state: S | undefined, x: T, i: number) => Awaitable<S>): sflow<S>;
reduce<S>(fn: Reducer$1<S, T>, initialState: S): sflow<S>;
reduceEmit(fn: EmitReducer<T, T, T>): sflow<T>;
reduceEmit<R>(fn: EmitReducer<T, T, R>): sflow<R>;
reduceEmit<S, R>(fn: EmitReducer<S, T, R>, state: S): sflow<R>;
skip: (...args: Parameters<typeof skips<T>>) => sflow<T>;
slice: (...args: Parameters<typeof slices<T>>) => sflow<T>;
tail: (...args: Parameters<typeof tails<T>>) => sflow<T>;
takeWhile: (...args: Parameters<typeof takeWhiles<T>>) => sflow<T>;
uniq: (...args: Parameters<typeof uniqs<T>>) => sflow<T>;
unique: (...args: Parameters<typeof uniqs<T>>) => sflow<T>;
uniqBy: <K>(...args: Parameters<typeof uniqBys<T, K>>) => sflow<T>;
/**
* @deprecated use fork, forkTo
* @warning Uses `ReadableStream.tee()` internally. If the forked branch is consumed slower than the main branch,
* the tee buffer will grow unboundedly in memory (no backpressure between tee branches).
*/
tees(fn: (s: sflow<T>) => undefined | any): sflow<T>;
/**
* @deprecated use fork, forkTo
* @warning Uses `ReadableStream.tee()` internally. If the forked branch is consumed slower than the main branch,
* the tee buffer will grow unboundedly in memory (no backpressure between tee branches).
*/
tees(stream: WritableStream<T>): sflow<T>;
/**
* Fork the stream, sending a copy to the given function or writable stream, while continuing the main pipeline.
* @warning Uses `ReadableStream.tee()` internally. If the forked branch is consumed slower than the main branch,
* the tee buffer will grow unboundedly in memory (no backpressure between tee branches).
*/
forkTo(fn: (s: sflow<T>) => undefined | any): sflow<T>;
/**
* Fork the stream, sending a copy to the given writable stream, while continuing the main pipeline.
* @warning Uses `ReadableStream.tee()` internally. If the forked branch is consumed slower than the main branch,
* the tee buffer will grow unboundedly in memory (no backpressure between tee branches).
*/
forkTo(stream: WritableStream<T>): sflow<T>;
/**
* Fork the stream into two independent branches. Returns the new branch; the original stream continues.
* @warning Uses `ReadableStream.tee()` internally. If one branch is consumed slower than the other,
* the tee buffer will grow unboundedly in memory (no backpressure between tee branches).
*/
fork(): sflow<T>;
throttle: (...args: Parameters<typeof throttles<T>>) => sflow<T>;
abort(...args: Parameters<typeof terminates<T>>): sflow<T>;
terminateSignal(...args: Parameters<typeof terminates<T>>): sflow<T>;
preventAbort: () => sflow<T>;
preventClose: () => sflow<T>;
preventCancel: () => sflow<T>;
onStart: (start: TransformerStartCallback<T>) => sflow<T>;
onTransform: <R>(transform: TransformerTransformCallback<T, R>) => sflow<R>;
onFlush: (flush: TransformerFlushCallback<T>) => sflow<T>;
done: () => Promise<void>;
end: (pipeTo?: WritableStream<T>) => Promise<void>;
run: () => Promise<void>;
/** alias of pipeTo */
to: (pipeTo?: WritableStream<T>) => Promise<void>;
toArray: () => Promise<T[]>;
toEnd: () => Promise<void>;
toNil: () => Promise<void>;
/** Count stream items, and drop items */
toCount: () => Promise<number>;
/** Get first item from stream, and terminate stream */
toFirst: () => Promise<T>;
/** Get first item from stream that matches predicate, and terminate stream */
toFirstMatch: (predicate: (value: T, index: number) => Awaitable<any>) => Promise<T | undefined>;
/** Get one item from stream
* throws if more than 1 item is emitted
* return undefined if no item returned
* return the item
*/
toExactlyOne: (options?: {
required?: boolean;
}) => Promise<T | undefined>;
/** Get one item from stream
* throws if more than 1 item is emitted
* return undefined if no item returned
* return the item
* @deprecated use toExactlyOne
*/
toOne: (options?: {
required?: boolean;
}) => Promise<T | undefined>;
/** Get one item from stream
* throws if more than 1 item is emitted
* throws if no items emitted, (required defaults to false)
* return the item
*/
toAtLeastOne: (options?: {
required?: boolean;
}) => Promise<T>;
/** Returns a promise that always give you latest value of the stream */
toLatest: () => ReturnType<typeof toLatests<T>>;
/** Get last item from stream, ignore others */
toLast: () => Promise<T>;
toLog(...args: Parameters<typeof logs<T>>): Promise<void>;
}
type ArrayFlow<T> = T extends ReadonlyArray<any> ? {
flat: (...args: Parameters<typeof flats<T>>) => sflow<T[number]>;
} : {};
type DictionaryFlow<T> = T extends Record<string, any> ? {
unwind<K extends FieldPathByValue<T, ReadonlyArray<any>>>(key: K): sflow<Unwinded<T, K>>;
mapAddField: <K extends string, R>(...args: Parameters<typeof mapAddFields<K, T, R>>) => sflow<Omit<T, K> & { [key in K]: R }>;
mapMixin: <T extends Record<string, any>, R extends Record<string, any>>(fn: (x: T, i: number) => Awaitable<R>) => sflow<Omit<T, keyof R> & R>;
} : {};
type StreamsFlow<T> = T extends ReadableStream<infer R> ? {
/** @deprecated use confluencesByBreth */confluence(...args: Parameters<typeof confluences<R>>): sflow<R>;
confluenceByZip(): sflow<R>;
confluenceByConcat(): sflow<R>;
confluenceByParallel(): sflow<R>;
confluenceByAscend(ordFn: (x: R) => Ord): sflow<R>;
confluenceByDescend(ordFn: (x: R) => Ord): sflow<R>;
} : {};
type TextFlow<T> = T extends string ? {
join: (sep: string) => sflow<string>;
lines: (...args: Parameters<typeof lines>) => sflow<ReturnType<typeof lines> extends TransformStream<any, infer R> ? R : never>;
match: (...args: Parameters<typeof matchs>) => sflow<ReturnType<typeof matchs> extends TransformStream<any, infer R> ? R : never>;
matchAll: (...args: Parameters<typeof matchAlls>) => sflow<ReturnType<typeof matchAlls> extends TransformStream<any, infer R> ? R : never>;
replace: (...args: Parameters<typeof replaces>) => sflow<ReturnType<typeof replaces> extends TransformStream<any, infer R> ? R : never>;
replaceAll: (...args: Parameters<typeof replaceAlls>) => sflow<ReturnType<typeof replaceAlls> extends TransformStream<any, infer R> ? R : never>;
} : {};
type ToResponse<T> = T extends string | Uint8Array ? {
toResponse: () => Response;
text: () => Promise<string>;
json: () => Promise<any>;
blob: () => Promise<Blob>;
arrayBuffer: () => Promise<ArrayBuffer>;
} : {};
type sflowType<T extends sflow<any>> = T extends sflow<infer R> ? R : never;
type sflow<T> = ReadableStream<T> & AsyncIterableIterator<T> & BaseFlow<T> & ArrayFlow<T> & DictionaryFlow<T> & StreamsFlow<T> & TextFlow<T> & ToResponse<T>;
/** stream flow */
declare function sflow<T0, SRCS extends FlowSource<T0>[] = FlowSource<T0>[]>(...srcs: SRCS): sflow<SourcesType<SRCS>>;
//#endregion
//#region src/bys.d.ts
declare function bys<T>(stream?: TransformStream<T, T>): TransformStream<T, T>;
declare function bys<T, R>(stream: TransformStream<T, R>): TransformStream<T, R>;
declare function bys<T, R>(fn: (s: ReadableStream<T>) => PromiseLike<ReadableStream<R>> | ReadableStream<R>): TransformStream<T, R>;
//#endregion
//#region src/chunkOverlaps.d.ts
declare function chunkOverlaps<T>({
step,
overlap
}: {
step: number;
overlap: number;
}): TransformStream<T, T[]>;
//#endregion
//#region src/concats.d.ts
/**
* return a transform stream that concats streams from sources
* don't get confused with mergeStream
* concats : returns a TransformStream, which also concats upstream
* concatStream: returns a ReadableStream, which doesnt have upstream
*/
declare const concats: <T>(streams?: FlowSource<FlowSource<T>>) => TransformStream<T, T>;
/**
* return a readable stream that concats streams from sources
* don't get confused with concats
* concatStream: returns a ReadableStream, which doesnt have upstream
* concats : returns a TransformStream, which also concats upstream
*/
declare const concatStream: <T>(srcs?: FlowSource<FlowSource<T>>) => ReadableStream<T>;
//#endregion
//#region src/distributeBys.d.ts
declare const distributeBys: <T>(groupFn: (x: T) => Awaitable<Ord>) => TransformStream<T, ReadableStream<T>>;
//#endregion
//#region src/filters.d.ts
/**
* Filter a stream, return a stream with non-null values.
* If a function is provided, it will be called with each value,
* and if it returns a truthy value, the value will be included in the output
* stream.
* If no function is provided, it will filter out null and undefined values.
* This is useful for creating a stream that only contains non-null and non-undefined values.
*
* Note: empty string is considered a valid value and will not be filtered out.
*
* if you want to filter out empty strings, you can "Boolean" the filter function.
*
* @param fn Optional function to determine if a value should be included.
* @returns A TransformStream that filters the input stream.
* @template T The type of the input stream.
* @template NonNullable<T> The type of the output stream, which will not include
* null or undefined values.
* @example
*/
declare const filters: {
<T>(): TransformStream<T, NonNullable<T>>;
<T>(fn: (x: T, i: number) => Awaitable<unknown>): TransformStream<T, T>;
};
//#endregion
//#region src/finds.d.ts
declare function finds<T>(predicate: (value: T, index: number) => Awaitable<unknown>): TransformStream<T, T>;
//#endregion
//#region src/forEachs.d.ts
type asyncMapOptions$2 = {
concurrency?: number;
};
/** For each loop on stream, you can modify the item by x.property = 123 */
declare function forEachs<T>(fn: (x: T, i: number) => Awaitable<undefined | unknown>, options?: asyncMapOptions$2): TransformStream<T, T>;
//#endregion
//#region src/maps.d.ts
type asyncMapOptions$1 = {
concurrency?: number;
};
declare function maps<T, R>(fn: (x: T, i: number) => Awaitable<R>, options?: asyncMapOptions$1): TransformStream<T, R>;
//#endregion
//#region src/mergeAscends.d.ts
interface MergeBy {
<T>(ordFn: (input: T) => Ord, srcs: FlowSource<FlowSource<T>>): sflow<T>;
<T>(ordFn: (input: T) => Ord): (srcs: FlowSource<FlowSource<T>>) => sflow<T>;
}
/**
* merge multiple stream by ascend order, assume all input stream is sorted by ascend
* output stream will be sorted by ascend too.
*
* if one of input stream is not sorted by ascend, it will throw an error.
*
* @param ordFn a function to get the order of input
* @param srcs a list of input stream
* @returns a new stream that merge all input stream by ascend order
* @deprecated use {@link mergeStreamsByAscend}, this will be removed in next major version
*/
declare const mergeAscends: MergeBy;
/**
* merge multiple stream by ascend order, assume all input stream is sorted by ascend
* output stream will be sorted by ascend too.
*
* if one of input stream is not sorted by ascend, it will throw an error.
*
* @param ordFn a function to get the order of input
* @param srcs a list of input stream
* @returns a new stream that merge all input stream by ascend order
* @deprecated use {@link mergeStreamsByAscend}
*/
declare const mergeDescends: MergeBy;
//#endregion
//#region src/mergeStream.d.ts
/**
* return a readable stream that merges streams from sources
* don't get confused with merges
* mergeStream: returns a ReadableStream, which doesnt have upstream
* merges : returns a TransformStream, which also merges upstream
*/
declare const mergeStream: {
<T, SRCS extends FlowSource<T>[]>(...streams: SRCS): ReadableStream<SourcesType<SRCS>>;
};
//#endregion
//#region src/mergeStreamsBy.d.ts
type Slots<T> = Array<{
value?: T;
done: boolean;
} | null>;
type Transformer<T> = (slots: Slots<T>, ctrl: ReadableStreamDefaultController<T>) => Awaitable<Slots<T>>;
type OrdFn<T> = (value: T) => Ord;
declare function mergeStreamsBy<T>(transform: Transformer<T>, srcs: FlowSource<T>[]): sflow<T>;
declare function mergeStreamsBy<T>(transform: Transformer<T>): (srcs: FlowSource<T>[]) => sflow<T>;
declare function mergeStreamsByAscend<T>(ordFn: OrdFn<T>, sources: FlowSource<T>[]): sflow<T>;
declare function mergeStreamsByAscend<T>(ordFn: OrdFn<T>): (sources: FlowSource<T>[]) => sflow<T>;
declare function mergeStreamsByDescend<T>(ordFn: OrdFn<T>, srcs: FlowSource<T>[]): sflow<T>;
declare function mergeStreamsByDescend<T>(ordFn: OrdFn<T>): (srcs: FlowSource<T>[]) => sflow<T>;
//#endregion
//#region src/merges.d.ts
/**
* return a transform stream that merges streams from sources
* don't get confused with mergeStreamw
* merges : returns a TransformStream, which also merges upstream
* mergeStream: returns a ReadableStream, which doesnt have upstream
*/
declare const merges: <T>(...streams: FlowSource<T>[]) => TransformStream<T, T>;
//#endregion
//#region src/nils.d.ts
declare function nils<T = null>(): WritableStream<T>;
declare function nil<T = null>(): T;
//#endregion
//#region src/pageStream.d.ts
/** Returns {data} */
type PageFetcher<Data, Cursor> = (cursor: Cursor) => Awaitable<{
data?: Data;
next?: Cursor | null;
}>;
declare function pageStream<Data, Cursor>(initialQuery: Awaitable<Cursor>, fetcher: PageFetcher<Data, Cursor>): ReadableStream<Data>;
//#endregion
//#region src/pageFlow.d.ts
declare function pageFlow<Data, Cursor>(initialCursor: Awaitable<Cursor>, fetcher: PageFetcher<Data, Cursor>): sflow<Data>;
//#endregion
//#region src/pMaps.d.ts
type asyncMapOptions = {
concurrency?: number;
};
declare const pMaps: <T, R>(fn: (x: T, i: number) => Awaitable<R>, options?: asyncMapOptions) => TransformStream<T, R>;
//#endregion
//#region src/portals.d.ts
/** pipe upstream through a PortalStream, aka. TransformStream<T, T> */
declare const portals: {
<T>(stream?: TransformStream<T, T>): TransformStream<T, T>;
<T>(fn: (s: ReadableStream<T>) => ReadableStream<T>): TransformStream<T, T>;
};
//#endregion
//#region src/rangeStream.d.ts
declare function rangeStream(minInclusive: number, maxExclusive: number): ReadableStream<number>;
declare function rangeStream(maxExclusive: number): ReadableStream<number>;
declare function rangeFlow(minInclusive: number, maxExclusive: number): sflow<number>;
declare function rangeFlow(maxExclusive: number): sflow<number>;
//#endregion
//#region src/reduces.d.ts
type Reducer<S, T> = (state: S, x: T, i: number) => Awaitable<S>;
type ReducerWithUndefinedInitialState<T> = (state: T | undefined, x: T, i: number) => Awaitable<T>;
/** return undefined to skip emit */
declare const reduces: {
<T>(fn: ReducerWithUndefinedInitialState<T>): TransformStream<T, T>;
<T>(fn: Reducer<T, T>, initialState: T): TransformStream<T, T>;
<T, S>(fn: Reducer<S, T>): TransformStream<T, S>;
<T, S>(fn: Reducer<S, T>, initialState: S): TransformStream<T, S>;
};
//#endregion
//#region src/retry.d.ts
declare function retry<T extends any[], R>(onError: (error: unknown, attempt: number, fn: (...args: T) => Promise<R>, ...args: T) => Awaitable<R>, fn: (...args: T) => Awaitable<R>): (...args: T) => Promise<R>;
//#endregion
//#region src/sfTemplate.d.ts
/** sflow Template */
declare function sfTemplate(tsa: TemplateStringsArray, ...args: FlowSource<string>[]): sflow<string>;
declare const sfT: typeof sfTemplate;
//#endregion
//#region src/streamAsyncIterator.d.ts
declare function streamAsyncIterator<T>(this: ReadableStream<T>): AsyncGenerator<Awaited<T>, void, unknown>;
//#endregion
//#region src/svector.d.ts
/** stream vector */
declare const svector: <T>(...src: ReadonlyArray<T>) => sflow<T>;
//#endregion
//#region src/tees.d.ts
/**
* Create a TransformStream that tees (forks) the stream, passing one branch to the given function or writable stream.
* @warning Uses `ReadableStream.tee()` internally. If the forked branch is consumed slower than the main branch,
* the tee buffer will grow unboundedly in memory (no backpressure between tee branches).
*/
declare const tees: {
<T>(fn: (s: ReadableStream<T>) => undefined | any): TransformStream<T, T>;
<T>(stream?: WritableStream<T>): TransformStream<T, T>;
};
//#endregion
//#region src/throughs.d.ts
/** pipe upstream through a transform stream */
declare const throughs: {
<T>(stream?: TransformStream<T, T>): TransformStream<T, T>;
<T, R>(stream: TransformStream<T, R>): TransformStream<T, R>;
<T, R>(fn: (s: ReadableStream<T>) => ReadableStream<R>): TransformStream<T, R>;
};
//#endregion
//#region src/unpromises.d.ts
/** unwrap promises of readable stream */
declare function unpromises<T>(promise: AsyncOrSync<ReadableStream<T>>): ReadableStream<T>;
//#endregion
//#region src/unwinds.d.ts
declare function unwinds<T extends Record<string, unknown>, K extends keyof T & string>(key: K): TransformStream<T, Unwinded<T, K>>;
//#endregion
//#region src/composers.d.ts
type COMOPSER<T, R> = TransformStream<T, R> & {
by: <Z>(stream: TransformStream<R, Z>) => COMOPSER<T, Z>;
};
declare function composers<T, R>(stream: TransformStream<T, R>): COMOPSER<T, R>;
declare namespace sf_d_exports {
export { FlowSource, Unwinded, terminates as aborts, chunks as buffers, bys, cacheLists, cacheSkips, cacheTails, chunkBys, chunkIfs, chunkIntervals, chunkOverlaps, chunkTransforms, chunks, composers, concatStream, concats, confluences, debounces, distributeBys as distributesBy, filters, flatMaps, flats, forEachs, sflow as from, chunkIntervals as intervals, merges as joins, lines, logs, mapAddFields, maps, matchAlls, matchs, mergeAscends, mergeDescends, mergeStream, mergeStreamsBy, mergeStreamsByAscend, mergeStreamsByDescend, merges, nil, nils, pMaps, pageFlow, pageStream, peeks, portals, rangeFlow, rangeStream, reduces, replaceAlls, replaces, retry, sflow as sf, sfT, sfTemplate, sflow, sflowType, skips, slices, sflow as snoflow, streamAsyncIterator, svector as sv, svector, tails, tees, throttles, throughs, uniqBys, uniqs, unpromises, unwinds };
}
//#endregion
export { type FlowSource, type Unwinded, terminates as aborts, andIgnoreError, chunks as buffers, chunks, bys, cacheLists, cacheSkips, cacheTails, chunkBys, chunkIfs, chunkIntervals, chunkIntervals as intervals, chunkOverlaps, chunkTransforms, concatStream, concats, confluences, debounces, sflow as default, sflow, sflow as snoflow, distributeBys as distributesBy, filters, finds, flatMaps, flats, forEachs, merges as joins, merges, lines, logs, mapAddFields, maps, matchAlls, matchs, mergeAscends, mergeDescends, mergeStream, mergeStreamsBy, mergeStreamsByAscend, mergeStreamsByDescend, nil, nils, pMaps, pageFlow, pageStream, peeks, portals, rangeFlow, rangeStream, reduces, replaceAlls, replaces, retry, sf_d_exports as sf, sfT, sfTemplate, type sflowType, skips, slices, streamAsyncIterator, svector as sv, svector, tails, takeWhiles, tees, throttles, throughs, uniqBys, uniqs, unpromises, unwinds };
//# sourceMappingURL=index.d.ts.map