adapt-authoring-core 2.4.3 → 2.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/index.js +1 -0
- package/lib/DataCache.js +49 -0
- package/package.json +1 -1
- package/tests/DataCache.spec.js +39 -0
package/index.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
export { default as AbstractModule } from './lib/AbstractModule.js'
|
|
2
2
|
export { default as App } from './lib/App.js'
|
|
3
|
+
export { default as DataCache } from './lib/DataCache.js'
|
|
3
4
|
export { default as DependencyLoader } from './lib/DependencyLoader.js'
|
|
4
5
|
export { default as Hook } from './lib/Hook.js'
|
|
5
6
|
export { metadataFileName, packageFileName, isObject, getArgs, spawn, readJson, writeJson, toBoolean, ensureDir, escapeRegExp, stringifyValues, loadDependencyFiles } from './lib/Utils.js'
|
package/lib/DataCache.js
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import App from './App.js'
|
|
2
|
+
/**
|
|
3
|
+
* Time-limited data cache
|
|
4
|
+
* @memberof core
|
|
5
|
+
*/
|
|
6
|
+
class DataCache {
|
|
7
|
+
/**
|
|
8
|
+
* @param {Object} options
|
|
9
|
+
* @param {Boolean} options.enable Whether the cache is enabled
|
|
10
|
+
* @param {Number} options.lifespan Cache entry lifespan in milliseconds
|
|
11
|
+
*/
|
|
12
|
+
constructor ({ enable, lifespan }) {
|
|
13
|
+
this.isEnabled = enable === true
|
|
14
|
+
this.lifespan = lifespan
|
|
15
|
+
this.cache = {}
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Retrieve cached data, or run fresh query if no cache exists or cache is invalid
|
|
20
|
+
* @param {Object} query
|
|
21
|
+
* @param {Object} options
|
|
22
|
+
* @param {Object} mongoOptions
|
|
23
|
+
* @returns {*} The cached data
|
|
24
|
+
*/
|
|
25
|
+
async get (query, options, mongoOptions) {
|
|
26
|
+
const key = JSON.stringify(query) + JSON.stringify(options) + JSON.stringify(mongoOptions)
|
|
27
|
+
this.prune()
|
|
28
|
+
if (this.isEnabled && this.cache[key]) {
|
|
29
|
+
return this.cache[key].data
|
|
30
|
+
}
|
|
31
|
+
const mongodb = await App.instance.waitForModule('mongodb')
|
|
32
|
+
const data = await mongodb.find(options.collectionName, query, mongoOptions)
|
|
33
|
+
this.cache[key] = { data, timestamp: Date.now() }
|
|
34
|
+
return data
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Removes invalid cache data
|
|
39
|
+
*/
|
|
40
|
+
prune () {
|
|
41
|
+
Object.keys(this.cache).forEach(k => {
|
|
42
|
+
if (Date.now() > (this.cache[k].timestamp + this.lifespan)) {
|
|
43
|
+
delete this.cache[k]
|
|
44
|
+
}
|
|
45
|
+
})
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
export default DataCache
|
package/package.json
CHANGED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { describe, it } from 'node:test'
|
|
2
|
+
import assert from 'node:assert/strict'
|
|
3
|
+
import DataCache from '../lib/DataCache.js'
|
|
4
|
+
|
|
5
|
+
describe('DataCache', () => {
|
|
6
|
+
describe('#prune()', () => {
|
|
7
|
+
it('should remove expired entries from the cache', () => {
|
|
8
|
+
const instance = Object.create(DataCache.prototype)
|
|
9
|
+
instance.lifespan = 100
|
|
10
|
+
instance.cache = {
|
|
11
|
+
expired: { data: [1], timestamp: Date.now() - 200 },
|
|
12
|
+
valid: { data: [2], timestamp: Date.now() }
|
|
13
|
+
}
|
|
14
|
+
instance.prune()
|
|
15
|
+
assert.equal(instance.cache.expired, undefined)
|
|
16
|
+
assert.ok(instance.cache.valid)
|
|
17
|
+
})
|
|
18
|
+
|
|
19
|
+
it('should keep entries that have not expired', () => {
|
|
20
|
+
const instance = Object.create(DataCache.prototype)
|
|
21
|
+
instance.lifespan = 10000
|
|
22
|
+
instance.cache = {
|
|
23
|
+
a: { data: [1], timestamp: Date.now() },
|
|
24
|
+
b: { data: [2], timestamp: Date.now() }
|
|
25
|
+
}
|
|
26
|
+
instance.prune()
|
|
27
|
+
assert.ok(instance.cache.a)
|
|
28
|
+
assert.ok(instance.cache.b)
|
|
29
|
+
})
|
|
30
|
+
|
|
31
|
+
it('should handle an empty cache', () => {
|
|
32
|
+
const instance = Object.create(DataCache.prototype)
|
|
33
|
+
instance.lifespan = 100
|
|
34
|
+
instance.cache = {}
|
|
35
|
+
instance.prune()
|
|
36
|
+
assert.deepEqual(instance.cache, {})
|
|
37
|
+
})
|
|
38
|
+
})
|
|
39
|
+
})
|