|
|
@@ -36,7 +36,8 @@ export default (options={}) => { |
|
|
|
// private model cache & meta-info |
|
|
|
let _cache = { |
|
|
|
data: null, |
|
|
|
count: null |
|
|
|
count: null, |
|
|
|
upstream_limit: null |
|
|
|
} |
|
|
|
|
|
|
|
// some random places to make things work |
|
|
@@ -49,10 +50,20 @@ export default (options={}) => { |
|
|
|
cache() { return _cache }, |
|
|
|
|
|
|
|
// main methods |
|
|
|
select(from=0, to) { |
|
|
|
select(offset=0, limit=Infinity) { |
|
|
|
// initialize data (singular or plural) |
|
|
|
_cache.data = _cache.data || [] |
|
|
|
|
|
|
|
// normalize limit |
|
|
|
if (limit == Infinity) |
|
|
|
limit = _cache.upstream_limit || _cache.count || Infinity |
|
|
|
|
|
|
|
// be lazy: 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)) |
|
|
|
|
|
|
|
// now the hard work |
|
|
|
return _configs.api.request({ |
|
|
|
method: 'GET', |
|
|
@@ -65,20 +76,29 @@ export default (options={}) => { |
|
|
|
// transform model state to postgest queries |
|
|
|
//queries: [...ambient_queries, ...paging_queries] |
|
|
|
}).then(response => { |
|
|
|
// gather begin/end/count |
|
|
|
let [_range, _count] = _xhr.getResponseHeader('content-range').split('/') |
|
|
|
let [_begin, _end] = _range.split('-').map(v => ~~v) |
|
|
|
// 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 |
|
|
|
|
|
|
|
// 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 |
|
|
|
}) |
|
|
|
// 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 |
|
|
|
}) |
|
|
|
|
|
|
|
// for promise |
|
|
|
// 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) |
|
|
|
}) |
|
|
|
} |
|
|
@@ -100,10 +120,7 @@ export const default1 = (args) => { |
|
|
|
|
|
|
|
return { |
|
|
|
// model & model state |
|
|
|
list: [], |
|
|
|
count: null, |
|
|
|
fully_loaded: false, |
|
|
|
xhr: null, |
|
|
|
|
|
|
|
// ambient |
|
|
|
ambient: null, |
|
|
@@ -134,14 +151,8 @@ export const default1 = (args) => { |
|
|
|
|
|
|
|
// load data |
|
|
|
load(args) { |
|
|
|
args = args || {begin: 0} |
|
|
|
|
|
|
|
let ambient_queries = this.reset() |
|
|
|
|
|
|
|
// be lazy: if the data is presented, return the value immediately |
|
|
|
if (this.list.slice(args.begin, args.end).length == args.limit && this.list.slice(args.begin, args.end).every(data => data != undefined)) |
|
|
|
return Promise.resolve(this.list.slice(args.begin, args.end)) |
|
|
|
|
|
|
|
// create limit&offset for postgrest |
|
|
|
let paging_queries = [] |
|
|
|
if (args.begin != undefined) { |
|
|
|