or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

development.mdindex.mdmemoization.mdselector-creation.mdselector-creator.mdstructured-selectors.md

development.mddocs/

0

# Development Mode Utilities

1

2

Development-only stability checks and debugging utilities to help identify common selector issues and ensure optimal performance.

3

4

## Capabilities

5

6

### setGlobalDevModeChecks

7

8

Configures global development mode check settings for all selectors in the application.

9

10

```typescript { .api }

11

/**

12

* Overrides the development mode checks settings for all selectors

13

* @param devModeChecks - Partial configuration object for dev mode checks

14

*/

15

function setGlobalDevModeChecks(devModeChecks: Partial<DevModeChecks>): void;

16

17

interface DevModeChecks {

18

/** Check for unstable input selector results */

19

inputStabilityCheck: DevModeCheckFrequency;

20

21

/** Check if result function is an identity function */

22

identityFunctionCheck: DevModeCheckFrequency;

23

}

24

25

type DevModeCheckFrequency = 'once' | 'always' | 'never';

26

```

27

28

**Basic Usage:**

29

30

```typescript

31

import { setGlobalDevModeChecks } from "reselect";

32

33

// Run checks only on first selector call (default)

34

setGlobalDevModeChecks({

35

inputStabilityCheck: 'once',

36

identityFunctionCheck: 'once'

37

});

38

39

// Run checks on every selector call

40

setGlobalDevModeChecks({

41

inputStabilityCheck: 'always',

42

identityFunctionCheck: 'always'

43

});

44

45

// Disable specific checks

46

setGlobalDevModeChecks({

47

inputStabilityCheck: 'never',

48

identityFunctionCheck: 'once'

49

});

50

51

// Partial configuration (unspecified settings retain current values)

52

setGlobalDevModeChecks({

53

inputStabilityCheck: 'always'

54

// identityFunctionCheck keeps its current setting

55

});

56

```

57

58

### Development Mode Checks Overview

59

60

Development mode checks help identify common selector performance issues and mistakes.

61

62

**Input Stability Check:**

63

- Detects when input selectors return different references for the same inputs

64

- Helps identify unnecessary recomputations due to unstable input selectors

65

- Warns when input selectors create new objects/arrays on each call

66

67

**Identity Function Check:**

68

- Detects when the result function just returns its first argument unchanged

69

- Helps identify selectors that don't add value and could be simplified

70

- Warns about potential performance issues with unnecessary selector layers

71

72

### Per-Selector Configuration

73

74

Override global settings for specific selectors using `CreateSelectorOptions`.

75

76

```typescript

77

import { createSelector } from "reselect";

78

79

// Override global settings for specific selector

80

const selectSpecialData = createSelector(

81

[selectInputData],

82

(data) => processData(data),

83

{

84

devModeChecks: {

85

inputStabilityCheck: 'always', // Always check this selector

86

identityFunctionCheck: 'never' // Never check identity for this one

87

}

88

}

89

);

90

91

// Disable all checks for performance-critical selector

92

const selectCriticalPath = createSelector(

93

[selectLargeDataset],

94

(data) => criticalProcessing(data),

95

{

96

devModeChecks: {

97

inputStabilityCheck: 'never',

98

identityFunctionCheck: 'never'

99

}

100

}

101

);

102

```

103

104

### Common Issues and Solutions

105

106

**Unstable Input Selectors:**

107

108

```typescript

109

import { createSelector } from "reselect";

110

111

// ❌ BAD: Creates new array on every call

112

const selectBadItems = (state) => state.items.filter(item => item.active);

113

114

// ✅ GOOD: Stable input selector

115

const selectItems = (state) => state.items;

116

const selectActiveFilter = (state) => true; // or from actual filter state

117

118

const selectActiveItems = createSelector(

119

[selectItems, selectActiveFilter],

120

(items, shouldFilterActive) =>

121

shouldFilterActive ? items.filter(item => item.active) : items

122

);

123

```

124

125

**Identity Function Issues:**

126

127

```typescript

128

import { createSelector } from "reselect";

129

130

// ❌ BAD: Identity function - just returns first argument

131

const selectBadUser = createSelector(

132

[(state) => state.user],

133

(user) => user // This is an identity function

134

);

135

136

// ✅ GOOD: Actually transforms the data

137

const selectUserDisplayName = createSelector(

138

[(state) => state.user],

139

(user) => user ? `${user.firstName} ${user.lastName}` : 'Anonymous'

140

);

141

142

// ✅ ALSO GOOD: Direct selector when no transformation needed

143

const selectUser = (state) => state.user;

144

```

145

146

### DevModeChecksExecutionInfo

147

148

Information about development mode check execution (internal type).

149

150

```typescript { .api }

151

interface DevModeChecksExecutionInfo {

152

/** Information about input stability check execution */

153

inputStabilityCheck: DevModeCheckExecutionInfo;

154

155

/** Information about identity function check execution */

156

identityFunctionCheck: DevModeCheckExecutionInfo;

157

}

158

159

interface DevModeCheckExecutionInfo {

160

/** Whether the check should run */

161

shouldRun: boolean;

162

163

/** Number of times this check has been executed */

164

timesRun: number;

165

}

166

```

167

168

### Production Behavior

169

170

Development mode checks are automatically disabled in production builds to ensure optimal performance.

171

172

```typescript

173

// Development mode checks only run when process.env.NODE_ENV !== 'production'

174

// In production, these checks are completely bypassed for performance

175

176

import { createSelector, setGlobalDevModeChecks } from "reselect";

177

178

// This configuration only affects development builds

179

setGlobalDevModeChecks({ inputStabilityCheck: 'always' });

180

181

const selectData = createSelector(

182

[selectInput],

183

(input) => processInput(input)

184

// Dev mode checks run in development, ignored in production

185

);

186

```

187

188

### Debugging and Monitoring

189

190

**Checking Recomputations:**

191

192

```typescript

193

import { createSelector } from "reselect";

194

195

const selectExpensiveData = createSelector(

196

[selectLargeDataset, selectFilters],

197

(data, filters) => expensiveProcessing(data, filters)

198

);

199

200

// Monitor recomputations in development

201

console.log('Recomputations:', selectExpensiveData.recomputations());

202

203

// Use the selector

204

const result = selectExpensiveData(state);

205

console.log('After use:', selectExpensiveData.recomputations());

206

207

// Reset counter for testing

208

selectExpensiveData.resetRecomputations();

209

```

210

211

**Custom Development Logging:**

212

213

```typescript

214

import { createSelector } from "reselect";

215

216

const selectWithLogging = createSelector(

217

[selectInput],

218

(input) => {

219

if (process.env.NODE_ENV === 'development') {

220

console.log('Selector recomputing with input:', input);

221

}

222

return processInput(input);

223

}

224

);

225

```

226

227

### Integration with Testing

228

229

```typescript

230

import { createSelector, setGlobalDevModeChecks } from "reselect";

231

232

describe('Selector Tests', () => {

233

beforeEach(() => {

234

// Enable all checks for testing

235

setGlobalDevModeChecks({

236

inputStabilityCheck: 'always',

237

identityFunctionCheck: 'always'

238

});

239

});

240

241

it('should not recompute with same inputs', () => {

242

const selector = createSelector(

243

[(state) => state.data],

244

(data) => processData(data)

245

);

246

247

selector(state1);

248

const recomputations1 = selector.recomputations();

249

250

selector(state1); // Same state

251

const recomputations2 = selector.recomputations();

252

253

expect(recomputations2).toBe(recomputations1); // Should not increase

254

});

255

});

256

```

257

258

## Types

259

260

```typescript { .api }

261

interface DevModeChecks {

262

inputStabilityCheck: DevModeCheckFrequency;

263

identityFunctionCheck: DevModeCheckFrequency;

264

}

265

266

type DevModeCheckFrequency = 'once' | 'always' | 'never';

267

268

interface DevModeChecksExecutionInfo {

269

inputStabilityCheck: DevModeCheckExecutionInfo;

270

identityFunctionCheck: DevModeCheckExecutionInfo;

271

}

272

273

interface DevModeCheckExecutionInfo {

274

shouldRun: boolean;

275

timesRun: number;

276

}

277

```