https://github.com/gullerya/resource-pool-js
Resources pooling for JS (generic abstraction, NodeJS worker_threads, Web Workers, etc)
https://github.com/gullerya/resource-pool-js
Last synced: 2 months ago
JSON representation
Resources pooling for JS (generic abstraction, NodeJS worker_threads, Web Workers, etc)
- Host: GitHub
- URL: https://github.com/gullerya/resource-pool-js
- Owner: gullerya
- License: isc
- Created: 2022-05-09T06:25:21.000Z (about 3 years ago)
- Default Branch: main
- Last Pushed: 2022-05-10T05:28:28.000Z (about 3 years ago)
- Last Synced: 2025-02-02T11:43:38.191Z (4 months ago)
- Language: JavaScript
- Size: 63.5 KB
- Stars: 1
- Watchers: 1
- Forks: 0
- Open Issues: 1
-
Metadata Files:
- Readme: readme.md
- Funding: .github/FUNDING.yml
- License: license
- Security: docs/security.md
Awesome Lists containing this project
README
[](https://www.npmjs.com/package/object-observer)
[](https://github.com/gullerya/object-observer)[](https://github.com/gullerya/object-observer/actions?query=workflow%3A%22Quality+pipeline%22)
[](https://codecov.io/gh/gullerya/object-observer/branch/main)
[](https://www.codacy.com/app/gullerya/object-observer)# `resource-pool`
TBD
---
Performance report can be found [here](docs/performance-report.md).
Changelog is [here](docs/changelog.md).
## Preview
For a preview/playground you are welcome to:
- [CodePen](https://codepen.io/gullerya/pen/zYrGMNB) - `Observable.from()` flavor
- [CodePen](https://codepen.io/gullerya/pen/WNRLJWY) - `new ObjectObserver()` flavor## Install
Use regular `npm install object-observer --save-prod` to use the library from your local environment:
```js
import { Observable } from 'node_modules/object-observer/dist/object-observer.min.js';
```Alternatively, a __CDN__ deployment available (AWS driven), so one can import it directly:
```js
import { Observable } from 'https://libs.gullerya.com/object-observer/x.y.z/object-observer.min.js';
```> Note: replace the `x.y.z` with the desired version, one of the listed in the [changelog](docs/changelog.md).
CDN features:
- security:
- __HTTPS__ only
- __intergrity__ checksums for SRI
- performance
- highly __available__ (with many geo spread edges)
- agressive __caching__ setupFull details about CDN usage and example are [found here](docs/cdn.md).
## API
Library implements `Observable` API as it is defined [here](docs/observable.md).
Additionally, from version 4.2.0 there is also '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](docs/dom-like-api.md).Starting from 4.3.x `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
Security policy is described [here](https://github.com/gullerya/object-observer/blob/main/docs/security.md). If/when any concern raised, please follow the process.
## Examples
##### Objects
```javascript
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 }
```##### Arrays
```javascript
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' for `sort`. 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.##### Observation options
`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 => {...}`.
```javascript
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
```