Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/visible/cruel/llms.txt

Use this file to discover all available pages before exploring further.

Stream Chaos

Stream chaos methods simulate issues that occur during data streaming, including cuts, pauses, corruption, and data integrity problems.

cut

Abruptly terminates a stream mid-transfer.
cruel.stream.cut(fn, rate)
fn
function
required
The streaming function to wrap
rate
number
default:"0.1"
Probability of stream cut (0 to 1). Default is 0.1 (10%)

Example

import { cruel } from 'cruel'

const streamVideo = async (url: string) => {
  const response = await fetch(url)
  return response.text()
}

// 15% chance of stream being cut
const unreliableStream = cruel.stream.cut(streamVideo, 0.15)

try {
  const data = await unreliableStream('/video/stream')
  console.log('Stream completed')
} catch (error) {
  // CruelError: stream cut mid-transfer
  console.error('Stream interrupted:', error.message)
}
Stream cuts happen after the function executes but before returning the result, simulating connection loss during transfer.

pause

Adds pauses/delays during streaming.
cruel.stream.pause(fn, ms)
fn
function
required
The streaming function to wrap
ms
number | [number, number]
default:"[500, 2000]"
Pause duration in milliseconds. Can be fixed or range [min, max]

Example

import { cruel } from 'cruel'

const downloadChunk = async (offset: number) => {
  return fetch(`/api/download?offset=${offset}`).then(r => r.text())
}

// Add 1 second pause after each chunk
const pausedDownload = cruel.stream.pause(downloadChunk, 1000)

const chunk = await pausedDownload(0)
// Returns after original time + 1000ms pause

corrupt

Corrupts data in the stream.
cruel.stream.corrupt(fn, rate)
fn
AsyncFn<string>
required
Function returning string data to corrupt
rate
number
default:"0.1"
Probability of corruption (0 to 1). Default is 0.1 (10%)

Example

import { cruel } from 'cruel'

const fetchJSON = async (url: string): Promise<string> => {
  const response = await fetch(url)
  return response.text()
}

// 20% chance of data corruption
const corruptedFetch = cruel.stream.corrupt(fetchJSON, 0.2)

const data = await corruptedFetch('/api/data')
// Data may contain corrupted bytes (�)

try {
  JSON.parse(data)
} catch (error) {
  console.error('Corrupted data received')
}
Corruption inserts the replacement character at a random position in the string.

truncate

Truncates stream data at a random point.
cruel.stream.truncate(fn, rate)
fn
AsyncFn<string>
required
Function returning string data to truncate
rate
number
default:"0.1"
Probability of truncation (0 to 1). Default is 0.1 (10%)

Example

import { cruel } from 'cruel'

const downloadFile = async (path: string): Promise<string> => {
  const response = await fetch(`/files/${path}`)
  return response.text()
}

// 10% chance of incomplete download
const truncatedDownload = cruel.stream.truncate(downloadFile, 0.1)

const content = await truncatedDownload('document.txt')
// Content may be cut off at ~80% of original length
Truncation occurs at a random point between 0% and 80% of the original content length.

slow

Creates a slow stream with long pauses.
cruel.stream.slow(fn)
fn
function
required
The streaming function to wrap

Behavior

Applies a random pause between 1000-5000ms.

Example

import { cruel } from 'cruel'

const streamData = async () => {
  return fetch('/api/stream').then(r => r.text())
}

// Slow streaming with 1-5 second pauses
const slowStream = cruel.stream.slow(streamData)

const data = await slowStream()
// Takes 1-5 seconds longer than normal

flaky

Combines stream cuts and pauses for realistic flaky streaming.
cruel.stream.flaky(fn)
fn
function
required
The streaming function to wrap

Behavior

Applies:
  • 10% stream cut rate
  • 100-1000ms random pauses

Example

import { cruel } from 'cruel'

const liveStream = async (channel: string) => {
  return websocket.connect(`/stream/${channel}`)
}

// Simulate unreliable streaming connection
const flakyLiveStream = cruel.stream.flaky(liveStream)

try {
  const stream = await flakyLiveStream('channel-1')
  console.log('Stream connected')
} catch (error) {
  if (error.code === 'CRUEL_STREAM_CUT') {
    console.log('Stream was interrupted')
  }
}

Advanced Stream Methods

The following methods are also available for more specific stream chaos:

reorder

Reorders stream data by swapping halves.
cruel.stream.reorder(fn, rate)

duplicate

Duplicates portions of stream data.
cruel.stream.duplicate(fn, rate)

dropChunks

Drops chunks of data from the stream.
cruel.stream.dropChunks(fn, rate)

corruptChunks

Alias for corrupt method.
cruel.stream.corruptChunks(fn, rate)

Combining Stream Chaos

import { cruel } from 'cruel'

const streamData = async () => { /* ... */ }

// Combine multiple stream issues
let chaotic = streamData
chaotic = cruel.stream.cut(chaotic, 0.05)
chaotic = cruel.stream.pause(chaotic, [100, 500])
chaotic = cruel.stream.corrupt(chaotic, 0.1)

await chaotic()

Real-World Scenarios

// Simulate buffering and interruptions
const videoStream = cruel.stream.flaky(
  cruel.stream.pause(streamVideo, [1000, 3000])
)

Testing Stream Resilience

import { cruel } from 'cruel'

const downloadWithRetry = async (url: string, maxRetries = 3) => {
  let attempt = 0
  
  while (attempt < maxRetries) {
    try {
      const flakyDownload = cruel.stream.flaky(fetch)
      return await flakyDownload(url)
    } catch (error) {
      attempt++
      if (error.code === 'CRUEL_STREAM_CUT') {
        console.log(`Stream cut, retry ${attempt}/${maxRetries}`)
      } else {
        throw error
      }
    }
  }
  
  throw new Error('Max retries exceeded')
}

Source Reference

Stream methods are defined in index.ts:429-525.

Build docs developers (and LLMs) love