recollections
Advanced tools
Comparing version 0.1.1 to 0.1.5
20
index.js
@@ -7,8 +7,14 @@ /** | ||
export * from "./lib/api.js" | ||
export * from "./lib/basic-operators.js" | ||
export * from "./lib/sort.js" | ||
export * from "./lib/array.js" | ||
export * from "./lib/map.js" | ||
export * from "./lib/set.js" | ||
export * from "./lib/dom.js" | ||
export * from "./lib/delegate.js" | ||
export * from "./lib/operator/add-concat.js" | ||
export * from "./lib/operator/add-merge.js" | ||
export * from "./lib/operator/subtract.js" | ||
export * from "./lib/operator/filter.js" | ||
export * from "./lib/operator/mapTo.js" | ||
export * from "./lib/operator/sort.js" | ||
export * from "./lib/operator/intersection.js" | ||
export * from "./lib/operator/notInCommon.js" | ||
export * from "./lib/collection/array.js" | ||
export * from "./lib/collection/set.js" | ||
export * from "./lib/collection/map.js" | ||
export * from "./lib/collection/dom.js" | ||
export * from "./lib/collection/delegate.js" |
@@ -139,8 +139,31 @@ import { assert, arrayRemove } from "./util.js" | ||
/** | ||
* @param filterFunc {Function(item)} | ||
* @returns {Array of items} where `filterFunc` returned `true` | ||
* Provides an iterator, i.e. allows to write: | ||
* var coll = new SetColl(); | ||
* for (let item of coll) { | ||
* debug(item); | ||
* } | ||
* | ||
* Subclasses may override this with a more | ||
* efficient implementation. But take care that | ||
* a `remove()` during the iteration doesn't confuse it. | ||
*/ | ||
filter(filterFunc) { | ||
return new FilteredCollection(this, filterFunc); | ||
[Symbol.iterator]() { | ||
let array = this.contents; | ||
let i = 0; | ||
return { | ||
next: () => { | ||
if (i >= array.length) { | ||
return { done: true }; | ||
} | ||
return { value: array[i++], done: false }; | ||
} | ||
} | ||
} | ||
/* | ||
iterator: function*() { | ||
var items = this.contents; | ||
for (var i = 0; i < items.length; i++) { | ||
yield items[i]; | ||
} | ||
}*/ | ||
@@ -160,29 +183,17 @@ /** | ||
map(mapFunc) { | ||
return new MapToCollection(this, mapFunc); | ||
} | ||
// Convenience methods for operators | ||
/** | ||
* Provides an iterator, i.e. allows to write: | ||
* var coll = new SetColl(); | ||
* for (let item of coll) { | ||
* debug(item); | ||
* } | ||
* | ||
* Subclasses may override this with a more | ||
* efficient implementation. But take care that | ||
* a remove() during the iteration doesn't confuse it. | ||
* | ||
iterator : function*() { | ||
var items = this.contents; | ||
for (var i = 0; i < items.length; i++) { | ||
yield items[i]; | ||
} | ||
* @param filterFunc {Function(item)} | ||
* @returns {Array of items} where `filterFunc` returned `true` | ||
*/ | ||
filter(filterFunc) { | ||
throw "Overwritten in operators"; | ||
} | ||
*/ | ||
map(mapFunc) { | ||
throw "Overwritten in operators"; | ||
} | ||
// Convenience methods for operators | ||
/** | ||
@@ -197,3 +208,3 @@ * operator + | ||
concat(otherColl) { | ||
return new AdditionCollection(this, otherColl); | ||
throw "Overwritten in operators"; | ||
} | ||
@@ -210,3 +221,3 @@ | ||
merge(otherColl) { | ||
return new AdditionCollectionWithDups(this, otherColl); | ||
throw "Overwritten in operators"; | ||
} | ||
@@ -222,3 +233,3 @@ | ||
subtract(collSubtract) { | ||
return new SubtractCollection(this, collSubtract); | ||
throw "Overwritten in operators"; | ||
} | ||
@@ -235,3 +246,3 @@ | ||
inCommon(otherColl) { | ||
return new IntersectionCollection(this, otherColl); | ||
throw "Overwritten in operators"; | ||
} | ||
@@ -247,11 +258,11 @@ | ||
notInCommon(otherColl) { | ||
return notInCommonColl(this, otherColl); | ||
throw "Overwritten in operators"; | ||
} | ||
/** | ||
* @param sortFunc {Function(item)} like Array.sort() | ||
* @param sortFunc {Function(itemA, itemB): boolean} @see SortedCollection | ||
* @returns {Array of items} sorted by `sortFunc` | ||
*/ | ||
sort(sortFunc) { | ||
return sortColl(this, sortFunc); | ||
throw "Overwritten in operators"; | ||
} | ||
@@ -258,0 +269,0 @@ |
@@ -5,5 +5,6 @@ { | ||
"description": "Collections like Array, Set, Map, with operators and observers, for reactive applications", | ||
"author": "Ben Bucksch", | ||
"version": "0.1.5", | ||
"main": "index.js", | ||
"license": "MIT", | ||
"version": "0.1.1" | ||
"author": "Ben Bucksch" | ||
} |
@@ -213,3 +213,3 @@ Author: Ben Bucksch | ||
##### `added(item, list)` | ||
* Called after an item has been added to the list. | ||
* Called after an item has been added to the collection. | ||
* @param item {`Object`} the removed item | ||
@@ -219,7 +219,6 @@ * @param coll {`Collection`} the observed list. convenience only. | ||
##### `removed(item, coll)` | ||
* Called after an item has been removed from the list | ||
* TODO should clear() call removed() for each item? Currently: yes. | ||
* Alternative: separate cleared() | ||
* Called after an item has been removed from the collection. | ||
* @param item {`Object`} the removed item | ||
* @param coll {`Collection`} the observed list. convenience only. | ||
* TODO should clear() call removed() for each item? Currently: yes. Alternative: separate cleared() | ||
@@ -249,19 +248,20 @@ | ||
##### `MapColl` | ||
* A `KeyValueCollection` which can hold each object only once. | ||
* A `KeyValueCollection` which can map one string or object to another object. | ||
* Properties: | ||
* - not ordered | ||
* - can *not* hold the same item several times | ||
* - can hold the same item several times, as long as the key is different | ||
* - fast | ||
* A |Collection| which can map one string or object to another object. | ||
* Properties: | ||
* - not ordered | ||
* - can *not* hold the same key several times | ||
* - fast | ||
##### `DOMColl` | ||
* A `Collection` which wraps a DOMNodeList. | ||
* It is static, i.e. changes in the DOM are not reflected here. | ||
* Static, i.e. changes in the DOM are not reflected here. | ||
* @param {`DOMNodeList`} | ||
##### `DynamicDOMColl` | ||
* A `Collection` which wraps a DOMNodeList. | ||
* Dynamic, i.e. changes in the DOM are reflected in the collection and trigger the observers. | ||
* @param {`DOMNodeList`} | ||
* Not yet implemented | ||
Operators | ||
@@ -317,6 +317,8 @@ ----------- | ||
##### `sortColl(coll, sortFunc)` | ||
* Returns a new collection that is sorted based on the `sortFunc`. | ||
* TODO | ||
* Returns a new collection that is sorted using the `sortFunc`. | ||
* @param coll {`Collection`} | ||
* @param sortFunc(a {`Item`}, b {`Item`}) returns {`Boolean`} a > b | ||
* @param sortFunc(a {`Item`}, b {`Item`}) returns {`Boolean`} a < b | ||
* If true: itemA before itemB. | ||
* If false: itemB before itemA. | ||
* Note: The result is boolean, not a number like `compareFunc` used by `Array.sort()`. | ||
* @returns {`Collection`} | ||
@@ -323,0 +325,0 @@ |
@@ -201,3 +201,3 @@ /************************* | ||
concat(otherColl) { | ||
return new AdditionCollection(this, otherColl); | ||
return new AdditionCollectionWithDups(this, otherColl); | ||
} | ||
@@ -214,3 +214,3 @@ | ||
merge(otherColl) { | ||
return new AdditionCollectionWithDups(this, otherColl); | ||
return new AdditionCollection(this, otherColl); | ||
} | ||
@@ -253,7 +253,7 @@ | ||
/** | ||
* @param sortFunc {Function(item)} like Array.sort() | ||
* @param sortFunc {Function(itemA, itemB): boolean} @see SortedCollection | ||
* @returns {Array of items} sorted by |sortFunc| | ||
*/ | ||
sort(sortFunc) { | ||
return sortColl(this, sortFunc); | ||
return new SortedCollection(this, sortFunc); | ||
} | ||
@@ -729,3 +729,3 @@ | ||
add(item) { | ||
var added = _addWithoutObserver(item); | ||
var added = this._addWithoutObserver(item); | ||
if (added) { | ||
@@ -1262,3 +1262,39 @@ this._notifyAdded([item], this); | ||
/** | ||
* Returns a new collection that is sorted using the `sortFunc`. | ||
* | ||
* @param source {Collection} Another collection that is to be sorted | ||
* @param sortFunc {Function(itemA, itemB): boolean} itemA <= itemB | ||
* If true: itemA before itemB. | ||
* If false: itemB before itemA. | ||
* Note: The result is boolean, not a number like `compareFunc` used by `Array.sort()`. | ||
*/ | ||
class SortedCollection extends ArrayColl { | ||
constructor(source, sortFunc) { | ||
super(); | ||
assert(typeof(sortFunc) == "function", "must be a function"); | ||
assert(source instanceof Collection, "must be a Collection"); | ||
this._source = source; | ||
this._sortFunc = sortFunc; | ||
// add initial contents | ||
this.addAll(source.contents.sort((a, b) => sortFunc(a, b) ? -1 : 1)); | ||
source.registerObserver(this); | ||
} | ||
// Implement CollectionObserver | ||
added(items) { | ||
// TODO re-implement by sorting only the new items, | ||
// then call the observer for those only (all at once) | ||
this.removeAll(this._source.contents); | ||
this.addAll(this._source.contents.sort((a, b) => this._sortFunc(a, b) ? -1 : 1)); | ||
} | ||
removed(items) { | ||
this.removeAll(items); | ||
} | ||
} | ||
/** | ||
@@ -1309,7 +1345,7 @@ * Has only those items that are in both coll1 and in coll2. | ||
* @param sortFunc(a {Item}, b {Item}) | ||
* returns {Boolean} a > b // TODO stable sort? {Integer: -1: <, 0: =, 1: >} | ||
* returns {Boolean} a < b // TODO stable sort? {Integer: -1: <, 0: =, 1: >} | ||
* @returns {Collection} | ||
*/ | ||
function sortColl(coll, sortFunc) { | ||
throw new "not yet implemented" | ||
return new SortedCollection(this, sortFunc); | ||
} | ||
@@ -1316,0 +1352,0 @@ |
99322
22
2769
353