```typescript
/**
 * Replaces every maximal run of one repeated character with that character followed by the run length,
 * in order: "aaabbc" encodes to "a3b2c1". A run of length one still carries its count, so "abc" ends up as "a1b1c1".
 */
export function runLengthEncode(input: string): string {
  if (typeof input !== 'string') throw new Error('Input must be a string');
  
  const result = [];
  let currentChar = input[0];
  let count = 1;
  
  for (let i = 1; i <= input.length; i++) {
    if (i < input.length && input[i] !== currentChar) {
      result.push(currentChar + (count > 9 ? `...` : `${count}`));
      currentChar = input[i];
      count = 1;
    } else {
      count++;
    }
  }
  
  return result.join('');
}
```