@urql/exchange-graphcache
Advanced tools
Comparing version 0.1.0-alpha.3 to 0.1.0-alpha.4
@@ -254,5 +254,8 @@ import stringify from 'fast-json-stable-stringify'; | ||
// This is a fragment (either inline or spread) | ||
var fragmentSelect = isInlineFragment(node) ? getSelectionSet(node) : fragments[getName(node)]; // Recursively process the fragments' selection sets | ||
var fragmentSelect = isInlineFragment(node) ? getSelectionSet(node) : fragments[getName(node)]; | ||
forEachFieldNode(ctx, fragmentSelect, cb); | ||
if (fragmentSelect !== undefined) { | ||
// Recursively process the fragments' selection sets | ||
forEachFieldNode(ctx, fragmentSelect, cb); | ||
} | ||
} else { | ||
@@ -263,16 +266,3 @@ cb(node); | ||
}; | ||
var merge$1 = function (dest, src) { | ||
if (src !== null && typeof src === 'object') { | ||
for (var key in src) { | ||
var srcVal = src[key]; | ||
if (!(key in dest)) { | ||
dest[key] = srcVal; | ||
} else { | ||
merge$1(dest[key], srcVal); | ||
} | ||
} | ||
} | ||
}; | ||
/** Reads a request entirely from the store */ | ||
@@ -291,3 +281,3 @@ | ||
var select = getSelectionSet(ctx.operation); | ||
var data = readEntity(ctx, 'query', select); | ||
var data = readEntity(ctx, 'query', select, Object.create(null)); | ||
return { | ||
@@ -300,3 +290,3 @@ data: data, | ||
var readEntity = function (ctx, key, select) { | ||
var readEntity = function (ctx, key, select, data) { | ||
var store = ctx.store; | ||
@@ -313,64 +303,57 @@ var entity = find(store, key); | ||
var data = Object.create(null); | ||
readSelection(ctx, entity, key, data, select); | ||
return data; | ||
return readSelection(ctx, entity, key, select, data); | ||
}; | ||
var readSelection = function (ctx, entity, key, data, select) { | ||
var readSelection = function (ctx, entity, key, select, data) { | ||
var store = ctx.store; | ||
var vars = ctx.vars; | ||
var fragments = ctx.fragments; | ||
select.forEach(function (node) { | ||
if (!shouldInclude(node, vars)) { | ||
// Directives instruct this node to be skipped | ||
return; | ||
} else if (!isFieldNode(node)) { | ||
// This is a fragment (either inline or spread) | ||
var fragmentSelect = isInlineFragment(node) ? getSelectionSet(node) : fragments[getName(node)]; // Recursively process the fragments' selection sets | ||
forEachFieldNode(ctx, select, function (node) { | ||
var fieldName = getName(node); // The field's key can include arguments if it has any | ||
var fragmentData = Object.create(null); | ||
readSelection(ctx, entity, key, fragmentData, fragmentSelect); | ||
merge$1(data, fragmentData); | ||
} else { | ||
var fieldName = getName(node); // The field's key can include arguments if it has any | ||
var fieldKey = keyOfField(fieldName, getFieldArguments(node, vars)); | ||
var fieldValue = entity[fieldKey]; | ||
var fieldAlias = getFieldAlias(node); | ||
var childFieldKey = joinKeys(key, fieldKey); | ||
var fieldKey = keyOfField(fieldName, getFieldArguments(node, vars)); | ||
var fieldValue = entity[fieldKey]; | ||
var fieldAlias = getFieldAlias(node); | ||
var childFieldKey = joinKeys(key, fieldKey); | ||
if (key === 'query') { | ||
ctx.dependencies.push(childFieldKey); | ||
} | ||
if (key === 'query') { | ||
ctx.dependencies.push(childFieldKey); | ||
} | ||
if (node.selectionSet === undefined || fieldValue !== null) { | ||
if (node.selectionSet === undefined || fieldValue !== null) { | ||
if (!(fieldAlias in data)) { | ||
// Cache Incomplete: An undefined field value means it wasn't cached | ||
ctx.isComplete = fieldValue !== undefined; | ||
data[fieldAlias] = fieldValue === undefined ? null : fieldValue; | ||
} | ||
} else { | ||
// null values mean that a field might be linked to other entities | ||
var ref = node.selectionSet; | ||
var fieldSelect = ref.selections; | ||
var link = readLink(store, childFieldKey); // Cache Incomplete: A missing link for a field means it's not cached | ||
if (link === undefined) { | ||
ctx.isComplete = false; | ||
data[fieldAlias] = null; | ||
} else { | ||
// null values mean that a field might be linked to other entities | ||
var ref = node.selectionSet; | ||
var fieldSelect = ref.selections; | ||
var link = readLink(store, childFieldKey); // Cache Incomplete: A missing link for a field means it's not cached | ||
if (link === undefined) { | ||
ctx.isComplete = false; | ||
data[fieldAlias] = null; | ||
} else { | ||
data[fieldAlias] = readField(ctx, link, fieldSelect); | ||
} | ||
var prevData = data[fieldAlias]; | ||
data[fieldAlias] = readField(ctx, link, fieldSelect, prevData); | ||
} | ||
} | ||
}); | ||
return data; | ||
}; | ||
var readField = function (ctx, link, select) { | ||
var readField = function (ctx, link, select, prevData) { | ||
if (Array.isArray(link)) { | ||
// @ts-ignore: Link cannot be expressed as a recursive type | ||
return link.map(function (childLink) { return readField(ctx, childLink, select); }); | ||
return link.map(function (childLink, index) { | ||
var data = prevData !== undefined ? prevData[index] : undefined; | ||
return readField(ctx, childLink, select, data); | ||
}); | ||
} else if (link === null) { | ||
return null; | ||
} else { | ||
var data = prevData === undefined ? Object.create(null) : prevData; | ||
return readEntity(ctx, link, select, data); | ||
} | ||
return readEntity(ctx, link, select); | ||
}; | ||
@@ -529,3 +512,3 @@ | ||
for (var fieldKey in entity) { | ||
var value = entity[key]; | ||
var value = entity[fieldKey]; | ||
@@ -532,0 +515,0 @@ if (value === null) { |
@@ -1,1 +0,1 @@ | ||
import stringify from"fast-json-stable-stringify";import{formatDocument}from"urql";import{filter,map,merge,pipe,share,tap}from"wonka";var getName=function(node){return node.name.value};var getSelectionSet=function(node){return node.selectionSet.selections};var isOperationNode=function(node){return node.kind==="OperationDefinition"};var isFragmentNode=function(node){return node.kind==="FragmentDefinition"};var evaluateValueNode=function(node,vars){switch(node.kind){case"NullValue":return null;case"IntValue":return parseInt(node.value,10);case"FloatValue":return parseFloat(node.value);case"ListValue":return node.values.map(function(v){return evaluateValueNode(v,vars)});case"ObjectValue":return node.fields.reduce(function(obj,field){obj[getName(field)]=evaluateValueNode(field.value,vars);return obj},{});case"Variable":var varValue=vars[getName(node)];return varValue!==undefined?varValue:null;default:return node.value}};var isFieldNode=function(node){return node.kind==="Field"};var isInlineFragment=function(node){return node.kind==="InlineFragment"};var getMainOperation=function(doc){return doc.definitions.find(isOperationNode)};var getNormalizedVars=function(node,input){if(node.variableDefinitions===undefined){return{}}var args=input?input:{};return node.variableDefinitions.reduce(function(vars,def){var name=getName(def.variable);var value=args[name];if(value===undefined){if(def.defaultValue!==undefined){value=evaluateValueNode(def.defaultValue,args)}else{return vars}}vars[name]=value;return vars},{})};var getFragmentSelectionSets=function(doc){return doc.definitions.filter(isFragmentNode).reduce(function(map$$1,node){map$$1[getName(node)]=getSelectionSet(node);return map$$1},{})};var getFieldAlias=function(node){return node.alias!==undefined?node.alias.value:getName(node)};var getFieldArguments=function(node,vars){if(node.arguments===undefined||node.arguments.length===0){return null}return node.arguments.reduce(function(args,arg){args[getName(arg)]=evaluateValueNode(arg.value,vars);return args},{})};var shouldInclude=function(node,vars){if(node.directives===undefined){return true}return!node.directives.some(function(directive){var name=getName(directive);var isInclude=name==="include";if(!isInclude&&name!=="skip"){return false}var firstArg=directive.arguments!==undefined?directive.arguments[0]:null;if(firstArg===null){return false}else if(getName(firstArg)!=="if"){return false}var value=evaluateValueNode(firstArg.value,vars);if(typeof value!=="boolean"&&value!==null){return false}return isInclude?!value:!!value})};var isOperation=function(typeName){return typeName==="Query"||typeName==="Mutation"||typeName==="Subscription"};var keyOfEntity=function(entity){var typeName=entity.__typename;var id=entity.id===undefined?entity._id:entity.id;if(typeName===undefined||typeName===null){return null}else if(isOperation(typeName)){return typeName}else if(id===null||id===undefined){return null}return typeName+":"+id};var keyOfField=function(fieldName,args){return args!==null?fieldName+"("+stringify(args)+")":fieldName};var joinKeys=function(parentKey,key){return parentKey+"."+key};var assignObjectToMap=function(map$$1,obj){for(var key in obj){if(obj.hasOwnProperty(key)){map$$1.set(key,obj[key])}}};var objectOfMap=function(map$$1){var res={};map$$1.forEach(function(value,key){res[key]=value});return res};var create=function(initial){var records=new Map;var links=new Map;if(initial!==undefined){assignObjectToMap(records,initial.records);assignObjectToMap(links,initial.links)}return{records:records,links:links}};var serialize=function(store){var records=objectOfMap(store.records);var links=objectOfMap(store.links);return{records:records,links:links}};var find=function(store,key){var entity=store.records.get(key);return entity!==undefined?entity:null};var findOrCreate=function(store,key){var entity=find(store,key);if(entity!==null){return entity}var record=Object.create(null);store.records.set(key,record);return record};var remove=function(store,key){store.records.delete(key)};var setLink=function(store,key,link){store.links.set(key,link)};var removeLink=function(store,key){store.links.delete(key)};var readLink=function(store,key){return store.links.get(key)};var makeContext=function(store,request){var query=request.query;var variables=request.variables;var operation=getMainOperation(query);if(operation===undefined){return}var dependencies=[];var fragments=getFragmentSelectionSets(query);var vars=getNormalizedVars(operation,variables);var isComplete=true;return{dependencies:dependencies,isComplete:isComplete,operation:operation,fragments:fragments,vars:vars,store:store}};var forEachFieldNode=function(ctx,select,cb){var vars=ctx.vars;var fragments=ctx.fragments;select.forEach(function(node){if(!shouldInclude(node,vars)){return}else if(!isFieldNode(node)){var fragmentSelect=isInlineFragment(node)?getSelectionSet(node):fragments[getName(node)];forEachFieldNode(ctx,fragmentSelect,cb)}else{cb(node)}})};var merge$1=function(dest,src){if(src!==null&&typeof src==="object"){for(var key in src){var srcVal=src[key];if(!(key in dest)){dest[key]=srcVal}else{merge$1(dest[key],srcVal)}}}};var query=function(store,request){var ctx=makeContext(store,request);if(ctx===undefined){return{isComplete:false,dependencies:[]}}var select=getSelectionSet(ctx.operation);var data=readEntity(ctx,"query",select);return{data:data,isComplete:ctx.isComplete,dependencies:ctx.dependencies}};var readEntity=function(ctx,key,select){var store=ctx.store;var entity=find(store,key);if(entity===null){ctx.isComplete=false;return null}else if(key!=="query"){ctx.dependencies.push(key)}var data=Object.create(null);readSelection(ctx,entity,key,data,select);return data};var readSelection=function(ctx,entity,key,data,select){var store=ctx.store;var vars=ctx.vars;var fragments=ctx.fragments;select.forEach(function(node){if(!shouldInclude(node,vars)){return}else if(!isFieldNode(node)){var fragmentSelect=isInlineFragment(node)?getSelectionSet(node):fragments[getName(node)];var fragmentData=Object.create(null);readSelection(ctx,entity,key,fragmentData,fragmentSelect);merge$1(data,fragmentData)}else{var fieldName=getName(node);var fieldKey=keyOfField(fieldName,getFieldArguments(node,vars));var fieldValue=entity[fieldKey];var fieldAlias=getFieldAlias(node);var childFieldKey=joinKeys(key,fieldKey);if(key==="query"){ctx.dependencies.push(childFieldKey)}if(node.selectionSet===undefined||fieldValue!==null){ctx.isComplete=fieldValue!==undefined;data[fieldAlias]=fieldValue===undefined?null:fieldValue}else{var ref=node.selectionSet;var fieldSelect=ref.selections;var link=readLink(store,childFieldKey);if(link===undefined){ctx.isComplete=false;data[fieldAlias]=null}else{data[fieldAlias]=readField(ctx,link,fieldSelect)}}}})};var readField=function(ctx,link,select){if(Array.isArray(link)){return link.map(function(childLink){return readField(ctx,childLink,select)})}else if(link===null){return null}return readEntity(ctx,link,select)};var write=function(store,request,data){var ctx=makeContext(store,request);if(ctx===undefined){return{isComplete:false,dependencies:[]}}var operation=ctx.operation;var select=getSelectionSet(operation);var operationName=operation.operation;if(operationName==="subscription"||operationName==="mutation"){writeRoot(ctx,data,select)}else{writeEntity(ctx,operationName,data,select)}return{isComplete:true,dependencies:ctx.dependencies}};var writeEntity=function(ctx,key,data,select){var store=ctx.store;var entity=findOrCreate(store,key);if(key!=="query"){ctx.dependencies.push(key)}writeSelection(ctx,entity,key,data,select)};var writeSelection=function(ctx,entity,key,data,select){forEachFieldNode(ctx,select,function(node){var store=ctx.store;var vars=ctx.vars;var fieldName=getName(node);var fieldValue=data[getFieldAlias(node)];var fieldKey=keyOfField(fieldName,getFieldArguments(node,vars));var childFieldKey=joinKeys(key,fieldKey);if(key==="query"){ctx.dependencies.push(childFieldKey)}if(node.selectionSet===undefined||fieldValue===null||typeof fieldValue!=="object"){entity[fieldKey]=fieldValue;removeLink(store,childFieldKey)}else{entity[fieldKey]=null;var ref=node.selectionSet;var fieldSelect=ref.selections;var link=writeField(ctx,childFieldKey,fieldValue,fieldSelect);setLink(store,childFieldKey,link)}})};var writeField=function(ctx,parentFieldKey,data,select){if(Array.isArray(data)){return data.map(function(item,index){var indexKey=joinKeys(parentFieldKey,""+index);var links=writeField(ctx,indexKey,item,select);return links})}else if(data===null){return null}var entityKey=keyOfEntity(data);var key=entityKey!==null?entityKey:parentFieldKey;writeEntity(ctx,key,data,select);return key};var writeRoot=function(ctx,data,select){forEachFieldNode(ctx,select,function(node){var fieldValue=data[getFieldAlias(node)];if(node.selectionSet!==undefined&&typeof fieldValue==="object"){var ref=node.selectionSet;var fieldSelect=ref.selections;writeRootField(ctx,fieldValue,fieldSelect)}})};var writeRootField=function(ctx,data,select){if(Array.isArray(data)){return data.map(function(item){return writeRootField(ctx,item,select)})}else if(data===null){return}var entityKey=keyOfEntity(data);if(entityKey!==null){writeEntity(ctx,entityKey,data,select)}};var gc=function(store){var visitedLinks=new Set;var visitedRecords=new Set;var ctx={store:store,visitedLinks:visitedLinks,visitedRecords:visitedRecords};walkEntity(ctx,"query");store.records.forEach(function(_entity,key){if(!visitedRecords.has(key)){remove(store,key)}});store.links.forEach(function(_link,key){if(!visitedLinks.has(key)){removeLink(store,key)}})};var walkEntity=function(ctx,key){var store=ctx.store;var visitedRecords=ctx.visitedRecords;var visitedLinks=ctx.visitedLinks;var entity=find(store,key);if(entity!==null&&!visitedRecords.has(key)){visitedRecords.add(key);for(var fieldKey in entity){var value=entity[key];if(value===null){var childFieldKey=joinKeys(key,fieldKey);var link=readLink(store,childFieldKey);if(link!==undefined&&!visitedLinks.has(childFieldKey)){visitedLinks.add(childFieldKey);walkLink(ctx,link)}}}}};var walkLink=function(ctx,link){if(Array.isArray(link)){link.forEach(function(childLink){return walkLink(ctx,childLink)})}else if(link!==null){walkEntity(ctx,link)}};var addTypeNames=function(op){return Object.assign({},op,{query:formatDocument(op.query)})};var getRequestPolicy=function(op){return op.context.requestPolicy};var isQueryOperation=function(op){var policy=getRequestPolicy(op);return op.operationName==="query"&&(policy==="cache-and-network"||policy==="cache-first"||policy==="cache-only")};var isCacheableQuery=function(op){var policy=getRequestPolicy(op);return isQueryOperation(op)&&(policy==="cache-and-network"||policy==="cache-first"||policy==="cache-only")};var toRequestPolicy=function(operation,requestPolicy){return Object.assign({},operation,{context:Object.assign({},operation.context,{requestPolicy:requestPolicy})})};var cacheExchange=function(opts){return function(ref){var forward=ref.forward;var client=ref.client;var store=create(opts.initial);var ops=new Map;var deps=Object.create(null);var processDependencies=function(triggerOp,dependencies){var pendingOperations=new Set;dependencies.forEach(function(dep){var keys=deps[dep];if(keys!==undefined){deps[dep]=[];keys.forEach(function(key){return pendingOperations.add(key)})}});pendingOperations.forEach(function(key){if(key!==triggerOp.key){var op=ops.get(key);ops.delete(key);client.reexecuteOperation(op)}})};var updateDependencies=function(op,dependencies){dependencies.forEach(function(dep){var keys=deps[dep]||(deps[dep]=[]);keys.push(op.key);if(!ops.has(op.key)){var isNetworkOnly=op.context.requestPolicy==="network-only";ops.set(op.key,isNetworkOnly?toRequestPolicy(op,"cache-and-network"):op)}})};var operationResultFromCache=function(operation){var policy=getRequestPolicy(operation);var res=query(store,operation);var isComplete=policy==="cache-only"||res.isComplete;if(isComplete){updateDependencies(operation,res.dependencies)}return{operation:operation,isComplete:isComplete,data:res.data}};var updateCacheWithResult=function(ref){var error=ref.error;var data=ref.data;var operation=ref.operation;if((error===undefined||error.networkError===undefined)&&data!==null&&data!==undefined){var ref$1=write(store,operation,data);var dependencies=ref$1.dependencies;processDependencies(operation,dependencies);if(isQueryOperation(operation)){updateDependencies(operation,dependencies)}}};return function(ops$){var sharedOps$=pipe(ops$,map(addTypeNames),share);var cache$=pipe(sharedOps$,filter(function(op){return isCacheableQuery(op)}),map(operationResultFromCache),share);var cacheOps$=pipe(cache$,filter(function(res){return!res.isComplete}),map(function(res){return res.operation}));var cacheResult$=pipe(cache$,filter(function(res){return res.isComplete}),tap(function(ref){var operation=ref.operation;var policy=getRequestPolicy(operation);if(policy==="cache-and-network"){var networkOnly=toRequestPolicy(operation,"network-only");client.reexecuteOperation(networkOnly)}}));var result$=pipe(forward(merge([pipe(sharedOps$,filter(function(op){return!isCacheableQuery(op)})),cacheOps$])),tap(updateCacheWithResult));return merge([result$,cacheResult$])}}};export{create,serialize,cacheExchange,query,write,gc}; | ||
import stringify from"fast-json-stable-stringify";import{formatDocument}from"urql";import{filter,map,merge,pipe,share,tap}from"wonka";var getName=function(node){return node.name.value};var getSelectionSet=function(node){return node.selectionSet.selections};var isOperationNode=function(node){return node.kind==="OperationDefinition"};var isFragmentNode=function(node){return node.kind==="FragmentDefinition"};var evaluateValueNode=function(node,vars){switch(node.kind){case"NullValue":return null;case"IntValue":return parseInt(node.value,10);case"FloatValue":return parseFloat(node.value);case"ListValue":return node.values.map(function(v){return evaluateValueNode(v,vars)});case"ObjectValue":return node.fields.reduce(function(obj,field){obj[getName(field)]=evaluateValueNode(field.value,vars);return obj},{});case"Variable":var varValue=vars[getName(node)];return varValue!==undefined?varValue:null;default:return node.value}};var isFieldNode=function(node){return node.kind==="Field"};var isInlineFragment=function(node){return node.kind==="InlineFragment"};var getMainOperation=function(doc){return doc.definitions.find(isOperationNode)};var getNormalizedVars=function(node,input){if(node.variableDefinitions===undefined){return{}}var args=input?input:{};return node.variableDefinitions.reduce(function(vars,def){var name=getName(def.variable);var value=args[name];if(value===undefined){if(def.defaultValue!==undefined){value=evaluateValueNode(def.defaultValue,args)}else{return vars}}vars[name]=value;return vars},{})};var getFragmentSelectionSets=function(doc){return doc.definitions.filter(isFragmentNode).reduce(function(map$$1,node){map$$1[getName(node)]=getSelectionSet(node);return map$$1},{})};var getFieldAlias=function(node){return node.alias!==undefined?node.alias.value:getName(node)};var getFieldArguments=function(node,vars){if(node.arguments===undefined||node.arguments.length===0){return null}return node.arguments.reduce(function(args,arg){args[getName(arg)]=evaluateValueNode(arg.value,vars);return args},{})};var shouldInclude=function(node,vars){if(node.directives===undefined){return true}return!node.directives.some(function(directive){var name=getName(directive);var isInclude=name==="include";if(!isInclude&&name!=="skip"){return false}var firstArg=directive.arguments!==undefined?directive.arguments[0]:null;if(firstArg===null){return false}else if(getName(firstArg)!=="if"){return false}var value=evaluateValueNode(firstArg.value,vars);if(typeof value!=="boolean"&&value!==null){return false}return isInclude?!value:!!value})};var isOperation=function(typeName){return typeName==="Query"||typeName==="Mutation"||typeName==="Subscription"};var keyOfEntity=function(entity){var typeName=entity.__typename;var id=entity.id===undefined?entity._id:entity.id;if(typeName===undefined||typeName===null){return null}else if(isOperation(typeName)){return typeName}else if(id===null||id===undefined){return null}return typeName+":"+id};var keyOfField=function(fieldName,args){return args!==null?fieldName+"("+stringify(args)+")":fieldName};var joinKeys=function(parentKey,key){return parentKey+"."+key};var assignObjectToMap=function(map$$1,obj){for(var key in obj){if(obj.hasOwnProperty(key)){map$$1.set(key,obj[key])}}};var objectOfMap=function(map$$1){var res={};map$$1.forEach(function(value,key){res[key]=value});return res};var create=function(initial){var records=new Map;var links=new Map;if(initial!==undefined){assignObjectToMap(records,initial.records);assignObjectToMap(links,initial.links)}return{records:records,links:links}};var serialize=function(store){var records=objectOfMap(store.records);var links=objectOfMap(store.links);return{records:records,links:links}};var find=function(store,key){var entity=store.records.get(key);return entity!==undefined?entity:null};var findOrCreate=function(store,key){var entity=find(store,key);if(entity!==null){return entity}var record=Object.create(null);store.records.set(key,record);return record};var remove=function(store,key){store.records.delete(key)};var setLink=function(store,key,link){store.links.set(key,link)};var removeLink=function(store,key){store.links.delete(key)};var readLink=function(store,key){return store.links.get(key)};var makeContext=function(store,request){var query=request.query;var variables=request.variables;var operation=getMainOperation(query);if(operation===undefined){return}var dependencies=[];var fragments=getFragmentSelectionSets(query);var vars=getNormalizedVars(operation,variables);var isComplete=true;return{dependencies:dependencies,isComplete:isComplete,operation:operation,fragments:fragments,vars:vars,store:store}};var forEachFieldNode=function(ctx,select,cb){var vars=ctx.vars;var fragments=ctx.fragments;select.forEach(function(node){if(!shouldInclude(node,vars)){return}else if(!isFieldNode(node)){var fragmentSelect=isInlineFragment(node)?getSelectionSet(node):fragments[getName(node)];if(fragmentSelect!==undefined){forEachFieldNode(ctx,fragmentSelect,cb)}}else{cb(node)}})};var query=function(store,request){var ctx=makeContext(store,request);if(ctx===undefined){return{isComplete:false,dependencies:[]}}var select=getSelectionSet(ctx.operation);var data=readEntity(ctx,"query",select,Object.create(null));return{data:data,isComplete:ctx.isComplete,dependencies:ctx.dependencies}};var readEntity=function(ctx,key,select,data){var store=ctx.store;var entity=find(store,key);if(entity===null){ctx.isComplete=false;return null}else if(key!=="query"){ctx.dependencies.push(key)}return readSelection(ctx,entity,key,select,data)};var readSelection=function(ctx,entity,key,select,data){var store=ctx.store;var vars=ctx.vars;forEachFieldNode(ctx,select,function(node){var fieldName=getName(node);var fieldKey=keyOfField(fieldName,getFieldArguments(node,vars));var fieldValue=entity[fieldKey];var fieldAlias=getFieldAlias(node);var childFieldKey=joinKeys(key,fieldKey);if(key==="query"){ctx.dependencies.push(childFieldKey)}if(node.selectionSet===undefined||fieldValue!==null){if(!(fieldAlias in data)){ctx.isComplete=fieldValue!==undefined;data[fieldAlias]=fieldValue===undefined?null:fieldValue}}else{var ref=node.selectionSet;var fieldSelect=ref.selections;var link=readLink(store,childFieldKey);if(link===undefined){ctx.isComplete=false;data[fieldAlias]=null}else{var prevData=data[fieldAlias];data[fieldAlias]=readField(ctx,link,fieldSelect,prevData)}}});return data};var readField=function(ctx,link,select,prevData){if(Array.isArray(link)){return link.map(function(childLink,index){var data=prevData!==undefined?prevData[index]:undefined;return readField(ctx,childLink,select,data)})}else if(link===null){return null}else{var data=prevData===undefined?Object.create(null):prevData;return readEntity(ctx,link,select,data)}};var write=function(store,request,data){var ctx=makeContext(store,request);if(ctx===undefined){return{isComplete:false,dependencies:[]}}var operation=ctx.operation;var select=getSelectionSet(operation);var operationName=operation.operation;if(operationName==="subscription"||operationName==="mutation"){writeRoot(ctx,data,select)}else{writeEntity(ctx,operationName,data,select)}return{isComplete:true,dependencies:ctx.dependencies}};var writeEntity=function(ctx,key,data,select){var store=ctx.store;var entity=findOrCreate(store,key);if(key!=="query"){ctx.dependencies.push(key)}writeSelection(ctx,entity,key,data,select)};var writeSelection=function(ctx,entity,key,data,select){forEachFieldNode(ctx,select,function(node){var store=ctx.store;var vars=ctx.vars;var fieldName=getName(node);var fieldValue=data[getFieldAlias(node)];var fieldKey=keyOfField(fieldName,getFieldArguments(node,vars));var childFieldKey=joinKeys(key,fieldKey);if(key==="query"){ctx.dependencies.push(childFieldKey)}if(node.selectionSet===undefined||fieldValue===null||typeof fieldValue!=="object"){entity[fieldKey]=fieldValue;removeLink(store,childFieldKey)}else{entity[fieldKey]=null;var ref=node.selectionSet;var fieldSelect=ref.selections;var link=writeField(ctx,childFieldKey,fieldValue,fieldSelect);setLink(store,childFieldKey,link)}})};var writeField=function(ctx,parentFieldKey,data,select){if(Array.isArray(data)){return data.map(function(item,index){var indexKey=joinKeys(parentFieldKey,""+index);var links=writeField(ctx,indexKey,item,select);return links})}else if(data===null){return null}var entityKey=keyOfEntity(data);var key=entityKey!==null?entityKey:parentFieldKey;writeEntity(ctx,key,data,select);return key};var writeRoot=function(ctx,data,select){forEachFieldNode(ctx,select,function(node){var fieldValue=data[getFieldAlias(node)];if(node.selectionSet!==undefined&&typeof fieldValue==="object"){var ref=node.selectionSet;var fieldSelect=ref.selections;writeRootField(ctx,fieldValue,fieldSelect)}})};var writeRootField=function(ctx,data,select){if(Array.isArray(data)){return data.map(function(item){return writeRootField(ctx,item,select)})}else if(data===null){return}var entityKey=keyOfEntity(data);if(entityKey!==null){writeEntity(ctx,entityKey,data,select)}};var gc=function(store){var visitedLinks=new Set;var visitedRecords=new Set;var ctx={store:store,visitedLinks:visitedLinks,visitedRecords:visitedRecords};walkEntity(ctx,"query");store.records.forEach(function(_entity,key){if(!visitedRecords.has(key)){remove(store,key)}});store.links.forEach(function(_link,key){if(!visitedLinks.has(key)){removeLink(store,key)}})};var walkEntity=function(ctx,key){var store=ctx.store;var visitedRecords=ctx.visitedRecords;var visitedLinks=ctx.visitedLinks;var entity=find(store,key);if(entity!==null&&!visitedRecords.has(key)){visitedRecords.add(key);for(var fieldKey in entity){var value=entity[fieldKey];if(value===null){var childFieldKey=joinKeys(key,fieldKey);var link=readLink(store,childFieldKey);if(link!==undefined&&!visitedLinks.has(childFieldKey)){visitedLinks.add(childFieldKey);walkLink(ctx,link)}}}}};var walkLink=function(ctx,link){if(Array.isArray(link)){link.forEach(function(childLink){return walkLink(ctx,childLink)})}else if(link!==null){walkEntity(ctx,link)}};var addTypeNames=function(op){return Object.assign({},op,{query:formatDocument(op.query)})};var getRequestPolicy=function(op){return op.context.requestPolicy};var isQueryOperation=function(op){var policy=getRequestPolicy(op);return op.operationName==="query"&&(policy==="cache-and-network"||policy==="cache-first"||policy==="cache-only")};var isCacheableQuery=function(op){var policy=getRequestPolicy(op);return isQueryOperation(op)&&(policy==="cache-and-network"||policy==="cache-first"||policy==="cache-only")};var toRequestPolicy=function(operation,requestPolicy){return Object.assign({},operation,{context:Object.assign({},operation.context,{requestPolicy:requestPolicy})})};var cacheExchange=function(opts){return function(ref){var forward=ref.forward;var client=ref.client;var store=create(opts.initial);var ops=new Map;var deps=Object.create(null);var processDependencies=function(triggerOp,dependencies){var pendingOperations=new Set;dependencies.forEach(function(dep){var keys=deps[dep];if(keys!==undefined){deps[dep]=[];keys.forEach(function(key){return pendingOperations.add(key)})}});pendingOperations.forEach(function(key){if(key!==triggerOp.key){var op=ops.get(key);ops.delete(key);client.reexecuteOperation(op)}})};var updateDependencies=function(op,dependencies){dependencies.forEach(function(dep){var keys=deps[dep]||(deps[dep]=[]);keys.push(op.key);if(!ops.has(op.key)){var isNetworkOnly=op.context.requestPolicy==="network-only";ops.set(op.key,isNetworkOnly?toRequestPolicy(op,"cache-and-network"):op)}})};var operationResultFromCache=function(operation){var policy=getRequestPolicy(operation);var res=query(store,operation);var isComplete=policy==="cache-only"||res.isComplete;if(isComplete){updateDependencies(operation,res.dependencies)}return{operation:operation,isComplete:isComplete,data:res.data}};var updateCacheWithResult=function(ref){var error=ref.error;var data=ref.data;var operation=ref.operation;if((error===undefined||error.networkError===undefined)&&data!==null&&data!==undefined){var ref$1=write(store,operation,data);var dependencies=ref$1.dependencies;processDependencies(operation,dependencies);if(isQueryOperation(operation)){updateDependencies(operation,dependencies)}}};return function(ops$){var sharedOps$=pipe(ops$,map(addTypeNames),share);var cache$=pipe(sharedOps$,filter(function(op){return isCacheableQuery(op)}),map(operationResultFromCache),share);var cacheOps$=pipe(cache$,filter(function(res){return!res.isComplete}),map(function(res){return res.operation}));var cacheResult$=pipe(cache$,filter(function(res){return res.isComplete}),tap(function(ref){var operation=ref.operation;var policy=getRequestPolicy(operation);if(policy==="cache-and-network"){var networkOnly=toRequestPolicy(operation,"network-only");client.reexecuteOperation(networkOnly)}}));var result$=pipe(forward(merge([pipe(sharedOps$,filter(function(op){return!isCacheableQuery(op)})),cacheOps$])),tap(updateCacheWithResult));return merge([result$,cacheResult$])}}};export{create,serialize,cacheExchange,query,write,gc}; |
@@ -256,5 +256,8 @@ function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; } | ||
// This is a fragment (either inline or spread) | ||
var fragmentSelect = isInlineFragment(node) ? getSelectionSet(node) : fragments[getName(node)]; // Recursively process the fragments' selection sets | ||
var fragmentSelect = isInlineFragment(node) ? getSelectionSet(node) : fragments[getName(node)]; | ||
forEachFieldNode(ctx, fragmentSelect, cb); | ||
if (fragmentSelect !== undefined) { | ||
// Recursively process the fragments' selection sets | ||
forEachFieldNode(ctx, fragmentSelect, cb); | ||
} | ||
} else { | ||
@@ -265,16 +268,3 @@ cb(node); | ||
}; | ||
var merge = function (dest, src) { | ||
if (src !== null && typeof src === 'object') { | ||
for (var key in src) { | ||
var srcVal = src[key]; | ||
if (!(key in dest)) { | ||
dest[key] = srcVal; | ||
} else { | ||
merge(dest[key], srcVal); | ||
} | ||
} | ||
} | ||
}; | ||
/** Reads a request entirely from the store */ | ||
@@ -293,3 +283,3 @@ | ||
var select = getSelectionSet(ctx.operation); | ||
var data = readEntity(ctx, 'query', select); | ||
var data = readEntity(ctx, 'query', select, Object.create(null)); | ||
return { | ||
@@ -302,3 +292,3 @@ data: data, | ||
var readEntity = function (ctx, key, select) { | ||
var readEntity = function (ctx, key, select, data) { | ||
var store = ctx.store; | ||
@@ -315,64 +305,57 @@ var entity = find(store, key); | ||
var data = Object.create(null); | ||
readSelection(ctx, entity, key, data, select); | ||
return data; | ||
return readSelection(ctx, entity, key, select, data); | ||
}; | ||
var readSelection = function (ctx, entity, key, data, select) { | ||
var readSelection = function (ctx, entity, key, select, data) { | ||
var store = ctx.store; | ||
var vars = ctx.vars; | ||
var fragments = ctx.fragments; | ||
select.forEach(function (node) { | ||
if (!shouldInclude(node, vars)) { | ||
// Directives instruct this node to be skipped | ||
return; | ||
} else if (!isFieldNode(node)) { | ||
// This is a fragment (either inline or spread) | ||
var fragmentSelect = isInlineFragment(node) ? getSelectionSet(node) : fragments[getName(node)]; // Recursively process the fragments' selection sets | ||
forEachFieldNode(ctx, select, function (node) { | ||
var fieldName = getName(node); // The field's key can include arguments if it has any | ||
var fragmentData = Object.create(null); | ||
readSelection(ctx, entity, key, fragmentData, fragmentSelect); | ||
merge(data, fragmentData); | ||
} else { | ||
var fieldName = getName(node); // The field's key can include arguments if it has any | ||
var fieldKey = keyOfField(fieldName, getFieldArguments(node, vars)); | ||
var fieldValue = entity[fieldKey]; | ||
var fieldAlias = getFieldAlias(node); | ||
var childFieldKey = joinKeys(key, fieldKey); | ||
var fieldKey = keyOfField(fieldName, getFieldArguments(node, vars)); | ||
var fieldValue = entity[fieldKey]; | ||
var fieldAlias = getFieldAlias(node); | ||
var childFieldKey = joinKeys(key, fieldKey); | ||
if (key === 'query') { | ||
ctx.dependencies.push(childFieldKey); | ||
} | ||
if (key === 'query') { | ||
ctx.dependencies.push(childFieldKey); | ||
} | ||
if (node.selectionSet === undefined || fieldValue !== null) { | ||
if (node.selectionSet === undefined || fieldValue !== null) { | ||
if (!(fieldAlias in data)) { | ||
// Cache Incomplete: An undefined field value means it wasn't cached | ||
ctx.isComplete = fieldValue !== undefined; | ||
data[fieldAlias] = fieldValue === undefined ? null : fieldValue; | ||
} | ||
} else { | ||
// null values mean that a field might be linked to other entities | ||
var ref = node.selectionSet; | ||
var fieldSelect = ref.selections; | ||
var link = readLink(store, childFieldKey); // Cache Incomplete: A missing link for a field means it's not cached | ||
if (link === undefined) { | ||
ctx.isComplete = false; | ||
data[fieldAlias] = null; | ||
} else { | ||
// null values mean that a field might be linked to other entities | ||
var ref = node.selectionSet; | ||
var fieldSelect = ref.selections; | ||
var link = readLink(store, childFieldKey); // Cache Incomplete: A missing link for a field means it's not cached | ||
if (link === undefined) { | ||
ctx.isComplete = false; | ||
data[fieldAlias] = null; | ||
} else { | ||
data[fieldAlias] = readField(ctx, link, fieldSelect); | ||
} | ||
var prevData = data[fieldAlias]; | ||
data[fieldAlias] = readField(ctx, link, fieldSelect, prevData); | ||
} | ||
} | ||
}); | ||
return data; | ||
}; | ||
var readField = function (ctx, link, select) { | ||
var readField = function (ctx, link, select, prevData) { | ||
if (Array.isArray(link)) { | ||
// @ts-ignore: Link cannot be expressed as a recursive type | ||
return link.map(function (childLink) { return readField(ctx, childLink, select); }); | ||
return link.map(function (childLink, index) { | ||
var data = prevData !== undefined ? prevData[index] : undefined; | ||
return readField(ctx, childLink, select, data); | ||
}); | ||
} else if (link === null) { | ||
return null; | ||
} else { | ||
var data = prevData === undefined ? Object.create(null) : prevData; | ||
return readEntity(ctx, link, select, data); | ||
} | ||
return readEntity(ctx, link, select); | ||
}; | ||
@@ -531,3 +514,3 @@ | ||
for (var fieldKey in entity) { | ||
var value = entity[key]; | ||
var value = entity[fieldKey]; | ||
@@ -534,0 +517,0 @@ if (value === null) { |
@@ -8,3 +8,3 @@ import { SelectionNode } from 'graphql'; | ||
export interface FragmentSelectionSets { | ||
[fragmentName: string]: SelectionSet; | ||
[fragmentName: string]: void | SelectionSet; | ||
} |
@@ -6,2 +6,1 @@ import { FieldNode } from 'graphql'; | ||
export declare const forEachFieldNode: (ctx: Context, select: ReadonlyArray<import("graphql").SelectionNode>, cb: (node: FieldNode) => void) => void; | ||
export declare const merge: (dest: any, src: any) => void; |
{ | ||
"name": "@urql/exchange-graphcache", | ||
"version": "0.1.0-alpha.3", | ||
"version": "0.1.0-alpha.4", | ||
"description": "A normalizing GraphQL cache configurable by defining exceptions to the rule", | ||
@@ -5,0 +5,0 @@ "main": "dist/graphcache.js", |
@@ -11,3 +11,3 @@ import { SelectionNode } from 'graphql'; | ||
export interface FragmentSelectionSets { | ||
[fragmentName: string]: SelectionSet; | ||
[fragmentName: string]: void | SelectionSet; | ||
} |
@@ -39,3 +39,3 @@ import { joinKeys } from '../helpers'; | ||
for (const fieldKey in entity) { | ||
const value = entity[key]; | ||
const value = entity[fieldKey]; | ||
if (value === null) { | ||
@@ -42,0 +42,0 @@ const childFieldKey = joinKeys(key, fieldKey); |
@@ -6,6 +6,3 @@ import { | ||
getSelectionSet, | ||
isFieldNode, | ||
isInlineFragment, | ||
SelectionSet, | ||
shouldInclude, | ||
} from '../ast'; | ||
@@ -17,3 +14,3 @@ | ||
import { makeContext, merge } from './shared'; | ||
import { forEachFieldNode, makeContext } from './shared'; | ||
import { Context, Data, Request, Result } from './types'; | ||
@@ -29,3 +26,3 @@ | ||
const select = getSelectionSet(ctx.operation); | ||
const data = readEntity(ctx, 'query', select); | ||
const data = readEntity(ctx, 'query', select, Object.create(null)); | ||
@@ -42,3 +39,4 @@ return { | ||
key: string, | ||
select: SelectionSet | ||
select: SelectionSet, | ||
data: Data | ||
): Data | null => { | ||
@@ -55,5 +53,3 @@ const { store } = ctx; | ||
const data = Object.create(null); | ||
readSelection(ctx, entity, key, data, select); | ||
return data; | ||
return readSelection(ctx, entity, key, select, data); | ||
}; | ||
@@ -65,51 +61,41 @@ | ||
key: string, | ||
data: Data, | ||
select: SelectionSet | ||
): void => { | ||
const { store, vars, fragments } = ctx; | ||
select: SelectionSet, | ||
data: Data | ||
): Data => { | ||
const { store, vars } = ctx; | ||
select.forEach(node => { | ||
if (!shouldInclude(node, vars)) { | ||
// Directives instruct this node to be skipped | ||
return; | ||
} else if (!isFieldNode(node)) { | ||
// This is a fragment (either inline or spread) | ||
const fragmentSelect = isInlineFragment(node) | ||
? getSelectionSet(node) | ||
: fragments[getName(node)]; | ||
forEachFieldNode(ctx, select, node => { | ||
const fieldName = getName(node); | ||
// The field's key can include arguments if it has any | ||
const fieldKey = keyOfField(fieldName, getFieldArguments(node, vars)); | ||
const fieldValue = entity[fieldKey]; | ||
const fieldAlias = getFieldAlias(node); | ||
const childFieldKey = joinKeys(key, fieldKey); | ||
if (key === 'query') { | ||
ctx.dependencies.push(childFieldKey); | ||
} | ||
// Recursively process the fragments' selection sets | ||
const fragmentData = Object.create(null); | ||
readSelection(ctx, entity, key, fragmentData, fragmentSelect); | ||
merge(data, fragmentData); | ||
} else { | ||
const fieldName = getName(node); | ||
// The field's key can include arguments if it has any | ||
const fieldKey = keyOfField(fieldName, getFieldArguments(node, vars)); | ||
const fieldValue = entity[fieldKey]; | ||
const fieldAlias = getFieldAlias(node); | ||
const childFieldKey = joinKeys(key, fieldKey); | ||
if (key === 'query') { | ||
ctx.dependencies.push(childFieldKey); | ||
} | ||
if (node.selectionSet === undefined || fieldValue !== null) { | ||
if (node.selectionSet === undefined || fieldValue !== null) { | ||
if (!(fieldAlias in data)) { | ||
// Cache Incomplete: An undefined field value means it wasn't cached | ||
ctx.isComplete = fieldValue !== undefined; | ||
data[fieldAlias] = fieldValue === undefined ? null : fieldValue; | ||
} | ||
} else { | ||
// null values mean that a field might be linked to other entities | ||
const { selections: fieldSelect } = node.selectionSet; | ||
const link = readLink(store, childFieldKey); | ||
// Cache Incomplete: A missing link for a field means it's not cached | ||
if (link === undefined) { | ||
ctx.isComplete = false; | ||
data[fieldAlias] = null; | ||
} else { | ||
// null values mean that a field might be linked to other entities | ||
const { selections: fieldSelect } = node.selectionSet; | ||
const link = readLink(store, childFieldKey); | ||
// Cache Incomplete: A missing link for a field means it's not cached | ||
if (link === undefined) { | ||
ctx.isComplete = false; | ||
data[fieldAlias] = null; | ||
} else { | ||
data[fieldAlias] = readField(ctx, link, fieldSelect); | ||
} | ||
const prevData = data[fieldAlias] as Data; | ||
data[fieldAlias] = readField(ctx, link, fieldSelect, prevData); | ||
} | ||
} | ||
}); | ||
return data; | ||
}; | ||
@@ -120,12 +106,17 @@ | ||
link: Link, | ||
select: SelectionSet | ||
select: SelectionSet, | ||
prevData: void | Data | Data[] | ||
): null | Data | Data[] => { | ||
if (Array.isArray(link)) { | ||
// @ts-ignore: Link cannot be expressed as a recursive type | ||
return link.map(childLink => readField(ctx, childLink, select)); | ||
return link.map((childLink, index) => { | ||
const data = prevData !== undefined ? prevData[index] : undefined; | ||
return readField(ctx, childLink, select, data); | ||
}); | ||
} else if (link === null) { | ||
return null; | ||
} else { | ||
const data = prevData === undefined ? Object.create(null) : prevData; | ||
return readEntity(ctx, link, select, data); | ||
} | ||
return readEntity(ctx, link, select); | ||
}; |
@@ -49,4 +49,7 @@ import { FieldNode } from 'graphql'; | ||
: fragments[getName(node)]; | ||
// Recursively process the fragments' selection sets | ||
forEachFieldNode(ctx, fragmentSelect, cb); | ||
if (fragmentSelect !== undefined) { | ||
// Recursively process the fragments' selection sets | ||
forEachFieldNode(ctx, fragmentSelect, cb); | ||
} | ||
} else { | ||
@@ -57,14 +60,1 @@ cb(node); | ||
}; | ||
export const merge = (dest, src) => { | ||
if (src !== null && typeof src === 'object') { | ||
for (const key in src) { | ||
const srcVal = src[key]; | ||
if (!(key in dest)) { | ||
dest[key] = srcVal; | ||
} else { | ||
merge(dest[key], srcVal); | ||
} | ||
} | ||
} | ||
}; |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
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
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
43
0
190539
2060