space-lift
Advanced tools
Comparing version 1.0.0-beta.11 to 1.0.0-beta.12
@@ -37,3 +37,3 @@ import { ObjectWrapper } from './object'; | ||
/** | ||
* Maps this map's value. | ||
* Maps this map's values. | ||
*/ | ||
@@ -40,0 +40,0 @@ mapValues<VV>(mapFunction: (value: V) => VV): MapWrapper<K, VV, MapOf<M, K, VV>>; |
@@ -59,3 +59,3 @@ "use strict"; | ||
/** | ||
* Maps this map's value. | ||
* Maps this map's values. | ||
*/ | ||
@@ -62,0 +62,0 @@ mapValues(mapFunction) { |
@@ -27,2 +27,6 @@ import { ArrayWrapper } from './array'; | ||
keys(): ArrayWrapper<Array<keyof T>>; | ||
/** | ||
* Maps this Object's values. | ||
*/ | ||
mapValues<V>(mapFunction: (value: T[keyof T]) => V): ObjectWrapper<Record<keyof T, V>>; | ||
pipe: typeof import("./lift").pipe; | ||
@@ -44,2 +48,7 @@ /** | ||
/** | ||
* Converts this Object to an Array of tuples. | ||
* Similar to Object.entries() but retains the type of keys. | ||
*/ | ||
toArray(): ArrayWrapper<[KeyAsString<keyof T>, T[keyof T]][]>; | ||
/** | ||
* Transforms this Object to a Map where the keys are the string typed keys of this Object. | ||
@@ -46,0 +55,0 @@ */ |
@@ -42,2 +42,11 @@ "use strict"; | ||
/** | ||
* Maps this Object's values. | ||
*/ | ||
mapValues(mapFunction) { | ||
return this.toArray().fold({}, (result, [key, value]) => { | ||
result[key] = mapFunction(value); | ||
return result; | ||
}); | ||
} | ||
/** | ||
* Removes a key/value from this object and return a new object (and type) | ||
@@ -65,2 +74,9 @@ * To delete a (nullable) key from an object while preserving its type, use "update()" instead. | ||
/** | ||
* Converts this Object to an Array of tuples. | ||
* Similar to Object.entries() but retains the type of keys. | ||
*/ | ||
toArray() { | ||
return this.pipe(Object.entries); | ||
} | ||
/** | ||
* Transforms this Object to a Map where the keys are the string typed keys of this Object. | ||
@@ -67,0 +83,0 @@ */ |
@@ -37,3 +37,3 @@ import { ObjectWrapper } from './object'; | ||
/** | ||
* Maps this map's value. | ||
* Maps this map's values. | ||
*/ | ||
@@ -40,0 +40,0 @@ mapValues<VV>(mapFunction: (value: V) => VV): MapWrapper<K, VV, MapOf<M, K, VV>>; |
@@ -56,3 +56,3 @@ import { update } from './immupdate'; | ||
/** | ||
* Maps this map's value. | ||
* Maps this map's values. | ||
*/ | ||
@@ -59,0 +59,0 @@ mapValues(mapFunction) { |
@@ -27,2 +27,6 @@ import { ArrayWrapper } from './array'; | ||
keys(): ArrayWrapper<Array<keyof T>>; | ||
/** | ||
* Maps this Object's values. | ||
*/ | ||
mapValues<V>(mapFunction: (value: T[keyof T]) => V): ObjectWrapper<Record<keyof T, V>>; | ||
pipe: typeof import("./lift").pipe; | ||
@@ -44,2 +48,7 @@ /** | ||
/** | ||
* Converts this Object to an Array of tuples. | ||
* Similar to Object.entries() but retains the type of keys. | ||
*/ | ||
toArray(): ArrayWrapper<[KeyAsString<keyof T>, T[keyof T]][]>; | ||
/** | ||
* Transforms this Object to a Map where the keys are the string typed keys of this Object. | ||
@@ -46,0 +55,0 @@ */ |
@@ -39,2 +39,11 @@ import { clone, update } from './immupdate'; | ||
/** | ||
* Maps this Object's values. | ||
*/ | ||
mapValues(mapFunction) { | ||
return this.toArray().fold({}, (result, [key, value]) => { | ||
result[key] = mapFunction(value); | ||
return result; | ||
}); | ||
} | ||
/** | ||
* Removes a key/value from this object and return a new object (and type) | ||
@@ -62,2 +71,9 @@ * To delete a (nullable) key from an object while preserving its type, use "update()" instead. | ||
/** | ||
* Converts this Object to an Array of tuples. | ||
* Similar to Object.entries() but retains the type of keys. | ||
*/ | ||
toArray() { | ||
return this.pipe(Object.entries); | ||
} | ||
/** | ||
* Transforms this Object to a Map where the keys are the string typed keys of this Object. | ||
@@ -64,0 +80,0 @@ */ |
{ | ||
"name": "space-lift", | ||
"version": "1.0.0-beta.11", | ||
"version": "1.0.0-beta.12", | ||
"description": "Idiomatic TypeScript Array, Object, Map, Set, Union, Enum utils", | ||
@@ -5,0 +5,0 @@ "sideEffects": true, |
119
README.md
@@ -64,3 +64,3 @@ **space-lift** | ||
- `Result`, `Ok`, `Err` are used to work with computation that may fail | ||
- `Immutable` a type that will recursively make a tree `Readonly`. | ||
- `Immutable` a helper type that will recursively make a tree `Readonly`. | ||
@@ -429,4 +429,16 @@ | ||
Make mutable modifications to a draft Array then return a new Array. | ||
See [update](#api.update) | ||
See [update for Array](#update-for-array) | ||
The method is also accessible on Array wrappers for convenience: | ||
```ts | ||
import {lift} from 'space-lift' | ||
const array = [{a: 1}, {a: 2}] | ||
const updated = lift(array).update(draft => { | ||
draft[0].a = 10 | ||
}).value() | ||
``` | ||
<a name="array.updateAt"></a> | ||
@@ -476,16 +488,113 @@ ### Array.updateAt | ||
`update` is your go-to function to perfor immutable updates on your `Objects`, `Array`, `Map` and `Set`, using a mutable API. If you know, [immerjs](https://immerjs.github.io/immer/docs/introduction), it's very similar but with different design constraints in mind: | ||
`update` is your go-to function to perform immutable updates on your `Objects`, `Array`, `Map` and `Set`, using a mutable API. If you know [immerjs](https://immerjs.github.io/immer/docs/introduction), it's very similar (great idea!) but with different design constraints in mind: | ||
- Tiny implementation (`space-lift` has a whole is way smaller than `immerjs`) | ||
- Tiny implementation (The entirety of `space-lift` is way smaller than `immerjs`) | ||
- The `Array` draft has special methods to update it as the traditional mutable Array API in JavaScript is awful. | ||
- Instead of creating tons of costly `Proxies`, they are created only when needed. | ||
- Instead of eagerly creating tons of costly `Proxies` (also called `drafts`), they are created only when strictly needed (look for: **will create a draft** in the documentation below). | ||
- `drafts` are only created for values of type `Object`, `Array`, `Map` or `Set`. | ||
- `update` should never have a returned value and will prevent it at the type level. | ||
- Remember that if you iterate through keys, values, etc drafts will **NOT** be created by default. Call one of the draft creating methods within the loop to perform the updates conditionally. | ||
- As long as you keep accessing drafts, the update can be done at any level of a tree. | ||
### update for Object | ||
Accessing a draft object property is the only `Object` operation that **will create a draft** | ||
#### Adding/updating an Object property | ||
```ts | ||
import {update} from 'space-lift' | ||
const obj: { a: 1; b?: number } = { a: 1 } | ||
const updated = update(obj, draft => { | ||
draft.b = 20 | ||
}) | ||
``` | ||
#### Deleting an Object property | ||
```ts | ||
import {update} from 'space-lift' | ||
const obj: { a: 1; b?: number } = { a: 1, b: 20 } | ||
const updated = update(obj, draft => { | ||
delete draft.b | ||
}) | ||
``` | ||
### update for Map | ||
All regular methods are available. | ||
`get` is the only `Map` draft method that **will create a draft** for the returned value. | ||
#### Map - Updating an existing value | ||
```ts | ||
import {update} from 'space-lift' | ||
const map = new Map([ | ||
[1, { id: 1, name: 'jon' }], | ||
[2, { id: 2, name: 'Julia' }] | ||
]) | ||
const updated = update(map, draft => { | ||
const value = draft.get(2) | ||
if (value) return | ||
value.name = 'Bob' | ||
}) | ||
``` | ||
### update for Set | ||
All regular `Set` methods are available. | ||
None of the `Set` draft methods **will create a draft** as a `Set` never hands value over. | ||
Still, it's useful to update an immutable `Set` whether it's found nested in a tree or not and Sets are most of the time only useful for primitives values that wouldn't be drafted. | ||
### update for Array | ||
Most Array methods are available but some are removed to make working with Arrays more pleasant: | ||
- `splice`: Replaced by `insert`, `removeIf`. | ||
- `unshift`: Replaced by `preprend`. | ||
- `shift`: Replaced by `removeIf`. | ||
- `pop`: Replaced by `removeIf`. | ||
- `push`: Replaced by `append`. | ||
- `map` is not removed but `updateIf` is added as the conceptual, mutable equivalent. | ||
As a result, the interface of a draft Array is not fully compatible with `Array`/`ReadonlyArray` and you must use `toDraft` if you want to assign a regular Array to a draft Array: | ||
```ts | ||
import {update, toDraft} from 'space-lift' | ||
const updated = update({arr: [1, 2, 3]}, draft => { | ||
draft.arr = toDraft([4, 5, 6]) | ||
}) | ||
``` | ||
- Accessing an Array element by index **will create a draft** (be careful with this if you somehow end up manually iterating the Array) | ||
- `updateIf` **will create a draft** for each item satisfying its predicate. | ||
#### Array - using updateIf | ||
```ts | ||
import {update} from 'space-lift' | ||
const arr = [ | ||
{ id: 1, name: 'Jon' }, | ||
{ id: 3, name: 'Julia' } | ||
] | ||
const updated = update(arr, draft => { | ||
draft.updateIf( | ||
(item, index) => item.id === 3, | ||
item => { | ||
item.name = 'Bob' | ||
} | ||
) | ||
}) | ||
``` | ||
<a name="api.enum"></a> | ||
@@ -492,0 +601,0 @@ ## createEnum |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
113946
2578
693