@rimbu/deep 0.9.2 → 0.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/main/index.js +12 -3
- package/dist/main/index.js.map +1 -1
- package/dist/main/internal.js +2 -4
- package/dist/main/internal.js.map +1 -1
- package/dist/main/match.js +197 -132
- package/dist/main/match.js.map +1 -1
- package/dist/main/patch.js +125 -106
- package/dist/main/patch.js.map +1 -1
- package/dist/main/path.js +12 -38
- package/dist/main/path.js.map +1 -1
- package/dist/main/protected.js +12 -0
- package/dist/main/protected.js.map +1 -0
- package/dist/module/index.js +3 -2
- package/dist/module/index.js.map +1 -1
- package/dist/module/internal.js +2 -4
- package/dist/module/internal.js.map +1 -1
- package/dist/module/match.js +180 -97
- package/dist/module/match.js.map +1 -1
- package/dist/module/patch.js +113 -87
- package/dist/module/patch.js.map +1 -1
- package/dist/module/path.js +12 -34
- package/dist/module/path.js.map +1 -1
- package/dist/module/protected.js +8 -0
- package/dist/module/protected.js.map +1 -0
- package/dist/types/index.d.ts +3 -2
- package/dist/types/internal.d.ts +2 -4
- package/dist/types/match.d.ts +93 -80
- package/dist/types/patch.d.ts +64 -61
- package/dist/types/path.d.ts +9 -20
- package/dist/types/protected.d.ts +13 -0
- package/package.json +4 -4
- package/src/index.ts +12 -2
- package/src/internal.ts +3 -4
- package/src/match.ts +254 -163
- package/src/patch.ts +204 -147
- package/src/path.ts +18 -43
- package/src/protected.ts +25 -0
- package/dist/main/immutable.js +0 -12
- package/dist/main/immutable.js.map +0 -1
- package/dist/main/literal.js +0 -41
- package/dist/main/literal.js.map +0 -1
- package/dist/module/immutable.js +0 -8
- package/dist/module/immutable.js.map +0 -1
- package/dist/module/literal.js +0 -37
- package/dist/module/literal.js.map +0 -1
- package/dist/types/immutable.d.ts +0 -13
- package/dist/types/literal.d.ts +0 -48
- package/src/immutable.ts +0 -21
- package/src/literal.ts +0 -70
package/dist/module/path.js
CHANGED
|
@@ -9,13 +9,13 @@ export var Path;
|
|
|
9
9
|
* @param path - the path into the object
|
|
10
10
|
* @example
|
|
11
11
|
* ```ts
|
|
12
|
-
* console.log(Path.
|
|
12
|
+
* console.log(Path.get({ a: { b: { c: 5 } } }), 'a.b')
|
|
13
13
|
* // => { c: 5 }
|
|
14
|
-
* console.log(Path.
|
|
14
|
+
* console.log(Path.get({ a: { b: { c: 5 } } }), 'a.b.c')
|
|
15
15
|
* // => 5
|
|
16
16
|
* ```
|
|
17
17
|
*/
|
|
18
|
-
function
|
|
18
|
+
function get(source, path) {
|
|
19
19
|
const items = path.split('.');
|
|
20
20
|
let result = source;
|
|
21
21
|
for (const item of items) {
|
|
@@ -23,7 +23,7 @@ export var Path;
|
|
|
23
23
|
}
|
|
24
24
|
return result;
|
|
25
25
|
}
|
|
26
|
-
Path.
|
|
26
|
+
Path.get = get;
|
|
27
27
|
/**
|
|
28
28
|
* Sets the value at the given path in the source to the given value.
|
|
29
29
|
* @param source - the object to update
|
|
@@ -31,44 +31,22 @@ export var Path;
|
|
|
31
31
|
* @param value - the new value to set at the given position
|
|
32
32
|
* @example
|
|
33
33
|
* ```ts
|
|
34
|
-
* console.log(Path.
|
|
34
|
+
* console.log(Path.update({ a: { b: { c: 5 } } }, 'a.b.c', v => v + 5)
|
|
35
|
+
* // => { a: { b: { c: 6 } } }
|
|
35
36
|
* ```
|
|
36
37
|
*/
|
|
37
|
-
function
|
|
38
|
+
function update(source, path, value) {
|
|
38
39
|
const items = path.split('.');
|
|
39
40
|
const last = items.pop();
|
|
40
|
-
const
|
|
41
|
-
let current =
|
|
41
|
+
const root = {};
|
|
42
|
+
let current = root;
|
|
42
43
|
for (const item of items) {
|
|
43
|
-
current[item] =
|
|
44
|
+
current[item] = {};
|
|
44
45
|
current = current[item];
|
|
45
46
|
}
|
|
46
|
-
const oldValue = current[last];
|
|
47
|
-
if (Object.is(oldValue, value))
|
|
48
|
-
return source;
|
|
49
47
|
current[last] = value;
|
|
50
|
-
return
|
|
51
|
-
}
|
|
52
|
-
Path.setValue = setValue;
|
|
53
|
-
/**
|
|
54
|
-
* Patches the value at the given path in the source to the given value using the given
|
|
55
|
-
* `patches`.
|
|
56
|
-
* @param source - the object to update
|
|
57
|
-
* @param path - the path in the object to update
|
|
58
|
-
* @param patches - one or more patches to update the value at the given path
|
|
59
|
-
* @example
|
|
60
|
-
* ```ts
|
|
61
|
-
* console.log(Path.setValue({ a: { b: { c: 5 } } }, 'a.b.c', 8)
|
|
62
|
-
* // => { a: { b: { c: 8 } } }
|
|
63
|
-
* ```
|
|
64
|
-
*/
|
|
65
|
-
function patchValue(source, path, ...patches) {
|
|
66
|
-
const value = Path.getValue(source, path);
|
|
67
|
-
const newValue = patch(value)(...patches);
|
|
68
|
-
if (Object.is(value, newValue))
|
|
69
|
-
return source;
|
|
70
|
-
return Path.setValue(source, path, newValue);
|
|
48
|
+
return patch(source, root);
|
|
71
49
|
}
|
|
72
|
-
Path.
|
|
50
|
+
Path.update = update;
|
|
73
51
|
})(Path || (Path = {}));
|
|
74
52
|
//# sourceMappingURL=path.js.map
|
package/dist/module/path.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"path.js","sourceRoot":"","sources":["../../src/path.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"path.js","sourceRoot":"","sources":["../../src/path.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAcnC,MAAM,KAAW,IAAI,CAqFpB;AArFD,WAAiB,IAAI;IAwBnB;;;;;;;;;;;;;OAaG;IACH,SAAgB,GAAG,CACjB,MAAuB,EACvB,IAAO;QAEP,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QAE9B,IAAI,MAAM,GAAQ,MAAM,CAAC;QAEzB,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE;YACxB,MAAM,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC;SACvB;QAED,OAAO,MAAM,CAAC;IAChB,CAAC;IAbe,QAAG,MAalB,CAAA;IAED;;;;;;;;;;OAUG;IACH,SAAgB,MAAM,CACpB,MAAuB,EACvB,IAAO,EACP,KAAgC;QAEhC,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QAC9B,MAAM,IAAI,GAAG,KAAK,CAAC,GAAG,EAAG,CAAC;QAE1B,MAAM,IAAI,GAAwB,EAAE,CAAC;QAErC,IAAI,OAAO,GAAG,IAAI,CAAC;QAEnB,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE;YACxB,OAAO,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC;YACnB,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;SACzB;QAED,OAAO,CAAC,IAAI,CAAC,GAAG,KAAK,CAAC;QAEtB,OAAO,KAAK,CAAI,MAAM,EAAE,IAAI,CAAC,CAAC;IAChC,CAAC;IApBe,WAAM,SAoBrB,CAAA;AACH,CAAC,EArFgB,IAAI,KAAJ,IAAI,QAqFpB"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"protected.js","sourceRoot":"","sources":["../../src/protected.ts"],"names":[],"mappings":"AAkBA;;;GAGG;AACH,MAAM,UAAU,SAAS,CAAI,KAAQ;IACnC,OAAO,KAAY,CAAC;AACtB,CAAC"}
|
package/dist/types/index.d.ts
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @packageDocumentation
|
|
3
3
|
*
|
|
4
|
-
* The `@rimbu/deep` package provides utilities to patch and match plain JavaScript objects
|
|
4
|
+
* The `@rimbu/deep` package provides utilities to patch and match plain JavaScript objects.<br/>
|
|
5
5
|
* <br/>
|
|
6
6
|
* See the [Rimbu docs Deep overview page](/docs/deep/overview) for more information.
|
|
7
7
|
*/
|
|
8
|
-
export
|
|
8
|
+
export { patch, patchNested, Patch, match, Match, Path, Protected, } from './internal';
|
|
9
|
+
export { Tuple } from './tuple';
|
package/dist/types/internal.d.ts
CHANGED
package/dist/types/match.d.ts
CHANGED
|
@@ -1,111 +1,124 @@
|
|
|
1
|
-
import type
|
|
2
|
-
import {
|
|
1
|
+
import { type IsPlainObj, type PlainObj } from '@rimbu/base';
|
|
2
|
+
import type { Protected } from './internal';
|
|
3
3
|
/**
|
|
4
|
-
*
|
|
5
|
-
* @typeparam T - the
|
|
6
|
-
* @typeparam P - the parant type
|
|
7
|
-
* @typeparam R - the root type
|
|
4
|
+
* The type to determine the allowed input values for the `match` functions.
|
|
5
|
+
* @typeparam T - the type of value to match
|
|
8
6
|
*/
|
|
9
|
-
export declare type Match<T> =
|
|
10
|
-
declare type MatchHelper<T, P, R> = T extends Literal.Obj ? Match.MatchObj<T, P, R> : T extends readonly any[] ? Match.MatchArray<T, P, R> : Match.Compare<T, P, R>;
|
|
7
|
+
export declare type Match<T> = Match.Options<T, T>;
|
|
11
8
|
export declare namespace Match {
|
|
12
9
|
/**
|
|
13
|
-
*
|
|
14
|
-
* @typeparam T - the
|
|
15
|
-
* @typeparam
|
|
16
|
-
* @typeparam R - the root type
|
|
10
|
+
* The types of supported match input.
|
|
11
|
+
* @typeparam T - the type of value to match
|
|
12
|
+
* @typeparam R - the root object type
|
|
17
13
|
*/
|
|
18
|
-
type
|
|
19
|
-
[K in keyof T]?: MatchHelper<T[K], T, R>;
|
|
20
|
-
}) & Literal.NoIterable;
|
|
14
|
+
type Options<T, R> = Every<T, R> | Some<T, R> | None<T, R> | Single<T, R> | Match.Obj<T, R>;
|
|
21
15
|
/**
|
|
22
|
-
*
|
|
23
|
-
* @typeparam T - the
|
|
16
|
+
* The type to determine allowed matchers for objects.
|
|
17
|
+
* @typeparam T - the type of value to match
|
|
18
|
+
* @typeparam R - the root object type
|
|
24
19
|
*/
|
|
25
|
-
type
|
|
20
|
+
type Obj<T, R> = {
|
|
21
|
+
[K in keyof T]?: Match.ObjItem<T[K], R> | ((current: Protected<T[K]>, parent: Protected<T>, root: Protected<R>) => boolean | Match.ObjItem<T[K], R>);
|
|
22
|
+
};
|
|
26
23
|
/**
|
|
27
|
-
*
|
|
28
|
-
* @typeparam T - the
|
|
29
|
-
* @typeparam
|
|
30
|
-
* @typeparam R - the root type
|
|
24
|
+
* The type to determine allowed matchers for object properties.
|
|
25
|
+
* @typeparam T - the type of value to match
|
|
26
|
+
* @typeparam R - the root object type
|
|
31
27
|
*/
|
|
32
|
-
type
|
|
28
|
+
type ObjItem<T, R> = IsPlainObj<T> extends true ? Match.Options<T, R> : T extends Iterable<infer U> ? T | Iterable<U> : T;
|
|
33
29
|
/**
|
|
34
|
-
*
|
|
35
|
-
* @typeparam T - the
|
|
36
|
-
* @typeparam
|
|
37
|
-
* @typeparam
|
|
38
|
-
|
|
39
|
-
type MatchArray<T extends readonly any[], P, R> = (Match.Compare<T, P, R> | {
|
|
40
|
-
[K in {
|
|
41
|
-
[K2 in keyof T]: K2;
|
|
42
|
-
}[keyof T]]?: MatchHelper<T[K], T, R>;
|
|
43
|
-
}) & Literal.NoIterable;
|
|
44
|
-
/**
|
|
45
|
-
* Returns true if the given `value` matches all of the given objects in the `matchers` array.
|
|
46
|
-
* @typeparam T - the type of the object to match
|
|
47
|
-
* @param value - the value to match
|
|
48
|
-
* @param matchers - one or more `Match` objects
|
|
30
|
+
* Returns a matcher that returns true if every given `matchItem` matches the given value.
|
|
31
|
+
* @typeparam T - the type of value to match
|
|
32
|
+
* @typeparam R - the root object type
|
|
33
|
+
* @typeparam Q - a utility type for the matcher
|
|
34
|
+
* @param matchItems - the match specifications to test
|
|
49
35
|
* @example
|
|
50
36
|
* ```ts
|
|
51
|
-
*
|
|
52
|
-
*
|
|
37
|
+
* const input = { a: 1, b: { c: true, d: 'a' } }
|
|
38
|
+
* match(input, Match.every({ a: 1, { c: true } } )) // => true
|
|
39
|
+
* match(input, Match.every({ a: 1, { c: false } } )) // => false
|
|
53
40
|
* ```
|
|
54
41
|
*/
|
|
55
|
-
function
|
|
42
|
+
function every<T, R, Q extends T = T>(...matchItems: Match.Options<Q, R>[]): Every<T, R, Q>;
|
|
56
43
|
/**
|
|
57
|
-
* Returns true if
|
|
58
|
-
* @typeparam T - the type of
|
|
59
|
-
* @
|
|
60
|
-
* @
|
|
44
|
+
* Returns a matcher that returns true if at least one of given `matchItem` matches the given value.
|
|
45
|
+
* @typeparam T - the type of value to match
|
|
46
|
+
* @typeparam R - the root object type
|
|
47
|
+
* @typeparam Q - a utility type for the matcher
|
|
48
|
+
* @param matchItems - the match specifications to test
|
|
61
49
|
* @example
|
|
62
50
|
* ```ts
|
|
63
|
-
*
|
|
64
|
-
*
|
|
51
|
+
* const input = { a: 1, b: { c: true, d: 'a' } }
|
|
52
|
+
* match(input, Match.some({ a: 5, { c: true } } )) // => true
|
|
53
|
+
* match(input, Match.some({ a: 5, { c: false } } )) // => false
|
|
65
54
|
* ```
|
|
66
55
|
*/
|
|
67
|
-
function
|
|
56
|
+
function some<T, R, Q extends T = T>(...matchItems: Match.Options<Q, R>[]): Some<T, R, Q>;
|
|
68
57
|
/**
|
|
69
|
-
* Returns a
|
|
70
|
-
*
|
|
71
|
-
* @typeparam
|
|
72
|
-
* @typeparam
|
|
73
|
-
* @param
|
|
58
|
+
* Returns a matcher that returns true if none of given `matchItem` matches the given value.
|
|
59
|
+
* @typeparam T - the type of value to match
|
|
60
|
+
* @typeparam R - the root object type
|
|
61
|
+
* @typeparam Q - a utility type for the matcher
|
|
62
|
+
* @param matchItems - the match specifications to test
|
|
74
63
|
* @example
|
|
75
64
|
* ```ts
|
|
76
|
-
*
|
|
77
|
-
*
|
|
78
|
-
*
|
|
79
|
-
* console.log(m({ name: 'abc', age: 10 }))
|
|
80
|
-
* // => false
|
|
81
|
-
* console.log(m({ name: 'abc', age: 20 }))
|
|
82
|
-
* // => true
|
|
83
|
-
* console.log(m({ name: 'a', age: 20 }))
|
|
84
|
-
* // => false
|
|
65
|
+
* const input = { a: 1, b: { c: true, d: 'a' } }
|
|
66
|
+
* match(input, Match.none({ a: 5, { c: true } } )) // => false
|
|
67
|
+
* match(input, Match.none({ a: 5, { c: false } } )) // => true
|
|
85
68
|
* ```
|
|
86
69
|
*/
|
|
87
|
-
function
|
|
70
|
+
function none<T, R, Q extends T = T>(...matchItems: Match.Options<Q, R>[]): None<T, R, Q>;
|
|
88
71
|
/**
|
|
89
|
-
* Returns a
|
|
90
|
-
*
|
|
91
|
-
* @typeparam
|
|
92
|
-
* @typeparam
|
|
93
|
-
* @param
|
|
72
|
+
* Returns a matcher that returns true if exactly one of given `matchItem` matches the given value.
|
|
73
|
+
* @typeparam T - the type of value to match
|
|
74
|
+
* @typeparam R - the root object type
|
|
75
|
+
* @typeparam Q - a utility type for the matcher
|
|
76
|
+
* @param matchItems - the match specifications to test
|
|
94
77
|
* @example
|
|
95
78
|
* ```ts
|
|
96
|
-
*
|
|
97
|
-
*
|
|
98
|
-
*
|
|
99
|
-
* console.log(m({ name: 'abc', age: 10 }))
|
|
100
|
-
* // => true
|
|
101
|
-
* console.log(m({ name: 'abc', age: 20 }))
|
|
102
|
-
* // => true
|
|
103
|
-
* console.log(m({ name: 'a', age: 20 }))
|
|
104
|
-
* // => true
|
|
105
|
-
* console.log(m({ name: 'a', age: 10 }))
|
|
106
|
-
* // => false
|
|
79
|
+
* const input = { a: 1, b: { c: true, d: 'a' } }
|
|
80
|
+
* match(input, Match.single({ a: 1, { c: true } } )) // => false
|
|
81
|
+
* match(input, Match.single({ a: 1, { c: false } } )) // => true
|
|
107
82
|
* ```
|
|
108
83
|
*/
|
|
109
|
-
function
|
|
84
|
+
function single<T, R, Q extends T = T>(...matchItems: Match.Options<Q, R>[]): Single<T, R, Q>;
|
|
85
|
+
/**
|
|
86
|
+
* The functions that are optionally provided to a match function.
|
|
87
|
+
*/
|
|
88
|
+
type Api = typeof Match;
|
|
89
|
+
}
|
|
90
|
+
declare class Every<T, R, Q extends T = T> {
|
|
91
|
+
readonly matchItems: Match.Options<Q, R>[];
|
|
92
|
+
constructor(matchItems: Match.Options<Q, R>[]);
|
|
110
93
|
}
|
|
94
|
+
declare class Some<T, R, Q extends T = T> {
|
|
95
|
+
readonly matchItems: Match.Options<Q, R>[];
|
|
96
|
+
constructor(matchItems: Match.Options<Q, R>[]);
|
|
97
|
+
}
|
|
98
|
+
declare class None<T, R, Q extends T = T> {
|
|
99
|
+
readonly matchItems: Match.Options<Q, R>[];
|
|
100
|
+
constructor(matchItems: Match.Options<Q, R>[]);
|
|
101
|
+
}
|
|
102
|
+
declare class Single<T, R, Q extends T = T> {
|
|
103
|
+
readonly matchItems: Match.Options<Q, R>[];
|
|
104
|
+
constructor(matchItems: Match.Options<Q, R>[]);
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* Returns true if the given `value` object matches the given `matcher`, false otherwise.
|
|
108
|
+
* @typeparam T - the input value type
|
|
109
|
+
* @param value - the value to match (should be a plain object)
|
|
110
|
+
* @param matcher - a matcher object or a function taking the matcher API and returning a match object
|
|
111
|
+
* @example
|
|
112
|
+
* ```ts
|
|
113
|
+
* const input = { a: 1, b: { c: true, d: 'a' } }
|
|
114
|
+
* match(input, { a: 1 }) // => true
|
|
115
|
+
* match(input, { a: 2 }) // => false
|
|
116
|
+
* match(input, { a: v => v > 10 }) // => false
|
|
117
|
+
* match(input, { b: { c: true }}) // => true
|
|
118
|
+
* match(input, ({ every }) => every({ a: v => v > 0 }, { b: { c: true } } )) // => true
|
|
119
|
+
* match(input, { b: { c: (v, parent, root) => v && parent.d.length > 0 && root.a > 0 } })
|
|
120
|
+
* // => true
|
|
121
|
+
* ```
|
|
122
|
+
*/
|
|
123
|
+
export declare function match<T>(value: T & PlainObj<T>, matcher: Match<T> | ((matchApi: Match.Api) => Match<T>)): boolean;
|
|
111
124
|
export {};
|
package/dist/types/patch.d.ts
CHANGED
|
@@ -1,79 +1,82 @@
|
|
|
1
|
-
import type
|
|
2
|
-
import {
|
|
1
|
+
import { type AnyFunc, type PlainObj } from '@rimbu/base';
|
|
2
|
+
import type { Protected } from './internal';
|
|
3
3
|
/**
|
|
4
|
-
*
|
|
5
|
-
* @typeparam T - the input type
|
|
6
|
-
* @typeparam P - the parant type
|
|
7
|
-
* @typeparam R - the root type
|
|
4
|
+
* A type to determine the allowed input type for the `patch` function.
|
|
5
|
+
* @typeparam T - the input type to be patched
|
|
8
6
|
*/
|
|
9
|
-
export declare type Patch<T> =
|
|
10
|
-
declare type PatchHelper<T, P, R> = T extends Literal.Obj ? Patch.PatchObj<T, P, R> : T extends readonly unknown[] ? Patch.PatchArray<T, P, R> : Patch.Update<T, P, R>;
|
|
11
|
-
/**
|
|
12
|
-
* Returns an updated version of given `value`, without modifying the value, where the contents
|
|
13
|
-
* are updated according to the given `patches` Patch array.
|
|
14
|
-
* @typeparam T - the type of the value to patch
|
|
15
|
-
* @param value - the value to update
|
|
16
|
-
* @param patches - one or more `Patch` objects indicating modifications to the value
|
|
17
|
-
* @example
|
|
18
|
-
* ```ts
|
|
19
|
-
* patch({ g: { h: 5 }})({ g: { h: 6 }}) // => { g: { h: 6 }}
|
|
20
|
-
* patch({ g: { h: 5 }})({ g: { h: v => v + 1 }}) // => { g: { h: 6 }}
|
|
21
|
-
* patch({ g: { h: 5 }})({ g: { h: 1 }}, { g: { h: v => v + 1 }})
|
|
22
|
-
* // => { g: { h: 2 }}
|
|
23
|
-
* patch({ a: 1, b: 3 })({ a: (v, p) => v * p.b, (v, p) => v + p.a })
|
|
24
|
-
* // => { a: 3, b: 4 }
|
|
25
|
-
* ```
|
|
26
|
-
*/
|
|
27
|
-
export declare function patch<T>(value: T): (...patches: Patch.Multi<T>) => T;
|
|
7
|
+
export declare type Patch<T> = Patch.Entry<T, T>;
|
|
28
8
|
export declare namespace Patch {
|
|
29
|
-
const MAP: unique symbol;
|
|
30
9
|
/**
|
|
31
|
-
*
|
|
32
|
-
* @typeparam T - the input type
|
|
33
|
-
* @typeparam
|
|
34
|
-
* @typeparam R - the root type
|
|
10
|
+
* The entry type for a (nested) patch. Can be either a patch object or a function accepting the nested patch function and returning a patch object.
|
|
11
|
+
* @typeparam T - the input value type
|
|
12
|
+
* @typeparam R - the root object type
|
|
35
13
|
*/
|
|
36
|
-
type
|
|
37
|
-
[K in keyof T]?: PatchHelper<T[K], T, R>;
|
|
38
|
-
};
|
|
14
|
+
type Entry<T, R> = Patch.Obj<T, R> | ((patchNested: Patch.Nested) => Patch.Obj<T, R>);
|
|
39
15
|
/**
|
|
40
|
-
*
|
|
41
|
-
*
|
|
16
|
+
* The object patch type, allows the user to specify keys in T that should be patched, and each given key contains either a new value or a nested patch, or a function receiving
|
|
17
|
+
* the current value, the parent object, and the root object, and returning a new value or a nested patch.
|
|
18
|
+
* @typeparam T - the input value type
|
|
19
|
+
* @typeparam R - the root object type
|
|
42
20
|
*/
|
|
43
|
-
type
|
|
21
|
+
type Obj<T, R> = {
|
|
22
|
+
[K in keyof T]?: (T[K] extends AnyFunc ? never : ObjItem<T[K], R>) | ((cur: Protected<T[K]>, parent: Protected<T>, root: Protected<R>) => ObjItem<T[K], R>);
|
|
23
|
+
};
|
|
44
24
|
/**
|
|
45
|
-
*
|
|
46
|
-
* @typeparam T - the input type
|
|
47
|
-
* @typeparam
|
|
48
|
-
* @typeparam R - the root type
|
|
25
|
+
* A patch object can have as update either a new value or a nested patch object
|
|
26
|
+
* @typeparam T - the input value type
|
|
27
|
+
* @typeparam R - the root object type
|
|
49
28
|
*/
|
|
50
|
-
type
|
|
29
|
+
type ObjItem<T, R> = T | NestedObj<T, R>;
|
|
51
30
|
/**
|
|
52
|
-
*
|
|
53
|
-
* @typeparam T - the array type
|
|
54
|
-
* @typeparam P - the parent type
|
|
55
|
-
* @typeparam R - the root type
|
|
31
|
+
* The function type to create a nested Patch object.
|
|
56
32
|
*/
|
|
57
|
-
type
|
|
58
|
-
[Patch.MAP]: PatchHelper<E, T, R>;
|
|
59
|
-
} : never) | {
|
|
60
|
-
[K in {
|
|
61
|
-
[K2 in keyof T]: K2;
|
|
62
|
-
}[keyof T]]?: PatchHelper<T[K], T, R>;
|
|
63
|
-
}) & Literal.NoIterable;
|
|
33
|
+
type Nested = typeof patchNested;
|
|
64
34
|
/**
|
|
65
|
-
* Returns a function that patches a given
|
|
66
|
-
*
|
|
67
|
-
* @typeparam
|
|
68
|
-
* @
|
|
69
|
-
* @param patches - the patches to apply to a given object
|
|
35
|
+
* Returns a function that patches a given `value` with the given `patchItems`.
|
|
36
|
+
* @typeparam T - the patch value type
|
|
37
|
+
* @typeparam Q - the input value type
|
|
38
|
+
* @param patchItems - a number of `Patch` objects that patch a given value of type T.
|
|
70
39
|
* @example
|
|
71
40
|
* ```ts
|
|
72
|
-
* const
|
|
73
|
-
*
|
|
74
|
-
* // => { a:
|
|
41
|
+
* const items = [{ a: 1, b: 'a' }, { a: 2, b: 'b' }]
|
|
42
|
+
* items.map(Patch.create({ a: v => v + 1 }))
|
|
43
|
+
* // => [{ a: 2, b: 'a' }, { a: 3, b: 'b' }]
|
|
75
44
|
* ```
|
|
76
45
|
*/
|
|
77
|
-
function create<T,
|
|
46
|
+
function create<T, Q extends T = T>(...patchItems: Patch<T & Q>[]): (value: Q & PlainObj<Q>) => Q;
|
|
78
47
|
}
|
|
48
|
+
declare class NestedObj<T, R, Q extends T = T> {
|
|
49
|
+
readonly patchDataItems: Patch.Obj<Q, R>[];
|
|
50
|
+
constructor(patchDataItems: Patch.Obj<Q, R>[]);
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Returns a nested patch object based on the given `patchDataItems` that work on a subpart
|
|
54
|
+
* of a larger object to be patched.
|
|
55
|
+
* @typeparam T - the input value type
|
|
56
|
+
* @typeparam R - the root object type
|
|
57
|
+
* @typeparam Q - the patch type
|
|
58
|
+
* @param patchDataItems - a number of `Patch` objects to be applied to the subpart of the object
|
|
59
|
+
* @example
|
|
60
|
+
* ```ts
|
|
61
|
+
* patch({ a: 1, b: { c: true, d: 'a' } }, { b: patchNested({ d: 'b' }) })
|
|
62
|
+
* // => { a: 1, b: { c: true, d: 'b' } }
|
|
63
|
+
* ```
|
|
64
|
+
*/
|
|
65
|
+
export declare function patchNested<T, R, Q extends T = T>(...patchDataItems: Patch.Obj<Q, R>[]): NestedObj<T, R, Q>;
|
|
66
|
+
/**
|
|
67
|
+
* Returns an immutably updated version of the given `value` where the given `patchItems` have been
|
|
68
|
+
* applied to the result.
|
|
69
|
+
* @param value - the input value to patch
|
|
70
|
+
* @param patchItems - the `Patch` objects to apply to the input value
|
|
71
|
+
* @example
|
|
72
|
+
* ```ts
|
|
73
|
+
* const input = { a: 1, b: { c: true, d: 'a' } }
|
|
74
|
+
* patch(input, { a: 2 }) // => { a: 2, b: { c: true, d: 'a' } }
|
|
75
|
+
* patch(input: ($) => ({ b: $({ c: v => !v }) }) )
|
|
76
|
+
* // => { a: 1, b: { c: false, d: 'a' } }
|
|
77
|
+
* patch(input: ($) => ({ a: v => v + 1, b: $({ d: 'q' }) }) )
|
|
78
|
+
* // => { a: 2, b: { c: true, d: 'q' } }
|
|
79
|
+
* ```
|
|
80
|
+
*/
|
|
81
|
+
export declare function patch<T>(value: T & PlainObj<T>, ...patchItems: Patch<T>[]): T;
|
|
79
82
|
export {};
|
package/dist/types/path.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import type { Update } from '@rimbu/common';
|
|
2
|
+
import type { IsPlainObj, PlainObj } from '@rimbu/base';
|
|
2
3
|
/**
|
|
3
4
|
* A string representing a path into an (nested) object of type T.
|
|
4
5
|
* @typeparam T - the object type to select in
|
|
@@ -7,7 +8,7 @@ import { Literal, Patch } from './internal';
|
|
|
7
8
|
* const p: Path<{ a: { b: { c : 5 }}}> = 'a.b'
|
|
8
9
|
* ```
|
|
9
10
|
*/
|
|
10
|
-
export declare type Path<T> = T extends
|
|
11
|
+
export declare type Path<T> = IsPlainObj<T> extends true ? {
|
|
11
12
|
[K in string & keyof T]: `${K}` | `${K}.${Path<T[K]>}`;
|
|
12
13
|
}[string & keyof T] : never;
|
|
13
14
|
export declare namespace Path {
|
|
@@ -30,13 +31,13 @@ export declare namespace Path {
|
|
|
30
31
|
* @param path - the path into the object
|
|
31
32
|
* @example
|
|
32
33
|
* ```ts
|
|
33
|
-
* console.log(Path.
|
|
34
|
+
* console.log(Path.get({ a: { b: { c: 5 } } }), 'a.b')
|
|
34
35
|
* // => { c: 5 }
|
|
35
|
-
* console.log(Path.
|
|
36
|
+
* console.log(Path.get({ a: { b: { c: 5 } } }), 'a.b.c')
|
|
36
37
|
* // => 5
|
|
37
38
|
* ```
|
|
38
39
|
*/
|
|
39
|
-
function
|
|
40
|
+
function get<T, P extends Path<T> = Path<T>>(source: T & PlainObj<T>, path: P): Path.Result<T, P>;
|
|
40
41
|
/**
|
|
41
42
|
* Sets the value at the given path in the source to the given value.
|
|
42
43
|
* @param source - the object to update
|
|
@@ -44,21 +45,9 @@ export declare namespace Path {
|
|
|
44
45
|
* @param value - the new value to set at the given position
|
|
45
46
|
* @example
|
|
46
47
|
* ```ts
|
|
47
|
-
* console.log(Path.
|
|
48
|
+
* console.log(Path.update({ a: { b: { c: 5 } } }, 'a.b.c', v => v + 5)
|
|
49
|
+
* // => { a: { b: { c: 6 } } }
|
|
48
50
|
* ```
|
|
49
51
|
*/
|
|
50
|
-
function
|
|
51
|
-
/**
|
|
52
|
-
* Patches the value at the given path in the source to the given value using the given
|
|
53
|
-
* `patches`.
|
|
54
|
-
* @param source - the object to update
|
|
55
|
-
* @param path - the path in the object to update
|
|
56
|
-
* @param patches - one or more patches to update the value at the given path
|
|
57
|
-
* @example
|
|
58
|
-
* ```ts
|
|
59
|
-
* console.log(Path.setValue({ a: { b: { c: 5 } } }, 'a.b.c', 8)
|
|
60
|
-
* // => { a: { b: { c: 8 } } }
|
|
61
|
-
* ```
|
|
62
|
-
*/
|
|
63
|
-
function patchValue<T, P extends Path<T> = Path<T>>(source: T, path: P, ...patches: Patch.Multi<Path.Result<T, P>>): T;
|
|
52
|
+
function update<T, P extends Path<T> = Path<T>>(source: T & PlainObj<T>, path: P, value: Update<Path.Result<T, P>>): T;
|
|
64
53
|
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { IsPlainObj } from '@rimbu/base';
|
|
2
|
+
/**
|
|
3
|
+
* A deep readonly typed version of given type T. Makes all properties or elements read only.
|
|
4
|
+
* @typeparam T - the input type
|
|
5
|
+
*/
|
|
6
|
+
export declare type Protected<T> = T extends readonly (infer E)[] ? readonly Protected<E>[] : T extends Map<infer K, infer V> ? Map<Protected<K>, Protected<V>> : T extends Set<infer E> ? Set<Protected<E>> : T extends Promise<infer E> ? Promise<Protected<E>> : IsPlainObj<T> extends true ? {
|
|
7
|
+
readonly [K in keyof T]: Protected<T[K]>;
|
|
8
|
+
} : T;
|
|
9
|
+
/**
|
|
10
|
+
* Returns the same value wrapped in the Protected type
|
|
11
|
+
* @param value - the value to wrap
|
|
12
|
+
*/
|
|
13
|
+
export declare function Protected<T>(value: T): Protected<T>;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rimbu/deep",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.10.0",
|
|
4
4
|
"description": "Tools to use handle plain JS objects as immutable objects",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"immutable",
|
|
@@ -57,8 +57,8 @@
|
|
|
57
57
|
},
|
|
58
58
|
"sideEffects": false,
|
|
59
59
|
"dependencies": {
|
|
60
|
-
"@rimbu/base": "^0.
|
|
61
|
-
"@rimbu/common": "^0.9.
|
|
60
|
+
"@rimbu/base": "^0.9.0",
|
|
61
|
+
"@rimbu/common": "^0.9.3",
|
|
62
62
|
"tslib": "^2.4.0"
|
|
63
63
|
},
|
|
64
64
|
"publishConfig": {
|
|
@@ -68,5 +68,5 @@
|
|
|
68
68
|
"index": "src/index.ts",
|
|
69
69
|
"replacer": "../../config/denoify-rimbu-replacer.js"
|
|
70
70
|
},
|
|
71
|
-
"gitHead": "
|
|
71
|
+
"gitHead": "4efaf8c469d606381517984436383fd6b1b61ec0"
|
|
72
72
|
}
|
package/src/index.ts
CHANGED
|
@@ -1,9 +1,19 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @packageDocumentation
|
|
3
3
|
*
|
|
4
|
-
* The `@rimbu/deep` package provides utilities to patch and match plain JavaScript objects
|
|
4
|
+
* The `@rimbu/deep` package provides utilities to patch and match plain JavaScript objects.<br/>
|
|
5
5
|
* <br/>
|
|
6
6
|
* See the [Rimbu docs Deep overview page](/docs/deep/overview) for more information.
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
|
-
export
|
|
9
|
+
export {
|
|
10
|
+
patch,
|
|
11
|
+
patchNested,
|
|
12
|
+
Patch,
|
|
13
|
+
match,
|
|
14
|
+
Match,
|
|
15
|
+
Path,
|
|
16
|
+
Protected,
|
|
17
|
+
} from './internal';
|
|
18
|
+
|
|
19
|
+
export { Tuple } from './tuple';
|