or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

browser.mdcore.mdindex.mdnode.md

browser.mddocs/

0

# Browser Storage

1

2

Browser storage adapters and presets for localStorage and sessionStorage integration. These adapters provide seamless integration with browser storage APIs while maintaining the same lowdb interface for consistent data management across environments.

3

4

## Capabilities

5

6

### Browser Storage Presets

7

8

Pre-configured database instances with browser storage adapters for immediate use.

9

10

```typescript { .api }

11

/**

12

* Create a LowSync instance with LocalStorage adapter for persistent browser storage

13

* @param key - Storage key for localStorage

14

* @param defaultData - Default data structure

15

* @returns Configured LowSync instance with data pre-loaded from localStorage

16

*/

17

function LocalStoragePreset<Data>(key: string, defaultData: Data): LowSync<Data>;

18

19

/**

20

* Create a LowSync instance with SessionStorage adapter for session-only browser storage

21

* @param key - Storage key for sessionStorage

22

* @param defaultData - Default data structure

23

* @returns Configured LowSync instance with data pre-loaded from sessionStorage

24

*/

25

function SessionStoragePreset<Data>(key: string, defaultData: Data): LowSync<Data>;

26

```

27

28

**Usage Examples:**

29

30

```typescript

31

import { LocalStoragePreset, SessionStoragePreset } from "lowdb/browser";

32

33

// Persistent storage across browser sessions

34

type AppData = {

35

user: { id: number; name: string; preferences: object };

36

settings: { theme: string; language: string };

37

};

38

39

const defaultData: AppData = {

40

user: { id: 0, name: "", preferences: {} },

41

settings: { theme: "light", language: "en" }

42

};

43

44

const db = LocalStoragePreset("myapp-data", defaultData);

45

46

// Update user preferences

47

db.update((data) => {

48

data.user.name = "Alice";

49

data.settings.theme = "dark";

50

});

51

52

// Session-only storage (cleared when tab closes)

53

const sessionDb = SessionStoragePreset("session-data", { cart: [] });

54

sessionDb.update(({ cart }) => cart.push({ id: 1, name: "Product" }));

55

```

56

57

### LocalStorage Adapter

58

59

Synchronous adapter for browser localStorage with automatic JSON serialization.

60

61

```typescript { .api }

62

/**

63

* Sync adapter for browser localStorage with automatic JSON parsing/stringifying

64

* @template T - The type of data stored in localStorage

65

*/

66

class LocalStorage<T> implements SyncAdapter<T> {

67

constructor(key: string);

68

69

/** Read and parse data from localStorage, returns null if key doesn't exist */

70

read(): T | null;

71

72

/** Stringify and store data in localStorage */

73

write(obj: T): void;

74

}

75

```

76

77

**Usage Examples:**

78

79

```typescript

80

import { LowSync } from "lowdb";

81

import { LocalStorage } from "lowdb/browser";

82

83

// Direct adapter usage

84

const adapter = new LocalStorage<{ count: number }>("app-counter");

85

const db = new LowSync(adapter, { count: 0 });

86

87

// Initialize from localStorage

88

db.read();

89

90

// Update and persist

91

db.data.count++;

92

db.write(); // Immediately saved to localStorage

93

94

// Data persists across browser sessions

95

console.log(localStorage.getItem("app-counter")); // {"count":1}

96

```

97

98

### SessionStorage Adapter

99

100

Synchronous adapter for browser sessionStorage with automatic JSON serialization.

101

102

```typescript { .api }

103

/**

104

* Sync adapter for browser sessionStorage with automatic JSON parsing/stringifying

105

* @template T - The type of data stored in sessionStorage

106

*/

107

class SessionStorage<T> implements SyncAdapter<T> {

108

constructor(key: string);

109

110

/** Read and parse data from sessionStorage, returns null if key doesn't exist */

111

read(): T | null;

112

113

/** Stringify and store data in sessionStorage */

114

write(obj: T): void;

115

}

116

```

117

118

**Usage Examples:**

119

120

```typescript

121

import { LowSync } from "lowdb";

122

import { SessionStorage } from "lowdb/browser";

123

124

// Session-only storage

125

const adapter = new SessionStorage<string[]>("temp-notes");

126

const notesDb = new LowSync(adapter, []);

127

128

notesDb.read();

129

notesDb.data.push("Temporary note");

130

notesDb.write(); // Saved to sessionStorage

131

132

// Data is cleared when tab closes

133

console.log(sessionStorage.getItem("temp-notes")); // ["Temporary note"]

134

```

135

136

### WebStorage Base Class

137

138

Base class for browser storage adapters (not directly exported, but used internally).

139

140

```typescript { .api }

141

/**

142

* Base sync adapter for browser storage APIs (localStorage/sessionStorage)

143

* @template T - The type of data stored

144

*/

145

class WebStorage<T> implements SyncAdapter<T> {

146

constructor(key: string, storage: Storage);

147

148

/** Read and parse JSON from storage, returns null if key doesn't exist */

149

read(): T | null;

150

151

/** Stringify and store JSON in storage */

152

write(obj: T): void;

153

}

154

```

155

156

## Browser-Specific Behavior

157

158

### Storage Persistence

159

160

**LocalStorage**:

161

- Data persists across browser sessions

162

- Survives page reloads and browser restarts

163

- Shared across all tabs/windows of the same origin

164

- Typically limited to 5-10MB per origin

165

166

**SessionStorage**:

167

- Data persists only for the current browser tab/window session

168

- Cleared when tab is closed

169

- Isolated per tab (not shared between tabs)

170

- Same storage limits as localStorage

171

172

### Storage Quotas

173

174

Browser storage has size limitations:

175

176

```typescript

177

import { LocalStoragePreset } from "lowdb/browser";

178

179

try {

180

const db = LocalStoragePreset("large-dataset", { data: [] });

181

182

// Add large amounts of data

183

db.update(({ data }) => {

184

for (let i = 0; i < 100000; i++) {

185

data.push({ id: i, content: "Large content string..." });

186

}

187

});

188

} catch (error) {

189

if (error.name === "QuotaExceededError") {

190

console.error("Storage quota exceeded");

191

// Handle storage limit reached

192

}

193

}

194

```

195

196

### Cross-Origin Restrictions

197

198

Storage is isolated by origin (protocol + domain + port):

199

200

```typescript

201

// Each origin has separate storage

202

// https://app.example.com - separate storage

203

// https://api.example.com - separate storage

204

// http://app.example.com - separate storage

205

206

const db = LocalStoragePreset("shared-data", {});

207

// This data is only accessible from the current origin

208

```

209

210

## Data Synchronization

211

212

### Multiple Tabs

213

214

LocalStorage data is shared between tabs and can be synchronized:

215

216

```typescript

217

import { LocalStoragePreset } from "lowdb/browser";

218

219

const db = LocalStoragePreset("shared-state", { count: 0 });

220

221

// Listen for storage changes from other tabs

222

window.addEventListener("storage", (event) => {

223

if (event.key === "shared-state" && event.newValue) {

224

// Reload data when changed by another tab

225

db.read();

226

console.log("Data updated by another tab:", db.data);

227

}

228

});

229

230

// Update data (will trigger storage event in other tabs)

231

db.update((data) => {

232

data.count++;

233

});

234

```

235

236

### React Integration

237

238

Example integration with React for reactive updates:

239

240

```typescript

241

import { useEffect, useState } from "react";

242

import { LocalStoragePreset } from "lowdb/browser";

243

244

function useLocalStorageDb<T>(key: string, defaultData: T) {

245

const [db] = useState(() => LocalStoragePreset(key, defaultData));

246

const [data, setData] = useState(db.data);

247

248

useEffect(() => {

249

const handleStorageChange = (event: StorageEvent) => {

250

if (event.key === key) {

251

db.read();

252

setData({ ...db.data });

253

}

254

};

255

256

window.addEventListener("storage", handleStorageChange);

257

return () => window.removeEventListener("storage", handleStorageChange);

258

}, [db, key]);

259

260

const updateData = (updater: (data: T) => void) => {

261

db.update(updater);

262

setData({ ...db.data });

263

};

264

265

return [data, updateData] as const;

266

}

267

268

// Usage in component

269

function App() {

270

const [data, updateData] = useLocalStorageDb("app-data", { todos: [] });

271

272

const addTodo = (todo: string) => {

273

updateData((data) => {

274

data.todos.push({ id: Date.now(), text: todo, done: false });

275

});

276

};

277

278

return <div>{/* Component JSX */}</div>;

279

}

280

```

281

282

## Error Handling

283

284

Browser storage adapters may encounter various errors:

285

286

```typescript

287

import { LocalStoragePreset } from "lowdb/browser";

288

289

try {

290

const db = LocalStoragePreset("my-data", { items: [] });

291

292

db.update(({ items }) => {

293

// Add large object that might exceed quota

294

items.push({ id: 1, largeData: "...".repeat(1000000) });

295

});

296

} catch (error) {

297

// Handle different storage errors

298

switch (error.name) {

299

case "QuotaExceededError":

300

console.error("Storage quota exceeded");

301

// Could implement cleanup or user notification

302

break;

303

case "SecurityError":

304

console.error("Storage access denied (private browsing?)");

305

break;

306

default:

307

console.error("Storage error:", error);

308

}

309

}

310

311

// Handle JSON parsing errors for corrupted data

312

try {

313

const db = LocalStoragePreset("potentially-corrupted", {});

314

db.read(); // Might fail if localStorage contains invalid JSON

315

} catch (error) {

316

if (error instanceof SyntaxError) {

317

console.error("Corrupted data in localStorage");

318

// Could clear corrupted data and reinitialize

319

localStorage.removeItem("potentially-corrupted");

320

}

321

}

322

```

323

324

## Performance Considerations

325

326

### Synchronous Operations

327

328

Browser storage adapters are synchronous and may block the main thread:

329

330

```typescript

331

// For large datasets, consider batching updates

332

const db = LocalStoragePreset("large-dataset", { items: [] });

333

334

// Instead of multiple individual updates

335

// for (let i = 0; i < 1000; i++) {

336

// db.update(({ items }) => items.push({ id: i })); // 1000 storage writes

337

// }

338

339

// Use single batch update

340

db.update(({ items }) => {

341

for (let i = 0; i < 1000; i++) {

342

items.push({ id: i });

343

}

344

}); // 1 storage write

345

```

346

347

### Memory Usage

348

349

Browser storage loads all data into memory. For large datasets:

350

351

- Consider data pagination or lazy loading

352

- Implement data cleanup strategies

353

- Use IndexedDB for larger datasets (via custom adapters)

354

355

### Private Browsing Mode

356

357

Some browsers restrict storage in private/incognito mode:

358

359

```typescript

360

function isStorageAvailable() {

361

try {

362

const test = "__storage_test__";

363

localStorage.setItem(test, test);

364

localStorage.removeItem(test);

365

return true;

366

} catch {

367

return false;

368

}

369

}

370

371

if (isStorageAvailable()) {

372

const db = LocalStoragePreset("app-data", {});

373

} else {

374

// Fallback to memory storage

375

const db = new LowSync(new MemorySync(), {});

376

}

377

```

378

379

## Browser Compatibility

380

381

Browser storage adapters work in all modern browsers that support:

382

383

- **localStorage/sessionStorage APIs** (IE8+, all modern browsers)

384

- **JSON.parse/JSON.stringify** (IE8+, all modern browsers)

385

- **ES6 Classes and Modules** (modern browsers or with transpilation)

386

387

For older browser support, ensure your build process includes appropriate polyfills and transpilation.