graphbrainz/src/loaders.js

94 lines
3 KiB
JavaScript
Raw Normal View History

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'
2016-08-08 07:54:06 +00:00
2016-11-26 01:38:32 +00:00
const debug = require('debug')('graphbrainz:loaders')
const ONE_DAY = 24 * 60 * 60 * 1000
2016-08-08 07:54:06 +00:00
2016-11-26 01:38:32 +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({
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 => {
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.
entity._type = entityType
entity._inc = params.inc
if (entityType === 'discid' && entity.releases) {
entity.releases.forEach(release => {
release._type = 'release'
release._inc = params.inc
})
} else if (entityType === 'isrc' && entity.recordings) {
entity.recordings.forEach(recording => {
recording._type = 'recording'
recording._inc = params.inc
})
} else if (entityType === 'iswc' && entity.works) {
entity.works.forEach(work => {
work._type = 'work'
work._inc = params.inc
})
}
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 => {
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.
entity._type = entityType
entity._inc = params.inc
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 => {
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.
entity._type = entityType
entity._inc = params.inc
2016-11-26 01:38:32 +00:00
})
return list
})
}))
}, {
cacheKeyFn: (key) => client.getSearchURL(...key),
cacheMap: cache
})
return { lookup, browse, search }
}