diff options
-rw-r--r-- | graffiti.js | 6 | ||||
-rw-r--r-- | src/array.js | 64 |
2 files changed, 67 insertions, 3 deletions
diff --git a/graffiti.js b/graffiti.js index 8875f8d..ad456b1 100644 --- a/graffiti.js +++ b/graffiti.js @@ -1,5 +1,5 @@ import Auth from './src/auth.js' -//import Collection from './src/collection.js' +import GraffitiArray from './src/array.js' export default class { @@ -240,8 +240,8 @@ export default class { const combinedMaps = Object.assign({}, ...tags.map(tag=> this.tagMap[tag].objectMap)) - // Return just the array - return Object.values(combinedMaps) + // Return an array wrapped with graffiti functions + return new GraffitiArray(this, ...Object.values(combinedMaps)) } async subscribe(...tags) { diff --git a/src/array.js b/src/array.js new file mode 100644 index 0000000..f0c251f --- /dev/null +++ b/src/array.js @@ -0,0 +1,64 @@ +// Extend the array class to expose update +// functionality, plus provide some +// useful helper methods +export default class GraffitiArray extends Array { + + constructor(graffiti, ...elements) { + super(...elements) + this.graffiti = graffiti + } + + get mine() { + return this.filter(o=> o._by==this.graffiti.myID) + } + + get notMine() { + return this.filter(o=> o._by!=this.graffiti.myID) + } + + get authors() { + return [...new Set(this.map(o=> o._by))] + } + + async removeMine() { + await Promise.all( + this.mine.map(async o=> await o._remove())) + } + + #getProperty(obj, propertyPath) { + // Split it up by periods + propertyPath = propertyPath.match(/([^\.]+)/g) + // Traverse down the path tree + for (const property of propertyPath) { + obj = obj[property] + } + return obj + } + + sortBy(propertyPath) { + + const sortOrder = propertyPath[0] == '-'? -1 : 1 + if (sortOrder < 0) propertyPath = propertyPath.substring(1) + + return this.sort((a, b)=> { + const propertyA = this.#getProperty(a, propertyPath) + const propertyB = this.#getProperty(b, propertyPath) + return sortOrder * ( + propertyA < propertyB? -1 : + propertyA > propertyB? 1 : 0 ) + }) + } + + groupBy(propertyPath) { + return this.reduce((chain, obj)=> { + const property = this.#getProperty(obj, propertyPath) + if (property in chain) { + chain[property].push(obj) + } else { + chain[property] = new GraffitiArray(this.graffiti, obj) + } + return chain + }, {}) + } + +} |