Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

observable-slim

Package Overview
Dependencies
Maintainers
1
Versions
16
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

observable-slim - npm Package Compare versions

Comparing version 0.0.8 to 0.0.9

75

observable-slim.js
/*
* Observable Slim
* Version 0.0.8
* Version 0.0.9
* https://github.com/elliotnb/observable-slim

@@ -15,3 +15,3 @@ *

var ObservableSlim = (function() {
paths = [];
// An array that stores all of the observables created through the public create() method below.

@@ -47,4 +47,5 @@ var observables = [];

allows one observable to observe change on any nested/child objects.
originalPath - string, the path of the property in relation to the target on the original observable,
exists for recursion purposes, allows one observable to observe change on any nested/child objects.
originalPath - array of objects, each object having the properties 'target' and 'property' -- target referring to the observed object itself
and property referring to the name of that object in the nested structure. the path of the property in relation to the target
on the original observable, exists for recursion purposes, allows one observable to observe change on any nested/child objects.

@@ -57,4 +58,12 @@ Returns:

var observable = originalObservable || null;
var path = originalPath || "";
// record the nested path taken to access this object -- if there was no path then we provide the first empty entry
var path = originalPath || [{"target":target,"property":""}];
paths.push(path);
// in order to accurately report the "previous value" of the "length" property on an Array
// we must use a helper property because intercepting a length change is not always possible as of 8/13/2018 in
// Chrome -- the new `length` value is already set by the time the `set` handler is invoked
if (target instanceof Array) target.__length = target.length;
var changes = [];

@@ -74,4 +83,26 @@

var _getPath = function(target, property, jsonPointer) {
var fullPath = (path !== "") ? (path + "." + property) : property;
var fullPath = "";
var lastTarget = null;
// loop over each item in the path and append it to full path
for (var i = 0; i < path.length; i++) {
// if the current object was a member of an array, it's possible that the array was at one point
// mutated and would cause the position of the current object in that array to change. we perform an indexOf
// lookup here to determine the current position of that object in the array before we add it to fullPath
if (lastTarget instanceof Array && !isNaN(path[i].property)) {
path[i].property = lastTarget.indexOf(path[i].target);
}
fullPath = fullPath + "." + path[i].property
lastTarget = path[i].target;
}
// add the current property
fullPath = fullPath + "." + property;
// remove the beginning two dots -- ..foo.bar becomes foo.bar (the first item in the nested chain doesn't have a property name)
fullPath = fullPath.substring(2);
if (jsonPointer === true) fullPath = "/" + fullPath.replace(/\./g, "/");

@@ -160,4 +191,6 @@

// have to create a new proxy for it
var newPath = (path !== "") ? (path + "." + property) : property;
// create a shallow copy of the path array -- if we didn't create a shallow copy then all nested objects would share the same path array and the path wouldn't be accurate
var newPath = path.slice(0);
newPath.push({"target":targetProp,"property":property});
return _create(targetProp, domDelay, observable, newPath);

@@ -225,3 +258,8 @@ } else {

set: function(target, property, value, receiver) {
// if the value we're assigning is an object, then we want to ensure
// that we're assigning the original object, not the proxy, in order to avoid mixing
// the actual targets and proxies -- creates issues with path logging if we don't do this
if (value.__isProxy) value = value.__getTarget;
// was this change an original change or was it a change that was re-triggered below

@@ -237,4 +275,10 @@ var originalChange = true;

// only record a change if the new value differs from the old one OR if this proxy was not the original proxy to receive the change
if (targetProp !== value || originalChange === false) {
// Only record this change if:
// 1. the new value differs from the old one
// 2. OR if this proxy was not the original proxy to receive the change
// 3. OR the modified target is an array and the modified property is "length" and our helper property __length indicates that the array length has changed
//
// Regarding #3 above: mutations of arrays via .push or .splice actually modify the .length before the set handler is invoked
// so in order to accurately report the correct previousValue for the .length, we have to use a helper property.
if (targetProp !== value || originalChange === false || (property === "length" && target instanceof Array && target.__length !== value)) {

@@ -260,2 +304,9 @@ var foundObservable = true;

});
// mutations of arrays via .push or .splice actually modify the .length before the set handler is invoked
// so in order to accurately report the correct previousValue for the .length, we have to use a helper property.
if (property === "length" && target instanceof Array && target.__length !== value) {
changes[changes.length-1].previousValue = target.__length;
target.__length = value;
}

@@ -262,0 +313,0 @@ // !!IMPORTANT!! if this proxy was the first proxy to receive the change, then we need to go check and see

2

observable-slim.min.js

@@ -1,1 +0,1 @@

var ObservableSlim=function(){var u=[],d=[],x=[],P=null,f=function(e,l,r,n){var v=r||null,i=n||"",g=[],h=function(e,r,n){var t=""!==i?i+"."+r:r;return!0===n&&(t="/"+t.replace(/\./g,"/")),t},b=function(n){if(!0!==v.paused)if(!0===l)setTimeout(function(){if(n===g.length){var e=g.slice(0);g=[];for(var r=0;r<v.observers.length;r++)v.observers[r](e)}},10);else{var e=g.slice(0);g=[];for(var r=0;r<v.observers.length;r++)v.observers[r](e)}},y=new Proxy(e,{get:function(e,r){if("__getTarget"===r)return e;if("__isProxy"===r)return!0;if("__getParent"===r)return function(e){if(void 0===e)e=1;var r,n=h(0,"__getParent").split(".");return n.splice(-(e+1),e+1),r=v.parentProxy,n.join(".").split(".").reduce(function(e,r){return e?e[r]:void 0},r||self)};var n=e[r];if(!(n instanceof Object&&null!==n&&e.hasOwnProperty(r)))return n;!0===n.__isProxy&&(n=n.__getTarget);for(var t=-1,o=v.targets,a=0,s=o.length;a<s;a++)if(n===o[a]){t=a;break}return-1<t?v.proxies[t]:f(n,l,v,""!==i?i+"."+r:r)},deleteProperty:function(e,r){var n=!0;P===y&&(n=!1,P=null);var t=Object.assign({},e);if(g.push({type:"delete",target:e,property:r,newValue:null,previousValue:t[r],currentPath:h(0,r),jsonPointer:h(0,r,!0),proxy:y}),!0===n){for(var o=0,a=d.length;o<a&&e!==d[o];o++);for(var s=x[o],l=s.length;l--;)s[l].proxy!==y&&(P=s[l].proxy,delete s[l].proxy[r]);v.changesPaused||delete e[r]}return b(g.length),!0},set:function(t,e,r,n){var o=!0;P===y&&(o=!1,P=null);var a=t[e];if(a!==r||!1===o){var s=!0,l=typeof a,i="update";if("undefined"===l&&(i="add"),g.push({type:i,target:t,property:e,newValue:r,previousValue:n[e],currentPath:h(0,e),jsonPointer:h(0,e,!0),proxy:y}),!0===o){for(var u=0,f=d.length;u<f&&t!==d[u];u++);if(s=u<f){var p=x[u],c=0;for(f=p.length;c<f;c++)p[c].proxy!==y&&(P=p[c].proxy,p[c].proxy[e]=r);setTimeout(function(){if("object"===l&&null!==a){for(var e=Object.keys(t),r=0,n=e.length;r<n;r++)if(t[e[r]]===a)return;!function e(r){for(var n=Object.keys(r),t=0,o=n.length;t<o;t++){var a=r[n[t]];a instanceof Object&&null!==a&&e(a)}var s=-1;for(t=0,o=d.length;t<o;t++)if(r===d[t]){s=t;break}if(-1<s){for(var l=x[s],i=l.length;i--;)if(v===l[i].observable){l.splice(i,1);break}0==l.length&&(x.splice(s,1),d.splice(s,1))}}(a)}},1e4)}v.changesPaused||(t[e]=r)}s&&b(g.length)}return!0}});null===v?(v={parentTarget:e,domDelay:l,parentProxy:y,observers:[],targets:[e],proxies:[y],paused:!1,path:i,changesPaused:!1},u.push(v)):(v.targets.push(e),v.proxies.push(y));for(var t={target:e,proxy:y,observable:v},o=-1,a=0,s=d.length;a<s;a++)if(e===d[a]){o=a;break}return-1<o?x[o].push(t):(d.push(e),x.push([t]),o=d.length-1),y};return{create:function(e,r,n){if(!0===e.__isProxy)e=e.__getTarget;var t=f(e,r);return"function"==typeof n&&this.observe(t,n),function e(r){for(var n=r.__getTarget,t=Object.keys(n),o=0,a=t.length;o<a;o++){var s=t[o];n[s]instanceof Object&&null!==n[s]&&e(r[s])}}(t),t},observe:function(e,r){for(var n=u.length;n--;)if(u[n].parentProxy===e){u[n].observers.push(r);break}},pause:function(e){for(var r=u.length,n=!1;r--;)if(u[r].parentProxy===e){n=u[r].paused=!0;break}if(0==n)throw new Error("ObseravableSlim could not pause observable -- matching proxy not found.")},resume:function(e){for(var r=u.length,n=!1;r--;)if(u[r].parentProxy===e){n=!(u[r].paused=!1);break}if(0==n)throw new Error("ObseravableSlim could not resume observable -- matching proxy not found.")},pauseChanges:function(e){for(var r=u.length,n=!1;r--;)if(u[r].parentProxy===e){n=u[r].changesPaused=!0;break}if(0==n)throw new Error("ObseravableSlim could not pause changes on observable -- matching proxy not found.")},resumeChanges:function(e){for(var r=u.length,n=!1;r--;)if(u[r].parentProxy===e){n=!(u[r].changesPaused=!1);break}if(0==n)throw new Error("ObseravableSlim could not resume changes on observable -- matching proxy not found.")},remove:function(e){for(var r=null,n=!1,t=u.length;t--;)if(u[t].parentProxy===e){r=u[t],n=!0;break}for(var o=x.length;o--;)for(var a=x[o].length;a--;)x[o][a].observable===r&&(x[o].splice(a,1),0===x[o].length&&(x.splice(o,1),d.splice(o,1)));!0===n&&u.splice(t,1)}}}();try{module.exports=ObservableSlim}catch(e){}
var ObservableSlim=function(){paths=[];var l=[],d=[],_=[],x=null,f=function(e,i,r,t){var h=r||null,u=t||[{target:e,property:""}];paths.push(u),e instanceof Array&&(e.__length=e.length);var c=[],v=function(e,r,t){for(var n="",a=null,o=0;o<u.length;o++)a instanceof Array&&!isNaN(u[o].property)&&(u[o].property=a.indexOf(u[o].target)),n=n+"."+u[o].property,a=u[o].target;return n=(n=n+"."+r).substring(2),!0===t&&(n="/"+n.replace(/\./g,"/")),n},b=function(t){if(!0!==h.paused)if(!0===i)setTimeout(function(){if(t===c.length){var e=c.slice(0);c=[];for(var r=0;r<h.observers.length;r++)h.observers[r](e)}},10);else{var e=c.slice(0);c=[];for(var r=0;r<h.observers.length;r++)h.observers[r](e)}},y=new Proxy(e,{get:function(e,r){if("__getTarget"===r)return e;if("__isProxy"===r)return!0;if("__getParent"===r)return function(e){if(void 0===e)e=1;var r,t=v(0,"__getParent").split(".");return t.splice(-(e+1),e+1),r=h.parentProxy,t.join(".").split(".").reduce(function(e,r){return e?e[r]:void 0},r||self)};var t=e[r];if(t instanceof Object&&null!==t&&e.hasOwnProperty(r)){!0===t.__isProxy&&(t=t.__getTarget);for(var n=-1,a=h.targets,o=0,s=a.length;o<s;o++)if(t===a[o]){n=o;break}if(-1<n)return h.proxies[n];var l=u.slice(0);return l.push({target:t,property:r}),f(t,i,h,l)}return t},deleteProperty:function(e,r){var t=!0;x===y&&(t=!1,x=null);var n=Object.assign({},e);if(c.push({type:"delete",target:e,property:r,newValue:null,previousValue:n[r],currentPath:v(0,r),jsonPointer:v(0,r,!0),proxy:y}),!0===t){for(var a=0,o=d.length;a<o&&e!==d[a];a++);for(var s=_[a],l=s.length;l--;)s[l].proxy!==y&&(x=s[l].proxy,delete s[l].proxy[r]);h.changesPaused||delete e[r]}return b(c.length),!0},set:function(n,e,r,t){r.__isProxy&&(r=r.__getTarget);var a=!0;x===y&&(a=!1,x=null);var o=n[e];if(o!==r||!1===a||"length"===e&&n instanceof Array&&n.__length!==r){var s=!0,l=typeof o,i="update";if("undefined"===l&&(i="add"),c.push({type:i,target:n,property:e,newValue:r,previousValue:t[e],currentPath:v(0,e),jsonPointer:v(0,e,!0),proxy:y}),"length"===e&&n instanceof Array&&n.__length!==r&&(c[c.length-1].previousValue=n.__length,n.__length=r),!0===a){for(var u=0,f=d.length;u<f&&n!==d[u];u++);if(s=u<f){var p=_[u],g=0;for(f=p.length;g<f;g++)p[g].proxy!==y&&(x=p[g].proxy,p[g].proxy[e]=r);setTimeout(function(){if("object"===l&&null!==o){for(var e=Object.keys(n),r=0,t=e.length;r<t;r++)if(n[e[r]]===o)return;!function e(r){for(var t=Object.keys(r),n=0,a=t.length;n<a;n++){var o=r[t[n]];o instanceof Object&&null!==o&&e(o)}var s=-1;for(n=0,a=d.length;n<a;n++)if(r===d[n]){s=n;break}if(-1<s){for(var l=_[s],i=l.length;i--;)if(h===l[i].observable){l.splice(i,1);break}0==l.length&&(_.splice(s,1),d.splice(s,1))}}(o)}},1e4)}h.changesPaused||(n[e]=r)}s&&b(c.length)}return!0}});null===h?(h={parentTarget:e,domDelay:i,parentProxy:y,observers:[],targets:[e],proxies:[y],paused:!1,path:u,changesPaused:!1},l.push(h)):(h.targets.push(e),h.proxies.push(y));for(var n={target:e,proxy:y,observable:h},a=-1,o=0,s=d.length;o<s;o++)if(e===d[o]){a=o;break}return-1<a?_[a].push(n):(d.push(e),_.push([n]),a=d.length-1),y};return{create:function(e,r,t){if(!0===e.__isProxy)e=e.__getTarget;var n=f(e,r);return"function"==typeof t&&this.observe(n,t),function e(r){for(var t=r.__getTarget,n=Object.keys(t),a=0,o=n.length;a<o;a++){var s=n[a];t[s]instanceof Object&&null!==t[s]&&e(r[s])}}(n),n},observe:function(e,r){for(var t=l.length;t--;)if(l[t].parentProxy===e){l[t].observers.push(r);break}},pause:function(e){for(var r=l.length,t=!1;r--;)if(l[r].parentProxy===e){t=l[r].paused=!0;break}if(0==t)throw new Error("ObseravableSlim could not pause observable -- matching proxy not found.")},resume:function(e){for(var r=l.length,t=!1;r--;)if(l[r].parentProxy===e){t=!(l[r].paused=!1);break}if(0==t)throw new Error("ObseravableSlim could not resume observable -- matching proxy not found.")},pauseChanges:function(e){for(var r=l.length,t=!1;r--;)if(l[r].parentProxy===e){t=l[r].changesPaused=!0;break}if(0==t)throw new Error("ObseravableSlim could not pause changes on observable -- matching proxy not found.")},resumeChanges:function(e){for(var r=l.length,t=!1;r--;)if(l[r].parentProxy===e){t=!(l[r].changesPaused=!1);break}if(0==t)throw new Error("ObseravableSlim could not resume changes on observable -- matching proxy not found.")},remove:function(e){for(var r=null,t=!1,n=l.length;n--;)if(l[n].parentProxy===e){r=l[n],t=!0;break}for(var a=_.length;a--;)for(var o=_[a].length;o--;)_[a][o].observable===r&&(_[a].splice(o,1),0===_[a].length&&(_.splice(a,1),d.splice(a,1)));!0===t&&l.splice(n,1)}}}();try{module.exports=ObservableSlim}catch(e){}
{
"name": "observable-slim",
"description": "Observable Slim is a singleton that utilizes ES6 Proxies to observe changes made to an object and any nested children of that object. It is intended to assist with state management and one-way data binding.",
"version": "0.0.8",
"version": "0.0.9",
"main": "observable-slim.js",

@@ -6,0 +6,0 @@ "devDependencies": {

@@ -6,3 +6,3 @@ [![Build Status](https://travis-ci.org/ElliotNB/observable-slim.svg?branch=master)](https://travis-ci.org/ElliotNB/observable-slim) [![Coverage Status](https://coveralls.io/repos/github/ElliotNB/observable-slim/badge.svg)](https://coveralls.io/github/ElliotNB/observable-slim)

Version 0.0.8
Version 0.0.9

@@ -9,0 +9,0 @@ Licensed under the MIT license:

@@ -160,7 +160,17 @@ var chai = require('chai');

var test = {"arr":[]};
var change = 0;
var p = ObservableSlim.create(test, false, function(changes) {
expect(changes[0].type).to.equal("add");
expect(changes[0].newValue).to.equal("hello world");
expect(changes[0].currentPath).to.equal("arr.0");
expect(changes[0].property).to.equal("0");
if (change === 0) {
expect(changes[0].type).to.equal("add");
expect(changes[0].newValue).to.equal("hello world");
expect(changes[0].currentPath).to.equal("arr.0");
expect(changes[0].property).to.equal("0");
} else if (change === 1) {
expect(changes[0].type).to.equal("update");
expect(changes[0].currentPath).to.equal("arr.length");
expect(changes[0].property).to.equal("length");
expect(changes[0].previousValue).to.equal(0);
expect(changes[0].newValue).to.equal(1);
}
change++;
});

@@ -278,3 +288,3 @@

}
change++
change++;
});

@@ -345,3 +355,48 @@

it('17. Delete a property (not supported with ES5 polyfill).', () => {
it('17. currentPath is updated correctly when the position of an Object in an Array changes.', () => {
var change = 0;
var test = [{},{"foo":"test"}];
var p = ObservableSlim.create(test, false, function(changes) {
// the change events differ slightly when using the ES5 Proxy polyfill, so we skip that part of the validation
// when the proxy is in use
if (global.Proxy === global.NativeProxy) {
if (change === 0) {
expect(changes[0].type).to.equal("update");
expect(changes[0].property).to.equal("0");
expect(changes[0].currentPath).to.equal("0");
} else if (change === 1) {
expect(changes[0].type).to.equal("delete");
expect(changes[0].property).to.equal("1");
expect(changes[0].currentPath).to.equal("1");
} else if (change === 2) {
expect(changes[0].type).to.equal("update");
expect(changes[0].property).to.equal("length");
expect(changes[0].newValue).to.equal(1);
expect(changes[0].previousValue).to.equal(2);
expect(changes[0].currentPath).to.equal("length");
} else if (change === 3) {
expect(changes[0].type).to.equal("update");
expect(changes[0].property).to.equal("foo");
expect(changes[0].newValue).to.equal("bar");
expect(changes[0].previousValue).to.equal("test");
expect(changes[0].currentPath).to.equal("0.foo");
}
}
change++;
});
p.splice(0, 1);
p[0].foo = "bar";
expect(test.length).to.equal(1);
expect(test[0].foo).to.equal("bar");
});
it('18. Delete a property (not supported with ES5 polyfill).', () => {
if (global.Proxy === global.NativeProxy) {

@@ -361,7 +416,7 @@ ObservableSlim.create(test, function(changes) {

it('18. __isProxy check', () => {
it('19. __isProxy check', () => {
expect(p.__isProxy).to.be.equal(true);
});
it('19. __getTarget check', () => {
it('20. __getTarget check', () => {
var isSameObject = false;

@@ -372,3 +427,3 @@ if (p.__getTarget === test) isSameObject = true;

it('20. __getParent on nested object (not supported with ES5 polyfill).', () => {
it('21. __getParent on nested object (not supported with ES5 polyfill).', () => {
if (global.Proxy === global.NativeProxy) {

@@ -383,3 +438,3 @@ p.hello = {};

it('21. Multiple observables on same object.', () => {
it('22. Multiple observables on same object.', () => {
var test = {"dummy":"blah"};

@@ -405,3 +460,3 @@ var firstProxy = false;

it('22. Multiple observables on same object with nested objects.', () => {
it('23. Multiple observables on same object with nested objects.', () => {
var firstProxy = false;

@@ -427,3 +482,3 @@ var secondProxy = false;

it('23. Multiple observables on same object with nested objects by passing in a Proxy to `create`.', () => {
it('24. Multiple observables on same object with nested objects by passing in a Proxy to `create`.', () => {
var firstProxy = false;

@@ -449,3 +504,3 @@ var secondProxy = false;

it('24. Multiple observables on same object and a Proxy nested within another object.', () => {
it('25. Multiple observables on same object and a Proxy nested within another object.', () => {

@@ -475,3 +530,3 @@ var firstObservableTriggered = false;

it.skip('25. Multiple observables on same object and a Proxy nested within another object set after initialization.', () => {
it.skip('26. Multiple observables on same object and a Proxy nested within another object set after initialization.', () => {

@@ -507,3 +562,3 @@ var firstObservableTriggered = 0;

it('26. Create an observable and then remove it.', () => {
it('27. Create an observable and then remove it.', () => {

@@ -528,3 +583,3 @@ var observed = false;

it('27. Pause and resume observables.', () => {
it('28. Pause and resume observables.', () => {

@@ -554,3 +609,3 @@ var changeCount = 0;

it('28. Pause and resume changes on observables', () => {
it('29. Pause and resume changes on observables', () => {

@@ -584,3 +639,3 @@ var changeCount = 0;

// ensures that the garbage clean-up code runs and that the garbage clean-up doesn't throw an error.
it('29. Clean-up observers of overwritten (orphaned) objects.', (done) => {
it('30. Clean-up observers of overwritten (orphaned) objects.', (done) => {

@@ -587,0 +642,0 @@ var data = {"testing":{"test":{"testb":"hello world"},"testc":"hello again"},"blah":{"tree":"world"}};

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc