
Security News
TypeScript is Porting Its Compiler to Go for 10x Faster Builds
TypeScript is porting its compiler to Go, delivering 10x faster builds, lower memory usage, and improved editor performance for a smoother developer experience.
object-observer
Advanced tools
object-observer utility provides simple means to (deeply) observe specified object/array changes; implemented via native Proxy; changes delivered in a synchronous way
object-observer
Starting with 6.0.0
this package will be relocated to @gullerya/object-observer
, please follow up there.
object-observer
provides a deep observation of a changes performed on an object/array graph.
Main aspects and features:
Observable
configuration; more details hereobserver
configuration; more details hereObservable
s
Array
mutation methods supported: pop
, push
, shift
, unshift
, reverse
, sort
, fill
, splice
, copyWithin
TypedArray
mutation methods supported: reverse
, sort
, fill
, set
, copyWithin
Map
, WeakMap
, Set
, WeakSet
(set
, delete
) etc are not observed (see this issue for more details)Date
Supported:
71+ |
65+ |
79+ |
12.1 |
12.0.0+
Performance report can be found here.
Changelog is here.
For a preview/playground you are welcome to:
Use regular npm install object-observer --save-prod
to use the library from your local environment.
ES module:
import { Observable } from 'object-observer';
CJS flavor:
const { Observable } = require('object-observer');
Huge thanks to seidelmartin providing the CJS build while greatly improving the build code overall along the way!
CDN (most suggested, when possible):
import { Observable } from 'https://libs.gullerya.com/object-observer/x.y.z/object-observer.min.js';
Replace the
x.y.z
with the desired version, one of the listed in the changelog.
CDN features:
Full details about CDN usage and example are found here.
Library implements Observable
API as it is defined here.
There is also a 'DOM-like' API flavor - constructable ObjectObserver
.
This API is resonating with DOM's MutationObserver
, ResizeObserver
etc from the syntax perspective.
Under the hood it uses the same Observable
mechanics.
Read docs about this API flavor here.
object-observer
is cross-instance operable.
Observables created by different instances of the library will still be detected correctly as such and handled correctly by any of the instances.
Security policy is described here. If/when any concern raised, please follow the process.
const
order = { type: 'book', pid: 102, ammount: 5, remark: 'remove me' },
observableOrder = Observable.from(order);
Observable.observe(observableOrder, changes => {
changes.forEach(change => {
console.log(change);
});
});
observableOrder.ammount = 7;
// { type: 'update', path: ['ammount'], value: 7, oldValue: 5, object: observableOrder }
observableOrder.address = {
street: 'Str 75',
apt: 29
};
// { type: "insert", path: ['address'], value: { ... }, object: observableOrder }
observableOrder.address.apt = 30;
// { type: "update", path: ['address','apt'], value: 30, oldValue: 29, object: observableOrder.address }
delete observableOrder.remark;
// { type: "delete", path: ['remark'], oldValue: 'remove me', object: observableOrder }
Object.assign(observableOrder, { amount: 1, remark: 'less is more' }, { async: true });
// - by default the changes below would be delivered in a separate callback
// - due to async use, they are delivered as a batch in a single callback
// { type: 'update', path: ['ammount'], value: 1, oldValue: 7, object: observableOrder }
// { type: 'insert', path: ['remark'], value: 'less is more', object: observableOrder }
let a = [ 1, 2, 3, 4, 5 ],
observableA = Observable.from(a);
Observable.observe(observableA, changes => {
changes.forEach(change => {
console.log(change);
});
});
// observableA = [ 1, 2, 3, 4, 5 ]
observableA.pop();
// { type: 'delete', path: [4], value: undefined, oldValue: 5, object: observableA }
// now observableA = [ 1, 2, 3, 4 ]
// following operation will cause a single callback to the observer with an array of 2 changes in it)
observableA.push('a', 'b');
// { type: 'insert', path: [4], value: 'a', oldValue: undefined, object: observableA }
// { type: 'insert', path: [5], value: 'b', oldValue: undefined, object: observableA }
// now observableA = [1, 2, 3, 4, 'a', 'b']
observableA.shift();
// { type: 'delete', path: [0] value: undefined, oldValue: 1, object: observableA }
// now observableA = [ 2, 3, 4, 'a', 'b' ]
// following operation will cause a single callback to the observer with an array of 2 changes in it)
observableA.unshift('x', 'y');
// { type: 'insert', path: [0], value: 'x', oldValue: undefined, object: observableA }
// { type: 'insert', path: [1], value: 'y', oldValue: undefined, object: observableA }
// now observableA = [ 2, 3, 4, 'a', 'b' ]
observableA.reverse();
// { type: 'reverse', path: [], object: observableA } (see below and exampe of this event for nested array)
// now observableA = [ 'b', 'a', 4, 3, 2 ]
observableA.sort();
// { type: 'shuffle', path: [], object: observableA } (see below and exampe of this event for nested array)
// observableA = [ 2, 3, 4, 'a', 'b' ]
observableA.fill(0, 0, 1);
// { type: 'update', path: [0], value: 0, oldValue: 2, object: observableA }
// observableA = [ 0, 3, 4, 'a', 'b' ]
// the following operation will cause a single callback to the observer with an array of 2 changes in it)
observableA.splice(0, 1, 'x', 'y');
// { type: 'update', path: [0], value: 'x', oldValue: 0, object: observableA }
// { type: 'insert', path: [1], value: 'y', oldValue: undefined, object: observableA }
let customer = { orders: [ ... ] },
oCustomer = Observable.from(customer);
// sorting the orders array, pay attention to the path in the event
oCustomer.orders.sort();
// { type: 'shuffle', path: ['orders'], object: oCustomer.orders }
oCustomer.orders.reverse();
// { type: 'reverse', path: ['orders'], object: oCustomer.orders }
Arrays notes: Some of array operations are effectively moving/reindexing the whole array (shift, unshift, splice, reverse, sort). In cases of massive changes touching presumably the whole array I took a pessimistic approach with a special non-detailed events: 'reverse' for
reverse
, 'shuffle' forsort
. The rest of these methods I'm handling in an optimistic way delivering the changes that are directly related to the method invocation, while leaving out the implicit outcomes like reindexing of the rest of the Array.
object-observer
allows to filter the events delivered to each callback/listener by an optional configuration object passed to the observe
API.
In the examples below assume that
callback = changes => {...}
.
let user = {
firstName: 'Aya',
lastName: 'Guller',
address: {
city: 'of mountaineers',
street: 'of the top ridges',
block: 123,
extra: {
data: {}
}
}
},
oUser = Observable.from(user);
// path
//
// going to observe ONLY the changes of 'firstName'
Observable.observe(oUser, callback, {path: 'firstName'});
// going to observe ONLY the changes of 'address.city'
Observable.observe(oUser, callback, {path: 'address.city'});
// pathsOf
//
// going to observe the changes of 'address' own properties ('city', 'block') but not else
Observable.observe(oUser, callback, {pathsOf: 'address'});
// here we'll be notified on changes of
// address.city
// address.extra
// pathsFrom
//
// going to observe the changes from 'address' and deeper
Observable.observe(oUser, callback, {pathsFrom: 'address'});
// here we'll be notified on changes of
// address
// address.city
// address.extra
// address.extra.data
FAQs
object-observer utility provides simple means to (deeply) observe specified object/array changes; implemented via native Proxy; changes delivered in a synchronous way
The npm package object-observer receives a total of 166 weekly downloads. As such, object-observer popularity was classified as not popular.
We found that object-observer demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
TypeScript is porting its compiler to Go, delivering 10x faster builds, lower memory usage, and improved editor performance for a smoother developer experience.
Research
Security News
The Socket Research Team has discovered six new malicious npm packages linked to North Korea’s Lazarus Group, designed to steal credentials and deploy backdoors.
Security News
Socket CEO Feross Aboukhadijeh discusses the open web, open source security, and how Socket tackles software supply chain attacks on The Pair Program podcast.