General
PromptBeginner5 minmarkdown
<h1 align="center">
<a href="https://prompts.chat">
118
1. Create `src/transforms/yourFunction.ts`
Loading actions...
# 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
<a href="https://prompts.chat">
TypeScript and ESLint rules that MUST be followed when creating, modifying, or reviewing any file under apps/frontend/, including .ts, .tsx, .js, and .jsx files. Also apply when discussing frontend linting, type safety, or ESLint configuration.
risks
src/transforms/yourFunction.tssrc/transforms/index.tssrc/pipeline.tstest/yourFunction.test.ts@group tag (Timing, Buffering, Filtering, Transformation, or Utilities)pnpm test && pnpm lint && pnpm build-fastexport async function* yourFunction<T>(source: AsyncIterable<T>, param: P): AsyncGenerator<T> {
for await (const item of source) {
yield transformedItem
}
}
map.ts, filter.tsminInterval.ts, throttle.tsbuffer.ts, chunk.tssplit.ts, replace.tsCritical rule: Errors must be thrown during await ticks, not in callbacks.
Errors in setTimeout/Promise.race callbacks escape user try/catch blocks. Instead, store errors and rethrow on the next await:
export async function* myTimingFunction<T>(source: AsyncIterable<T>) {
let error: Error | null = null
const consumer = (async () => {
try {
for await (const item of source) {
/* ... */
}
} catch (err) {
error = err instanceof Error ? err : new Error(String(err))
}
})()
while (true) {
if (error) throw error // Thrown during await tick - catchable by user
// ... yield logic
}
}
When to apply: Any function using setTimeout, setInterval, Promise.race, or background async operations.
Reference: buffer.ts has the canonical error handling pattern.
consume().return()test/timing-helpers.tstap() must pass through parent's return type, not just yield typetransforms/index.ts AND pipeline.ts