or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

configuration.mdcore-mixing.mddecorators.mdgeneric-classes.mdindex.mdmixin-detection.md

configuration.mddocs/

0

# Configuration

1

2

Global configuration settings for controlling mixin behavior. The `settings` object allows you to customize how ts-mixer handles prototype mixing, static properties, constructor initialization, and decorator inheritance.

3

4

## Capabilities

5

6

### Settings Object

7

8

Global configuration object that controls ts-mixer behavior across all mixin operations.

9

10

```typescript { .api }

11

/**

12

* Global settings object for configuring ts-mixer behavior

13

* Changes affect all subsequent mixin operations

14

*/

15

interface Settings {

16

/** Name of init function to call after construction, null to disable */

17

initFunction: string | null;

18

/** Strategy for handling static properties: 'copy' or 'proxy' */

19

staticsStrategy: "copy" | "proxy";

20

/** Strategy for mixing prototypes: 'copy' or 'proxy' */

21

prototypeStrategy: "copy" | "proxy";

22

/** Decorator inheritance strategy: 'deep', 'direct', or 'none' */

23

decoratorInheritance: "deep" | "direct" | "none";

24

}

25

26

/**

27

* Global settings instance - modify properties to change behavior

28

*/

29

declare const settings: Settings;

30

```

31

32

## Configuration Options

33

34

### Prototype Strategy

35

36

Controls how class prototypes are mixed together.

37

38

```typescript

39

import { settings } from "ts-mixer";

40

41

// Copy strategy (default) - better performance, ES5 compatible

42

settings.prototypeStrategy = "copy";

43

44

// Proxy strategy - dynamic updates, ES6+ only

45

settings.prototypeStrategy = "proxy";

46

```

47

48

**Copy Strategy (`"copy"`):**

49

- **Pros**: Better performance, ES5 compatible, no proxy overhead

50

- **Cons**: Static references - changes to base class prototypes after mixing aren't reflected

51

- **Use when**: Performance is critical, you don't modify prototypes after mixing

52

53

**Proxy Strategy (`"proxy"`):**

54

- **Pros**: Dynamic - updates to base classes are reflected in mixed classes

55

- **Cons**: Slower property access, requires ES6+ Proxy support

56

- **Use when**: You need dynamic prototype updates, prototype methods change at runtime

57

58

```typescript

59

import { Mixin, settings } from "ts-mixer";

60

61

class Base {

62

getValue(): string {

63

return "original";

64

}

65

}

66

67

class Other {

68

getOther(): string {

69

return "other";

70

}

71

}

72

73

// Test copy strategy

74

settings.prototypeStrategy = "copy";

75

class CopyMixed extends Mixin(Base, Other) {}

76

77

const copyInstance = new CopyMixed();

78

console.log(copyInstance.getValue()); // "original"

79

80

// Modify base class after mixing

81

Base.prototype.getValue = () => "modified";

82

83

console.log(copyInstance.getValue()); // Still "original" - not updated

84

85

// Test proxy strategy

86

settings.prototypeStrategy = "proxy";

87

class ProxyMixed extends Mixin(Base, Other) {}

88

89

const proxyInstance = new ProxyMixed();

90

console.log(proxyInstance.getValue()); // "modified" - dynamically updated

91

```

92

93

### Statics Strategy

94

95

Controls how static properties and methods are inherited.

96

97

```typescript

98

import { settings } from "ts-mixer";

99

100

// Copy strategy (default)

101

settings.staticsStrategy = "copy";

102

103

// Proxy strategy

104

settings.staticsStrategy = "proxy";

105

```

106

107

**Copy Strategy (`"copy"`):**

108

- Copies all static properties at mixin creation time

109

- Changes to base class statics after mixing aren't reflected

110

- Better performance for static property access

111

112

**Proxy Strategy (`"proxy"`):**

113

- Proxies static property access to base classes

114

- Dynamic updates to base class statics are reflected

115

- Slightly slower static property access

116

117

```typescript

118

import { Mixin, settings } from "ts-mixer";

119

120

class BaseClass {

121

static baseStaticProp: string = "base";

122

static baseStaticMethod(): string {

123

return "base method";

124

}

125

}

126

127

class OtherClass {

128

static otherStaticProp: string = "other";

129

}

130

131

// Test copy strategy

132

settings.staticsStrategy = "copy";

133

class CopyMixed extends Mixin(BaseClass, OtherClass) {}

134

135

console.log(CopyMixed.baseStaticProp); // "base"

136

console.log(CopyMixed.baseStaticMethod()); // "base method"

137

138

// Modify base class static after mixing

139

BaseClass.baseStaticProp = "modified base";

140

141

console.log(CopyMixed.baseStaticProp); // Still "base" - not updated

142

143

// Test proxy strategy

144

settings.staticsStrategy = "proxy";

145

class ProxyMixed extends Mixin(BaseClass, OtherClass) {}

146

147

console.log(ProxyMixed.baseStaticProp); // "modified base" - dynamically updated

148

```

149

150

### Init Function

151

152

Specifies a function name to call after construction with proper `this` context.

153

154

```typescript

155

import { settings } from "ts-mixer";

156

157

// Enable init function (disabled by default)

158

settings.initFunction = "init";

159

160

// Disable init function

161

settings.initFunction = null;

162

```

163

164

**Purpose:**

165

ES6 constructor limitations prevent ts-mixer from passing the correct `this` to constructors. The init function workaround allows constructor-like behavior with proper `this` context.

166

167

**Usage Pattern:**

168

169

```typescript

170

import { Mixin, settings } from "ts-mixer";

171

172

settings.initFunction = "init";

173

174

class Person {

175

public static allPeople: Set<Person> = new Set();

176

177

name: string;

178

179

constructor(name: string) {

180

this.name = name;

181

// Cannot use 'this' for side effects here in mixins

182

}

183

184

// Init function receives proper 'this' context

185

protected init(name: string) {

186

Person.allPeople.add(this); // This works correctly

187

}

188

}

189

190

class Employee {

191

public static allEmployees: Set<Employee> = new Set();

192

193

employeeId: number;

194

195

constructor(name: string, employeeId: number) {

196

this.employeeId = employeeId;

197

}

198

199

protected init(name: string, employeeId: number) {

200

Employee.allEmployees.add(this); // This works correctly

201

}

202

}

203

204

class PersonEmployee extends Mixin(Person, Employee) {}

205

206

// Both constructors and both init functions are called

207

const emp = new PersonEmployee("John Doe", 12345);

208

209

console.log(Person.allPeople.has(emp)); // true - init function worked

210

console.log(Employee.allEmployees.has(emp)); // true - init function worked

211

console.log(emp.name); // "John Doe" - constructor worked

212

console.log(emp.employeeId); // 12345 - constructor worked

213

```

214

215

**Init Function Features:**

216

- Called with the same arguments passed to the constructor

217

- Receives proper `this` context (unlike constructors in mixins)

218

- All init functions from mixed classes are called in order

219

- Optional - only classes that define the init function participate

220

221

### Decorator Inheritance

222

223

Controls how decorators are inherited during mixing.

224

225

```typescript

226

import { settings } from "ts-mixer";

227

228

// Deep inheritance (default) - inherit from all ancestors

229

settings.decoratorInheritance = "deep";

230

231

// Direct inheritance - only from direct mixin classes

232

settings.decoratorInheritance = "direct";

233

234

// No inheritance - disable decorator inheritance

235

settings.decoratorInheritance = "none";

236

```

237

238

**Deep Inheritance (`"deep"`):**

239

- Inherits decorators from all classes in the prototype chain

240

- Includes decorators from ancestor classes of mixed classes

241

- Most comprehensive decorator inheritance

242

243

**Direct Inheritance (`"direct"`):**

244

- Only inherits decorators from classes directly passed to `Mixin()`

245

- Ignores decorators from ancestor classes

246

- More predictable decorator behavior

247

248

**None (`"none"`):**

249

- Disables decorator inheritance completely

250

- Fastest option when decorators aren't needed

251

- Use for better performance when decorators aren't used

252

253

```typescript

254

import { Mixin, decorate, settings } from "ts-mixer";

255

256

function MyDecorator(name: string) {

257

return function(target: any) {

258

target.decoratorApplied = name;

259

};

260

}

261

262

@decorate(MyDecorator("grandparent"))

263

class GrandParent {}

264

265

@decorate(MyDecorator("parent"))

266

class Parent extends GrandParent {}

267

268

@decorate(MyDecorator("mixin"))

269

class MixinClass {}

270

271

// Deep inheritance

272

settings.decoratorInheritance = "deep";

273

class DeepMixed extends Mixin(Parent, MixinClass) {}

274

// Inherits decorators from: GrandParent, Parent, MixinClass

275

276

// Direct inheritance

277

settings.decoratorInheritance = "direct";

278

class DirectMixed extends Mixin(Parent, MixinClass) {}

279

// Inherits decorators from: Parent, MixinClass (not GrandParent)

280

281

// No inheritance

282

settings.decoratorInheritance = "none";

283

class NoDecorators extends Mixin(Parent, MixinClass) {}

284

// Inherits no decorators

285

```

286

287

## Configuration Examples

288

289

### Performance-Optimized Configuration

290

291

```typescript

292

import { settings } from "ts-mixer";

293

294

// Optimize for performance

295

settings.prototypeStrategy = "copy"; // Faster property access

296

settings.staticsStrategy = "copy"; // Faster static access

297

settings.decoratorInheritance = "none"; // Skip decorator processing

298

settings.initFunction = null; // Skip init function calls

299

300

// Use for high-performance scenarios where you don't need:

301

// - Dynamic prototype updates

302

// - Dynamic static updates

303

// - Decorator inheritance

304

// - Init function workarounds

305

```

306

307

### Dynamic Update Configuration

308

309

```typescript

310

import { settings } from "ts-mixer";

311

312

// Optimize for dynamic behavior

313

settings.prototypeStrategy = "proxy"; // Dynamic prototype updates

314

settings.staticsStrategy = "proxy"; // Dynamic static updates

315

settings.decoratorInheritance = "deep"; // Full decorator inheritance

316

settings.initFunction = "init"; // Enable init functions

317

318

// Use when you need:

319

// - Runtime modifications to base classes

320

// - Full decorator support

321

// - Constructor workarounds

322

```

323

324

### Balanced Configuration

325

326

```typescript

327

import { settings } from "ts-mixer";

328

329

// Balanced approach (default settings)

330

settings.prototypeStrategy = "copy"; // Good performance

331

settings.staticsStrategy = "copy"; // Good performance

332

settings.decoratorInheritance = "deep"; // Full decorator support

333

settings.initFunction = null; // Disabled by default

334

335

// Good for most use cases providing:

336

// - Reasonable performance

337

// - Full decorator inheritance

338

// - Simple constructor behavior

339

```

340

341

## Runtime Configuration Changes

342

343

Settings can be changed at runtime and affect all subsequent mixin operations:

344

345

```typescript

346

import { Mixin, settings } from "ts-mixer";

347

348

// Initial setting

349

settings.prototypeStrategy = "copy";

350

351

class A {}

352

class B {}

353

354

class Mixed1 extends Mixin(A, B) {} // Uses copy strategy

355

356

// Change setting

357

settings.prototypeStrategy = "proxy";

358

359

class Mixed2 extends Mixin(A, B) {} // Uses proxy strategy

360

361

// Mixed1 still uses copy, Mixed2 uses proxy

362

```

363

364

**Important Notes:**

365

- Settings changes don't affect already-created mixed classes

366

- Each mixin operation uses the current settings at the time of creation

367

- Consider setting configuration early in your application lifecycle