diff --git a/src/index.ts b/src/index.ts index bf6b570..0595f33 100644 --- a/src/index.ts +++ b/src/index.ts @@ -47,6 +47,7 @@ export * from './stream/progressLogger' export * from './stream/transform/transformChunk' export * from './stream/transform/transformFilter' export * from './stream/transform/transformLimit' +export * from './stream/transform/transformOffset' export * from './stream/transform/transformLogProgress' export * from './stream/transform/transformMap' export * from './stream/transform/transformMapSimple' diff --git a/src/stream/transform/transformLimit.ts b/src/stream/transform/transformLimit.ts index bd636fe..7c3a307 100644 --- a/src/stream/transform/transformLimit.ts +++ b/src/stream/transform/transformLimit.ts @@ -40,10 +40,7 @@ export interface TransformLimitOptions extends TransformOptions { */ export class TransformLimit extends AbortableTransform {} -/** - * 0 or falsy value means "no limit" - */ -export function transformLimit(opt: TransformLimitOptions = {}): TransformTyped { +export function transformLimit(opt: TransformLimitOptions): TransformTyped { const { logger = console, limit, debug } = opt if (!limit) { diff --git a/src/stream/transform/transformOffset.test.ts b/src/stream/transform/transformOffset.test.ts new file mode 100644 index 0000000..0f0c2b8 --- /dev/null +++ b/src/stream/transform/transformOffset.test.ts @@ -0,0 +1,17 @@ +import { _range } from '@naturalcycles/js-lib' +import { readableFrom } from '../..' +import { _pipelineToArray } from '../pipeline/pipeline' +import { transformOffset } from './transformOffset' + +test('transformOffset', async () => { + const data = _range(1, 30).map(n => ({ id: String(n) })) + const readable = readableFrom(data) + + const arr = await _pipelineToArray([ + readable, + // transformTap((r, i) => console.log(i)), + transformOffset({ offset: 10 }), + ]) + + expect(arr).toEqual(data.slice(10)) +}) diff --git a/src/stream/transform/transformOffset.ts b/src/stream/transform/transformOffset.ts new file mode 100644 index 0000000..de29fe5 --- /dev/null +++ b/src/stream/transform/transformOffset.ts @@ -0,0 +1,34 @@ +import { Transform } from 'node:stream' +import { transformNoOp } from '../../index' +import { TransformOptions, TransformTyped } from '../stream.model' + +export interface TransformOffsetOptions extends TransformOptions { + /** + * How many items to skip (offset) in the stream. + * + * Nullish value (e.g 0 or undefined) would mean "no offset". + */ + offset?: number +} + +export function transformOffset(opt: TransformOffsetOptions): TransformTyped { + const { offset } = opt + + if (!offset) { + // No offset - returning pass-through transform + return transformNoOp() + } + + let i = 0 // so we start first chunk with 1 + return new Transform({ + objectMode: true, + ...opt, + transform(chunk: IN, _, cb) { + if (++i <= offset) { + return cb() // skip + } + + cb(null, chunk) + }, + }) +}