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
```