Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Replaced fixed order with dynamic ordering #286

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions can/map/map.js
Original file line number Diff line number Diff line change
Expand Up @@ -343,6 +343,12 @@ var canMapBehavior = connect.behavior("can/map",function(baseConnection){

return behavior;

}, {
"data/localstorage-cache": "base",
"data/url": "base",
"data/parse": "base",
"cache-requests": "base",
"data/combine-requests": "base"
});

/**
Expand Down
5 changes: 5 additions & 0 deletions can/merge/merge.js
Original file line number Diff line number Diff line change
Expand Up @@ -96,4 +96,9 @@ module.exports = connect.behavior("can/merge",function(baseConnection){
canBatch.stop();
}
};
}, {
"constructor/callbacks-once": "derived",
"real-time": "derived",
"can/map": "base",
"constructor": "derived"
});
6 changes: 6 additions & 0 deletions can/ref/ref.js
Original file line number Diff line number Diff line change
Expand Up @@ -388,4 +388,10 @@ module.exports = connect.behavior("can/ref",function(baseConnection){
this.Map.Ref = makeRef(this);
}
};
}, {
"data/localstorage-cache": "base",
"data/url": "base",
"data/parse": "base",
"cache-requests": "base",
"data/combine-requests": "base"
});
146 changes: 95 additions & 51 deletions connect.js
Original file line number Diff line number Diff line change
@@ -1,43 +1,72 @@
var assign = require("can-util/js/assign/assign");
var each = require("can-util/js/each/each");
var CID = require("can-cid");
/**
*
* @param {Array<String,Behavior,function>} behaviors - An array of behavior names or custom behaviors.
* The order of named execution gets run in order.
* @param {Object} options
*/
var connect = function(behaviors, options){

behaviors = behaviors.map(function(behavior, index){
var sortedIndex = -1;
var i, behavior, scores = {};
behaviors = behaviors.slice(0);
for (i = 0; i < behaviors.length; i++) {
behavior = behaviors[i];
if(typeof behavior === "string") {
sortedIndex = connect.order.indexOf(behavior);
behavior = behaviorsMap[behavior];
} else if(behavior.isBehavior) {
sortedIndex = connect.order.indexOf(behavior.behaviorName);
} else {
} else if(!behavior.isBehavior) {
behavior = connect.behavior(behavior);
}

return {
originalIndex: index,
sortedIndex: sortedIndex,
behavior: behavior
};
})
.sort(function(b1, b2){
// if both have a sorted index
if(~b1.sortedIndex && ~b2.sortedIndex) {
return b1.sortedIndex - b2.sortedIndex;
// Make sure required dependencies are found.
each(behavior.dependencies, function(level, dep) {
if(typeof dep === "string") {
dep = behaviorsMap[dep];
}
if(dep &&
(level === "required:base" || level === "required:derived") &&
behaviors.indexOf(dep) === -1 &&
behaviors.indexOf(dep.behaviorName) === -1
) {
behaviors.push(dep);
}
return b1.originalIndex - b2.originalIndex;
});
behaviors[i] = behavior;
// give everything an initial score based on its order
scores[behavior.behaviorName] = i;
}

var updated;
do {
updated = false;
each(behaviors, function(behavior) {
each(behavior.dependencies, function(direction, dep) {
if(typeof dep === "string") {
dep = behaviorsMap[dep];
}
if(direction === "required:base" || direction === "base") {
if(scores[behavior.behaviorName] <= scores[dep.behaviorName]) {
updated = true;
scores[behavior.behaviorName] = scores[dep.behaviorName] + 1;
}
} else if(direction === "required:derived" || direction === "derived") {
if(scores[behavior.behaviorName] >= scores[dep.behaviorName]) {
updated = true;
scores[dep.behaviorName] = scores[behavior.behaviorName] + 1;
}
}
});
});

behaviors = behaviors.map(function(b){
return b.behavior;
} while(updated);
behaviors.sort(function(a, b) {
return scores[a.behaviorName] > scores[b.behaviorName] ? 1 : -1;
});

var behavior = connect.base( connect.behavior("options",function(){return options; })() );
// set up a base behavior
behavior = connect.base( connect.behavior("options",function(){ return options; })() );

// then add all of the others in score order
behaviors.forEach(function(behave){
behavior = behave(behavior);
});
Expand All @@ -47,41 +76,56 @@ var connect = function(behaviors, options){
return behavior;
};

// connect.order = ["data/localstorage-cache","data/url","data/parse","cache-requests","data/combine-requests",

// "constructor","constructor/store","can/map","can/ref",
// "fall-through-cache",

connect.order = ["data/localstorage-cache","data/url","data/parse","cache-requests","data/combine-requests",

"constructor","constructor/store","can/map","can/ref",
"fall-through-cache",
// "data/worker","real-time",

"data/worker","real-time",
/*, {
"data/localstorage-cache": "base",
"data/url": "base",
"data/parse": "base",
"cache-requests": "base",
"data/combine-requests": "base",
"constructor": "base",
"constructor/store": "base",
"can/map": "base",
"can/ref": "base",
"fall-through-cache": "base"
"data/worker": "base",
"real-time": "base"
}*/

"data/callbacks-cache","data/callbacks","constructor/callbacks-once"
];
// "data/callbacks-cache","data/callbacks","constructor/callbacks-once"
// ];

connect.behavior = function(name, behavior){
if(typeof name !== "string") {
behavior = name;
name = undefined;
}
var behaviorMixin = function(base){
// basically Object.create
var Behavior = function(){};
Behavior.name = name;
Behavior.prototype = base;
var newBehavior = new Behavior();
// allows behaviors to be a simple object, not always a function
var res = typeof behavior === "function" ? behavior.apply(newBehavior, arguments) : behavior;
assign(newBehavior, res);
newBehavior.__behaviorName = name;
return newBehavior;
};
if(name) {
behaviorMixin.behaviorName = name;
behaviorsMap[name] = behaviorMixin;
}
behaviorMixin.isBehavior = true;
return behaviorMixin;
connect.behavior = function(name, behavior, dependencies){
if(typeof name !== "string") {
dependencies = behavior;
behavior = name;
name = CID({}, "behavior");
}
var behaviorMixin = function(base){
// basically Object.create
var Behavior = function(){};
Behavior.name = name;
Behavior.prototype = base;
var newBehavior = new Behavior();
// allows behaviors to be a simple object, not always a function
var res = typeof behavior === "function" ? behavior.apply(newBehavior, arguments) : behavior;
assign(newBehavior, res);
newBehavior.__behaviorName = name;
return newBehavior;
};
if(name) {
behaviorMixin.behaviorName = name;
behaviorsMap[name] = behaviorMixin;
}
behaviorMixin.isBehavior = true;
behaviorMixin.dependencies = dependencies;
return behaviorMixin;
};

var behaviorsMap = {};
Expand Down
13 changes: 13 additions & 0 deletions constructor/callbacks-once/callbacks-once.js
Original file line number Diff line number Diff line change
Expand Up @@ -71,4 +71,17 @@ module.exports = connect.behavior("constructor/callbacks-once",function(baseConn
});

return behavior;
}, {
"data/localstorage-cache": "base",
"data/url": "base",
"data/parse": "base",
"cache-requests": "base",
"data/combine-requests": "base",
"constructor": "base",
"constructor/store": "base",
"can/map": "base",
"can/ref": "base",
"fall-through-cache": "base",
"data/worker": "base",
"real-time": "base"
});
6 changes: 6 additions & 0 deletions constructor/constructor.js
Original file line number Diff line number Diff line change
Expand Up @@ -687,6 +687,12 @@ module.exports = connect.behavior("constructor",function(baseConnection){

return behavior;

}, {
"data/localstorage-cache": "base",
"data/url": "base",
"data/parse": "base",
"cache-requests": "base",
"data/combine-requests": "base"
});

function copyMetadata(listData, list){
Expand Down
7 changes: 7 additions & 0 deletions constructor/store/store.js
Original file line number Diff line number Diff line change
Expand Up @@ -642,6 +642,13 @@ var constructorStore = connect.behavior("constructor/store",function(baseConnect

return behavior;

}, {
"data/localstorage-cache": "base",
"data/url": "base",
"data/parse": "base",
"cache-requests": "base",
"data/combine-requests": "base",
"constructor": "base"
});
constructorStore.requests = requests;

Expand Down
1 change: 1 addition & 0 deletions constructor/store/store_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,7 @@ QUnit.test("list store is kept and re-used and possibly discarded", function(){
return new PersonList(arr.data, sets);
}
});
console.log(connection)

var resolvedList;
connection.getList({}).then(function(list){
Expand Down
13 changes: 13 additions & 0 deletions data/callbacks-cache/callbacks-cache.js
Original file line number Diff line number Diff line change
Expand Up @@ -60,4 +60,17 @@ module.exports = connect.behavior("data/callbacks-cache",function(baseConnection
};
});
return behavior;
}, {
"data/localstorage-cache": "base",
"data/url": "base",
"data/parse": "base",
"cache-requests": "base",
"data/combine-requests": "base",
"constructor": "base",
"constructor/store": "base",
"can/map": "base",
"can/ref": "base",
"fall-through-cache": "base",
"data/worker": "base",
"real-time": "base"
});
13 changes: 13 additions & 0 deletions data/callbacks/callbacks.js
Original file line number Diff line number Diff line change
Expand Up @@ -106,4 +106,17 @@ module.exports = connect.behavior("data/callbacks",function(baseConnection){

});
return behavior;
}, {
"data/localstorage-cache": "base",
"data/url": "base",
"data/parse": "base",
"cache-requests": "base",
"data/combine-requests": "base",
"constructor": "base",
"constructor/store": "base",
"can/map": "base",
"can/ref": "base",
"fall-through-cache": "base",
"data/worker": "base",
"real-time": "base"
});
10 changes: 10 additions & 0 deletions fall-through-cache/fall-through-cache.js
Original file line number Diff line number Diff line change
Expand Up @@ -284,4 +284,14 @@ module.exports = connect.behavior("fall-through-cache",function(baseConnection){

return behavior;

}, {
"data/localstorage-cache": "base",
"data/url": "base",
"data/parse": "base",
"cache-requests": "base",
"data/combine-requests": "base",
"constructor": "base",
"constructor/store": "base",
"can/map": "base",
"can/ref": "base"
});
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
"description": "Data connection middleware and utilities",
"main": "can-connect.js",
"dependencies": {
"can-cid": "^1.0.3",
"can-compute": "^3.0.4",
"can-construct": "^3.1.0",
"can-define": "^1.0.9",
Expand Down
13 changes: 13 additions & 0 deletions real-time/real-time.js
Original file line number Diff line number Diff line change
Expand Up @@ -366,6 +366,19 @@ module.exports = connect.behavior("real-time",function(baseConnection){
}
//!steal-remove-end
};
}, {
// dependencies
"data/callbacks": "required:derived",
"data/localstorage-cache": "base",
"data/url": "base",
"data/parse": "base",
"cache-requests": "base",
"data/combine-requests": "base",
"constructor": "base",
"constructor/store": "base",
"can/map": "base",
"can/ref": "base",
"fall-through-cache": "base"
});

var create = function(props){
Expand Down