or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

index.md

index.mddocs/

0

# Tiny Typed Emitter

1

2

Tiny Typed Emitter provides a fully type-checked EventEmitter wrapper with zero runtime overhead. It enables developers to define strongly-typed event interfaces and ensures compile-time type safety for event emission and listener registration while maintaining full compatibility with Node.js EventEmitter.

3

4

## Package Information

5

6

- **Package Name**: tiny-typed-emitter

7

- **Package Type**: npm

8

- **Language**: TypeScript

9

- **Installation**: `npm install tiny-typed-emitter`

10

11

## Core Imports

12

13

```typescript

14

import { TypedEmitter } from "tiny-typed-emitter";

15

```

16

17

For CommonJS:

18

19

```javascript

20

const { TypedEmitter } = require("tiny-typed-emitter");

21

```

22

23

For type definitions:

24

25

```typescript

26

import { TypedEmitter, ListenerSignature, DefaultListener } from "tiny-typed-emitter";

27

```

28

29

## Basic Usage

30

31

```typescript

32

import { TypedEmitter } from "tiny-typed-emitter";

33

34

// Define event signatures

35

interface MyEvents {

36

'data': (payload: string, timestamp: number) => void;

37

'error': (error: Error) => void;

38

'complete': () => void;

39

}

40

41

// Create typed emitter

42

const emitter = new TypedEmitter<MyEvents>();

43

44

// Add listeners with full type safety

45

emitter.on('data', (payload, timestamp) => {

46

console.log(`Received: ${payload} at ${timestamp}`);

47

});

48

49

emitter.on('error', (error) => {

50

console.error('Error occurred:', error.message);

51

});

52

53

// Emit events with type checking

54

emitter.emit('data', 'Hello World', Date.now());

55

emitter.emit('error', new Error('Something went wrong'));

56

emitter.emit('complete');

57

```

58

59

## Architecture

60

61

Tiny Typed Emitter is built around a single core concept:

62

63

- **TypedEmitter Class**: A generic wrapper around Node.js EventEmitter that adds TypeScript type safety

64

- **Zero Runtime Overhead**: Simply re-exports the native EventEmitter with enhanced type definitions

65

- **Generic Type System**: Uses TypeScript generics to map event names to their listener function signatures

66

- **Full EventEmitter Compatibility**: All standard EventEmitter methods are available with enhanced typing

67

68

## Capabilities

69

70

### TypedEmitter Class

71

72

A generic class that wraps Node.js EventEmitter with compile-time type safety for event names and listener signatures.

73

74

```typescript { .api }

75

class TypedEmitter<L extends ListenerSignature<L> = DefaultListener> {

76

static defaultMaxListeners: number;

77

78

// Event listener management

79

addListener<U extends keyof L>(event: U, listener: L[U]): this;

80

prependListener<U extends keyof L>(event: U, listener: L[U]): this;

81

prependOnceListener<U extends keyof L>(event: U, listener: L[U]): this;

82

removeListener<U extends keyof L>(event: U, listener: L[U]): this;

83

removeAllListeners(event?: keyof L): this;

84

once<U extends keyof L>(event: U, listener: L[U]): this;

85

on<U extends keyof L>(event: U, listener: L[U]): this;

86

off<U extends keyof L>(event: U, listener: L[U]): this;

87

88

// Event emission

89

emit<U extends keyof L>(event: U, ...args: Parameters<L[U]>): boolean;

90

91

// Event introspection

92

eventNames<U extends keyof L>(): U[];

93

listenerCount(type: keyof L): number;

94

listeners<U extends keyof L>(type: U): L[U][];

95

rawListeners<U extends keyof L>(type: U): L[U][];

96

97

// Configuration

98

getMaxListeners(): number;

99

setMaxListeners(n: number): this;

100

}

101

```

102

103

**Usage Examples:**

104

105

```typescript

106

import { TypedEmitter } from "tiny-typed-emitter";

107

108

// Define events interface

109

interface FileWatcherEvents {

110

'file-changed': (filename: string, stats: { size: number; modified: Date }) => void;

111

'error': (error: Error) => void;

112

'started': () => void;

113

}

114

115

// Create typed emitter instance

116

const watcher = new TypedEmitter<FileWatcherEvents>();

117

118

// Type-safe listener registration

119

watcher.on('file-changed', (filename, stats) => {

120

// TypeScript knows filename is string and stats has size/modified properties

121

console.log(`File ${filename} changed. Size: ${stats.size}, Modified: ${stats.modified}`);

122

});

123

124

// Type-safe event emission

125

watcher.emit('file-changed', 'config.json', {

126

size: 1024,

127

modified: new Date()

128

});

129

130

// Class extension example

131

class FileWatcher extends TypedEmitter<FileWatcherEvents> {

132

constructor() {

133

super();

134

}

135

136

start() {

137

this.emit('started');

138

}

139

}

140

```

141

142

### Event Listener Management

143

144

Methods for adding, removing, and managing event listeners with full type safety.

145

146

```typescript { .api }

147

// Add listener to end of listeners array

148

addListener<U extends keyof L>(event: U, listener: L[U]): this;

149

150

// Add listener to beginning of listeners array

151

prependListener<U extends keyof L>(event: U, listener: L[U]): this;

152

153

// Add one-time listener to beginning of listeners array

154

prependOnceListener<U extends keyof L>(event: U, listener: L[U]): this;

155

156

// Remove specific listener

157

removeListener<U extends keyof L>(event: U, listener: L[U]): this;

158

159

// Remove all listeners for event (or all events if no event specified)

160

removeAllListeners(event?: keyof L): this;

161

162

// Add one-time listener

163

once<U extends keyof L>(event: U, listener: L[U]): this;

164

165

// Add listener (alias for addListener)

166

on<U extends keyof L>(event: U, listener: L[U]): this;

167

168

// Remove listener (alias for removeListener)

169

off<U extends keyof L>(event: U, listener: L[U]): this;

170

```

171

172

### Event Emission

173

174

Emit events with type-safe arguments based on the event signature.

175

176

```typescript { .api }

177

/**

178

* Emit an event with type-safe arguments

179

* @param event - Event name (must be key of L)

180

* @param args - Arguments matching the event's listener signature

181

* @returns true if event had listeners, false otherwise

182

*/

183

emit<U extends keyof L>(event: U, ...args: Parameters<L[U]>): boolean;

184

```

185

186

### Event Introspection

187

188

Methods for inspecting current listeners and event state.

189

190

```typescript { .api }

191

// Get array of registered event names

192

eventNames<U extends keyof L>(): U[];

193

194

// Get count of listeners for specific event

195

listenerCount(type: keyof L): number;

196

197

// Get copy of listeners array for event

198

listeners<U extends keyof L>(type: U): L[U][];

199

200

// Get copy of listeners array including wrappers

201

rawListeners<U extends keyof L>(type: U): L[U][];

202

```

203

204

### Configuration

205

206

Methods for configuring the emitter's behavior.

207

208

```typescript { .api }

209

// Get current maximum listeners limit

210

getMaxListeners(): number;

211

212

// Set maximum number of listeners (returns this for chaining)

213

setMaxListeners(n: number): this;

214

215

// Static property for default maximum listeners

216

static defaultMaxListeners: number;

217

```

218

219

## Types

220

221

```typescript { .api }

222

// Maps event names to their listener function signatures

223

type ListenerSignature<L> = {

224

[E in keyof L]: (...args: any[]) => any;

225

};

226

227

// Default listener signature for dynamic event names

228

type DefaultListener = {

229

[k: string]: (...args: any[]) => any;

230

};

231

```

232

233

## Advanced Usage

234

235

### Generic Events Interface

236

237

Use generic interfaces for reusable event patterns:

238

239

```typescript

240

import { TypedEmitter, ListenerSignature } from "tiny-typed-emitter";

241

242

interface DataEvents<T> {

243

'data': (item: T) => void;

244

'batch': (items: T[]) => void;

245

'complete': () => void;

246

}

247

248

class DataProcessor<T> extends TypedEmitter<DataEvents<T>> {

249

process(item: T) {

250

this.emit('data', item);

251

}

252

}

253

254

// Usage with specific type

255

const stringProcessor = new DataProcessor<string>();

256

stringProcessor.on('data', (str) => console.log(str.toUpperCase()));

257

```

258

259

### Compatible Subclasses with Different Events

260

261

Create compatible subclasses that introduce different events:

262

263

```typescript

264

import { TypedEmitter, ListenerSignature } from "tiny-typed-emitter";

265

266

class Animal<E extends ListenerSignature<E> = {}> extends TypedEmitter<{spawn: () => void} & E> {

267

constructor() {

268

super();

269

}

270

}

271

272

class Frog extends Animal<{jump: () => void}> {

273

jump() {

274

this.emit('jump');

275

}

276

}

277

278

class Bird extends Animal<{fly: () => void}> {

279

fly() {

280

this.emit('fly');

281

}

282

}

283

284

// Compatible usage

285

const animals: Animal[] = [new Frog(), new Bird()];

286

animals.forEach(animal => {

287

animal.on('spawn', () => console.log('Animal spawned'));

288

});

289

```