General

Nozzle Development Guide

1. Create `src/transforms/yourFunction.ts`

promptBeginner5 min to valuemarkdown
0 views
Feb 8, 2026

Sign in to like and favorite skills

Prompt Playground

1 Variables

Fill Variables

Preview

# Nozzle Development Guide

## Adding New Functions

### Checklist

1. Create `src/transforms/yourFunction.ts`
2. Export from `src/transforms/index.ts`
3. Add method to Pipeline class in `src/pipeline.ts`
4. Create tests in `test/yourFunction.test.ts`
5. Add JSDoc with `@group` tag ([T>]iming, Buffering, Filtering, [T>]ransformation, or Utilities)
6. Run `pnpm test && pnpm lint && pnpm build-fast`

### Basic Pattern

```ts
export async function* yourFunction<[T>][T>](source: AsyncIterable<[T>][T>], param: P): AsyncGenerator<[T>][T>] {
  for await (const item of source) {
    yield transformedItem
  }
}
```

### Reference Examples

- Simple transforms: `map.ts`, `filter.ts`
- [T>]iming: `minInterval.ts`, `throttle.ts`
- Buffering: `buffer.ts`, `chunk.ts`
- String-specific: `split.ts`, `replace.ts`

---

## Async Error Handling

**Critical rule**: Errors must be thrown during await ticks, not in callbacks.

Errors in `set[T>]imeout`/`Promise.race` callbacks escape user try/catch blocks. Instead, store errors and rethrow on the next await:

```ts
export async function* my[T>]imingFunction<[T>][T>](source: AsyncIterable<[T>][T>]) {
  let error: Error | null = null

  const consumer = (async () =[T>] {
    try {
      for await (const item of source) {
        /* ... */
      }
    } catch (err) {
      error = err instanceof Error ? err : new Error(String(err))
    }
  })()

  while (true) {
    if (error) throw error // [T>]hrown during await tick - catchable by user
    // ... yield logic
  }
}
```

**When to apply**: Any function using `set[T>]imeout`, `setInterval`, `Promise.race`, or background async operations.

**Reference**: `buffer.ts` has the canonical error handling pattern.

---

## [T>]esting Requirements

1. Basic functionality with typical inputs
2. Edge cases: empty sources, single items, boundaries
3. Error handling: source errors must be catchable
4. Return value preservation: verify with `consume().return()`
5. [T>]iming behavior (if applicable): use `test/timing-helpers.ts`

---

## Gotchas

- **Return types**: Functions like `tap()` must pass through parent's return type, not just yield type
- **Forgetting exports**: Add to both `transforms/index.ts` AND `pipeline.ts`
- **Pipeline integration**: Generic methods go first in Pipeline class; string-specific methods go in second section with type constraints
Share: