or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

core-api.mdindex.mdplugins.mdstorage-config.md

plugins.mddocs/

0

# Plugin Extensions

1

2

Store.js provides a modular plugin system that extends the core functionality with features like data expiration, event handling, array operations, compression, and more.

3

4

## Capabilities

5

6

### Events Plugin

7

8

Get notified when stored values change with watch/unwatch functionality.

9

10

```javascript { .api }

11

/**

12

* Watch for changes to a specific key

13

* @param {string} key - Key to watch for changes

14

* @param {function} listener - Function called when key changes

15

* @returns {number} Subscription ID for unwatching

16

*/

17

store.watch(key, listener)

18

19

/**

20

* Remove an event subscription

21

* @param {number} subscriptionId - ID returned from watch()

22

*/

23

store.unwatch(subscriptionId)

24

25

/**

26

* Listen for a single change event

27

* @param {string} key - Key to watch for changes

28

* @param {function} listener - Function called once when key changes

29

*/

30

store.once(key, listener)

31

32

// Listener callback signature

33

type WatchCallback = (newValue: any, oldValue: any) => void

34

```

35

36

**Usage Examples:**

37

38

```javascript

39

var eventsPlugin = require('store/plugins/events')

40

store.addPlugin(eventsPlugin)

41

42

// Watch for user changes

43

var subscriptionId = store.watch('user', function(newUser, oldUser) {

44

console.log('User changed from', oldUser, 'to', newUser)

45

})

46

47

store.set('user', { name: 'Alice' }) // Triggers callback

48

store.set('user', { name: 'Bob' }) // Triggers callback

49

50

// Stop watching

51

store.unwatch(subscriptionId)

52

53

// One-time listener

54

store.once('settings', function(newSettings, oldSettings) {

55

console.log('Settings changed for the first time')

56

})

57

```

58

59

### Expiration Plugin

60

61

Store values with automatic expiration based on timestamps.

62

63

```javascript { .api }

64

/**

65

* Set a value with expiration timestamp

66

* @param {string} key - Storage key

67

* @param {any} value - Value to store

68

* @param {number} expiration - Expiration timestamp (milliseconds since epoch)

69

* @returns {any} The stored value

70

*/

71

store.set(key, value, expiration)

72

73

/**

74

* Get expiration timestamp for a key

75

* @param {string} key - Storage key

76

* @returns {number|undefined} Expiration timestamp or undefined

77

*/

78

store.getExpiration(key)

79

80

/**

81

* Remove all expired keys from storage

82

*/

83

store.removeExpiredKeys()

84

```

85

86

**Usage Examples:**

87

88

```javascript

89

var expirePlugin = require('store/plugins/expire')

90

store.addPlugin(expirePlugin)

91

92

// Set value that expires in 1 hour

93

var oneHourFromNow = Date.now() + (60 * 60 * 1000)

94

store.set('session', { token: 'abc123' }, oneHourFromNow)

95

96

// Set value that expires in 5 minutes

97

var fiveMinutesFromNow = Date.now() + (5 * 60 * 1000)

98

store.set('temp-data', 'temporary', fiveMinutesFromNow)

99

100

// Check expiration

101

console.log('Session expires at:', new Date(store.getExpiration('session')))

102

103

// Clean up expired keys manually

104

store.removeExpiredKeys()

105

106

// Expired values return undefined when accessed

107

setTimeout(function() {

108

console.log(store.get('temp-data')) // undefined after expiration

109

}, 6 * 60 * 1000)

110

```

111

112

### Operations Plugin

113

114

Perform array and object operations directly on stored values.

115

116

```javascript { .api }

117

// Array operations

118

/**

119

* Push values to a stored array

120

* @param {string} key - Array storage key

121

* @param {...any} values - Values to push

122

* @returns {number} New array length

123

*/

124

store.push(key, ...values)

125

126

/**

127

* Pop value from a stored array

128

* @param {string} key - Array storage key

129

* @returns {any} Popped value

130

*/

131

store.pop(key)

132

133

/**

134

* Shift value from beginning of stored array

135

* @param {string} key - Array storage key

136

* @returns {any} Shifted value

137

*/

138

store.shift(key)

139

140

/**

141

* Unshift values to beginning of stored array

142

* @param {string} key - Array storage key

143

* @param {...any} values - Values to unshift

144

* @returns {number} New array length

145

*/

146

store.unshift(key, ...values)

147

148

// Object operations

149

/**

150

* Assign properties to a stored object

151

* @param {string} key - Object storage key

152

* @param {...Object} objects - Objects to assign

153

* @returns {Object} Updated object

154

*/

155

store.assign(key, ...objects)

156

```

157

158

**Usage Examples:**

159

160

```javascript

161

var operationsPlugin = require('store/plugins/operations')

162

store.addPlugin(operationsPlugin)

163

164

// Array operations

165

store.set('todos', ['Buy milk', 'Walk dog'])

166

167

store.push('todos', 'Do homework', 'Call mom')

168

console.log(store.get('todos')) // ['Buy milk', 'Walk dog', 'Do homework', 'Call mom']

169

170

var lastTodo = store.pop('todos')

171

console.log(lastTodo) // 'Call mom'

172

173

var firstTodo = store.shift('todos')

174

console.log(firstTodo) // 'Buy milk'

175

176

store.unshift('todos', 'Wake up', 'Drink coffee')

177

console.log(store.get('todos')) // ['Wake up', 'Drink coffee', 'Walk dog', 'Do homework']

178

179

// Object operations

180

store.set('user', { name: 'Alice', age: 25 })

181

182

store.assign('user', { email: 'alice@example.com' }, { verified: true })

183

console.log(store.get('user'))

184

// { name: 'Alice', age: 25, email: 'alice@example.com', verified: true }

185

```

186

187

### Update Plugin

188

189

Update stored values using transformation functions.

190

191

```javascript { .api }

192

/**

193

* Update a stored value using a function

194

* @param {string} key - Storage key

195

* @param {function} updateFn - Function to transform current value

196

*/

197

store.update(key, updateFn)

198

199

/**

200

* Update a stored value with default if key doesn't exist

201

* @param {string} key - Storage key

202

* @param {any} defaultValue - Default value if key doesn't exist

203

* @param {function} updateFn - Function to transform current value

204

*/

205

store.update(key, defaultValue, updateFn)

206

207

// Update function signature

208

type UpdateCallback = (currentValue: any) => any

209

```

210

211

**Usage Examples:**

212

213

```javascript

214

var updatePlugin = require('store/plugins/update')

215

store.addPlugin(updatePlugin)

216

217

// Update counter

218

store.set('counter', 5)

219

store.update('counter', function(count) {

220

return count + 1

221

})

222

console.log(store.get('counter')) // 6

223

224

// Update with default value

225

store.update('visits', 0, function(visits) {

226

return visits + 1

227

})

228

console.log(store.get('visits')) // 1 (started from default 0)

229

230

// Update object properties

231

store.set('user', { name: 'Alice', loginCount: 5 })

232

store.update('user', function(user) {

233

return {

234

...user,

235

loginCount: user.loginCount + 1,

236

lastLogin: new Date().toISOString()

237

}

238

})

239

```

240

241

### Defaults Plugin

242

243

Define default values that are returned when keys don't exist.

244

245

```javascript { .api }

246

/**

247

* Set default values for keys

248

* @param {Object} defaultValues - Object mapping keys to default values

249

*/

250

store.defaults(defaultValues)

251

```

252

253

**Usage Examples:**

254

255

```javascript

256

var defaultsPlugin = require('store/plugins/defaults')

257

store.addPlugin(defaultsPlugin)

258

259

// Set defaults

260

store.defaults({

261

theme: 'light',

262

language: 'en',

263

notifications: true,

264

maxItems: 10

265

})

266

267

// Get values (returns defaults if not set)

268

console.log(store.get('theme')) // 'light'

269

console.log(store.get('language')) // 'en'

270

console.log(store.get('maxItems')) // 10

271

272

// Set actual values

273

store.set('theme', 'dark')

274

console.log(store.get('theme')) // 'dark' (actual value)

275

console.log(store.get('language')) // 'en' (still default)

276

```

277

278

### Compression Plugin

279

280

Automatically compress stored data using LZ-String compression to save space.

281

282

```javascript { .api }

283

// Compression plugin transparently compresses data on set() and decompresses on get()

284

// Enhanced set and get methods with compression/decompression

285

store.set(key, value) // Automatically compresses before storing

286

store.get(key) // Automatically decompresses after retrieving

287

```

288

289

**Usage Examples:**

290

291

```javascript

292

var compressionPlugin = require('store/plugins/compression')

293

store.addPlugin(compressionPlugin)

294

295

// Large data is automatically compressed using LZ-String

296

var largeData = {

297

users: Array.from({ length: 1000 }, (_, i) => ({

298

id: i,

299

name: `User ${i}`,

300

email: `user${i}@example.com`

301

}))

302

}

303

304

store.set('large-dataset', largeData)

305

// Data is compressed when stored and decompressed when retrieved

306

var retrieved = store.get('large-dataset')

307

console.log(retrieved.users.length) // 1000

308

309

// Fallback: existing uncompressed values still work

310

// Plugin automatically detects and handles both compressed and uncompressed data

311

```

312

313

### Observe Plugin

314

315

Observe stored values and their changes with immediate callback execution and ongoing change notifications.

316

317

```javascript { .api }

318

/**

319

* Observe a key for changes, immediately calling callback with current value

320

* @param {string} key - Key to observe

321

* @param {function} callback - Function called immediately and on changes

322

* @returns {number} Subscription ID for unobserving

323

*/

324

store.observe(key, callback)

325

326

/**

327

* Stop observing a key

328

* @param {number} subscriptionId - ID returned from observe()

329

*/

330

store.unobserve(subscriptionId)

331

332

// Callback signature (same as events plugin)

333

type ObserveCallback = (newValue: any, oldValue: any) => void

334

```

335

336

**Usage Examples:**

337

338

```javascript

339

var observePlugin = require('store/plugins/observe')

340

store.addPlugin(observePlugin)

341

342

// Observe immediately gets current value, then watches for changes

343

var subId = store.observe('user', function(newUser, oldUser) {

344

console.log('User:', newUser) // Called immediately with current value

345

if (oldUser !== undefined) {

346

console.log('Changed from:', oldUser, 'to:', newUser)

347

}

348

})

349

350

store.set('user', { name: 'Alice' }) // Triggers callback

351

store.set('user', { name: 'Bob' }) // Triggers callback

352

353

// Stop observing

354

store.unobserve(subId)

355

```

356

357

### Dump Plugin

358

359

Utility for dumping all stored values for debugging.

360

361

```javascript { .api }

362

/**

363

* Dump all stored values

364

* @returns {Object} Object containing all key-value pairs

365

*/

366

store.dump()

367

```

368

369

**Usage Examples:**

370

371

```javascript

372

var dumpPlugin = require('store/plugins/dump')

373

store.addPlugin(dumpPlugin)

374

375

store.set('user', { name: 'Alice' })

376

store.set('theme', 'dark')

377

store.set('count', 42)

378

379

var allData = store.dump()

380

console.log(allData)

381

// {

382

// user: { name: 'Alice' },

383

// theme: 'dark',

384

// count: 42

385

// }

386

```

387

388

### V1 Backcompat Plugin

389

390

Provides full backwards compatibility with store.js version 1.x API, allowing legacy code to work without modification.

391

392

```javascript { .api }

393

/**

394

* Check if a key exists in storage

395

* @param {string} key - Key to check

396

* @returns {boolean} True if key exists

397

*/

398

store.has(key)

399

400

/**

401

* Perform a transactional update on a stored value

402

* @param {string} key - Storage key

403

* @param {any} defaultValue - Default value if key doesn't exist

404

* @param {function} transactionFn - Function to transform current value

405

*/

406

store.transact(key, defaultValue, transactionFn)

407

408

/**

409

* Clear all storage (alias for clearAll)

410

*/

411

store.clear()

412

413

/**

414

* Iterate over all key-value pairs (v1 style)

415

* @param {function} fn - Function called with (key, value) for each pair

416

*/

417

store.forEach(fn)

418

419

/**

420

* Get all stored values as an object (alias for dump)

421

* @returns {Object} Object containing all key-value pairs

422

*/

423

store.getAll()

424

425

/**

426

* Manually serialize a value (normally done automatically)

427

* @param {any} value - Value to serialize

428

* @returns {string} Serialized value

429

*/

430

store.serialize(value)

431

432

/**

433

* Manually deserialize a value (normally done automatically)

434

* @param {string} value - Serialized value to deserialize

435

* @returns {any} Deserialized value

436

*/

437

store.deserialize(value)

438

439

// V1 property compatibility

440

store.disabled // Boolean - inverse of store.enabled

441

```

442

443

**Usage Examples:**

444

445

```javascript

446

var v1Plugin = require('store/plugins/v1-backcompat')

447

store.addPlugin(v1Plugin)

448

449

// V1 style API usage

450

if (store.has('user')) {

451

console.log('User exists')

452

}

453

454

// Transactional updates

455

store.transact('counter', 0, function(currentValue) {

456

return currentValue + 1

457

})

458

459

// V1 style iteration

460

store.forEach(function(key, value) {

461

console.log(key + ' = ' + JSON.stringify(value))

462

})

463

464

// Get all data

465

var allData = store.getAll()

466

console.log(allData) // { user: {...}, settings: {...} }

467

468

// Manual serialization (rarely needed)

469

var serialized = store.serialize({ foo: 'bar' })

470

var deserialized = store.deserialize(serialized)

471

472

// V1 property

473

if (!store.disabled) {

474

console.log('Storage is enabled')

475

}

476

```

477

478

### JSON2 Plugin

479

480

Provides JSON polyfill for legacy browsers that don't have native JSON support.

481

482

```javascript { .api }

483

// No additional API - provides JSON.parse and JSON.stringify for old browsers

484

// Automatically included in legacy builds

485

```

486

487

## Plugin Loading

488

489

### Loading Individual Plugins

490

491

```javascript { .api }

492

// Load specific plugins

493

var expirePlugin = require('store/plugins/expire')

494

var eventsPlugin = require('store/plugins/events')

495

496

store.addPlugin(expirePlugin)

497

store.addPlugin([eventsPlugin, expirePlugin]) // Multiple plugins

498

```

499

500

### Loading All Plugins

501

502

```javascript { .api }

503

// Load all plugins at once

504

var allPlugins = require('store/plugins/all')

505

store.addPlugin(allPlugins)

506

507

// Or use the everything build which includes all plugins

508

var store = require('store/dist/store.everything')

509

```

510

511

**Usage Examples:**

512

513

```javascript

514

// Custom store with specific plugins

515

var engine = require('store/src/store-engine')

516

var storages = require('store/storages/all')

517

518

var myPlugins = [

519

require('store/plugins/expire'),

520

require('store/plugins/events'),

521

require('store/plugins/operations')

522

]

523

524

var customStore = engine.createStore(storages, myPlugins)

525

526

// Now all selected plugin methods are available

527

customStore.set('data', 'value', Date.now() + 60000) // expire plugin

528

customStore.watch('data', function(newVal, oldVal) { // events plugin

529

console.log('Data changed')

530

})

531

customStore.push('items', 'new item') // operations plugin

532

```