-
-
Notifications
You must be signed in to change notification settings - Fork 84
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
fix: Add
opBuffer
operator to pipes (#5475)
- Loading branch information
Showing
14 changed files
with
216 additions
and
4 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
25 changes: 25 additions & 0 deletions
25
packages/cspell-pipe/src/async/__snapshots__/index.test.ts.snap
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html | ||
|
||
exports[`Pipe Sync API > pipe api 1`] = ` | ||
[ | ||
"opAppend", | ||
"opBuffer", | ||
"opCombine", | ||
"opConcatMap", | ||
"opFilter", | ||
"opFirst", | ||
"opFlatten", | ||
"opJoinStrings", | ||
"opLast", | ||
"opMap", | ||
"opReduce", | ||
"opSkip", | ||
"opTake", | ||
"opTap", | ||
"opUnique", | ||
"pipe", | ||
"pipeAsync", | ||
"reduce", | ||
"toArray", | ||
] | ||
`; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
import { describe, expect, test } from 'vitest'; | ||
|
||
import * as pipe from './index.js'; | ||
|
||
describe('Pipe Sync API', () => { | ||
test('pipe api', () => { | ||
expect(Object.keys(pipe).sort()).toMatchSnapshot(); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
export { toArrayAsync as toArray } from '../helpers/toArray.js'; | ||
export type { OperatorAsync as Operator } from '../operators/index.js'; | ||
export { | ||
opAppendAsync as opAppend, | ||
opBufferAsync as opBuffer, | ||
opCombineAsync as opCombine, | ||
opConcatMapAsync as opConcatMap, | ||
opFilterAsync as opFilter, | ||
opFirstAsync as opFirst, | ||
opFlattenAsync as opFlatten, | ||
opJoinStringsAsync as opJoinStrings, | ||
opLastAsync as opLast, | ||
opMapAsync as opMap, | ||
opReduceAsync as opReduce, | ||
opSkipAsync as opSkip, | ||
opTakeAsync as opTake, | ||
opTapAsync as opTap, | ||
opUniqueAsync as opUnique, | ||
} from '../operators/index.js'; | ||
export { pipeAsync as pipe, pipeAsync } from '../pipe.js'; | ||
export { reduceAsync as reduce } from '../reduce.js'; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
import { describe, expect, test } from 'vitest'; | ||
|
||
import { toArray } from '../helpers/index.js'; | ||
import { pipeAsync, pipeSync } from '../pipe.js'; | ||
import { opBuffer } from './buffer.js'; | ||
import { opTake } from './take.js'; | ||
|
||
describe('Validate buffer', () => { | ||
const values = ['one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight', 'nine', 'ten', 'eleven']; | ||
const values2 = [ | ||
['one', 'two'], | ||
['three', 'four'], | ||
['five', 'six'], | ||
['seven', 'eight'], | ||
['nine', 'ten'], | ||
['eleven'], | ||
]; | ||
const values3 = [ | ||
['one', 'two', 'three'], | ||
['four', 'five', 'six'], | ||
['seven', 'eight', 'nine'], | ||
['ten', 'eleven'], | ||
]; | ||
|
||
test.each` | ||
values | size | expected | ||
${values} | ${1} | ${values.map((v) => [v])} | ||
${values} | ${2} | ${values2} | ||
${values} | ${3} | ${values3} | ||
`('buffer $size', async ({ values, size, expected }) => { | ||
const resultSync = toArray(pipeSync(values, opBuffer(size))); | ||
expect(resultSync).toEqual(expected); | ||
|
||
const resultAsync = await toArray(pipeAsync(values, opBuffer(size))); | ||
expect(resultAsync).toEqual(expected); | ||
}); | ||
|
||
test('buffer async array of promises', async () => { | ||
const result = await toArray(pipeAsync(delay(mapP(values), 1), opBuffer(3))); | ||
expect(result).toEqual(values3); | ||
}); | ||
|
||
test('buffer stop early', async () => { | ||
let i = 0; | ||
let finallyCalled = false; | ||
function* gen() { | ||
try { | ||
i = 0; | ||
for (const v of values) { | ||
++i; | ||
yield v; | ||
} | ||
} finally { | ||
finallyCalled = true; | ||
} | ||
} | ||
|
||
const result = toArray(pipeSync(gen(), opBuffer(3), opTake(3))); | ||
expect(i).toBe(3 * 3); | ||
expect(finallyCalled).toBe(true); | ||
expect(result).toEqual(values3.slice(0, 3)); | ||
|
||
finallyCalled = false; | ||
const resultAsync = await toArray(pipeAsync(gen(), opBuffer(3), opTake(2))); | ||
expect(i).toBe(3 * 2); | ||
expect(finallyCalled).toBe(true); | ||
expect(resultAsync).toEqual(values3.slice(0, 2)); | ||
}); | ||
}); | ||
|
||
function mapP<T>(v: T[]): Promise<T>[] { | ||
return v.map((v) => Promise.resolve(v)); | ||
} | ||
|
||
async function* delay<T>(values: T[], ms: number): AsyncIterable<T> { | ||
for (const v of values) { | ||
await new Promise((resolve) => setTimeout(resolve, ms)); | ||
yield v; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
import { isAsyncIterable } from '../helpers/util.js'; | ||
import type { PipeFn } from '../internalTypes.js'; | ||
|
||
/** | ||
* Buffer the input iterable into arrays of the given size. | ||
* @param size - The size of the buffer. | ||
* @returns A function that takes an async iterable and returns an async iterable of arrays of the given size. | ||
*/ | ||
export function opBufferAsync<T>(size: number): (iter: AsyncIterable<T>) => AsyncIterable<T[]> { | ||
async function* fn(iter: Iterable<T> | AsyncIterable<T>) { | ||
let buffer: T[] = []; | ||
for await (const v of iter) { | ||
buffer.push(v); | ||
if (buffer.length >= size) { | ||
yield buffer; | ||
buffer = []; | ||
} | ||
} | ||
|
||
if (buffer.length > 0) { | ||
yield buffer; | ||
} | ||
} | ||
|
||
return fn; | ||
} | ||
|
||
/** | ||
* @param size - The size of the buffer. | ||
* @returns A function that takes an iterable and returns an iterable of arrays of the given size. | ||
*/ | ||
export function opBufferSync<T>(size: number): (iter: Iterable<T>) => Iterable<T[]> { | ||
function* fn(iter: Iterable<T>) { | ||
let buffer: T[] = []; | ||
for (const v of iter) { | ||
buffer.push(v); | ||
if (buffer.length >= size) { | ||
yield buffer; | ||
buffer = []; | ||
} | ||
} | ||
|
||
if (buffer.length > 0) { | ||
yield buffer; | ||
} | ||
} | ||
|
||
return fn; | ||
} | ||
|
||
export function opBuffer<T>(size: number): PipeFn<T, T[]> { | ||
const asyncFn = opBufferAsync<T>(size); | ||
const syncFn = opBufferSync<T>(size); | ||
|
||
function _(i: Iterable<T>): Iterable<T[]>; | ||
function _(i: AsyncIterable<T>): AsyncIterable<T[]>; | ||
function _(i: Iterable<T> | AsyncIterable<T>): Iterable<T[]> | AsyncIterable<T[]> { | ||
return isAsyncIterable(i) ? asyncFn(i) : syncFn(i); | ||
} | ||
return _; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters