or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

actions.mdconfiguration.mddebugging-service.mdindex.mdstate-types.md

debugging-service.mddocs/

0

# Core Debugging Service

1

2

The main devtools service providing programmatic access to debugging functionality including time-travel operations, state inspection, and recording controls.

3

4

## Capabilities

5

6

### StoreDevtools Service

7

8

Core service that manages devtools state and provides debugging methods.

9

10

```typescript { .api }

11

/**

12

* Main devtools service implementing Observer pattern for action handling

13

*/

14

class StoreDevtools implements Observer<any>, OnDestroy {

15

/** Action dispatcher for devtools actions */

16

dispatcher: ActionsSubject;

17

/** Observable of enhanced state with devtools metadata */

18

liftedState: Observable<LiftedState>;

19

/** Observable of current application state */

20

state: StateObservable;

21

22

/**

23

* Dispatch an action through the devtools system

24

* @param action - Action to dispatch

25

*/

26

dispatch(action: Action): void;

27

28

/**

29

* Observer interface method for handling next action

30

* @param action - Action to handle

31

*/

32

next(action: any): void;

33

34

/**

35

* Observer interface method for handling errors

36

* @param error - Error to handle

37

*/

38

error(error: any): void;

39

40

/**

41

* Observer interface method for completion

42

*/

43

complete(): void;

44

45

/**

46

* Perform a user action through the devtools system

47

* @param action - User action to perform

48

*/

49

performAction(action: any): void;

50

51

/**

52

* Refresh the devtools state

53

*/

54

refresh(): void;

55

56

/**

57

* Reset the devtools to initial state

58

*/

59

reset(): void;

60

61

/**

62

* Rollback to the previous committed state

63

*/

64

rollback(): void;

65

66

/**

67

* Commit the current state as the new baseline

68

*/

69

commit(): void;

70

71

/**

72

* Remove all skipped actions from history

73

*/

74

sweep(): void;

75

76

/**

77

* Toggle an action between active and inactive state

78

* @param id - ID of the action to toggle

79

*/

80

toggleAction(id: number): void;

81

82

/**

83

* Jump to a specific action in the history

84

* @param actionId - ID of the action to jump to

85

*/

86

jumpToAction(actionId: number): void;

87

88

/**

89

* Jump to a specific state index in the history

90

* @param index - Index of the state to jump to

91

*/

92

jumpToState(index: number): void;

93

94

/**

95

* Import a previously exported state

96

* @param nextLiftedState - Lifted state to import

97

*/

98

importState(nextLiftedState: any): void;

99

100

/**

101

* Lock or unlock state changes

102

* @param status - True to lock changes, false to unlock

103

*/

104

lockChanges(status: boolean): void;

105

106

/**

107

* Pause or resume recording of actions

108

* @param status - True to pause recording, false to resume

109

*/

110

pauseRecording(status: boolean): void;

111

112

/**

113

* Cleanup method called when service is destroyed

114

*/

115

ngOnDestroy(): void;

116

}

117

```

118

119

**Usage Examples:**

120

121

```typescript

122

import { Component, OnInit } from "@angular/core";

123

import { StoreDevtools } from "@ngrx/store-devtools";

124

125

@Component({

126

selector: "app-debug-controls",

127

template: `

128

<button (click)="reset()">Reset</button>

129

<button (click)="commit()">Commit</button>

130

<button (click)="rollback()">Rollback</button>

131

<button (click)="toggleRecording()">

132

{{ isPaused ? 'Resume' : 'Pause' }} Recording

133

</button>

134

`,

135

})

136

export class DebugControlsComponent implements OnInit {

137

isPaused = false;

138

139

constructor(private devtools: StoreDevtools) {}

140

141

ngOnInit() {

142

// Subscribe to lifted state to monitor devtools state

143

this.devtools.liftedState.subscribe((liftedState) => {

144

this.isPaused = liftedState.isPaused;

145

console.log("Current action count:", liftedState.nextActionId);

146

});

147

}

148

149

reset() {

150

this.devtools.reset();

151

}

152

153

commit() {

154

this.devtools.commit();

155

}

156

157

rollback() {

158

this.devtools.rollback();

159

}

160

161

toggleRecording() {

162

this.devtools.pauseRecording(!this.isPaused);

163

}

164

}

165

```

166

167

### DevtoolsDispatcher

168

169

Specialized dispatcher extending ActionsSubject for devtools operations.

170

171

```typescript { .api }

172

/**

173

* Injectable dispatcher service extending ActionsSubject for devtools

174

*/

175

class DevtoolsDispatcher extends ActionsSubject {}

176

```

177

178

### Extension Integration Service

179

180

Service managing connection to Redux DevTools browser extension.

181

182

```typescript { .api }

183

/**

184

* Service for integrating with Redux DevTools browser extension

185

*/

186

class DevtoolsExtension {

187

/** Observable of actions from the extension */

188

actions$: Observable<any>;

189

/** Observable of lifted actions from the extension */

190

liftedActions$: Observable<any>;

191

/** Observable indicating when extension starts */

192

start$: Observable<any>;

193

194

/**

195

* Notify the extension of state changes

196

* @param action - Action that caused the change

197

* @param state - New lifted state

198

*/

199

notify(action: any, state: LiftedState): void;

200

}

201

202

/**

203

* Interface for Redux DevTools extension connection

204

*/

205

interface ReduxDevtoolsExtensionConnection {

206

/** Subscribe to extension changes */

207

subscribe(listener: (change: any) => void): void;

208

/** Unsubscribe from extension changes */

209

unsubscribe(): void;

210

/** Send action and state to extension */

211

send(action: any, state: any): void;

212

/** Initialize extension with state */

213

init(state: any): void;

214

/** Send error message to extension */

215

error(message: string): void;

216

}

217

218

/**

219

* Redux DevTools browser extension interface

220

*/

221

interface ReduxDevtoolsExtension {

222

connect(options?: any): ReduxDevtoolsExtensionConnection;

223

}

224

```

225

226

### State Observable Factory

227

228

Factory function for creating state observable from devtools service.

229

230

```typescript { .api }

231

/**

232

* Create state observable from devtools service

233

* @param devtools - StoreDevtools service instance

234

* @returns StateObservable for current application state

235

*/

236

function createStateObservable(devtools: StoreDevtools): StateObservable;

237

```

238

239

### Zone Configuration

240

241

Zone configuration utilities for controlling Angular zone behavior with devtools.

242

243

```typescript { .api }

244

/**

245

* Zone configuration type for devtools connection

246

*/

247

type ZoneConfig =

248

| { connectInZone: true; ngZone: NgZone }

249

| { connectInZone: false; ngZone: null };

250

251

/**

252

* Inject zone configuration based on connectInZone setting

253

* @param connectInZone - Whether to connect within Angular zone

254

* @returns Zone configuration object

255

*/

256

function injectZoneConfig(connectInZone: boolean): ZoneConfig;

257

```

258

259

**Advanced Usage Example:**

260

261

```typescript

262

import { Injectable } from "@angular/core";

263

import { StoreDevtools } from "@ngrx/store-devtools";

264

import { map, filter, take } from "rxjs/operators";

265

266

@Injectable({

267

providedIn: "root",

268

})

269

export class CustomDebuggingService {

270

constructor(private devtools: StoreDevtools) {}

271

272

// Monitor specific action types

273

watchActionType(actionType: string) {

274

return this.devtools.liftedState.pipe(

275

map((liftedState) => liftedState.actionsById),

276

map((actions) =>

277

Object.values(actions).filter((action) => action.action.type === actionType)

278

)

279

);

280

}

281

282

// Get current error state

283

getCurrentErrors() {

284

return this.devtools.liftedState.pipe(

285

map((liftedState) => liftedState.computedStates),

286

map((states) => states.filter((state) => state.error)),

287

filter((errorStates) => errorStates.length > 0)

288

);

289

}

290

291

// Jump to first occurrence of action type

292

jumpToFirstAction(actionType: string) {

293

this.devtools.liftedState.pipe(take(1)).subscribe((liftedState) => {

294

const actionId = Object.keys(liftedState.actionsById).find(

295

(id) => liftedState.actionsById[parseInt(id)].action.type === actionType

296

);

297

298

if (actionId) {

299

this.devtools.jumpToAction(parseInt(actionId));

300

}

301

});

302

}

303

304

// Export current devtools state

305

exportState() {

306

return this.devtools.liftedState.pipe(

307

take(1),

308

map((liftedState) => JSON.stringify(liftedState, null, 2))

309

);

310

}

311

312

// Import devtools state from JSON

313

importStateFromJson(jsonState: string) {

314

try {

315

const liftedState = JSON.parse(jsonState);

316

this.devtools.importState(liftedState);

317

} catch (error) {

318

console.error("Failed to import state:", error);

319

}

320

}

321

}

322

```