or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

application-framework.mdindex.mdlayout-restoration.mdmime-rendering.mdservice-tokens.mdshell-management.mdstatus-management.mdurl-routing.mdutility-functions.md
tile.json

layout-restoration.mddocs/

0

# Layout Restoration

1

2

Persistent layout state management for saving and restoring widget arrangements, positions, and application state across sessions.

3

4

## Capabilities

5

6

### LayoutRestorer Class

7

8

Main implementation for layout restoration providing persistent state management across application sessions.

9

10

```typescript { .api }

11

/**

12

* Layout restoration implementation for persistent widget state management

13

*/

14

class LayoutRestorer implements ILayoutRestorer {

15

constructor(options: LayoutRestorer.IOptions);

16

17

/** Whether restoration is deferred until later */

18

readonly isDeferred: boolean;

19

20

/** Promise that resolves when restoration is complete */

21

readonly restored: Promise<void>;

22

23

/**

24

* Add a widget to be tracked for restoration

25

* @param widget - Widget to track

26

* @param name - Unique name for the widget

27

*/

28

add(widget: Widget, name: string): void;

29

30

/**

31

* Fetch the saved layout from storage

32

* @returns Promise resolving to saved layout or null

33

*/

34

fetch(): Promise<ILabShell.ILayout>;

35

36

/**

37

* Restore a widget tracker with saved state

38

* @param tracker - Widget tracker to restore

39

* @param options - Restoration options

40

* @returns Promise resolving when restoration is complete

41

*/

42

restore(

43

tracker: WidgetTracker,

44

options: IRestorer.IOptions<Widget>

45

): Promise<any>;

46

47

/**

48

* Restore deferred widgets

49

* @returns Promise resolving to main area layout or null

50

*/

51

restoreDeferred(): Promise<ILabShell.IMainArea | null>;

52

53

/**

54

* Save the current layout to storage

55

* @param layout - Layout to save

56

* @returns Promise resolving when save is complete

57

*/

58

save(layout: ILabShell.ILayout): Promise<void>;

59

}

60

```

61

62

**Usage Examples:**

63

64

```typescript

65

import { LayoutRestorer, ILayoutRestorer } from "@jupyterlab/application";

66

import { StateDB } from "@jupyterlab/statedb";

67

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

68

69

// Create layout restorer

70

const restorer = new LayoutRestorer({

71

connector: new StateDB(),

72

first: Promise.resolve(),

73

registry: commandRegistry

74

});

75

76

// Add widgets for tracking

77

const myWidget = new Widget();

78

myWidget.id = 'my-important-widget';

79

restorer.add(myWidget, 'my-important-widget');

80

81

// Wait for restoration to complete

82

await restorer.restored;

83

console.log('Layout restoration completed');

84

85

// Save current layout

86

const currentLayout = shell.saveLayout();

87

await restorer.save(currentLayout);

88

89

// Restore a widget tracker

90

await restorer.restore(widgetTracker, {

91

command: 'myapp:open-widget',

92

args: (widget) => ({ id: widget.id }),

93

name: (widget) => widget.id

94

});

95

```

96

97

### ILayoutRestorer Interface

98

99

Service interface for layout restoration functionality with dependency injection support.

100

101

```typescript { .api }

102

/**

103

* Layout restoration service interface

104

*/

105

interface ILayoutRestorer extends IRestorer {

106

/** Promise that resolves when restoration is complete */

107

readonly restored: Promise<void>;

108

109

/**

110

* Add a widget to be tracked for restoration

111

* @param widget - Widget to track

112

* @param name - Unique name for the widget

113

*/

114

add(widget: Widget, name: string): void;

115

116

/**

117

* Restore a widget tracker with saved state

118

* @param tracker - Widget tracker to restore

119

* @param options - Restoration options

120

* @returns Promise resolving when restoration is complete

121

*/

122

restore<T extends Widget>(

123

tracker: WidgetTracker<T>,

124

options: IRestorer.IOptions<T>

125

): Promise<any>;

126

}

127

128

/**

129

* Service token for layout restoration

130

*/

131

const ILayoutRestorer: Token<ILayoutRestorer>;

132

```

133

134

**Usage in Plugins:**

135

136

```typescript

137

import { ILayoutRestorer } from "@jupyterlab/application";

138

import { JupyterFrontEndPlugin } from "@jupyterlab/application";

139

import { WidgetTracker } from "@jupyterlab/apputils";

140

141

const plugin: JupyterFrontEndPlugin<void> = {

142

id: 'my-restoration-plugin',

143

autoStart: true,

144

requires: [ILayoutRestorer],

145

activate: (app, restorer: ILayoutRestorer) => {

146

const tracker = new WidgetTracker<MyWidget>({

147

namespace: 'my-widgets'

148

});

149

150

// Restore widgets from previous session

151

restorer.restore(tracker, {

152

command: 'myapp:create-widget',

153

args: (widget) => ({

154

id: widget.id,

155

config: widget.config

156

}),

157

name: (widget) => widget.id,

158

when: app.serviceManager.ready

159

});

160

161

// Add new widgets to restoration

162

tracker.widgetAdded.connect((sender, widget) => {

163

restorer.add(widget, widget.id);

164

});

165

}

166

};

167

```

168

169

### Restoration Options

170

171

Configuration options for controlling how widgets and trackers are restored.

172

173

```typescript { .api }

174

/**

175

* Options for restoring widget trackers (from @jupyterlab/apputils)

176

*/

177

interface IRestorer.IOptions<T extends Widget> {

178

/**

179

* Command to execute when restoring a widget

180

*/

181

command: string;

182

183

/**

184

* Function to extract command arguments from widget

185

* @param widget - Widget to extract args from

186

* @returns Command arguments

187

*/

188

args?: (widget: T) => ReadonlyPartialJSONObject;

189

190

/**

191

* Function to generate unique name for widget

192

* @param widget - Widget to name

193

* @returns Unique name string

194

*/

195

name: (widget: T) => string;

196

197

/**

198

* Promise to wait for before restoration

199

*/

200

when?: Promise<any>;

201

}

202

```

203

204

### Constructor Options

205

206

Configuration for creating LayoutRestorer instances.

207

208

```typescript { .api }

209

namespace LayoutRestorer {

210

/**

211

* Constructor options for LayoutRestorer

212

*/

213

interface IOptions {

214

/**

215

* State storage connector

216

*/

217

connector: IDataConnector<ReadonlyPartialJSONObject>;

218

219

/**

220

* Promise to resolve before restoration begins

221

*/

222

first: Promise<any>;

223

224

/**

225

* Command registry for executing restoration commands

226

*/

227

registry: CommandRegistry;

228

}

229

}

230

```

231

232

**Usage Examples:**

233

234

```typescript

235

import { LayoutRestorer } from "@jupyterlab/application";

236

import { StateDB } from "@jupyterlab/statedb";

237

import { CommandRegistry } from "@lumino/commands";

238

239

// Custom state connector

240

class CustomStateConnector implements IDataConnector<ReadonlyPartialJSONObject> {

241

async fetch(id: string): Promise<ReadonlyPartialJSONObject | undefined> {

242

// Custom fetch implementation

243

return JSON.parse(localStorage.getItem(id) || '{}');

244

}

245

246

async save(id: string, value: ReadonlyPartialJSONObject): Promise<void> {

247

// Custom save implementation

248

localStorage.setItem(id, JSON.stringify(value));

249

}

250

251

async remove(id: string): Promise<void> {

252

localStorage.removeItem(id);

253

}

254

255

async list(query?: string): Promise<any> {

256

// List implementation

257

return {};

258

}

259

}

260

261

// Create restorer with custom options

262

const commands = new CommandRegistry();

263

const restorer = new LayoutRestorer({

264

connector: new CustomStateConnector(),

265

first: Promise.resolve(), // Or wait for some initialization

266

registry: commands

267

});

268

269

// Check if restoration is deferred

270

if (restorer.isDeferred) {

271

console.log('Restoration will happen later');

272

273

// Manually trigger deferred restoration

274

const deferredLayout = await restorer.restoreDeferred();

275

if (deferredLayout) {

276

console.log('Deferred widgets restored');

277

}

278

}

279

```

280

281

### Integration with Shell

282

283

How layout restoration integrates with the shell system for complete state management.

284

285

```typescript { .api }

286

// Integration example showing how restoration works with shell

287

interface ShellRestorationWorkflow {

288

/**

289

* 1. Shell saves its layout periodically or on shutdown

290

*/

291

saveShellLayout(): Promise<void>;

292

293

/**

294

* 2. Layout restorer fetches saved layout on startup

295

*/

296

fetchSavedLayout(): Promise<ILabShell.ILayout | null>;

297

298

/**

299

* 3. Shell restores layout with layout restorer

300

*/

301

restoreShellLayout(layout: ILabShell.ILayout): Promise<void>;

302

303

/**

304

* 4. Individual widgets are restored via trackers

305

*/

306

restoreWidgetTrackers(): Promise<void>;

307

}

308

```

309

310

**Complete Restoration Example:**

311

312

```typescript

313

import {

314

LayoutRestorer,

315

ILayoutRestorer,

316

LabShell,

317

ILabShell

318

} from "@jupyterlab/application";

319

import { StateDB } from "@jupyterlab/statedb";

320

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

321

322

// Complete restoration workflow

323

async function setupLayoutRestoration(

324

shell: LabShell,

325

commands: CommandRegistry

326

) {

327

// 1. Create layout restorer

328

const restorer = new LayoutRestorer({

329

connector: new StateDB(),

330

first: Promise.resolve(),

331

registry: commands

332

});

333

334

// 2. Wait for restoration to complete

335

await restorer.restored;

336

337

// 3. Restore shell layout from saved state

338

const savedLayout = await restorer.fetch();

339

if (savedLayout) {

340

await shell.restoreLayout(

341

DockPanel.Mode.Multiple,

342

restorer,

343

savedLayout

344

);

345

}

346

347

// 4. Set up periodic saving

348

let saveTimer: any;

349

const scheduleSave = () => {

350

clearTimeout(saveTimer);

351

saveTimer = setTimeout(async () => {

352

const currentLayout = shell.saveLayout();

353

await restorer.save(currentLayout);

354

}, 1000); // Save after 1 second of inactivity

355

};

356

357

// Save when layout changes

358

shell.layoutModified.connect(scheduleSave);

359

360

// Save when widgets are added/removed

361

shell.currentChanged.connect(scheduleSave);

362

363

return restorer;

364

}

365

```

366

367

## Error Handling

368

369

Common error scenarios and how to handle them in layout restoration.

370

371

```typescript

372

// Error handling patterns

373

try {

374

await restorer.restore(tracker, options);

375

} catch (error) {

376

if (error instanceof Error) {

377

console.warn('Failed to restore widgets:', error.message);

378

// Fallback to default layout or create new widgets

379

}

380

}

381

382

// Graceful degradation

383

const layout = await restorer.fetch().catch(() => null);

384

if (!layout) {

385

console.log('No saved layout found, using defaults');

386

// Set up default layout

387

}

388

```