wappsto-redux
Advanced tools
Comparing version 3.3.0 to 3.4.0
@@ -6,3 +6,3 @@ import querystring from 'query-string'; | ||
import { addEntities, removeEntities } from './entities'; | ||
import { addSession, invalidSession, removeSession } from './session'; | ||
import { invalidSession } from './session'; | ||
@@ -20,2 +20,5 @@ export const REQUEST_PENDING = 'REQUEST_PENDING'; | ||
const pendingRequestsCache = {}; | ||
let nextPendingId = 0; | ||
function getQueryObj(query) { | ||
@@ -76,3 +79,3 @@ var urlParams = {}; | ||
function getOptions(method, url, data, options, sessionJSON){ | ||
let requestOptions = {method, headers: options.headers || {}}; | ||
let requestOptions = {method, headers: options.headers || {}, rawOptions: {...options}}; | ||
if(sessionJSON && sessionJSON.meta && !requestOptions.headers['x-session']){ | ||
@@ -141,3 +144,3 @@ requestOptions.headers['x-session'] = sessionJSON.meta.id; | ||
case 'DELETE': | ||
const deleted = [...(json.deleted || []), ...(json.shared_deleted || [])]; | ||
const deleted = [...(json.deleted || []), ...(json.shared_deleted || []), ...(json.owned_deleted || [])]; | ||
if(deleted.length > 0){ | ||
@@ -174,26 +177,26 @@ dispatch(removeEntities(service, deleted, { ...options, parent, reset: false })); | ||
status: response.status, | ||
json | ||
json, | ||
options | ||
}; | ||
}catch(e){ | ||
const text = await response.clone().text(); | ||
return { ok: response.ok, status: response.status, text }; | ||
return { ok: response.ok, status: response.status, text, options }; | ||
} | ||
} catch(e){ | ||
return { ok: false, status: e.status }; | ||
return { ok: false, status: e.status, options }; | ||
} | ||
}; | ||
export function findRequest(state, url, method, data, options = {}) { | ||
for (let id in state.request) { | ||
const stateRequest = state.request[id]; | ||
const rUrl = querystring.parseUrl(stateRequest.url); | ||
function findRequest(url, method, data, options = {}) { | ||
for (let id in pendingRequestsCache) { | ||
const pendingRequest = pendingRequestsCache[id]; | ||
const rUrl = querystring.parseUrl(pendingRequest.url); | ||
const parsedUrl = querystring.parseUrl(url); | ||
const rQuery = { ...stateRequest.query, ...rUrl.query, ...(stateRequest.options.query || {}) }; | ||
const rQuery = { ...pendingRequest.query, ...rUrl.query, ...(pendingRequest.options.query || {}) }; | ||
const query = options.query ? { ...options.query, ...parsedUrl.query } : parsedUrl.query; | ||
if (stateRequest.status === 'pending' | ||
&& stateRequest.method === method | ||
if (pendingRequest.method === method | ||
&& equal(rUrl.url, parsedUrl.url) | ||
&& equal(rQuery, query) | ||
&& equal(stateRequest.data, data)) { | ||
return stateRequest.id; | ||
&& equal(pendingRequest.body, data)) { | ||
return pendingRequest.promise; | ||
} | ||
@@ -203,14 +206,23 @@ } | ||
let nextId = 1; | ||
export function startRequest(dispatch, url, method, data, options, session){ | ||
let promise; | ||
export function startRequest(dispatch, options, session){ | ||
let promise, pendingId; | ||
const { url, id } = options; | ||
const data = options.data || options.body; | ||
const method = options.method.toUpperCase(); | ||
const result = splitUrlAndOptions(url, options); | ||
const requestOptions = getOptions(method, url, data, options, session); | ||
const id = nextId; | ||
nextId += 1; | ||
if(id){ | ||
pendingId = id; | ||
} else { | ||
pendingId = nextPendingId; | ||
nextPendingId++; | ||
} | ||
const checkResponse = (response) => { | ||
delete pendingRequestsCache[pendingId]; | ||
if(response.ok){ | ||
dispatchMethodAction(dispatch, requestOptions.method, result.url, response.json, result.options); | ||
dispatch(requestSuccess(id, requestOptions.method, result.url, data, response.status, response.json, response.text, result.options, promise)); | ||
if(id){ | ||
dispatch(requestSuccess(id, requestOptions.method, result.url, data, response.status, response.json, response.text, result.options, promise)); | ||
} | ||
} else { | ||
@@ -220,3 +232,5 @@ if(response.json && response.json.code === 117000000){ | ||
} | ||
dispatch(requestError(id, requestOptions.method, result.url, data, response.status, response.json, response.text, result.options, promise)); | ||
if(id){ | ||
dispatch(requestError(id, requestOptions.method, result.url, data, response.status, response.json, response.text, result.options, promise)); | ||
} | ||
} | ||
@@ -226,5 +240,14 @@ return response; | ||
promise = _request(requestOptions).then(checkResponse).catch(checkResponse); | ||
dispatch(requestPending(id, requestOptions.method, result.url, data, result.options, promise)); | ||
return {id, promise}; | ||
promise = findRequest(url, method, data, options); | ||
if (!promise) { | ||
promise = _request(requestOptions); | ||
} | ||
promise.then(checkResponse).catch(checkResponse); | ||
const requestPendingObj = requestPending(pendingId, requestOptions.method, result.url, data, result.options, promise); | ||
pendingRequestsCache[pendingId] = requestPendingObj; | ||
if(id){ | ||
dispatch(requestPendingObj); | ||
} | ||
return promise; | ||
} | ||
@@ -234,5 +257,2 @@ | ||
return (dispatch, getState) => { | ||
const data = options.data || options.body; | ||
const url = options.url; | ||
const method = options.method.toUpperCase(); | ||
if(!_request){ | ||
@@ -242,10 +262,5 @@ console.log('request function is not set'); | ||
} | ||
const result = splitUrlAndOptions(url, options); | ||
const state = getState(); | ||
const existingRequest = findRequest(state, url, method, data, options); | ||
if (existingRequest) { | ||
return existingRequest; | ||
} | ||
const { id } = startRequest(dispatch, url, method, data, options, state.session); | ||
return id; | ||
const promise = startRequest(dispatch, options, state.session); | ||
return promise; | ||
}; | ||
@@ -252,0 +267,0 @@ } |
{ | ||
"name": "wappsto-redux", | ||
"version": "3.3.0", | ||
"version": "3.4.0", | ||
"description": "", | ||
@@ -5,0 +5,0 @@ "main": "index.js", |
@@ -57,22 +57,26 @@ import { normalize } from 'normalizr'; | ||
let childDef = def.dependencies.find(d => d.key === child); | ||
if(childDef){ | ||
if(childDef.type === "many"){ | ||
newData = addEntities(state, child, data); | ||
result = newData.result; | ||
if(element && !equal(element[child], data.map(i => i.meta.id))){ | ||
const newElement = Object.assign({}, element); | ||
newElement[child] = reset ? result : mergeUnique(element[child], result); | ||
state[def.name][id] = newElement; | ||
} | ||
} else { | ||
newData = addEntity(state, child, data); | ||
result = newData.result; | ||
if(element && !equal(element[child], data.meta.id)){ | ||
const newElement = Object.assign({}, element); | ||
newElement[child] = result; | ||
state[def.name][id] = newElement; | ||
} | ||
if(!childDef){ | ||
childDef = { | ||
"key": child, | ||
"type": data.constructor === Array && "many" | ||
}; | ||
} | ||
if(childDef.type === "many"){ | ||
newData = addEntities(state, child, data); | ||
result = newData.result; | ||
if(element && !equal(element[child], data.map(i => i.meta.id))){ | ||
const newElement = Object.assign({}, element); | ||
newElement[child] = reset ? result : mergeUnique(element[child], result); | ||
state[def.name][id] = newElement; | ||
} | ||
state = newData.state; | ||
} else { | ||
newData = addEntity(state, child, data); | ||
result = newData.result; | ||
if(element && !equal(element[child], data.meta.id)){ | ||
const newElement = Object.assign({}, element); | ||
newElement[child] = result; | ||
state[def.name][id] = newElement; | ||
} | ||
} | ||
state = newData.state; | ||
return { state, result }; | ||
@@ -86,20 +90,18 @@ } | ||
let childDef = def.dependencies.find(d => d.key === child); | ||
if(childDef){ | ||
newData = removeEntities(state, child, ids || (element && element[child]) || []); | ||
state = newData.state; | ||
if(childDef.type === "many"){ | ||
if(ids && element){ | ||
result = element[child].filter(c => !ids.includes(c)); | ||
} else { | ||
result = []; | ||
} | ||
newData = removeEntities(state, child, ids || (element && element[child]) || []); | ||
state = newData.state; | ||
if((childDef && childDef.type === "many") || element && element[child] && element[child].constructor === Array){ | ||
if(ids && element){ | ||
result = element[child].filter(c => !ids.includes(c)); | ||
} else { | ||
result = undefined; | ||
result = []; | ||
} | ||
if(element){ | ||
const newElement = Object.assign({}, element); | ||
newElement[child] = result; | ||
state[def.name][id] = newElement; | ||
} | ||
} else { | ||
result = undefined; | ||
} | ||
if(element){ | ||
const newElement = Object.assign({}, element); | ||
newElement[child] = result; | ||
state[def.name][id] = newElement; | ||
} | ||
return { state, result }; | ||
@@ -106,0 +108,0 @@ } |
@@ -66,3 +66,3 @@ import { createSelector } from "reselect"; | ||
(_, _1, options) => options, | ||
(entities, parent, type, options={}) => { | ||
(entities, parent, type, options) => { | ||
if(entities && options){ | ||
@@ -142,34 +142,54 @@ if(options.constructor === String){ | ||
if(entities){ | ||
let filters; | ||
if(options instanceof Array){ | ||
filters = options.map(id => ({meta: {id}})); | ||
let filters, ids, lookIn; | ||
if(options.constructor === String){ | ||
ids = [options]; | ||
} else if(options.constructor === Array){ | ||
ids = options; | ||
} else { | ||
filters = options.filter; | ||
if(filters){ | ||
if(!(filters instanceof Array)){ | ||
filters = [filters]; | ||
ids = options.ids; | ||
if(options.filter){ | ||
if(options.filter.constructor === Object){ | ||
filters = [options.filter]; | ||
} else if(options.filter.constructor === Array){ | ||
if(options.filter.length && options.filter[0].constructor === String){ | ||
ids = [...(options.ids || []), ...options.filter]; | ||
} else { | ||
filters = options.filter; | ||
} | ||
} else { | ||
ids = [...(options.ids || []), options.filter];; | ||
} | ||
if(!(filters[0] instanceof Object)){ | ||
filters = filters.map(id => ({meta: {id}})); | ||
} | ||
} | ||
} | ||
if(ids){ | ||
lookIn = {}; | ||
ids.forEach(id => { | ||
const found = entities[id]; | ||
if(found){ | ||
lookIn[id] = found; | ||
} | ||
}); | ||
} else { | ||
lookIn = entities; | ||
} | ||
if(options.parent){ | ||
result = []; | ||
if(parent && parent.hasOwnProperty(type)){ | ||
parent[type].forEach((id) => { | ||
let found = entities[id]; | ||
if(found){ | ||
if(filters){ | ||
for(let i = 0; i < filters.length; i++){ | ||
if(matchObject(found, filters[i])){ | ||
result.push(found); | ||
break; | ||
} | ||
if(filters){ | ||
filters.forEach(filter => { | ||
parent[type].forEach((id) => { | ||
const found = lookIn[id]; | ||
if(found && matchObject(found, filter) && !result.includes(found)){ | ||
result.push(found); | ||
} | ||
} else { | ||
}); | ||
}); | ||
} else { | ||
parent[type].forEach((id) => { | ||
const found = lookIn[id]; | ||
if(found){ | ||
result.push(found); | ||
} | ||
} | ||
}); | ||
}); | ||
} | ||
} | ||
@@ -179,13 +199,12 @@ } else { | ||
result = []; | ||
for(let key in entities){ | ||
const val = entities[key]; | ||
for(let i = 0; i < filters.length; i++){ | ||
if(matchObject(val, filters[i])){ | ||
filters.forEach(filter => { | ||
for(let key in lookIn){ | ||
const val = lookIn[key]; | ||
if(matchObject(val, filter) && !result.includes(val)){ | ||
result.push(val); | ||
break; | ||
} | ||
} | ||
} | ||
}); | ||
} else { | ||
result = Object.values(entities); | ||
result = Object.values(lookIn); | ||
} | ||
@@ -192,0 +211,0 @@ } |
@@ -30,2 +30,13 @@ let schemaTree = { | ||
}] | ||
}, | ||
"permission": { | ||
"name": "permission", | ||
"dependencies": [] | ||
}, | ||
"acl": { | ||
"name": "acl", | ||
"dependencies": [{ | ||
"key": "permission", | ||
"type": "many" | ||
}] | ||
} | ||
@@ -32,0 +43,0 @@ } |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
51905
1342