or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

application-core.mdapplication-lifecycle.mdindex.mdplugin-management.mdservice-resolution.md

application-lifecycle.mddocs/

0

# Application Lifecycle

1

2

Application startup process and event handling for managing the complete application lifecycle from initialization to shutdown. The Application class provides comprehensive lifecycle management including plugin activation, DOM attachment, and event listener setup.

3

4

## Capabilities

5

6

### Application Startup

7

8

Start the application with optional configuration for hosting, plugin selection, and event handling behavior.

9

10

```typescript { .api }

11

/**

12

* Start the application.

13

* @param options - The options for starting the application

14

* @returns A promise which resolves when all bootstrapping work is complete and the shell is mounted to the DOM

15

*/

16

start(options?: Application.IStartOptions): Promise<void>;

17

18

interface Application.IStartOptions {

19

/** The ID of the DOM node to host the application shell */

20

hostID?: string;

21

/** The plugins to activate on startup (in addition to autoStart plugins) */

22

startPlugins?: string[];

23

/** The plugins to NOT activate on startup (overrides startPlugins and autoStart) */

24

ignorePlugins?: string[];

25

/** Whether to capture keydown events at bubbling or capturing phase */

26

bubblingKeydown?: boolean;

27

}

28

```

29

30

**Usage Examples:**

31

32

```typescript

33

import { Application } from "@lumino/application";

34

import { Widget } from "@lumino/widgets";

35

36

const app = new Application({ shell: new Widget() });

37

38

// Basic startup

39

await app.start();

40

41

// Startup with custom host element

42

await app.start({

43

hostID: 'my-app-container'

44

});

45

46

// Startup with specific plugins

47

await app.start({

48

startPlugins: ['essential-plugin', 'ui-plugin'],

49

ignorePlugins: ['debug-plugin']

50

});

51

52

// Startup with custom event handling

53

await app.start({

54

bubblingKeydown: true // Use bubbling phase for keyboard events

55

});

56

```

57

58

### Startup Process

59

60

The application startup process follows a specific sequence of steps:

61

62

1. **Check if Already Started**: Returns immediately if `start()` has already been called

63

2. **Mark as Started**: Sets internal started flag to prevent multiple startups

64

3. **Configure Event Handling**: Sets up keydown event capture mode

65

4. **Activate Startup Plugins**: Activates plugins marked with `autoStart: true` plus any specified in `startPlugins`

66

5. **Attach Shell**: Mounts the shell widget to the DOM

67

6. **Add Event Listeners**: Registers application-wide event handlers

68

7. **Resolve Started Promise**: Signals that startup is complete

69

70

**Monitoring Startup:**

71

72

```typescript

73

// Check if application has started

74

if (await app.started) {

75

console.log('Application startup complete');

76

}

77

78

// Wait for startup completion

79

app.start().then(() => {

80

console.log('Application is now running');

81

});

82

83

// Monitor startup with multiple operations

84

Promise.all([

85

app.start(),

86

// other async operations

87

]).then(() => {

88

console.log('Everything is ready');

89

});

90

```

91

92

### Event Handling System

93

94

The Application class implements comprehensive DOM event handling for application-wide functionality.

95

96

```typescript { .api }

97

/**

98

* Handle the DOM events for the application.

99

* @param event - The DOM event sent to the application

100

*/

101

handleEvent(event: Event): void;

102

```

103

104

**Supported Events:**

105

106

- **`keydown`**: Keyboard shortcuts and command processing

107

- **`keyup`**: Key release handling for command completion

108

- **`contextmenu`**: Right-click context menu activation

109

- **`resize`**: Window resize handling for layout updates

110

111

**Event Handling Behavior:**

112

113

```typescript

114

// The application automatically handles these events:

115

116

// Keyboard events - processed by command registry

117

document.addEventListener('keydown', app); // Triggers app.commands.processKeydownEvent()

118

document.addEventListener('keyup', app); // Triggers app.commands.processKeyupEvent()

119

120

// Context menu events - opens application context menu

121

document.addEventListener('contextmenu', app); // Opens app.contextMenu if not shift-clicked

122

123

// Window events - updates shell layout

124

window.addEventListener('resize', app); // Triggers app.shell.update()

125

```

126

127

### Custom Event Handling

128

129

Subclasses can override event handling methods for custom behavior:

130

131

```typescript { .api }

132

/**

133

* A method invoked on a document 'keydown' event.

134

* @param event - The keyboard event

135

*/

136

protected evtKeydown(event: KeyboardEvent): void;

137

138

/**

139

* A method invoked on a document 'keyup' event.

140

* @param event - The keyboard event

141

*/

142

protected evtKeyup(event: KeyboardEvent): void;

143

144

/**

145

* A method invoked on a document 'contextmenu' event.

146

* @param event - The pointer event

147

*/

148

protected evtContextMenu(event: PointerEvent): void;

149

150

/**

151

* A method invoked on a window 'resize' event.

152

* @param event - The resize event

153

*/

154

protected evtResize(event: Event): void;

155

```

156

157

**Custom Event Handling Example:**

158

159

```typescript

160

class CustomApplication extends Application {

161

protected evtKeydown(event: KeyboardEvent): void {

162

// Add custom keyboard shortcuts

163

if (event.ctrlKey && event.key === 'k') {

164

console.log('Custom shortcut triggered');

165

event.preventDefault();

166

return;

167

}

168

169

// Fall back to default behavior

170

super.evtKeydown(event);

171

}

172

173

protected evtContextMenu(event: PointerEvent): void {

174

// Custom context menu logic

175

if (event.target instanceof Element && event.target.classList.contains('no-context')) {

176

return; // Skip context menu for certain elements

177

}

178

179

super.evtContextMenu(event);

180

}

181

182

protected evtResize(event: Event): void {

183

console.log('Window resized, updating layout');

184

super.evtResize(event);

185

}

186

}

187

```

188

189

### DOM Integration

190

191

The application integrates with the DOM through shell attachment and event listener registration:

192

193

```typescript { .api }

194

/**

195

* Attach the application shell to the DOM.

196

* @param id - The ID of the host node for the shell, or empty string

197

*/

198

protected attachShell(id: string): void;

199

200

/**

201

* Add the application event listeners.

202

*/

203

protected addEventListeners(): void;

204

```

205

206

**Shell Attachment:**

207

208

```typescript

209

// Default behavior - attaches to document.body if no ID provided

210

app.start(); // Shell attached to document.body

211

212

// Custom host element

213

app.start({ hostID: 'app-root' }); // Shell attached to element with id="app-root"

214

215

// Custom attachment logic

216

class CustomApplication extends Application {

217

protected attachShell(id: string): void {

218

const host = id ? document.getElementById(id) : document.querySelector('.app-container');

219

if (host) {

220

Widget.attach(this.shell, host);

221

} else {

222

console.warn('Host element not found, using document.body');

223

super.attachShell('');

224

}

225

}

226

}

227

```

228

229

### Application State

230

231

The Application class provides properties to monitor application state:

232

233

```typescript { .api }

234

/** A promise which resolves after the application has started */

235

readonly started: Promise<void>;

236

237

/** The list of all the deferred plugins */

238

readonly deferredPlugins: string[];

239

```

240

241

**State Monitoring:**

242

243

```typescript

244

// Wait for application startup

245

await app.started;

246

console.log('Application is running');

247

248

// Check deferred plugins

249

const deferred = app.deferredPlugins;

250

if (deferred.length > 0) {

251

console.log('Deferred plugins:', deferred);

252

253

// Activate them later

254

await app.activateDeferredPlugins();

255

console.log('All deferred plugins now active');

256

}

257

258

// Check if specific functionality is available

259

const hasStarted = app.started.then(() => true).catch(() => false);

260

```

261

262

### Lifecycle Best Practices

263

264

1. **Single Startup**: Only call `start()` once - subsequent calls return the same promise

265

2. **Plugin Order**: Use `requires`/`optional` dependencies rather than `startPlugins` for plugin ordering

266

3. **Error Handling**: Handle startup failures gracefully as some plugins may fail to activate

267

4. **DOM Ready**: Ensure the DOM is ready before calling `start()` if using a custom `hostID`

268

5. **Event Bubbling**: Consider `bubblingKeydown: true` if you need to handle keyboard events in your own code first

269

6. **Cleanup**: The Application class doesn't provide explicit cleanup methods - manage this in your own application code