Package Exports
- can-set
- can-set/src/clause
- can-set/src/compare
- can-set/src/get
- can-set/src/helpers
- can-set/src/props
- can-set/src/set-core
- can-set/test/test
This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (can-set) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.
Readme
can-set
can-set is a utility for comparing sets that are represented by the parameters commonly passed to service requests.
For example, the set {type: "critical"} might represent all
critical todos. It is a superset of the set {type: "critical", due: "today"}
which might represent all critical todos due today.
can-set is useful for building caching and other data-layer optimizations. It can be used in client or server environments. can-connect uses can-set to create data modeling utilities and middleware for the client.
- Install
- Use
new set.Algebra(compares...)Compares Object<String,Prop()>prop(aValue, bValue, a, b, prop, algebra)algebra.difference(a, b)algebra.equal(a, b)algebra.getSubset(a, b, bData)algebra.getUnion(a, b, aItems, bItems)algebra.index(set, items, item)algebra.count(set)algebra.has(set, props)algebra.properSubset(a, b)algebra.subset(a, b)algebra.union(a, b)
props Objectnew set.Translate(clauseType, propertyName)- Contributing
Install
Use npm to install can-set:
npm install can-set --save
Use
Use require in Node/Browserify workflows to import can-set like:
var set = require('can-set');Use define, require or import in StealJS workflows to import can-set like:
import set from 'can-set'Once you've imported set into your project, use it to create a set.Algebra and then
use that to compare and perform operations on sets.
// create an algebra
var algebra = new set.Algebra(
// specify the unique identifier on data
set.props.id("_id"),
// specify that completed can be true, false or undefined
set.props.boolean("completed"),
// specify properties that define pagination
set.props.rangeInclusive("start","end"),
// specify the property that controls sorting
set.props.sort("orderBy"),
)
// compare two sets
algebra.subset({start: 2, end: 3}, {start: 1, end: 4}) //-> true
algebra.difference({} , {completed: true}) //-> {completed: false}
// perform operations on sets
algebra.getSubset({start: 2,end: 3},{start: 1,end: 4},
[{id: 1},{id: 2},{id: 3},{id: 4}])
//-> [{id: 2},{id: 3}]Once you have the basics, you can use set algebra to all sorts of intelligent caching
and performance optimizations. The following example
defines a getTodos function that gets todo data from a memory cache or from the server.
var algebra = new set.Algebra(
set.props.boolean("completed")
);
var cache = [];
// `params` might look like `{complete: true}`
var getTodos = function(set, cb) {
// Check cache for a superset of what we are looking for.
for(var i = 0 ; i < cache.length; i++) {
var cacheEntry = cache[i];
if(algebra.subset( set, cacheEntry.set ) ) {
// If a match is found get those items.
var matchingTodos = algebra.getSubset(set, cacheEntry.set, cacheEntry.items)
return cb(matchingTodos);
}
}
// not in cache, get and save in cache
$.get("/todos",set, function(todos){
cache.push({
set: set,
items: todos
});
cb(todos);
});
}API
new set.Algebra(compares...)
Creates an object that can perform binary operations on sets with an awareness of how certain properties represent the set.
var set = require("can-set");
var algebra = new set.Algebra(
set.props.boolean("completed"),
set.props.id("_id")
);- compares
{Compares}: Each argument is a compares. These are returned by the functions on props or can be created manually.
Compares {Object\<String,Prop()\>}
An object of property names and prop functions.
{
// return `true` if the values should be considered the same:
lastName: function(aValue, bValue){
return (""+aValue).toLowerCase() === (""+bValue).toLowerCase();
}
}prop(aValue, bValue, a, b, prop, algebra)
A prop function returns algebra values for two values for a given property.
- aValue
{*}: The value of A's property in a set difference A and B (A B). - bValue
{*}: The value of A's property in a set difference A and B (A B). - a
{*}: The A set in a set difference A and B (A B). - b
{*}: The B set in a set difference A and B (A B).
returns
{Object|Boolean}: A prop function should either return a Boolean which indicates ifaValueandbValueare equal or anAlgebraResultobject that details information about the union, intersection, and difference ofaValueandbValue.An
AlgebraResultobject has the following values:union- A value the represents the union of A and B.intersection- A value that represents the intersection of A and B.difference- A value that represents all items in A that are not in B.count- The count of the items in A.
For example, if you had a
colorsproperty and A is["Red","Blue"]and B is["Green","Yellow","Blue"], the AlgebraResult object might look like:{ union: ["Red","Blue","Green","Yellow"], intersection: ["Blue"], difference: ["Red"], count: 2000 }
The count is
2000because there might be 2000 items represented by colors "Red" and "Blue". Often the real number can not be known.
algebra.difference(a, b)
Returns a set that represents the difference of sets A and B (A \ B), or returns if a difference exists.
algebra1 = new set.Algebra(set.props.boolean("completed"));
algebra2 = new set.Algebra();
// A has all of B
algebra1.difference( {} , {completed: true} ) //-> {completed: false}
// A has all of B, but we can't figure out how to create a set object
algebra2.difference( {} , {completed: true} ) //-> true
// A is totally inside B
algebra2.difference( {completed: true}, {} ) //-> falsereturns
{Set|Boolean}: If an object is returned, it is difference of sets A and B (A \ B).If
trueis returned, that means that B is a subset of A, but no set object can be returned that represents that set.If
falseis returned, that means there is no difference or the sets are not comparable.
algebra.equal(a, b)
Returns true if the two sets the exact same.
algebra.equal({type: "critical"}, {type: "critical"}) //-> true- returns
{Boolean}: True if the two sets are equal.
algebra.getSubset(a, b, bData)
Gets a set's items given a super set b and its items.
algebra.getSubset(
{type: "dog"},
{},
[{id: 1, type:"cat"},
{id: 2, type: "dog"},
{id: 3, type: "dog"},
{id: 4, type: "zebra"}]
) //-> [{id: 2, type: "dog"},{id: 3, type: "dog"}]- a
{Set}: The set whose data will be returned. - b
{Set}: A superset of seta. - bData
{Array<Object>}: The data in setb.
- returns
{Array<Object>}: The data in seta.
algebra.getUnion(a, b, aItems, bItems)
Unifies items from set A and setB into a single array of items.
algebra = new set.Algebra(
set.props.rangeInclusive("start","end")
);
algebra.getUnion(
{start: 1,end: 2},
{start: 2,end: 4},
[{id: 1},{id: 2}],
[{id: 2},{id: 3},{id: 4}]);
//-> [{id: 1},{id: 2},{id: 3},{id: 4}]- a
{Set}: A set. - b
{Set}: A set. - aItems
{Array<Object>}: Seta's items. - bItems
{Array<Object>}: Setb's items.
- returns
{Array<Object>}: Returns items in both setaand setb.
algebra.index(set, items, item)
Returns where item should be inserted into items which is represented by set.
algebra = new set.Algebra(
set.props.sort("orderBy")
);
algebra.index(
{orderBy: "age"},
[{id: 1, age: 3},{id: 2, age: 5},{id: 3, age: 8},{id: 4, age: 10}],
{id: 6, age: 3}
) //-> 2The default sort property is what is specified by id. This means if that if the sort property is not specified, it will assume the set is sorted by the specified id property.
- set
{Set}: Thesetthat describesitems. - items
{Array<Object>}: An array of data objects. - item
{Object}: The data object to be inserted.
- returns
{Number}: The position to insertitem.
algebra.count(set)
Returns the number of items that might be loaded by the set. This makes use of set.Algebra's
By default, this returns Infinity.
var algebra = new set.Algebra({
set.props.rangeInclusive("start", "end")
});
algebra.count({start: 10, end: 19}) //-> 10
algebra.count({}) //-> Infinity- set
{Set}: [description]
- returns
{Number}: The number of items in the set if known,Infinityif unknown.
algebra.has(set, props)
Used to tell if the set contains the instance object props.
var algebra = new set.Algebra(
new set.Translate("where","$where")
);
algebra.has(
{"$where": {playerId: 5}},
{id: 5, type: "3pt", playerId: 5, gameId: 7}
) //-> true- set
{Set}: A set. - props
{Object}: An instance's raw data.
- returns
{Boolean}: Returnstrueifpropsbelongs insetandfalseit not.
algebra.properSubset(a, b)
Returns true if A is a strict subset of B (A ⊂ B).
algebra.properSubset({type: "critical"}, {}) //-> true
algebra.properSubset({}, {}) //-> false- returns
{Boolean}:trueifais a subset ofband not equal tob.
algebra.subset(a, b)
Returns true if A is a subset of B or A is equal to B (A ⊆ B).
algebra.subset({type: "critical"}, {}) //-> true
algebra.subset({}, {}) //-> true- returns
{Boolean}:trueifais a subset ofb.
algebra.union(a, b)
Returns a set that represents the union of A and B (A ∪ B).
algebra.union(
{start: 0, end: 99},
{start: 100, end: 199},
) //-> {start: 0, end: 199}returns
{Set|undefined}: If an object is returned, it is the union of A and B (A ∪ B).If
undefinedis returned, it means a union can't be created.
props {Object}
Contains a collection of prop generating functions.
The following functions create compares objects that can be mixed together to create a set Algebra.
var set = require("can-set");
var algebra = new set.Algebra(
{
// ignore this property in set algebra
sessionId: function(){ return true }
},
set.props.boolean("completed"),
set.props.rangeInclusive("start","end")
);set.props.boolean(property)
Makes a compare object with a property function that has the following logic:
A(true) ∪ B(false) = undefined
A(undefined) \ B(true) = false
A(undefined) \ B(false) = trueIt understands that true and false are complementary sets that combined to undefined. Another way to think of this is that if you load {complete: false} and {complete: true} you've loaded {}.
- property
{String}: The name of the boolean property. - A
{Compares}:Comparesobject that can be an argument to Algebra
set.props.rangeInclusive(startIndexProperty, endIndexProperty)
Makes a prop for two ranged properties that specify a range of items that includes both the startIndex and endIndex. For example, a range of [0,20] loads 21 items.
set.props.rangeInclusive("start","end")- startIndexProperty
{String}: The starting property name - endIndexProperty
{String}: The ending property name
- returns
{Compares}: Returns a prop
set.props.enum(property, propertyValues)
Makes a prop for a set of values.
var compare = set.props.enum("type", ["new","accepted","pending","resolved"])set.props.sort(prop, [sortFunc])
Defines the sortable property and behavior.
var algebra = new set.Algebra(set.props.sort("sortBy"));
algebra.index(
{sortBy: "name desc"},
[{name: "Meyer"}],
{name: "Adams"}) //-> 1
algebra.index(
{sortBy: "name"},
[{name: "Meyer"}],
{name: "Adams"}) //-> 0- prop
{String}: The sortable property. - sortFunc
{function(sortPropValue, item1, item2)}: The sortable behavior. The default behavior assumes the sort property value looks likePROPERTY DIRECTION(ex:name desc).
- returns
{Compares}: Returns a compares that can be used to create aset.Algebra.
set.props.id(prop)
Defines the property name on items that uniquely identifies them. This is the default sorted property if no sort is provided.
var algebra = new set.Algebra(set.props.id("_id"));
algebra.index(
{sortBy: "name desc"},
[{name: "Meyer"}],
{name: "Adams"}) //-> 1
algebra.index(
{sortBy: "name"},
[{name: "Meyer"}],
{name: "Adams"}) //-> 0- prop
{String}: The property name that defines the unique property id.
- returns
{Compares}: Returns a compares that can be used to create aset.Algebra.
new set.Translate(clauseType, propertyName)
Localizes a clause's properties within another nested property.
var algebra = new set.Algebra(
new set.Translate("where","$where")
);
algebra.has(
{$where: {complete: true}},
{id: 5, complete: true}
) //-> trueThis is useful when filters (which are where clauses) are
within a nested object.
- clause
{String}: A clause type. One of'where','order','paginate','id'. - propertyName
{String|Object}: The property name which contains the clauses's properties.
- returns
{Compares}: A set compares object that can do the translation.
Contributing
To setup your dev environment:
- Clone and fork this repo.
- Run
npm install. - Open
test.htmlin your browser. Everything should pass. - Run
npm test. Everything should pass. - Run
npm run-script build. Everything should build ok.
To publish:
- Update the version number in package.json and commit and push this.
- Run
npm publish. This should generate the dist folder. - Create and checkout a "release" branch.
- Run
git add -f dist. - Commit the addition and tag it
git tag v0.2.0. Push the taggit push origin --tags.