or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

ask.mdgetopt.mdindex.mdprogress-bar.mdread.mdreadLine.md

readLine.mddocs/

0

# Single Line Input

1

2

Read individual lines from standard input with stream management, automatic cleanup, and singleton stream handling for optimal resource usage.

3

4

## Capabilities

5

6

### Main ReadLine Function

7

8

Reads a single line from input stream with automatic stream management and resource cleanup.

9

10

```typescript { .api }

11

/**

12

* Read a single line from input stream

13

* @param options - Configuration options for stream and cleanup behavior

14

* @returns Promise resolving to the line content as string

15

*/

16

function readLine(options?: ReadLineOptions): Promise<string>;

17

18

interface ReadLineOptions {

19

/** Input stream to read from (defaults to process.stdin) */

20

stream?: NodeJS.ReadableStream;

21

/** Whether to close the stream after reading (defaults to false) */

22

close?: boolean;

23

}

24

```

25

26

**Usage Examples:**

27

28

```typescript

29

import { readLine } from "stdio";

30

31

// Read single line from stdin

32

const userInput = await readLine();

33

console.log(`You entered: ${userInput}`);

34

35

// Read with explicit stream closure

36

const input = await readLine({ close: true });

37

console.log(`Final input: ${input}`);

38

39

// Read from custom stream

40

import { createReadStream } from 'fs';

41

42

const fileStream = createReadStream('input.txt');

43

const firstLine = await readLine({ stream: fileStream });

44

console.log(`First line from file: ${firstLine}`);

45

46

// Interactive input loop

47

console.log('Enter commands (type "quit" to exit):');

48

while (true) {

49

const command = await readLine();

50

if (command === 'quit') {

51

// Close stream on final read

52

await readLine({ close: true });

53

break;

54

}

55

console.log(`Processing command: ${command}`);

56

}

57

58

// Error handling

59

try {

60

const input = await readLine({ close: true });

61

const number = parseInt(input);

62

if (isNaN(number)) {

63

throw new Error('Invalid number format');

64

}

65

console.log(`Number: ${number}`);

66

} catch (error) {

67

console.error('Input error:', error.message);

68

}

69

```

70

71

### Stream Management

72

73

The readLine function uses efficient singleton stream management for optimal resource usage.

74

75

**Singleton Pattern:**

76

- Reuses the same `InputStream` instance across multiple calls

77

- Reduces resource overhead for multiple readline operations

78

- Automatically manages stream lifecycle

79

80

**Stream Lifecycle:**

81

- Stream is created on first use

82

- Remains open for subsequent reads (unless `close: true`)

83

- Properly cleans up resources when closed

84

85

### InputStream Class

86

87

Internal class that manages readline operations with buffering and event handling.

88

89

```typescript { .api }

90

class InputStream {

91

constructor(input?: NodeJS.ReadableStream);

92

93

/**

94

* Get the next line from the input stream

95

* @returns Promise resolving to line content or null on stream end

96

*/

97

getLine(): Promise<string>;

98

99

/**

100

* Close the input stream and clean up resources

101

*/

102

close(): void;

103

}

104

```

105

106

**Internal Implementation Details:**

107

108

The `InputStream` class provides:

109

- **Event-driven Processing**: Uses readline events for efficient line handling

110

- **Buffer Management**: Maintains internal buffer for immediate line availability

111

- **Promise Queue**: Handles multiple concurrent readLine calls correctly

112

- **Stream End Handling**: Properly resolves with `null` when stream closes

113

114

## Advanced Features

115

116

### Buffering and Queue Management

117

118

Handles multiple readline requests efficiently:

119

120

```typescript

121

// Multiple concurrent reads are properly queued

122

const promise1 = readLine();

123

const promise2 = readLine();

124

const promise3 = readLine();

125

126

// Lines are returned in order as they arrive

127

const [line1, line2, line3] = await Promise.all([promise1, promise2, promise3]);

128

```

129

130

### Stream End Detection

131

132

Properly handles stream closure and end-of-input:

133

134

```typescript

135

import { readLine } from "stdio";

136

137

try {

138

const line = await readLine();

139

if (line === null) {

140

console.log('Stream ended (Ctrl+D pressed or pipe closed)');

141

} else {

142

console.log(`Read: ${line}`);

143

}

144

} catch (error) {

145

console.error('Read error:', error);

146

}

147

```

148

149

### Resource Management

150

151

Efficient resource usage with proper cleanup:

152

153

```typescript

154

// Stream stays open for multiple reads (efficient)

155

const name = await readLine();

156

const age = await readLine();

157

const email = await readLine();

158

159

// Explicitly close when done

160

await readLine({ close: true });

161

162

// Or close in final operation

163

const confirmation = await readLine({ close: true });

164

```

165

166

### Integration Patterns

167

168

Common integration patterns for different use cases:

169

170

**Interactive CLI Applications:**

171

172

```typescript

173

import { readLine } from "stdio";

174

175

async function runCLI() {

176

console.log('Welcome to My CLI');

177

178

while (true) {

179

process.stdout.write('> ');

180

const command = await readLine();

181

182

if (command === 'exit') {

183

console.log('Goodbye!');

184

await readLine({ close: true });

185

break;

186

}

187

188

await processCommand(command);

189

}

190

}

191

```

192

193

**Configuration Input:**

194

195

```typescript

196

async function getConfiguration() {

197

const config = {};

198

199

console.log('Please enter configuration:');

200

config.host = await readLine();

201

config.port = parseInt(await readLine());

202

config.database = await readLine({ close: true });

203

204

return config;

205

}

206

```

207

208

**File Processing:**

209

210

```typescript

211

import { createReadStream } from 'fs';

212

213

async function processFileLines(filename: string) {

214

const stream = createReadStream(filename);

215

216

try {

217

while (true) {

218

const line = await readLine({ stream });

219

if (line === null) break; // End of file

220

221

await processLine(line);

222

}

223

} finally {

224

// Stream is automatically closed when file ends

225

}

226

}

227

```

228

229

## Error Handling

230

231

Comprehensive error handling for various failure scenarios:

232

233

```typescript

234

try {

235

const input = await readLine();

236

// Process input

237

} catch (error) {

238

if (error.code === 'ENOENT') {

239

console.error('Input stream not available');

240

} else if (error.code === 'EPERM') {

241

console.error('Permission denied reading input');

242

} else {

243

console.error('Unexpected error:', error.message);

244

}

245

}

246

```