Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/loilo/computed-properties
A data store with support for computed properties
https://github.com/loilo/computed-properties
Last synced: about 23 hours ago
JSON representation
A data store with support for computed properties
- Host: GitHub
- URL: https://github.com/loilo/computed-properties
- Owner: loilo
- License: mit
- Created: 2018-03-21T22:15:39.000Z (almost 7 years ago)
- Default Branch: master
- Last Pushed: 2019-12-29T23:17:36.000Z (about 5 years ago)
- Last Synced: 2025-01-31T20:44:00.357Z (21 days ago)
- Language: TypeScript
- Size: 118 KB
- Stars: 2
- Watchers: 3
- Forks: 0
- Open Issues: 2
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# Computed Properties
[](https://standardjs.com)
[](https://travis-ci.org/Loilo/computed-properties)
[](https://www.npmjs.com/package/computed-properties)This package helps deriving data from other data. It's especially well suited for computation-heavier dependencies since it caches and lazy-evaluates computed properties.
It conceptually borrows heavily from [Vue.js](https://vuejs.org)' computed properties, supports all evergreen browsers and IE 11 and features a reasonably small size (1.6 KB minified & gzipped).
## Installation
Install it from npm:```bash
npm install --save computed-properties
```### Include in the Browser
You can use this package in your browser with one of the following snippets:* The most common version. Compiled to ES5, runs in all major browsers down to IE 11:
```html
```* If you're really living on the bleeding edge and use ES modules directly in the browser, you can `import` the package as well:
```javascript
import Store from "./node_modules/computed-properties/dist/store.mjs"// or from CDN:
import Store from "https://unpkg.com/computed-properties/dist/store.mjs"
```As opposed to the snippets above, this will not create a global `Store` function.
### Include in Node.js
Include this package in Node.js like you usually do:```javascript
const Store = require('computed-properties')
```## Usage
Create a store by passing a configuration object to the `Store` function:```javascript
const programmer = Store({
firstName: 'Jane',
lastName: 'Doe',
hobbies: [ 'programming', 'reading' ],
skills: {
communication: 3,
cleverness: 4
},
fullName () {
return this.firstName + ' ' + this.lastName
},
bestAt () {
return Object.entries(this.skills).sort(([,ratingA], [,ratingB]) => ratingB - ratingA)[0][0]
},
developerStory () {
return `Hi, I'm ${this.fullName}.
I like ${this.hobbies.slice(0, -1).join(', ')}${this.hobbies.length > 1 ? ' and ' : ''}${this.hobbies[this.hobbies.length - 1]}.
I'm especially good with ${this.bestAt}.`
}
})
```> You can play with this example [on CodePen](https://codepen.io/loilo/pen/xxbrewd?editors=0012).
All functions in the configuration object (`fullName`, `bestAt` and `developerStory` in our case) will be treated as computed properties. You can get their values just like with any regular property:
```javascript
programmer.fullName // "Jane Doe"
```Now if we adjust the first name of our programmer, the `fullName` will also be updated:
```javascript
programmer.firstName = 'John'
programmer.fullName // "John Doe"
```## Context-free Computed Properties
If you don't like the style of computed properties accessing the `this` object, they also get passed the store as their first parameter.The `programmer.fullName` computed property, for example, could also have been written as follows:
```javascript
Store({
// ...fullName: store => store.firstName + ' ' + store.lastName
// or even:
fullName: ({ firstName, lastName }) => firstName + ' ' + lastName
})
```## Watch Properties
You can watch any regular or computed property on the created `programmer` using the `$watch()` method:```javascript
const unwatch = programmer.$watch('fullName', (newValue, oldValue) => {
// This is executed when the `fullName` computed property changes
})// Calling unwatch() will stop watching the `fullName` property
```## Set a new Property in an Object
All properties of an object present at initialization time will be tracked. However, if you want to add a new property, you have to use the `$set()` method:```javascript
programmer.skills.$set('experience', 5)
```## Set an Array Item's Value
While all array methods (e.g. `push()`) are tracked, setting an array's item via bracket access cannot be tracked:```javascript
programmer.hobbies[0] = 'Cycling' // Will not update the `developerStory`
```To trigger dependency changes you'd either have to replace the whole `hobbies` array, or set the respective item via the `$set()` method:
```javascript
programmer.hobbies.$set(0, 'Cycling') // Will update the `developerStory`
```## Functions as Properties
Since all functions in a `Store`'s configuration object are treated as computed properties, there's no way that a regular property can contain a function.```javascript
Store({
// Evaluated as a computed property
someProp: function () {
// ...
}
})
```However, there's a very simple workaround: Create a computed property that returns the desired function.
```javascript
Store({
someProp () {
return function () {
// ...
}
}
})
```## Methods
The `Store` function has no built-in way to attach methods to it, but you can assign them onto the created store:```javascript
// Possibly update last name on marriage
programmer.marry = function (newLastName) {
if (newLastName) {
this.lastName = newLastName
}
}
```