2016-08-08 07:54:06 +00:00
|
|
|
import DataLoader from 'dataloader'
|
2016-11-26 01:38:32 +00:00
|
|
|
import LRUCache from 'lru-cache'
|
|
|
|
|
import { toPlural } from './types/helpers'
|
2017-10-19 08:00:21 +00:00
|
|
|
import { ONE_DAY } from './util'
|
2016-08-08 07:54:06 +00:00
|
|
|
|
2016-11-26 01:38:32 +00:00
|
|
|
const debug = require('debug')('graphbrainz:loaders')
|
2016-08-08 07:54:06 +00:00
|
|
|
|
2017-10-19 08:00:21 +00:00
|
|
|
export default function createLoaders (client) {
|
2016-11-26 10:37:23 +00:00
|
|
|
// All loaders share a single LRU cache that will remember 8192 responses,
|
|
|
|
|
// each cached for 1 day.
|
2016-11-26 01:38:32 +00:00
|
|
|
const cache = LRUCache({
|
2016-11-28 13:49:04 +00:00
|
|
|
max: parseInt(process.env.GRAPHBRAINZ_CACHE_SIZE || 8192, 10),
|
|
|
|
|
maxAge: parseInt(process.env.GRAPHBRAINZ_CACHE_TTL || ONE_DAY, 10),
|
2016-11-26 01:38:32 +00:00
|
|
|
dispose (key) {
|
2016-12-03 07:59:19 +00:00
|
|
|
debug(`Removed from cache. key=${key}`)
|
2016-11-26 01:38:32 +00:00
|
|
|
}
|
|
|
|
|
})
|
2016-11-26 10:37:23 +00:00
|
|
|
// Make the cache Map-like.
|
2016-11-26 01:38:32 +00:00
|
|
|
cache.delete = cache.del
|
|
|
|
|
cache.clear = cache.reset
|
2016-08-20 05:59:32 +00:00
|
|
|
|
2016-11-26 01:38:32 +00:00
|
|
|
const lookup = new DataLoader(keys => {
|
|
|
|
|
return Promise.all(keys.map(key => {
|
2016-12-08 22:33:18 +00:00
|
|
|
const [ entityType, id, params = {} ] = key
|
2016-11-26 01:38:32 +00:00
|
|
|
return client.lookup(entityType, id, params).then(entity => {
|
|
|
|
|
if (entity) {
|
2016-11-26 10:37:23 +00:00
|
|
|
// Store the entity type so we can determine what type of object this
|
|
|
|
|
// is elsewhere in the code.
|
2016-11-28 13:49:04 +00:00
|
|
|
entity._type = entityType
|
2016-11-26 01:38:32 +00:00
|
|
|
}
|
|
|
|
|
return entity
|
2016-08-20 05:59:32 +00:00
|
|
|
})
|
2016-11-26 01:38:32 +00:00
|
|
|
}))
|
|
|
|
|
}, {
|
|
|
|
|
cacheKeyFn: (key) => client.getLookupURL(...key),
|
|
|
|
|
cacheMap: cache
|
|
|
|
|
})
|
2016-08-20 05:59:32 +00:00
|
|
|
|
2016-11-26 01:38:32 +00:00
|
|
|
const browse = new DataLoader(keys => {
|
|
|
|
|
return Promise.all(keys.map(key => {
|
2016-12-08 22:33:18 +00:00
|
|
|
const [ entityType, params = {} ] = key
|
2016-11-26 01:38:32 +00:00
|
|
|
return client.browse(entityType, params).then(list => {
|
|
|
|
|
list[toPlural(entityType)].forEach(entity => {
|
2016-11-26 10:37:23 +00:00
|
|
|
// Store the entity type so we can determine what type of object this
|
|
|
|
|
// is elsewhere in the code.
|
2016-11-28 13:49:04 +00:00
|
|
|
entity._type = entityType
|
2016-11-26 01:38:32 +00:00
|
|
|
})
|
|
|
|
|
return list
|
2016-08-20 05:59:32 +00:00
|
|
|
})
|
2016-11-26 01:38:32 +00:00
|
|
|
}))
|
|
|
|
|
}, {
|
|
|
|
|
cacheKeyFn: (key) => client.getBrowseURL(...key),
|
|
|
|
|
cacheMap: cache
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
const search = new DataLoader(keys => {
|
|
|
|
|
return Promise.all(keys.map(key => {
|
2016-12-08 22:33:18 +00:00
|
|
|
const [ entityType, query, params = {} ] = key
|
2016-11-26 01:38:32 +00:00
|
|
|
return client.search(entityType, query, params).then(list => {
|
|
|
|
|
list[toPlural(entityType)].forEach(entity => {
|
2016-11-26 10:37:23 +00:00
|
|
|
// Store the entity type so we can determine what type of object this
|
|
|
|
|
// is elsewhere in the code.
|
2016-11-28 13:49:04 +00:00
|
|
|
entity._type = entityType
|
2016-11-26 01:38:32 +00:00
|
|
|
})
|
|
|
|
|
return list
|
|
|
|
|
})
|
|
|
|
|
}))
|
|
|
|
|
}, {
|
2016-12-20 05:21:07 +00:00
|
|
|
cacheKeyFn: key => client.getSearchURL(...key),
|
2016-11-26 01:38:32 +00:00
|
|
|
cacheMap: cache
|
|
|
|
|
})
|
|
|
|
|
|
2017-10-19 08:00:21 +00:00
|
|
|
return { lookup, browse, search }
|
2016-11-26 01:38:32 +00:00
|
|
|
}
|