summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--graffiti.js6
-rw-r--r--src/array.js64
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
+ }, {})
+ }
+
+}