|
|
@@ -40,8 +40,9 @@ export default (options={}) => { |
|
|
|
upstream_limit: null |
|
|
|
} |
|
|
|
|
|
|
|
// some random places to make things work |
|
|
|
// some random variables to make things work |
|
|
|
let _xhr = null |
|
|
|
let _promise = null |
|
|
|
|
|
|
|
// construct the model |
|
|
|
return { |
|
|
@@ -58,14 +59,20 @@ export default (options={}) => { |
|
|
|
if (limit == Infinity) |
|
|
|
limit = _cache.upstream_limit || _cache.count || Infinity |
|
|
|
|
|
|
|
// be lazy: if the data is presented, return the value immediately |
|
|
|
// be lazy 1: if the data is presented, return the value immediately |
|
|
|
// |
|
|
|
// note that Array.every(list) == true if list is empty |
|
|
|
if (_cache.data.slice(offset, offset+limit).length > 0 && _cache.data.slice(offset, offset+limit).every(data => data != undefined)) |
|
|
|
return Promise.resolve(_cache.data.slice(offset, offset+limit)) |
|
|
|
let _portion = _cache.data.slice(offset, offset+limit) |
|
|
|
if (_portion.length > 0 && _portion.every(data => data != undefined)) |
|
|
|
return Promise.resolve(_portion) |
|
|
|
|
|
|
|
// be lazy 2: if there is a promise, return it if ambient matches or |
|
|
|
// cancel it |
|
|
|
if (_promise != null) |
|
|
|
return _promise |
|
|
|
|
|
|
|
// now the hard work |
|
|
|
return _configs.api.request({ |
|
|
|
_promise = _configs.api.request({ |
|
|
|
method: 'GET', |
|
|
|
url: _configs.endpoint, |
|
|
|
headers: _cache.count == null ? { |
|
|
@@ -76,34 +83,39 @@ export default (options={}) => { |
|
|
|
// transform model state to postgest queries |
|
|
|
//...ambient_queries, |
|
|
|
offset == 0 ? undefined : {label: 'offset', value: offset}, |
|
|
|
limit == Infinity ? undefined : {label: 'limit', value: limit} |
|
|
|
] |
|
|
|
}).then(response => { |
|
|
|
// gather begin/end/count |
|
|
|
let [_range, _count] = _xhr.getResponseHeader('content-range').split('/') |
|
|
|
let [_begin, _end] = _range.split('-').map(v => ~~v) |
|
|
|
|
|
|
|
// update count if presented |
|
|
|
if (_count != '*') _cache.count = _count |
|
|
|
|
|
|
|
// see if an upstream limit is exposed |
|
|
|
if (_end - _begin + 1 < limit) _cache.upstream_limit = _end - _begin + 1 |
|
|
|
|
|
|
|
// fill the data cache |
|
|
|
response.forEach((data, i) => { |
|
|
|
// _value_filters.forEach(([label, config]) => data[config.alias || label] = config.value_filter(data[config.alias || label])) |
|
|
|
_cache.data[_begin + i] = data |
|
|
|
limit == Infinity ? undefined : {label: 'limit', value: limit} |
|
|
|
] |
|
|
|
}).then(response => { |
|
|
|
// gather begin/end/count |
|
|
|
let [_range, _count] = _xhr.getResponseHeader('content-range').split('/') |
|
|
|
let [_begin, _end] = _range.split('-').map(v => ~~v) |
|
|
|
|
|
|
|
// update count if presented |
|
|
|
if (_count != '*') _cache.count = _count |
|
|
|
|
|
|
|
// see if an upstream limit is exposed |
|
|
|
if (_end - _begin + 1 < limit) _cache.upstream_limit = _end - _begin + 1 |
|
|
|
|
|
|
|
// fill the data cache |
|
|
|
response.forEach((data, i) => { |
|
|
|
// _value_filters.forEach(([label, config]) => data[config.alias || label] = config.value_filter(data[config.alias || label])) |
|
|
|
_cache.data[_begin + i] = data |
|
|
|
}) |
|
|
|
|
|
|
|
// assert offset/limit and returned range |
|
|
|
if (offset != _begin || _end - _begin + 1 > limit) |
|
|
|
throw 'The request and response data range mismatches!' |
|
|
|
if (_end - _begin + 1 < limit) |
|
|
|
console.warn('The response range is narrower than requested, probably due to an upstream hard limit.') |
|
|
|
|
|
|
|
// clean model state |
|
|
|
_promise = null |
|
|
|
|
|
|
|
// return data |
|
|
|
return _cache.data.slice(_begin, _end + 1) |
|
|
|
}) |
|
|
|
|
|
|
|
// assert offset/limit and returned range |
|
|
|
if (offset != _begin || _end - _begin + 1 > limit) |
|
|
|
throw 'The request and response data range mismatches!' |
|
|
|
if (_end - _begin + 1 < limit) |
|
|
|
console.warn('The response range is narrower than requested, probably due to an upstream hard limit.') |
|
|
|
|
|
|
|
// return |
|
|
|
return _cache.data.slice(_begin, _end + 1) |
|
|
|
}) |
|
|
|
return _promise |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|