mirror of
https://github.com/vale981/grapher
synced 2025-03-05 09:31:42 -05:00
updating reducer implementation
This commit is contained in:
parent
91c1f49f6f
commit
5c21c0f5e9
7 changed files with 229 additions and 17 deletions
|
@ -103,6 +103,9 @@ export default class Exposure {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializing the publication for reactive query fetching
|
||||
*/
|
||||
initPublication() {
|
||||
const collection = this.collection;
|
||||
const config = this.config;
|
||||
|
@ -122,6 +125,9 @@ export default class Exposure {
|
|||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializez the method to retrieve the data via Meteor.call
|
||||
*/
|
||||
initMethod() {
|
||||
const collection = this.collection;
|
||||
const config = this.config;
|
||||
|
@ -147,6 +153,10 @@ export default class Exposure {
|
|||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializez the method to retrieve the count of the data via Meteor.call
|
||||
* @returns {*}
|
||||
*/
|
||||
initCountMethod() {
|
||||
const collection = this.collection;
|
||||
|
||||
|
@ -159,6 +169,10 @@ export default class Exposure {
|
|||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes security enforcement
|
||||
* THINK: Maybe instead of overriding .find, I could store this data of security inside the collection object.
|
||||
*/
|
||||
initSecurity() {
|
||||
const collection = this.collection;
|
||||
const {firewall, maxLimit, restrictedFields} = this.config;
|
||||
|
|
|
@ -8,21 +8,26 @@ const specialFields = ['$filters', '$options'];
|
|||
* Creates node objects from the body
|
||||
* @param root
|
||||
*/
|
||||
function createNodes(root) {
|
||||
// fix for phantomjs tests
|
||||
export function createNodes(root) {
|
||||
// this is a fix for phantomjs tests (don't really understand it.)
|
||||
if (!_.isObject(root.body)) {
|
||||
return;
|
||||
}
|
||||
|
||||
let reducers = {};
|
||||
|
||||
_.each(root.body, (body, fieldName) => {
|
||||
if (!body) {
|
||||
return;
|
||||
}
|
||||
|
||||
// if it's a prop
|
||||
if (_.contains(specialFields, fieldName)) {
|
||||
return _.extend(root.props, {
|
||||
_.extend(root.props, {
|
||||
[fieldName]: body
|
||||
});
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// checking if it is a link.
|
||||
|
@ -32,26 +37,42 @@ function createNodes(root) {
|
|||
let subroot = new CollectionNode(linker.getLinkedCollection(), body, fieldName);
|
||||
root.add(subroot, linker);
|
||||
|
||||
return createNodes(subroot);
|
||||
createNodes(subroot);
|
||||
return;
|
||||
}
|
||||
|
||||
// it's not a link and not a special variable => we assume it's a field.
|
||||
if (_.isObject(body)) {
|
||||
let dotted = dotize.convert({[fieldName]: body});
|
||||
_.each(dotted, (value, key) => {
|
||||
root.add(new FieldNode(key, value));
|
||||
});
|
||||
} else {
|
||||
let fieldNode = new FieldNode(fieldName, body);
|
||||
root.add(fieldNode);
|
||||
// checking if it's a reducer
|
||||
const reducer = root.collection.getReducer(fieldName);
|
||||
|
||||
if (reducer) {
|
||||
reducers[fieldName] = reducer;
|
||||
return;
|
||||
}
|
||||
|
||||
// it's most likely a field then
|
||||
addFieldNode(body, fieldName, root);
|
||||
});
|
||||
|
||||
// applyReducersOnGraph(root, reducers);
|
||||
|
||||
if (root.fieldNodes.length === 0) {
|
||||
root.add(new FieldNode('_id', 1));
|
||||
}
|
||||
}
|
||||
|
||||
export function addFieldNode(body, fieldName, root) {
|
||||
// it's not a link and not a special variable => we assume it's a field
|
||||
if (_.isObject(body)) {
|
||||
let dotted = dotize.convert({[fieldName]: body});
|
||||
_.each(dotted, (value, key) => {
|
||||
root.add(new FieldNode(key, value));
|
||||
});
|
||||
} else {
|
||||
let fieldNode = new FieldNode(fieldName, body);
|
||||
root.add(fieldNode);
|
||||
}
|
||||
}
|
||||
|
||||
export default function (collection, body) {
|
||||
let root = new CollectionNode(collection, body);
|
||||
createNodes(root);
|
||||
|
|
|
@ -16,6 +16,8 @@ export default class CollectionNode {
|
|||
this.parent = null;
|
||||
this.linker = null;
|
||||
this.linkStorageField = null;
|
||||
this.reducers = [];
|
||||
this.scheduledForDeletion = false;
|
||||
}
|
||||
|
||||
get collectionNodes() {
|
||||
|
@ -52,7 +54,7 @@ export default class CollectionNode {
|
|||
* @param _node
|
||||
*/
|
||||
remove(_node) {
|
||||
this.nodes = _.filter(this.nodes, node => _node !== node);
|
||||
this.nodes = _.filter(this.nodes, node => _node !== node);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -103,6 +105,39 @@ export default class CollectionNode {
|
|||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* @param fieldName
|
||||
* @returns {FieldNode}
|
||||
*/
|
||||
getField(fieldName) {
|
||||
return _.find(this.fieldNodes, fieldNode => {
|
||||
return fieldNode.name == fieldName
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* @param name
|
||||
* @returns {boolean}
|
||||
*/
|
||||
hasCollectionNode(name) {
|
||||
return !!_.find(this.collectionNodes, node => {
|
||||
return node.linkName == name
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* @param name
|
||||
* @returns {CollectionNode}
|
||||
*/
|
||||
getCollectionNode(name) {
|
||||
return _.find(this.collectionNodes, node => {
|
||||
return node.linkName == name
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {*}
|
||||
*/
|
||||
getName() {
|
||||
return this.linkName
|
||||
? this.linkName
|
||||
|
|
|
@ -2,6 +2,7 @@ export default class FieldNode {
|
|||
constructor(name, body) {
|
||||
this.name = name;
|
||||
this.body = _.isObject(body) ? 1 : body;
|
||||
this.scheduledForDeletion = false;
|
||||
}
|
||||
|
||||
applyFields(fields) {
|
||||
|
|
|
@ -1,13 +1,17 @@
|
|||
import dot from 'dot-object';
|
||||
|
||||
export default class ReducerNode {
|
||||
constructor(name, body, reducer) {
|
||||
this.collectionNode = collectionNode;
|
||||
this.name = name;
|
||||
this.body = body;
|
||||
this.reducer = reducer;
|
||||
}
|
||||
|
||||
// reducer nodes should always be added last.
|
||||
|
||||
init(collectionNode) {
|
||||
// store fields that are needed, but not specified are fields
|
||||
// so when we prepare data for delivery it we can clean-it-up
|
||||
|
||||
}
|
||||
|
||||
applyFields(fields) {
|
||||
|
|
136
lib/query/reducers/lib/applyReducersOnGraph.js
Normal file
136
lib/query/reducers/lib/applyReducersOnGraph.js
Normal file
|
@ -0,0 +1,136 @@
|
|||
import dot from 'dot-object';
|
||||
import { createNodes } from '../../lib/createGraph';
|
||||
import CollectionNode from '../../nodes/collectionNode';
|
||||
import FieldNode from '../../nodes/fieldNode';
|
||||
|
||||
export default function addReducers(root, reducers, addToRoot = true) {
|
||||
// we add reducers last, after we have added all the fields.
|
||||
const collection = root.collection;
|
||||
|
||||
reducers.forEach(reducer => {
|
||||
if (addToRoot) {
|
||||
root.reducers.push(reducer);
|
||||
}
|
||||
|
||||
_.each(reducer.body, (body, fieldName) => {
|
||||
// if it's a link
|
||||
const linker = collection.getLinker(fieldName);
|
||||
if (linker) {
|
||||
if (root.hasCollectionNode(fieldName)) {
|
||||
// TODO: go deep and perform the same process
|
||||
const collectionNode = root.getCollectionNode(fieldName);
|
||||
|
||||
diffWithReducerBody(body, collectionNode);
|
||||
|
||||
return;
|
||||
} else {
|
||||
// add
|
||||
let collectionNode = new CollectionNode(linker.getLinkedCollection(), body, fieldName);
|
||||
collectionNode.scheduledForDeletion = true;
|
||||
root.add(collectionNode, linker);
|
||||
|
||||
createNodes(collectionNode);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
const reducer = collection.getReducer(fieldName);
|
||||
if (reducer) {
|
||||
addReducers(root, [reducer]);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// we assume it's a field in this case
|
||||
handleAddField(body, root, fieldName);
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @param body
|
||||
* @param root
|
||||
* @param fieldName
|
||||
*/
|
||||
function handleAddField(body, fieldName, root) {
|
||||
if (_.isObject(body)) {
|
||||
// if reducer specifies a nested field
|
||||
const dots = dot.dot(body);
|
||||
_.each(dots, (value, key) => {
|
||||
if (!root.hasField(fieldName)) {
|
||||
let fieldNode = new FieldNode(key, value);
|
||||
fieldNode.scheduledForDeletion = true;
|
||||
|
||||
root.add(fieldNode);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
// if reducer does not specify a nested field, and the field does not exist.
|
||||
if (!root.hasField(fieldName)) {
|
||||
let fieldNode = new FieldNode(fieldName, body);
|
||||
fieldNode.scheduledForDeletion = true;
|
||||
|
||||
root.add(fieldNode);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param reducerBody
|
||||
* @param collectionNode
|
||||
*/
|
||||
function diffWithReducerBody(reducerBody, collectionNode) {
|
||||
_.each(reducerBody, (value, key) => {
|
||||
const collection = collectionNode.collection;
|
||||
|
||||
if (_.isObject(value)) {
|
||||
// nested field or link
|
||||
if (collectionNode.body[key]) {
|
||||
// if it exists
|
||||
const linker = collection.getLinker(key);
|
||||
|
||||
// if it's a link
|
||||
if (linker) {
|
||||
diffWithReducerBody(value, collectionNode.getCollectionNode(key));
|
||||
return;
|
||||
}
|
||||
|
||||
handleAddField(value, key, collectionNode);
|
||||
} else {
|
||||
// does not exist, so it may be a field or a linker
|
||||
const linker = collection.getLinker(key);
|
||||
|
||||
// if it's a link
|
||||
if (linker) {
|
||||
let childCollectionNode = new CollectionNode(linker.getLinkedCollection(), value, key);
|
||||
childCollectionNode.scheduledForDeletion = true;
|
||||
collectionNode.add(collectionNode, linker);
|
||||
|
||||
createNodes(childCollectionNode);
|
||||
return;
|
||||
}
|
||||
|
||||
const reducer = collection.getReducer(key);
|
||||
if (reducer) {
|
||||
// if it's another reducer
|
||||
addReducers(collectionNode, [reducer], false);
|
||||
return;
|
||||
}
|
||||
|
||||
// it's a field
|
||||
handleAddField(value, key, collectionNode)
|
||||
}
|
||||
} else {
|
||||
const reducer = collection.getReducer(key);
|
||||
if (reducer) {
|
||||
// if it's another reducer
|
||||
addReducers(collectionNode, [reducer], false);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
handleAddField(value, key, collectionNode);
|
||||
}
|
||||
})
|
||||
}
|
|
@ -11,7 +11,8 @@ Package.describe({
|
|||
});
|
||||
|
||||
Npm.depends({
|
||||
'sift': '3.2.6'
|
||||
'sift': '3.2.6',
|
||||
'dot-object': '1.5.4',
|
||||
});
|
||||
|
||||
Package.onUse(function (api) {
|
||||
|
|
Loading…
Add table
Reference in a new issue