@rimbu/deep 2.0.0 → 2.0.2
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/README.md +37 -27
- package/dist/bun/deep.mts +2 -2
- package/dist/bun/match.mts +27 -25
- package/dist/bun/patch.mts +10 -9
- package/dist/bun/path.mts +94 -95
- package/dist/bun/protected.mts +18 -17
- package/dist/bun/selector.mts +22 -20
- package/dist/bun/tuple.mts +1 -1
- package/dist/cjs/deep.cjs +197 -576
- package/dist/cjs/deep.cjs.map +1 -0
- package/dist/cjs/deep.d.cts +284 -0
- package/dist/cjs/index.cjs +18 -662
- package/dist/cjs/index.cjs.map +1 -0
- package/dist/cjs/index.d.cts +18 -0
- package/dist/cjs/internal.cjs +8 -582
- package/dist/cjs/internal.cjs.map +1 -0
- package/dist/cjs/internal.d.cts +7 -0
- package/dist/cjs/match.cjs +250 -343
- package/dist/cjs/match.cjs.map +1 -0
- package/dist/cjs/match.d.cts +140 -0
- package/dist/cjs/patch.cjs +120 -93
- package/dist/cjs/patch.cjs.map +1 -0
- package/dist/cjs/patch.d.cts +89 -0
- package/dist/cjs/path.cjs +114 -573
- package/dist/cjs/path.cjs.map +1 -0
- package/dist/cjs/path.d.cts +199 -0
- package/dist/cjs/protected.cjs +2 -17
- package/dist/cjs/protected.cjs.map +1 -0
- package/dist/cjs/selector.cjs +32 -574
- package/dist/cjs/selector.cjs.map +1 -0
- package/dist/cjs/selector.d.cts +47 -0
- package/dist/cjs/tuple.cjs +162 -71
- package/dist/cjs/tuple.cjs.map +1 -0
- package/dist/esm/match.mjs.map +1 -1
- package/dist/esm/patch.mjs.map +1 -1
- package/dist/{types → esm}/path.d.mts +4 -1
- package/dist/esm/path.mjs.map +1 -1
- package/dist/esm/protected.d.mts +17 -0
- package/dist/esm/selector.mjs.map +1 -1
- package/dist/esm/tuple.d.mts +142 -0
- package/package.json +20 -14
- package/src/deep.mts +2 -2
- package/src/match.mts +27 -25
- package/src/patch.mts +10 -9
- package/src/path.mts +94 -95
- package/src/protected.mts +18 -17
- package/src/selector.mts +22 -20
- package/src/tuple.mts +1 -1
- /package/dist/{types/protected.d.mts → cjs/protected.d.cts} +0 -0
- /package/dist/{types/tuple.d.mts → cjs/tuple.d.cts} +0 -0
- /package/dist/{types → esm}/deep.d.mts +0 -0
- /package/dist/{types → esm}/index.d.mts +0 -0
- /package/dist/{types → esm}/internal.d.mts +0 -0
- /package/dist/{types → esm}/match.d.mts +0 -0
- /package/dist/{types → esm}/patch.d.mts +0 -0
- /package/dist/{types → esm}/selector.d.mts +0 -0
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
import { type IsAnyFunc, type IsArray, type IsPlainObj, type NotIterable } from '@rimbu/base';
|
|
2
|
+
import type { Protected } from './internal.cjs';
|
|
3
|
+
import type { Tuple } from './tuple.cjs';
|
|
4
|
+
/**
|
|
5
|
+
* The type to determine the allowed input values for the `match` function.
|
|
6
|
+
* @typeparam T - the type of value to match
|
|
7
|
+
* @typeparam C - utility type
|
|
8
|
+
*/
|
|
9
|
+
export type Match<T, C extends Partial<T> = Partial<T>> = Match.Entry<T, C, T, T>;
|
|
10
|
+
export declare namespace Match {
|
|
11
|
+
/**
|
|
12
|
+
* Determines the various allowed match types for given type `T`.
|
|
13
|
+
* @typeparam T - the input value type
|
|
14
|
+
* @typeparam C - utility type
|
|
15
|
+
* @typeparam P - the parent type
|
|
16
|
+
* @typeparam R - the root object type
|
|
17
|
+
*/
|
|
18
|
+
type Entry<T, C, P, R> = IsAnyFunc<T> extends true ? T : IsPlainObj<T> extends true ? Match.WithResult<T, P, R, Match.Obj<T, C, P, R>> : IsArray<T> extends true ? Match.Arr<T, C, P, R> | Match.Entry<T[number & keyof T], C[number & keyof C], P, R>[] | Match.Func<T, P, R, Match.Arr<T, C, P, R> | Match.Entry<T[number & keyof T], C[number & keyof C], P, R>[]> : Match.WithResult<T, P, R, {
|
|
19
|
+
[K in keyof C]: C[K & keyof T];
|
|
20
|
+
}>;
|
|
21
|
+
/**
|
|
22
|
+
* The type that determines allowed matchers for objects.
|
|
23
|
+
* @typeparam T - the input value type
|
|
24
|
+
* @typeparam C - utility type
|
|
25
|
+
* @typeparam P - the parent type
|
|
26
|
+
* @typeparam R - the root object type
|
|
27
|
+
*/
|
|
28
|
+
type Obj<T, C, P, R> = Match.ObjProps<T, C, R> | Match.CompoundForObj<T, C, P, R>;
|
|
29
|
+
/**
|
|
30
|
+
* The type to determine allowed matchers for object properties.
|
|
31
|
+
* @typeparam T - the input value type
|
|
32
|
+
* @typeparam C - utility type
|
|
33
|
+
* @typeparam R - the root object type
|
|
34
|
+
*/
|
|
35
|
+
type ObjProps<T, C, R> = {
|
|
36
|
+
[K in keyof C]?: K extends keyof T ? Match.Entry<T[K], C[K], T, R> : never;
|
|
37
|
+
};
|
|
38
|
+
/**
|
|
39
|
+
* The type that determines allowed matchers for arrays/tuples.
|
|
40
|
+
* @typeparam T - the input value type
|
|
41
|
+
* @typeparam C - utility type
|
|
42
|
+
* @typeparam P - the parent type
|
|
43
|
+
* @typeparam R - the root object type
|
|
44
|
+
*/
|
|
45
|
+
type Arr<T, C, P, R> = C | Match.CompoundForArr<T, C, P, R> | Match.TraversalForArr<T, C, R> | (Match.TupIndices<T, C, R> & {
|
|
46
|
+
[K in Match.CompoundType | Match.ArrayTraversalType]?: never;
|
|
47
|
+
});
|
|
48
|
+
/**
|
|
49
|
+
* A type that either directly results in result type `S` or is a function taking the value, parent, and root values, and
|
|
50
|
+
* returns a value of type `S`.
|
|
51
|
+
* @typeparam T - the input value type
|
|
52
|
+
* @typeparam P - the parent type
|
|
53
|
+
* @typeparam R - the root object type
|
|
54
|
+
* @typeparam S - the result type
|
|
55
|
+
*/
|
|
56
|
+
type WithResult<T, P, R, S> = S | Match.Func<T, P, R, S>;
|
|
57
|
+
/**
|
|
58
|
+
* Type used to determine the allowed function types. Always includes booleans.
|
|
59
|
+
* @typeparam T - the input value type
|
|
60
|
+
* @typeparam P - the parent type
|
|
61
|
+
* @typeparam R - the root object type
|
|
62
|
+
* @typeparam S - the allowed return value type
|
|
63
|
+
*/
|
|
64
|
+
type Func<T, P, R, S> = (current: Protected<T>, parent: Protected<P>, root: Protected<R>) => boolean | S;
|
|
65
|
+
/**
|
|
66
|
+
* Type used to indicate an object containing matches for tuple indices.
|
|
67
|
+
* @typeparam T - the input value type
|
|
68
|
+
* @typeparam C - utility type
|
|
69
|
+
* @typeparam R - the root object type
|
|
70
|
+
*/
|
|
71
|
+
type TupIndices<T, C, R> = {
|
|
72
|
+
[K in Tuple.KeysOf<C>]?: Match.Entry<T[K & keyof T], C[K], T, R>;
|
|
73
|
+
} & NotIterable;
|
|
74
|
+
/**
|
|
75
|
+
* Compound keys used to indicate the type of compound.
|
|
76
|
+
*/
|
|
77
|
+
type CompoundType = 'every' | 'some' | 'none' | 'single';
|
|
78
|
+
/**
|
|
79
|
+
* Keys used to indicate an array match traversal.
|
|
80
|
+
*/
|
|
81
|
+
type ArrayTraversalType = `${CompoundType}Item`;
|
|
82
|
+
/**
|
|
83
|
+
* Compount matcher for objects, can only be an array staring with a compound type keyword.
|
|
84
|
+
* @typeparam T - the input value type
|
|
85
|
+
* @typeparam C - utility type
|
|
86
|
+
* @typeparam P - the parent type
|
|
87
|
+
* @typeparam R - the root object type
|
|
88
|
+
*/
|
|
89
|
+
type CompoundForObj<T, C, P, R> = [
|
|
90
|
+
Match.CompoundType,
|
|
91
|
+
...Match.Entry<T, C, P, R>[]
|
|
92
|
+
];
|
|
93
|
+
/**
|
|
94
|
+
* Defines an object containing exactly one `CompoundType` key, having an array of matchers.
|
|
95
|
+
* @typeparam T - the input value type
|
|
96
|
+
* @typeparam C - utility type
|
|
97
|
+
* @typeparam P - the parent type
|
|
98
|
+
* @typeparam R - the root object type
|
|
99
|
+
*/
|
|
100
|
+
type CompoundForArr<T, C, P, R> = {
|
|
101
|
+
[K in Match.CompoundType]: {
|
|
102
|
+
[K2 in Match.CompoundType]?: K2 extends K ? Match.Entry<T, C, P, R>[] : never;
|
|
103
|
+
};
|
|
104
|
+
}[Match.CompoundType];
|
|
105
|
+
/**
|
|
106
|
+
* Defines an object containing exactly one `TraversalType` key, having a matcher for the array element type.
|
|
107
|
+
* @typeparam T - the input value type
|
|
108
|
+
* @typeparam C - utility type
|
|
109
|
+
* @typeparam R - the root object type
|
|
110
|
+
*/
|
|
111
|
+
type TraversalForArr<T, C, R> = {
|
|
112
|
+
[K in Match.ArrayTraversalType]: {
|
|
113
|
+
[K2 in Match.ArrayTraversalType]?: K2 extends K ? Match.Entry<T[number & keyof T], C[number & keyof C], T, R> : never;
|
|
114
|
+
};
|
|
115
|
+
}[Match.ArrayTraversalType];
|
|
116
|
+
/**
|
|
117
|
+
* Utility type for collecting match failure reasons
|
|
118
|
+
*/
|
|
119
|
+
type FailureLog = string[];
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Returns true if the given `value` object matches the given `matcher`, false otherwise.
|
|
123
|
+
* @typeparam T - the input value type
|
|
124
|
+
* @typeparam C - utility type
|
|
125
|
+
* @param source - the value to match (should be a plain object)
|
|
126
|
+
* @param matcher - a matcher object or a function taking the matcher API and returning a match object
|
|
127
|
+
* @param failureLog - (optional) a string array that can be passed to collect reasons why the match failed
|
|
128
|
+
* @example
|
|
129
|
+
* ```ts
|
|
130
|
+
* const input = { a: 1, b: { c: true, d: 'a' } }
|
|
131
|
+
* match(input, { a: 1 }) // => true
|
|
132
|
+
* match(input, { a: 2 }) // => false
|
|
133
|
+
* match(input, { a: (v) => v > 10 }) // => false
|
|
134
|
+
* match(input, { b: { c: true }}) // => true
|
|
135
|
+
* match(input, (['every', { a: (v) => v > 0 }, { b: { c: true } }]) // => true
|
|
136
|
+
* match(input, { b: { c: (v, parent, root) => v && parent.d.length > 0 && root.a > 0 } })
|
|
137
|
+
* // => true
|
|
138
|
+
* ```
|
|
139
|
+
*/
|
|
140
|
+
export declare function match<T, C extends Partial<T> = Partial<T>>(source: T, matcher: Match<T, C>, failureLog?: Match.FailureLog): boolean;
|
package/dist/cjs/patch.cjs
CHANGED
|
@@ -1,105 +1,132 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
var
|
|
5
|
-
var
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
})
|
|
25
|
-
|
|
26
|
-
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.patch = patch;
|
|
4
|
+
var tslib_1 = require("tslib");
|
|
5
|
+
var base_1 = require("@rimbu/base");
|
|
6
|
+
/**
|
|
7
|
+
* Returns an immutably updated version of the given `value` where the given `patchItems` have been
|
|
8
|
+
* applied to the result.
|
|
9
|
+
* The Rimbu patch notation is as follows:
|
|
10
|
+
* - if the target is a simple value or array, the patch can be the same type or a function returning the same type
|
|
11
|
+
* - 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
|
|
12
|
+
* - 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
|
|
13
|
+
* @typeparam T - the type of the value to patch
|
|
14
|
+
* @typeparam TE - a utility type
|
|
15
|
+
* @typeparam TT - a utility type
|
|
16
|
+
* @param value - the input value to patch
|
|
17
|
+
* @param patchItem - the `Patch` value to apply to the input value
|
|
18
|
+
* @example
|
|
19
|
+
* ```ts
|
|
20
|
+
* const input = { a: 1, b: { c: true, d: 'a' } }
|
|
21
|
+
* patch(input, [{ a: 2 }]) // => { a: 2, b: { c: true, d: 'a' } }
|
|
22
|
+
* patch(input, [{ b: [{ c: (v) => !v }] }] )
|
|
23
|
+
* // => { a: 1, b: { c: false, d: 'a' } }
|
|
24
|
+
* patch(input: [{ a: (v) => v + 1, b: [{ d: 'q' }] }] )
|
|
25
|
+
* // => { a: 2, b: { c: true, d: 'q' } }
|
|
26
|
+
* ```
|
|
27
|
+
*/
|
|
27
28
|
function patch(value, patchItem) {
|
|
28
|
-
|
|
29
|
+
return patchEntry(value, value, value, patchItem);
|
|
29
30
|
}
|
|
30
31
|
function patchEntry(value, parent, root, patchItem) {
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
32
|
+
if (Object.is(value, patchItem)) {
|
|
33
|
+
// patching a value with itself never changes the value
|
|
34
|
+
return value;
|
|
35
|
+
}
|
|
36
|
+
if (typeof value === 'function') {
|
|
37
|
+
// function input, directly return patch
|
|
38
|
+
return patchItem;
|
|
39
|
+
}
|
|
40
|
+
if (typeof patchItem === 'function') {
|
|
41
|
+
// function patch always needs to be resolved first
|
|
42
|
+
var item = patchItem(value, parent, root);
|
|
43
|
+
return patchEntry(value, parent, root, item);
|
|
44
|
+
}
|
|
45
|
+
if ((0, base_1.isPlainObj)(value)) {
|
|
46
|
+
// value is plain object
|
|
47
|
+
return patchPlainObj(value, root, patchItem);
|
|
48
|
+
}
|
|
49
|
+
if (Array.isArray(value)) {
|
|
50
|
+
// value is tuple or array
|
|
51
|
+
return patchArr(value, root, patchItem);
|
|
52
|
+
}
|
|
53
|
+
// value is primitive type or complex object
|
|
35
54
|
return patchItem;
|
|
36
|
-
}
|
|
37
|
-
if (typeof patchItem === "function") {
|
|
38
|
-
const item = patchItem(value, parent, root);
|
|
39
|
-
return patchEntry(value, parent, root, item);
|
|
40
|
-
}
|
|
41
|
-
if ((0, import_base.isPlainObj)(value)) {
|
|
42
|
-
return patchPlainObj(value, root, patchItem);
|
|
43
|
-
}
|
|
44
|
-
if (Array.isArray(value)) {
|
|
45
|
-
return patchArr(value, root, patchItem);
|
|
46
|
-
}
|
|
47
|
-
return patchItem;
|
|
48
55
|
}
|
|
49
56
|
function patchPlainObj(value, root, patchItem) {
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
57
|
+
var e_1, _a;
|
|
58
|
+
if (!Array.isArray(patchItem)) {
|
|
59
|
+
// the patch is a complete replacement of the current value
|
|
60
|
+
return patchItem;
|
|
61
|
+
}
|
|
62
|
+
// patch is an array of partial updates
|
|
63
|
+
// copy the input value
|
|
64
|
+
var result = tslib_1.__assign({}, value);
|
|
65
|
+
var anyChange = false;
|
|
66
|
+
try {
|
|
67
|
+
// loop over patches in array
|
|
68
|
+
for (var patchItem_1 = tslib_1.__values(patchItem), patchItem_1_1 = patchItem_1.next(); !patchItem_1_1.done; patchItem_1_1 = patchItem_1.next()) {
|
|
69
|
+
var entry = patchItem_1_1.value;
|
|
70
|
+
// update root if needed
|
|
71
|
+
var currentRoot = value === root ? tslib_1.__assign({}, result) : root;
|
|
72
|
+
// keep current updated result as parent
|
|
73
|
+
var parent = tslib_1.__assign({}, result);
|
|
74
|
+
// loop over all the patch keys
|
|
75
|
+
for (var key in entry) {
|
|
76
|
+
// patch the value at the given key with the patch at that key
|
|
77
|
+
var currentValue = result[key];
|
|
78
|
+
var newValue = patchEntry(currentValue, parent, currentRoot, entry[key]);
|
|
79
|
+
if (!Object.is(currentValue, newValue)) {
|
|
80
|
+
// if value changed, set it in result and mark change
|
|
81
|
+
anyChange = true;
|
|
82
|
+
result[key] = newValue;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
}
|
|
70
86
|
}
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
87
|
+
catch (e_1_1) { e_1 = { error: e_1_1 }; }
|
|
88
|
+
finally {
|
|
89
|
+
try {
|
|
90
|
+
if (patchItem_1_1 && !patchItem_1_1.done && (_a = patchItem_1.return)) _a.call(patchItem_1);
|
|
91
|
+
}
|
|
92
|
+
finally { if (e_1) throw e_1.error; }
|
|
93
|
+
}
|
|
94
|
+
if (anyChange) {
|
|
95
|
+
// something changed, return new value
|
|
96
|
+
return result;
|
|
97
|
+
}
|
|
98
|
+
// nothing changed, return old value
|
|
99
|
+
return value;
|
|
76
100
|
}
|
|
77
101
|
function patchArr(value, root, patchItem) {
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
let anyChange = false;
|
|
83
|
-
for (const index in patchItem) {
|
|
84
|
-
const numIndex = index;
|
|
85
|
-
const currentValue = result[numIndex];
|
|
86
|
-
const newValue = patchEntry(
|
|
87
|
-
currentValue,
|
|
88
|
-
value,
|
|
89
|
-
root,
|
|
90
|
-
patchItem[index]
|
|
91
|
-
);
|
|
92
|
-
if (!Object.is(newValue, currentValue)) {
|
|
93
|
-
anyChange = true;
|
|
94
|
-
result[numIndex] = newValue;
|
|
102
|
+
if (Array.isArray(patchItem)) {
|
|
103
|
+
// value is a normal array
|
|
104
|
+
// patch is a complete replacement of current array
|
|
105
|
+
return patchItem;
|
|
95
106
|
}
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
107
|
+
// value is a tuple
|
|
108
|
+
// patch is an object containing numeric keys with function values
|
|
109
|
+
// that update the tuple at the given indices
|
|
110
|
+
// copy the tuple
|
|
111
|
+
var result = tslib_1.__spreadArray([], tslib_1.__read(value), false);
|
|
112
|
+
var anyChange = false;
|
|
113
|
+
// loop over all index keys in object
|
|
114
|
+
for (var index in patchItem) {
|
|
115
|
+
var numIndex = index;
|
|
116
|
+
// patch the tuple at the given index
|
|
117
|
+
var currentValue = result[numIndex];
|
|
118
|
+
var newValue = patchEntry(currentValue, value, root, patchItem[index]);
|
|
119
|
+
if (!Object.is(newValue, currentValue)) {
|
|
120
|
+
// if value changed, set it in result and mark change
|
|
121
|
+
anyChange = true;
|
|
122
|
+
result[numIndex] = newValue;
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
if (anyChange) {
|
|
126
|
+
// something changed, return new value
|
|
127
|
+
return result;
|
|
128
|
+
}
|
|
129
|
+
// nothing changed, return old value
|
|
130
|
+
return value;
|
|
101
131
|
}
|
|
102
|
-
|
|
103
|
-
0 && (module.exports = {
|
|
104
|
-
patch
|
|
105
|
-
});
|
|
132
|
+
//# sourceMappingURL=patch.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"patch.cjs","sourceRoot":"","sources":["../../_cjs_prepare/patch.cts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import { type IsAnyFunc, type IsArray, type IsPlainObj } from '@rimbu/base';
|
|
2
|
+
import type { Protected } from './internal.cjs';
|
|
3
|
+
import type { Tuple } from './tuple.cjs';
|
|
4
|
+
/**
|
|
5
|
+
* A type to determine the allowed input type for the `patch` function.
|
|
6
|
+
* @typeparam T - the input type to be patched
|
|
7
|
+
*/
|
|
8
|
+
export type Patch<T, C = T> = Patch.Entry<T, C, T, T>;
|
|
9
|
+
export declare namespace Patch {
|
|
10
|
+
/**
|
|
11
|
+
* 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.
|
|
12
|
+
* @typeparam T - the input value type
|
|
13
|
+
* @typeparam C - a utility type
|
|
14
|
+
* @typeparam P - the parent type
|
|
15
|
+
* @typeparam R - the root object type
|
|
16
|
+
*/
|
|
17
|
+
type Entry<T, C, P, R> = IsAnyFunc<T> extends true ? T : IsPlainObj<T> extends true ? Patch.WithResult<T, P, R, Patch.Obj<T, C, R>> : Tuple.IsTuple<T> extends true ? Patch.WithResult<T, P, R, T | Patch.Tup<T, C, R>> : IsArray<T> extends true ? Patch.WithResult<T, P, R, T> : Patch.WithResult<T, P, R, T>;
|
|
18
|
+
/**
|
|
19
|
+
* Either result type S, or a patch function with the value type, the parent type, and the root type.
|
|
20
|
+
* @typeparam T - the value type
|
|
21
|
+
* @typeparam P - the parent type
|
|
22
|
+
* @typeparam R - the root type
|
|
23
|
+
* @typeparam S - the result type
|
|
24
|
+
*/
|
|
25
|
+
type WithResult<T, P, R, S> = S | Patch.Func<T, P, R, S>;
|
|
26
|
+
/**
|
|
27
|
+
* A function patch type that is a function taking the current value, the parent and root values,
|
|
28
|
+
* and returns a return value.
|
|
29
|
+
* @typeparam T - the value type
|
|
30
|
+
* @typeparam P - the parent type
|
|
31
|
+
* @typeparam R - the root type
|
|
32
|
+
* @typeparam S - the result type
|
|
33
|
+
*/
|
|
34
|
+
type Func<T, P, R, S> = (current: Protected<T>, parent: Protected<P>, root: Protected<R>) => Protected<S>;
|
|
35
|
+
/**
|
|
36
|
+
* A type defining the allowed patch values for tuples.
|
|
37
|
+
* @typeparam T - the input tuple type
|
|
38
|
+
* @typeparam C - a utility type
|
|
39
|
+
* @typeparam R - the root type
|
|
40
|
+
*/
|
|
41
|
+
type Tup<T, C, R> = {
|
|
42
|
+
[K in Tuple.KeysOf<T>]?: Patch.Entry<T[K & keyof T], C[K & keyof C], T, R>;
|
|
43
|
+
} & NotIterable;
|
|
44
|
+
/**
|
|
45
|
+
* Utility type to exclude Iterable types.
|
|
46
|
+
*/
|
|
47
|
+
type NotIterable = {
|
|
48
|
+
[Symbol.iterator]?: never;
|
|
49
|
+
};
|
|
50
|
+
/**
|
|
51
|
+
* A type defining the allowed patch values for objects.
|
|
52
|
+
* @typeparam T - the input value type
|
|
53
|
+
* @typeparam C - a utility type
|
|
54
|
+
* @typeparam R - the root object type
|
|
55
|
+
*/
|
|
56
|
+
type Obj<T, C, R> = T | Patch.ObjProps<T, C, R>[];
|
|
57
|
+
/**
|
|
58
|
+
* A type defining the allowed patch values for object properties.
|
|
59
|
+
* @typeparam T - the input value type
|
|
60
|
+
* @typeparam C - a utility type
|
|
61
|
+
* @typeparam R - the root object type
|
|
62
|
+
*/
|
|
63
|
+
type ObjProps<T, C, R> = {
|
|
64
|
+
[K in keyof C]?: K extends keyof T ? Patch.Entry<T[K], C[K], T, R> : never;
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Returns an immutably updated version of the given `value` where the given `patchItems` have been
|
|
69
|
+
* applied to the result.
|
|
70
|
+
* The Rimbu patch notation is as follows:
|
|
71
|
+
* - if the target is a simple value or array, the patch can be the same type or a function returning the same type
|
|
72
|
+
* - 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
|
|
73
|
+
* - 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
|
|
74
|
+
* @typeparam T - the type of the value to patch
|
|
75
|
+
* @typeparam TE - a utility type
|
|
76
|
+
* @typeparam TT - a utility type
|
|
77
|
+
* @param value - the input value to patch
|
|
78
|
+
* @param patchItem - the `Patch` value to apply to the input value
|
|
79
|
+
* @example
|
|
80
|
+
* ```ts
|
|
81
|
+
* const input = { a: 1, b: { c: true, d: 'a' } }
|
|
82
|
+
* patch(input, [{ a: 2 }]) // => { a: 2, b: { c: true, d: 'a' } }
|
|
83
|
+
* patch(input, [{ b: [{ c: (v) => !v }] }] )
|
|
84
|
+
* // => { a: 1, b: { c: false, d: 'a' } }
|
|
85
|
+
* patch(input: [{ a: (v) => v + 1, b: [{ d: 'q' }] }] )
|
|
86
|
+
* // => { a: 2, b: { c: true, d: 'q' } }
|
|
87
|
+
* ```
|
|
88
|
+
*/
|
|
89
|
+
export declare function patch<T, TE extends T = T, TT = T>(value: T, patchItem: Patch<TE, T & TT>): T;
|