From 42e4e0c14d9ca379b1feb96c8e88151c8f8037c2 Mon Sep 17 00:00:00 2001 From: Mat Taylor Date: Fri, 7 Oct 2022 14:01:42 -0700 Subject: [PATCH] truthy traps --- README.md | 54 +++++++++++++++++++++++++++------------------------- objix.js | 2 +- objix.min.js | 2 +- package.json | 2 +- 4 files changed, 31 insertions(+), 29 deletions(-) diff --git a/README.md b/README.md index 6284ffb..1132b21 100644 --- a/README.md +++ b/README.md @@ -52,7 +52,7 @@ console.log({a:1}.map(v => v+1 )) ### Chaining -Most of these function return objects including those modifying this and so can be easily chained together. +Most of these function return objects including those modifying `this` and so can be easily chained together. ```javascript {a: 0, b: 1, c: 2}.clean().map(v => v+1) // {b: 2, c: 3} @@ -86,7 +86,7 @@ let P = { firstName: 'john', lastName: 'doe', fullName () { - return this.firstName + ' ' + this.lastName + return `this`.firstName + ' ' + `this`.lastName } } let p1 = { firstName: 'mat' }.extend(P) @@ -97,7 +97,7 @@ p1.fullName() // 'mat doe' ### Object.prototype.map(function) -Create a clone of this with function applied to each value. +Create a clone of `this` with function applied to each value. Function takes value and key as arguments. ```javascript @@ -117,7 +117,7 @@ Function takes value and key as arguments. ### Object.prototype.values() -Object.values(this) +Object.values(`this`) ```javascript { a: 1 }.values // [1] @@ -125,7 +125,7 @@ Object.values(this) ### Object.prototype.keys() -Object.keys(this) +Object.keys(`this`) ```javascript { a: 1 }.keys // ['a'] @@ -133,7 +133,7 @@ Object.keys(this) ### Object.prototype.entries() -Object.entries(this) +Object.entries(`this`) ```javascript { a: 1 }.entries // [[a, 1]] @@ -141,7 +141,7 @@ Object.entries(this) ### Object.prototype.isArray() -True if this is an array +True if `this` is an array ```javascript [].isArray() // true @@ -150,7 +150,7 @@ True if this is an array ### Object.prototype.isString() -True if this is a string +True if `this` is a string ```javascript ''.isString() // true @@ -189,7 +189,7 @@ Function takes value and key as arguments. ### Object.prototype.assign(...objects) -Assign and overwrite entries from arguments into this and return this. +Assign and overwrite entries from arguments into `this` and return `this`. ```javascript { a: 1, b: 1 }.assign({ b: 2, c: 2 }, {c: 3 }) // { a: 1, b: 2, c: 3 } @@ -197,7 +197,7 @@ Assign and overwrite entries from arguments into this and return this. ### Object.prototype.extend(...objects) -Return a new object with new entries assigned from arguments without overwriting this. +Return a new object with new entries assigned from arguments without overwriting `this`. ```javascript { a: 1, b: 1 }.extend({ b: 2, c: 2 }, {c: 3 }) // { a: 1, b: 1, c: 3 } @@ -213,7 +213,7 @@ Return new object with common entries intersecting with supplied object ### Object.prototype.delete(...keys) -Return this with keys in arguments removed +Return `this` with keys in arguments removed ```javascript { a: 1, b: 2, c: 3 }.delete('a','b') // { c: 3 } @@ -240,7 +240,7 @@ Function takes value and key as arguments. ### Object.prototype.json() -JSON.stringfy(this) +JSON.stringfy(`this`) ```javascript { a: 1 }.json() // '{ "a": 1 }' @@ -248,7 +248,7 @@ JSON.stringfy(this) ### Object.prototype.clone(depth) -Return new object with entries cloned from this. +Return new object with entries cloned from `this`. Nested objects are also cloned to specified depth (-1 = any depth) ```javascript @@ -272,7 +272,7 @@ Return new Object with values concatenated from arguments having the common keys ### Object.prototype.split() -Return Array of new objects for each value in each entry of this with a value array +Return Array of new objects for each value in each entry of `this` with a value array ```javascript { a: [1,2] }.split() // [ { a: 1 }, { a: 2 } ] @@ -280,7 +280,7 @@ Return Array of new objects for each value in each entry of this with a value ar ### Object.prototype.contains(object, depth) -True if all entries of argument are also in this. May recurse to a given depth (-1 = any depth) +True if all entries of argument are also in `this`. May recurse to a given depth (-1 = any depth) ```javascript { a: 1 }.contains({ a: 1, b: 2 }) // false @@ -292,7 +292,7 @@ True if all entries of argument are also in this. May recurse to a given depth ( ### Object.prototype.equals(object, depth) -True if all entries of this equal the argument and argument has no other entries +True if all entries of `this` equal the argument and argument has no other entries May recurse to a given depth (-1 for any depth) ```javascript @@ -305,7 +305,7 @@ May recurse to a given depth (-1 for any depth) ### Object.prototype.size() -Return number of entries of this. +Return number of entries of `this`. ```javascript {}.size() // 0 @@ -314,7 +314,7 @@ Return number of entries of this. ### Object.prototype.keyBy(array, key) -Index an array of objects into this using the given key, and return this. +Index an array of objects into `this` using the given key, and return `this`. ```javascript o = {} @@ -324,19 +324,19 @@ o // { o1: { a: 'o1' }, o2: [ { a: 'o2', b: 1 }, { a: 'o2' } ] ### Object.prototype.bind(key, function) -Binds a function to this object using the given key and applies this as its first argument. Returns this. +Binds a function to `this` object using the given key and applies `this` as its first argument. Returns `this`. ```javascript o = { a: 1, b: 2, c: 3 } o.bind('max', m => m.values().sort((a, b) => b - a)[0]) -// o.max = function() { return this.values().sort((a, b) => b - a)[0]) } +// o.max = function() { return `this`.values().sort((a, b) => b - a)[0]) } o.max() // 3 ``` ### Object.prototype.log(msg, type='log') -Prints a deep clone of this to the console together with a time stamp and an optional msg. -Alternative console methods such as 'trace', 'info', 'error' and 'debug' may also be specified. Returns this. +Prints a deep clone of `this` to the console together with a time stamp and an optional msg. +Alternative console methods such as 'trace', 'info', 'error' and 'debug' may also be specified. Returns `this`. ```javascript let o = { a: 0, b: 1 } @@ -354,15 +354,17 @@ Trace: 2022-10-06T21:21 STACK { b: 2 } ### Object.prototype.trap(function, error) -Returns a proxy of this which traps all property assignments using the supplied function. The function takes `key`, `val` and `this` as arguments. If the function returns false and an error message is supplied then an exception will be thrown. If no error message is provided then the function just acts as an observer. +Returns a proxy of `this` which traps all property assignments using the supplied function. The function takes `key`, `val` and `this` as arguments. If the function returns truthy and an error message is supplied then an exception will be thrown. If no error message is provided the function just acts as an observer, although updates to `this` are still possible. ```javascript -let o = { sum: 1, a: 1 } +let o = { a: 1, sum: 1 } .trap(console.log) - .trap((k, v) => v > 0, 'Values must be positive') + .trap((k, v) => v < 0, 'Values must be positive') .trap((k, v, t) => k != 'sum' && (t.sum += v - (t[k] || 0))) + .trap((k, v) => k == 'sum', 'Sum is read only') -o.b = 2 // b 2 { a: 1 } +o.b = 2 // b 2 { a: 1, sum: 1 } o.c = 0 // Uncaught [ 'Values must be positive', 'c', 0 ] +o.sum = 1 // Uncaught [ 'Sum is read only', 'sum', 1 ] o // { a: 1, b: 2, sum: 3 } ``` diff --git a/objix.js b/objix.js index ea33395..0a45d41 100644 --- a/objix.js +++ b/objix.js @@ -118,7 +118,7 @@ P.log = function(msg='', c='log') { P.trap = function(fn, e) { return new Proxy(this, { set(t,k,v) { - if (!fn(k,v,t) && e) throw([e,k,v]) + if (fn(k,v,t) && e) throw([e,k,v]) return t[k] = v } }) diff --git a/objix.min.js b/objix.min.js index bbc9739..d62962e 100644 --- a/objix.min.js +++ b/objix.min.js @@ -1 +1 @@ -const P=Object.prototype,F=Object.fromEntries,K=Object.keys,A=Object.assign;for(let t of["keys","values","entries"])P[t]=function(){return Object[t](this)};P.every=function(t){for(let n of K(this))if(!t(this[n],n))return!1;return!0},P.some=function(t){for(let n of K(this))if(t(this[n],n))return!0;return!1},P.map=function(t){let n={};for(let i of K(this))n[i]=t(this[i],i);return n},P.filter=function(t){return F(K(this).flatMap((n=>t(this[n],n)?[[n,this[n]]]:[])))},P.flatMap=function(t){return F(K(this).flatMap((n=>t(n,this[n]))))},P.clean=function(){return F(K(this).flatMap((t=>this[t]?[[t,this[t]]]:[])))},P.isArray=function(){return this instanceof Array},P.isString=function(){return"string"==typeof this},P.find=P.find=function(t){for(let n of K(this))if(t(this[n],n))return n},P.assign=function(...t){return A(this,...t)},P.extend=function(...t){return A({},...t,this)},P.delete=function(...t){for(let n of t)delete this[n];return this},P.json=function(t){return JSON.stringify(this)},P.clone=function(t){let n={};return K(this).map((i=>n[i]=t&&t.size()?this[i].clone(t-1):this[i])),n},P.join=function(...t){let n=A({},this);for(let i of t)K(i).map((t=>n[t]&&=[].concat(n[t],i[t])));return n},P.split=function(){let t=[];for(let n of K(this))this[n].map(((i,e)=>t[e]?t[e][n]=i:t[e]={[n]:i}));return t},P.common=function(t){return F(K(this).flatMap((n=>t[n]==this[n]?[[n,this[n]]]:[])))},P.contains=function(t,n){for(let i of K(t))if(!(this[i]==t[i]||n&&this.some((i=>i.contains(t,n-1)))))return!1;return!0},P.equals=function(t,n){return!(this.size()==t.size()&&this.some(((i,e)=>i!=t[e]&&!(n&&i.equals(t[e],n-1)))))},P.size=function(){return K(this).length},P.keyBy=function(t,n){return t.map((t=>this[t[n]]=this[t[n]]?[t].concat(this[t[n]]):t)),this},P.bind=function(t,n){return this[t]=function(...t){return n(this,...t)},this},P.log=function(t="",n="log"){return console[n]((new Date).toISOString().slice(0,-8),t,this.clone(-1)),this},P.trap=function(t,n){return new Proxy(this,{set(i,e,r){if(!t(e,r,i)&&n)throw[n,e,r];return i[e]=r}})};for(let t of K(P)){"_"!=t[0]&&(P["_"+t]=P[t]);try{module.exports[t]=(n,...i)=>n["_"+t](...i)}catch{}} \ No newline at end of file +const P=Object.prototype,F=Object.fromEntries,K=Object.keys,A=Object.assign;for(let t of["keys","values","entries"])P[t]=function(){return Object[t](this)};P.every=function(t){for(let n of K(this))if(!t(this[n],n))return!1;return!0},P.some=function(t){for(let n of K(this))if(t(this[n],n))return!0;return!1},P.map=function(t){let n={};for(let i of K(this))n[i]=t(this[i],i);return n},P.filter=function(t){return F(K(this).flatMap((n=>t(this[n],n)?[[n,this[n]]]:[])))},P.flatMap=function(t){return F(K(this).flatMap((n=>t(n,this[n]))))},P.clean=function(){return F(K(this).flatMap((t=>this[t]?[[t,this[t]]]:[])))},P.isArray=function(){return this instanceof Array},P.isString=function(){return"string"==typeof this},P.find=P.find=function(t){for(let n of K(this))if(t(this[n],n))return n},P.assign=function(...t){return A(this,...t)},P.extend=function(...t){return A({},...t,this)},P.delete=function(...t){for(let n of t)delete this[n];return this},P.json=function(t){return JSON.stringify(this)},P.clone=function(t){let n={};return K(this).map((i=>n[i]=t&&t.size()?this[i].clone(t-1):this[i])),n},P.join=function(...t){let n=A({},this);for(let i of t)K(i).map((t=>n[t]&&=[].concat(n[t],i[t])));return n},P.split=function(){let t=[];for(let n of K(this))this[n].map(((i,e)=>t[e]?t[e][n]=i:t[e]={[n]:i}));return t},P.common=function(t){return F(K(this).flatMap((n=>t[n]==this[n]?[[n,this[n]]]:[])))},P.contains=function(t,n){for(let i of K(t))if(!(this[i]==t[i]||n&&this.some((i=>i.contains(t,n-1)))))return!1;return!0},P.equals=function(t,n){return!(this.size()==t.size()&&this.some(((i,e)=>i!=t[e]&&!(n&&i.equals(t[e],n-1)))))},P.size=function(){return K(this).length},P.keyBy=function(t,n){return t.map((t=>this[t[n]]=this[t[n]]?[t].concat(this[t[n]]):t)),this},P.bind=function(t,n){return this[t]=function(...t){return n(this,...t)},this},P.log=function(t="",n="log"){return console[n]((new Date).toISOString().slice(0,-8),t,this.clone(-1)),this},P.trap=function(t,n){return new Proxy(this,{set(i,e,r){if(t(e,r,i)&&n)throw[n,e,r];return i[e]=r}})};for(let t of K(P)){"_"!=t[0]&&(P["_"+t]=P[t]);try{module.exports[t]=(n,...i)=>n["_"+t](...i)}catch{}} \ No newline at end of file diff --git a/package.json b/package.json index 9a15da2..5f46f71 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "objix", - "version": "1.3.0", + "version": "1.3.1", "description": "A dangerously convienient, high performance and low overhead (2kb) utility that injects methods into the Object prototype to sugar for many common use cases working with Javascript objects.", "main": "objix.js", "scripts": {