Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/b-gran/immutable-record
Typed immutable Records inspired by ImmutableJS
https://github.com/b-gran/immutable-record
immutable immutable-record immutablejs record typed
Last synced: 8 days ago
JSON representation
Typed immutable Records inspired by ImmutableJS
- Host: GitHub
- URL: https://github.com/b-gran/immutable-record
- Owner: b-gran
- Created: 2016-11-24T20:18:14.000Z (almost 8 years ago)
- Default Branch: master
- Last Pushed: 2018-04-05T18:49:48.000Z (over 6 years ago)
- Last Synced: 2024-04-29T13:20:33.520Z (7 months ago)
- Topics: immutable, immutable-record, immutablejs, record, typed
- Language: JavaScript
- Homepage: https://b-gran.github.io/immutable-record/
- Size: 59.6 KB
- Stars: 3
- Watchers: 3
- Forks: 1
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
## `immutable-record` -- typed & immutable Javascript objects
[![Build Status](https://travis-ci.org/b-gran/immutable-record.svg?branch=master)](https://travis-ci.org/b-gran/immutable-record) [![npm version](https://badge.fury.io/js/immutable-record.svg)](https://badge.fury.io/js/immutable-record)
`immutable-record` is a small JavaScript library inspired by Facebook's ImmutableJS
that allows you to create immutable `Records`.
`Records` behave very much like Objects (even `Object.keys()`), but they are
typed and immutable.### What does it look like?
```
// ImmutableRecord() returns a Record class
import ImmutableRecord from 'immutable-record'
const Record = ImmutableRecord({
foo: { default: 5 },
optional: { type: 'number' }
someField: {
type: value => 'foo' in value,
required: true
},
})// You just pass ordinary objects to the Record constructor
const object = new Record({
someField: { foo: 'bar' }
// You don't have to provide optional fields
})// Object.keys() works as if the Record was a normal Object
Object.keys(object) // [ 'foo', 'someField' ]// Records are immutable, so Record#set() returns a new Record
const another = object.set('optional', 8)
another.optional // 8// Validation happens automatically
object.remove('someField')
// Error: "someField" is missing from the record {"foo":5}```
### Why pick `immutable-record` ?
Compared to ImmutableJS, the key feature is __automatic validation.__ With
`immutable-record`, you can specify a type of each field and it will be
automatically checked. Additionally:* `Object.keys()` works just how you would expect
* You can mark fields as `required`
* You can create optional fields that may not be present on a record, but will
validate when set.## Documentation
### Installing
```
# immutable-record is available on npm
npm install --save immutable-record
```### Importing
```
import ImmutableRecord from 'immutable-record'// If you're not using ES6 modules
const ImmutableRecord = require('immutable-record')
```### Creating Records
The ImmutableRecord() function takes an object whose values describe the
validation that is applied to the fields.```
const Record = ImmutableRecord({
optional: { type: 'string' },
required: { required: true },
validation: {
type: value => value > 5,
default: 6
})
```You can also pass a second parameter to the ImmutableRecord() function
which specifies a custom name for the Record class.```
const Foo = ImmutableRecord({
foo: { type: 'string' }
}, 'Foo')
Foo.name === 'Foo' // true
console.log(Foo) // [Function: Foo]
```There are three validation options available for each field:
> > `type`, `required`, and `default`#### The `type` option
1. A primitive string (AKA one of the values returned by typeof). The possible
values at the time of writing are:
> > 'object', 'string', 'number', 'symbol', 'boolean',
function', 'undefined'2. A validation function that takes a single argument (the field's value) and
returns a boolean.```
const Record = ImmutableRecord({
// Strings (typeof x === 'string') are valid
string: { type: 'string' },// Arrays of length 4 or greater are valid
array: {
type: value => (
Array.isArray(value) &&
value.length > 3
)
}
})
```#### The `default` option
If a field has a default and a Record is created without the field explicitly set,
the default value is used automatically.```
const Record = ImmutableRecord({
withDefault: { default: 5 }
})// The default is automatically used if the field isn't set
const object = new Record({})
object.withDefault // 5// undefined is a legal field value, so the default won't be used
const noDefault = new Record({
withDefault: undefined
})
noDefault.withDefault // undefined
```#### The `required` option
Fields marked as "required" must be present on the Record for it to validate.
```
const Record = ImmutableRecord({
required: { required: true },
optional: { required: false }
})// No problems here
const object = new Record({
required: 1
})
'optional' in object // false// This doesn't work
const bad = new Record({
optional: 1
})
// Error: "required" is missing from the record {"optional":1}
```If a field is required and it also has a default, the Record will still validate
even if the field isn't set.```
const Record = ImmutableRecord({
field: {
required: true,
default: 5
}
})// No problems here
const object = new Record({})
object.field // 5
```#### Fields with no options
You can also leave the options out to get optional, untyped fields.
```
const Record = ImmutableRecord({
optionalUntyped: {},// setting the field equal to null works too
alsoWorks: null
})
```### Using Records
Records mostly work just like normal Objects, except they're immutable.
```
const ABCRecord = ImmutableRecord({
a: {}, b: {}, c: {}
})const object = new ABCRecord({ a: 1, c: 3 })
object.a // 1
object.c // 3
object.b // undefined
'b' in object // false// Object.keys() also works how you would expect
Object.keys(object) // [ 'a', 'c' ]
```When you try to set or delete a Record's value directly, the Record will throw.
```
const object = new ABCRecord({ a: 1, c: 3 })object.b = 2
// Error: Use the "set" function to update the values of an ImmutableRecord.delete object.a
// TypeError: Cannot delete property 'a' of [object Object]
```#### `Record#set()`
Use the `set()` function to update Record values. `set()` returns a new Record instance.
```
const object = new ABCRecord({ a: 1, c: 3 })const withB = object.set('b', 2)
withB instanceof ABCRecord // true
withB.b // 2// The original record is unmodified
object.b // undefined
```#### `Record#remove()`
Use the `remove()` function to remove Record values. `remove()` returns a new Record instance.
```
const object = new ABCRecord({ a: 1, b: 2, c: 3 })const withoutB = object.remove('b')
withoutB instanceof ABCRecord // true
withoutB.b // undefined
```#### A point about validation
Records are validated when they are constructed, so all of your fields will be validated
when you use `set()` and `remove()`.