package @rimbu/deep
The @rimbu/deep package provides utilities to patch and match plain JavaScript objects.
See the Rimbu docs Deep overview page for more information.
Interfaces
| Name | Description |
|---|---|
WithType<T> | Typed and curried Deep API, used in situations where the target type is known but the value will be applied later. |
Namespaces
| Name | Description |
|---|---|
Deep | undocumented |
Match | The type to determine the allowed input values for the match function. |
Patch | A type to determine the allowed input type for the patch function. |
Path | undocumented |
Selector | Type defining the allowed selectors on an object of type T. Selectors can be: - a path string into type T. - a function receiving a Protected version of type T, and returning an arbitrary value. - a tuple of Selectors for type T - an object where the property values are Selectors for type T. |
Tuple | A readonly array of fixed length and types. |
Functions
getAt
Returns the value resulting from selecting the given path in the given source object. It supports optional chaining for nullable values or values that may be undefined, and also for accessing objects inside an array. There is currently no support for forcing non-null (the ! operator).
getAtpath in the given source object. It supports optional chaining for nullable values or values that may be undefined, and also for accessing objects inside an array. There is currently no support for forcing non-null (the ! operator).Definition
export declare function getAt<T, P extends Path.Get<T>>(source: T, path: P): Path.Result<T, P>;
Type parameters
| Name | Description |
|---|---|
| T | the object type to select in |
| P | a Path in object type T |
Parameters
| Name | Type | Description |
|---|---|---|
source | T | the object to select in |
path | P | the path into the object |
const value = { a: { b: { c: [{ d: 5 }, { d: 6 }] } } }
Deep.getAt(value, 'a.b');
// => { c: 5 }
Deep.getAt(value, 'a.b.c');
// => [{ d: 5 }, { d: 5 }]
Deep.getAt(value, 'a.b.c[1]');
// => { d: 6 }
Deep.getAt(value, 'a.b.c[1]?.d');
// => 6
getAtWith
Returns a function that gets the value at the given string path inside an object.
getAtWithpath inside an object.Definition
export declare function getAtWith<T, P extends Path.Get<T>>(path: P): (source: T) => Path.Result<T, P>;
Type parameters
| Name | Description |
|---|---|
| T | the input value type |
| P | the string literal path type in the object |
Parameters
| Name | Type | Description |
|---|---|---|
path | P | the string path in the object |
const items = [{ a: { b: 1, c: 'a' } }, { a: { b: 2, c: 'b' } }];
items.map(Deep.getAtWith('a.c'));
// => ['a', 'b']
match
Returns true if the given value object matches the given matcher, false otherwise.
matchvalue object matches the given matcher, false otherwise.Definition
export declare function match<T, C extends Partial<T> = Partial<T>>(source: T, matcher: Match<T, C>, failureLog?: Match.FailureLog): boolean;
Type parameters
| Name | Description |
|---|---|
| T | the input value type |
| C | utility type |
Parameters
| Name | Type | Description |
|---|---|---|
source | T | the value to match (should be a plain object) |
matcher | Match<T, C> | a matcher object or a function taking the matcher API and returning a match object |
failureLog | Match.FailureLog | (optional) a string array that can be passed to collect reasons why the match failed |
const input = { a: 1, b: { c: true, d: 'a' } }
match(input, { a: 1 }) // => true
match(input, { a: 2 }) // => false
match(input, { a: (v) => v > 10 }) // => false
match(input, { b: { c: true }}) // => true
match(input, (['every', { a: (v) => v > 0 }, { b: { c: true } }]) // => true
match(input, { b: { c: (v, parent, root) => v && parent.d.length > 0 && root.a > 0 } })
// => true
matchAt
Returns true if the given value object matches the given matcher at the given path, false otherwise.
matchAtvalue object matches the given matcher at the given path, false otherwise.Definition
export declare function matchAt<T, P extends Path.Get<T>>(source: T, path: P, matcher: Match<Path.Result<T, P>>): boolean;
Type parameters
| Name | Description |
|---|---|
| T | the input value type |
| P | the string literal path type in the object |
Parameters
| Name | Type | Description |
|---|---|---|
source | T | the input value |
path | P | the string path in the object |
matcher | Match<Path.Result<T, P>> | a matcher object or a function taking the matcher API and returning a match object |
const input = { a: 1, b: { c: true, d: 'a' } }
Deep.matchAt(input, 'b', { c: true })
// => true
matchAtWith
Returns a function that matches a given value with the given matcher at the given string path.
matchAtWithvalue with the given matcher at the given string path.Definition
export declare function matchAtWith<T, P extends Path.Get<T>, TE extends T = T>(path: P, matcher: Match<Path.Result<T & TE, P>>): (source: T) => boolean;
Type parameters
| Name | Description |
|---|---|
| T | the patch value type |
| P | the string literal path type in the object |
| TE | utility type |
Parameters
| Name | Type | Description |
|---|---|---|
path | P | the string path in the object |
matcher | Match<Path.Result<T & TE, P>> | a matcher object that matches input values. |
const items = [{ a: { b: 1, c: 'a' } }, { a: { b: 2, c: 'b' } }];
items.filter(Deep.matchAtWith('a.b', 2));
// => [{ a: 2, b: 'b' }]
matchWith
Returns a function that matches a given value with the given matcher.
matchWithvalue with the given matcher.Definition
export declare function matchWith<T>(matcher: Match<T>): (source: T) => boolean;
Type parameters
| Name | Description |
|---|---|
| T | the patch value type |
Parameters
| Name | Type | Description |
|---|---|---|
matcher | Match<T> | a matcher object that matches input values. |
const items = [{ a: 1, b: 'a' }, { a: 2, b: 'b' }];
items.filter(Deep.matchWith({ a: 2 }));
// => [{ a: 2, b: 'b' }]
patch
Returns an immutably updated version of the given value where the given patchItems have been applied to the result. The Rimbu patch notation is as follows: - if the target is a simple value or array, the patch can be the same type or a function returning the same type - if the target is a tuple (array of fixed length), the patch be the same type or an object containing numeric keys with patches indicating the tuple index to patch - if the target is an object, the patch can be the same type, or an array containing partial keys with their patches for the object
patchvalue where the given patchItems have been applied to the result. The Rimbu patch notation is as follows: - if the target is a simple value or array, the patch can be the same type or a function returning the same type - if the target is a tuple (array of fixed length), the patch be the same type or an object containing numeric keys with patches indicating the tuple index to patch - if the target is an object, the patch can be the same type, or an array containing partial keys with their patches for the objectDefinition
export declare function patch<T, TE extends T = T, TT = T>(value: T, patchItem: Patch<TE, T & TT>): T;
Type parameters
| Name | Description |
|---|---|
| T | the type of the value to patch |
| TE | a utility type |
| TT | a utility type |
Parameters
| Name | Type | Description |
|---|---|---|
value | T | the input value to patch |
patchItem | Patch<TE, T & TT> | the Patch value to apply to the input value |
const input = { a: 1, b: { c: true, d: 'a' } }
patch(input, [{ a: 2 }]) // => { a: 2, b: { c: true, d: 'a' } }
patch(input, [{ b: [{ c: (v) => !v }] }] )
// => { a: 1, b: { c: false, d: 'a' } }
patch(input: [{ a: (v) => v + 1, b: [{ d: 'q' }] }] )
// => { a: 2, b: { c: true, d: 'q' } }
patchAt
Patches the value at the given path in the source to the given value. Because the path to update must exist in the source object, optional chaining and array indexing is not allowed.
patchAtsource object, optional chaining and array indexing is not allowed.Definition
export declare function patchAt<T, P extends Path.Set<T>, C = Path.Result<T, P>>(source: T, path: P, patchItem: Patch<Path.Result<T, P>, Path.Result<T, P> & C>): T;
Type parameters
| Name | Description |
|---|---|
| T | |
| P | |
| C |
Parameters
| Name | Type | Description |
|---|---|---|
source | T | the object to update |
path | P | the path in the object to update |
patchItem | Patch<Path.Result<T, P>, Path.Result<T, P> & C> | the patch for the value at the given path |
const value = { a: { b: { c: 5 } } };
Deep.patchAt(value, 'a.b.c', v => v + 5);
// => { a: { b: { c: 6 } } }
patchAtWith
Returns a function that patches a given value with the given patchItems at the given path.
patchAtWithvalue with the given patchItems at the given path.Definition
export declare function patchAtWith<T, P extends Path.Set<T>, TE extends T = T, TT = T>(path: P, patchItem: Patch<Path.Result<TE, P>, Path.Result<TT, P>>): (source: T) => T;
Type parameters
| Name | Description |
|---|---|
| T | the patch value type |
| P | the string literal path type in the object |
| TE | utility type |
| TT | utility type |
Parameters
| Name | Type | Description |
|---|---|---|
path | P | the string path in the object |
patchItem | Patch<Path.Result<TE, P>, Path.Result<TT, P>> | the Patch definition to update the value at the given path in T with. |
const items = [{ a: { b: 1, c: 'a' } }, { a: { b: 2, c: 'b' } }];
items.map(Deep.patchAtWith('a', [{ b: (v) => v + 1 }]));
// => [{ a: { b: 2, c: 'a' } }, { a: { b: 3, c: 'b' } }]
patchWith
Returns a function that patches a given source with the given patchItems.
patchWithsource with the given patchItems.Definition
export declare function patchWith<T, TE extends T = T, TT = T>(patchItem: Patch<TT, TE>): (source: TE) => T;
Type parameters
| Name | Description |
|---|---|
| T | the patch value type |
| TE | utility type |
| TT | utility type |
Parameters
| Name | Type | Description |
|---|---|---|
patchItem | Patch<TT, TE> | the Patch definition to update the given value of type T with. |
const items = [{ a: 1, b: 'a' }, { a: 2, b: 'b' }];
items.map(Deep.patchWith([{ a: v => v + 1 }]));
// => [{ a: 2, b: 'a' }, { a: 3, b: 'b' }]
protect
Returns the same value wrapped in the Protected type.
protectProtected type.Definition
export declare function protect<T>(source: T): Protected<T>;
Type parameters
| Name | Description |
|---|---|
| T | the source value type |
Parameters
| Name | Type | Description |
|---|---|---|
source | T | the value to wrap |
does not perform any runtime protection, it is only a utility to easily add the Protected type to a value
const obj = Deep.protect({ a: 1, b: { c: true, d: [1] } })
obj.a = 2 // compiler error: a is readonly
obj.b.c = false // compiler error: c is readonly
obj.b.d.push(2) // compiler error: d is a readonly array
(obj as any).b.d.push(2) // will actually mutate the object
select
Returns the result of applying the given selector shape to the given source value.
selectselector shape to the given source value.Definition
export declare function select<T, SL extends Selector<T>>(source: T, selector: Selector.Shape<SL>): Selector.Result<T, SL>;
Type parameters
| Name | Description |
|---|---|
| T | the patch value type |
| SL | the selector shape type |
Parameters
| Name | Type | Description |
|---|---|---|
source | T | the source value to select from |
selector | Selector.Shape<SL> | a shape indicating the selection from the source values |
const item = { a: { b: 1, c: 'a' } };
Deep.select(item, { q: 'a.c', y: ['a.b', 'a.c'], z: (v) => v.a.b + 1 });
// => { q: 'a', y: [1, 'a'], z: 2 }
selectAt
Returns the result of applying the given selector shape to the given source value.
selectAtselector shape to the given source value.Definition
export declare function selectAt<T, P extends Path.Get<T>, SL extends Selector<Path.Result<T, P>>>(source: T, path: P, selector: Selector.Shape<SL>): Selector.Result<Path.Result<T, P>, SL>;
Type parameters
| Name | Description |
|---|---|
| T | the patch value type |
| P | the string literal path type in the object |
| SL | the selector shape type |
Parameters
| Name | Type | Description |
|---|---|---|
source | T | the source value to select from |
path | P | the string path in the object |
selector | Selector.Shape<SL> | a shape indicating the selection from the source value at the given path |
const item = { a: { b: 1, c: 'a' } };
Deep.selectAt(item, 'a', { q: 'c', z: ['b', v => v.b + 1] as const });
// => { q: 'a', z: [1, 2] }
selectAtWith
Returns a function that selects a certain shape from a given value with the given selector at the given string path.
selectAtWithvalue with the given selector at the given string path.Definition
export declare function selectAtWith<T, P extends Path.Get<T>, SL extends Selector<Path.Result<T, P>>>(path: P, selector: Selector.Shape<SL>): (source: T) => Selector.Result<Path.Result<T, P>, SL>;
Type parameters
| Name | Description |
|---|---|
| T | the patch value type |
| P | the string literal path type in the object |
| SL | the selector shape type |
Parameters
| Name | Type | Description |
|---|---|---|
path | P | the string path in the object |
selector | Selector.Shape<SL> | a shape indicating the selection from the source values |
const items = [{ a: { b: 1, c: 'a' } }, { a: { b: 2, c: 'b' } }];
items.map(Deep.selectAtWith('a', { q: 'c', z: ['b', v => v.b + 1] as const }));
// => [{ q: 'a', z: [1, 2] }, { q: 'b', z: [2, 3] }]
selectWith
Returns a function that selects a certain shape from a given value with the given selector.
selectWithvalue with the given selector.Definition
export declare function selectWith<T, SL extends Selector<T>>(selector: Selector.Shape<SL>): (source: T) => Selector.Result<T, SL>;
Type parameters
| Name | Description |
|---|---|
| T | the patch value type |
| SL | the selector shape type |
Parameters
| Name | Type | Description |
|---|---|---|
selector | Selector.Shape<SL> | a shape indicating the selection from the source values |
const items = [{ a: { b: 1, c: 'a' } }, { a: { b: 2, c: 'b' } }];
items.map(Deep.selectWith({ q: 'a.c', z: ['a.b', v => v.a.b + 1] as const }));
// => [{ q: 'a', z: [1, 2] }, { q: 'b', z: [2, 3] }]
withType
Returns a curried API with a known target type. This can be useful for using the methods in contexts where the target type can be inferred from the usage.
withType