@rimbu/deep 0.11.3 → 0.12.1
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/deep.js +211 -0
- package/dist/main/deep.js.map +1 -0
- package/dist/main/index.js +7 -9
- package/dist/main/index.js.map +1 -1
- package/dist/main/internal.js +6 -4
- package/dist/main/internal.js.map +1 -1
- package/dist/main/match.js +160 -199
- package/dist/main/match.js.map +1 -1
- package/dist/main/patch.js +101 -125
- package/dist/main/patch.js.map +1 -1
- package/dist/main/path.js +109 -62
- package/dist/main/path.js.map +1 -1
- package/dist/main/protected.js +0 -19
- package/dist/main/protected.js.map +1 -1
- package/dist/main/selector.js +40 -0
- package/dist/main/selector.js.map +1 -0
- package/dist/main/tuple.js.map +1 -1
- package/dist/module/deep.js +192 -0
- package/dist/module/deep.js.map +1 -0
- package/dist/module/index.js +9 -1
- package/dist/module/index.js.map +1 -1
- package/dist/module/internal.js +4 -4
- package/dist/module/internal.js.map +1 -1
- package/dist/module/match.js +159 -179
- package/dist/module/match.js.map +1 -1
- package/dist/module/patch.js +91 -112
- package/dist/module/patch.js.map +1 -1
- package/dist/module/path.js +99 -44
- package/dist/module/path.js.map +1 -1
- package/dist/module/protected.js +1 -17
- package/dist/module/protected.js.map +1 -1
- package/dist/module/selector.js +36 -0
- package/dist/module/selector.js.map +1 -0
- package/dist/module/tuple.js.map +1 -1
- package/dist/types/deep.d.ts +284 -0
- package/dist/types/index.d.ts +10 -1
- package/dist/types/internal.d.ts +7 -4
- package/dist/types/match.d.ts +74 -80
- package/dist/types/patch.d.ts +57 -50
- package/dist/types/path.d.ts +177 -34
- package/dist/types/protected.d.ts +1 -16
- package/dist/types/selector.d.ts +47 -0
- package/dist/types/tuple.d.ts +10 -0
- package/package.json +3 -3
- package/src/deep.ts +364 -0
- package/src/index.ts +14 -10
- package/src/internal.ts +7 -4
- package/src/match.ts +396 -212
- package/src/patch.ts +173 -176
- package/src/path.ts +400 -74
- package/src/protected.ts +14 -25
- package/src/selector.ts +90 -0
- package/src/tuple.ts +12 -0
|
@@ -0,0 +1,284 @@
|
|
|
1
|
+
import type { Match, Patch, Path, Protected, Selector } from './internal';
|
|
2
|
+
export { match, type Match } from './match';
|
|
3
|
+
export { patch, type Patch } from './patch';
|
|
4
|
+
export { getAt, patchAt, type Path } from './path';
|
|
5
|
+
export { select, type Selector } from './selector';
|
|
6
|
+
export type { Protected } from './protected';
|
|
7
|
+
/**
|
|
8
|
+
* Returns the same value wrapped in the `Protected` type.
|
|
9
|
+
* @typeparam T - the source value type
|
|
10
|
+
* @param source - the value to wrap
|
|
11
|
+
* @note does not perform any runtime protection, it is only a utility to easily add the `Protected`
|
|
12
|
+
* type to a value
|
|
13
|
+
* @example
|
|
14
|
+
* ```ts
|
|
15
|
+
* const obj = Deep.protect({ a: 1, b: { c: true, d: [1] } })
|
|
16
|
+
* obj.a = 2 // compiler error: a is readonly
|
|
17
|
+
* obj.b.c = false // compiler error: c is readonly
|
|
18
|
+
* obj.b.d.push(2) // compiler error: d is a readonly array
|
|
19
|
+
* (obj as any).b.d.push(2) // will actually mutate the object
|
|
20
|
+
* ```
|
|
21
|
+
*/
|
|
22
|
+
export declare function protect<T>(source: T): Protected<T>;
|
|
23
|
+
/**
|
|
24
|
+
* Returns a function that gets the value at the given string `path` inside an object.
|
|
25
|
+
* @typeparam T - the input value type
|
|
26
|
+
* @typeparam P - the string literal path type in the object
|
|
27
|
+
* @param path - the string path in the object
|
|
28
|
+
* @param source - the value from which to extract the path value
|
|
29
|
+
* @example
|
|
30
|
+
* ```ts
|
|
31
|
+
* const items = [{ a: { b: 1, c: 'a' } }, { a: { b: 2, c: 'b' } }];
|
|
32
|
+
* items.map(Deep.getAtWith('a.c'));
|
|
33
|
+
* // => ['a', 'b']
|
|
34
|
+
* ```
|
|
35
|
+
*/
|
|
36
|
+
export declare function getAtWith<T, P extends Path.Get<T>>(path: P): (source: T) => Path.Result<T, P>;
|
|
37
|
+
/**
|
|
38
|
+
* Returns a function that patches a given `source` with the given `patchItems`.
|
|
39
|
+
* @typeparam T - the patch value type
|
|
40
|
+
* @typeparam TE - utility type
|
|
41
|
+
* @typeparam TT - utility type
|
|
42
|
+
* @param patchItem - the `Patch` definition to update the given value of type `T` with.
|
|
43
|
+
* @param source - the value to use the given `patchItem` on.
|
|
44
|
+
* @example
|
|
45
|
+
* ```ts
|
|
46
|
+
* const items = [{ a: 1, b: 'a' }, { a: 2, b: 'b' }];
|
|
47
|
+
* items.map(Deep.patchWith([{ a: v => v + 1 }]));
|
|
48
|
+
* // => [{ a: 2, b: 'a' }, { a: 3, b: 'b' }]
|
|
49
|
+
* ```
|
|
50
|
+
*/
|
|
51
|
+
export declare function patchWith<T, TE extends T = T, TT = T>(patchItem: Patch<TT, TE>): (source: TE) => T;
|
|
52
|
+
/**
|
|
53
|
+
* Returns a function that patches a given `value` with the given `patchItems` at the given `path`.
|
|
54
|
+
* @typeparam T - the patch value type
|
|
55
|
+
* @typeparam P - the string literal path type in the object
|
|
56
|
+
* @typeparam TE - utility type
|
|
57
|
+
* @typeparam TT - utility type
|
|
58
|
+
* @param path - the string path in the object
|
|
59
|
+
* @param patchItem - the `Patch` definition to update the value at the given `path` in `T` with.
|
|
60
|
+
* @param source - the value to use the given `patchItem` on at the given `path`.
|
|
61
|
+
* @example
|
|
62
|
+
* ```ts
|
|
63
|
+
* const items = [{ a: { b: 1, c: 'a' } }, { a: { b: 2, c: 'b' } }];
|
|
64
|
+
* items.map(Deep.patchAtWith('a', [{ b: (v) => v + 1 }]));
|
|
65
|
+
* // => [{ a: { b: 2, c: 'a' } }, { a: { b: 3, c: 'b' } }]
|
|
66
|
+
* ```
|
|
67
|
+
*/
|
|
68
|
+
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;
|
|
69
|
+
/**
|
|
70
|
+
* Returns a function that matches a given `value` with the given `matcher`.
|
|
71
|
+
* @typeparam T - the patch value type
|
|
72
|
+
* @param matcher - a matcher object that matches input values.
|
|
73
|
+
* @param source - the value to use the given `patchItem` on at the given `path`.
|
|
74
|
+
* @example
|
|
75
|
+
* ```ts
|
|
76
|
+
* const items = [{ a: 1, b: 'a' }, { a: 2, b: 'b' }];
|
|
77
|
+
* items.filter(Deep.matchWith({ a: 2 }));
|
|
78
|
+
* // => [{ a: 2, b: 'b' }]
|
|
79
|
+
* ```
|
|
80
|
+
*/
|
|
81
|
+
export declare function matchWith<T>(matcher: Match<T>): (source: T) => boolean;
|
|
82
|
+
/**
|
|
83
|
+
* Returns true if the given `value` object matches the given `matcher` at the given `path`, false otherwise.
|
|
84
|
+
* @typeparam T - the input value type
|
|
85
|
+
* @typeparam P - the string literal path type in the object
|
|
86
|
+
* @param source - the input value
|
|
87
|
+
* @param path - the string path in the object
|
|
88
|
+
* @param matcher - a matcher object or a function taking the matcher API and returning a match object
|
|
89
|
+
* @example
|
|
90
|
+
* ```ts
|
|
91
|
+
* const input = { a: 1, b: { c: true, d: 'a' } }
|
|
92
|
+
* Deep.matchAt(input, 'b', { c: true })
|
|
93
|
+
* // => true
|
|
94
|
+
* ```
|
|
95
|
+
*/
|
|
96
|
+
export declare function matchAt<T, P extends Path.Get<T>>(source: T, path: P, matcher: Match<Path.Result<T, P>>): boolean;
|
|
97
|
+
/**
|
|
98
|
+
* Returns a function that matches a given `value` with the given `matcher` at the given string `path`.
|
|
99
|
+
* @typeparam T - the patch value type
|
|
100
|
+
* @typeparam P - the string literal path type in the object
|
|
101
|
+
* @typeparam TE - utility type
|
|
102
|
+
* @param path - the string path in the object
|
|
103
|
+
* @param matcher - a matcher object that matches input values.
|
|
104
|
+
* @param source - the value to use the given `matcher` on at the given `path`.
|
|
105
|
+
* @example
|
|
106
|
+
* ```ts
|
|
107
|
+
* const items = [{ a: { b: 1, c: 'a' } }, { a: { b: 2, c: 'b' } }];
|
|
108
|
+
* items.filter(Deep.matchAtWith('a.b', 2));
|
|
109
|
+
* // => [{ a: 2, b: 'b' }]
|
|
110
|
+
* ```
|
|
111
|
+
*/
|
|
112
|
+
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;
|
|
113
|
+
/**
|
|
114
|
+
* Returns a function that selects a certain shape from a given `value` with the given `selector`.
|
|
115
|
+
* @typeparam T - the patch value type
|
|
116
|
+
* @typeparam SL - the selector shape type
|
|
117
|
+
* @param selector - a shape indicating the selection from the source values
|
|
118
|
+
* @param source - the value to use the given `selector` on.
|
|
119
|
+
* @example
|
|
120
|
+
* ```ts
|
|
121
|
+
* const items = [{ a: { b: 1, c: 'a' } }, { a: { b: 2, c: 'b' } }];
|
|
122
|
+
* items.map(Deep.selectWith({ q: 'a.c', z: ['a.b', v => v.a.b + 1] as const }));
|
|
123
|
+
* // => [{ q: 'a', z: [1, 2] }, { q: 'b', z: [2, 3] }]
|
|
124
|
+
* ```
|
|
125
|
+
*/
|
|
126
|
+
export declare function selectWith<T, SL extends Selector<T>>(selector: Selector.Shape<SL>): (source: T) => Selector.Result<T, SL>;
|
|
127
|
+
/**
|
|
128
|
+
* Returns the result of applying the given `selector` shape to the given `source` value.
|
|
129
|
+
* @typeparam T - the patch value type
|
|
130
|
+
* @typeparam P - the string literal path type in the object
|
|
131
|
+
* @typeparam SL - the selector shape type
|
|
132
|
+
* @param source - the source value to select from
|
|
133
|
+
* @param path - the string path in the object
|
|
134
|
+
* @param selector - a shape indicating the selection from the source value at the given path
|
|
135
|
+
* @example
|
|
136
|
+
* ```ts
|
|
137
|
+
* const item = { a: { b: 1, c: 'a' } };
|
|
138
|
+
* Deep.selectAt(item, 'a', { q: 'c', z: ['b', v => v.b + 1] as const });
|
|
139
|
+
* // => { q: 'a', z: [1, 2] }
|
|
140
|
+
* ```
|
|
141
|
+
*/
|
|
142
|
+
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>;
|
|
143
|
+
/**
|
|
144
|
+
* Returns a function that selects a certain shape from a given `value` with the given `selector` at the given string `path`.
|
|
145
|
+
* @typeparam T - the patch value type
|
|
146
|
+
* @typeparam P - the string literal path type in the object
|
|
147
|
+
* @typeparam SL - the selector shape type
|
|
148
|
+
* @param path - the string path in the object
|
|
149
|
+
* @param selector - a shape indicating the selection from the source values
|
|
150
|
+
* @example
|
|
151
|
+
* ```ts
|
|
152
|
+
* const items = [{ a: { b: 1, c: 'a' } }, { a: { b: 2, c: 'b' } }];
|
|
153
|
+
* items.map(Deep.selectAtWith('a', { q: 'c', z: ['b', v => v.b + 1] as const }));
|
|
154
|
+
* // => [{ q: 'a', z: [1, 2] }, { q: 'b', z: [2, 3] }]
|
|
155
|
+
* ```
|
|
156
|
+
*/
|
|
157
|
+
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>;
|
|
158
|
+
/**
|
|
159
|
+
* Typed and curried Deep API, used in situations where the target type
|
|
160
|
+
* is known but the value will be applied later.
|
|
161
|
+
* @typeparam T - the target type
|
|
162
|
+
* @example
|
|
163
|
+
* ```ts
|
|
164
|
+
* const s = { a: 1, b: { c: 'a', d: true }};
|
|
165
|
+
* const upd = Deep.withType<typeof s>().patchWith([{ a: (v) => v + 1 }]);
|
|
166
|
+
* upd(s);
|
|
167
|
+
* // => { a: 2, b: { c: 'a', d: true }}
|
|
168
|
+
* ```
|
|
169
|
+
*/
|
|
170
|
+
export interface WithType<T> {
|
|
171
|
+
/**
|
|
172
|
+
* Returns a function that given an object returns the value at the given `path`.
|
|
173
|
+
* @typeparam P - a Path in object type T
|
|
174
|
+
* @param path - the path into the object
|
|
175
|
+
* @example
|
|
176
|
+
* ```ts
|
|
177
|
+
* const value = { a: { b: { c: 5 } } }
|
|
178
|
+
* const getValue = Deep.withType<typeof value>().getAtWith('a.b.c');
|
|
179
|
+
* getValue(value);
|
|
180
|
+
* // => 5
|
|
181
|
+
* ```
|
|
182
|
+
*/
|
|
183
|
+
getAtWith<P extends Path.Get<T>>(path: P): (source: T) => Path.Result<T, P>;
|
|
184
|
+
/**
|
|
185
|
+
* Returns a function that patches a given `value` with the given `patchItems`.
|
|
186
|
+
* @typeparam TT - utility type
|
|
187
|
+
* @param patchItem - the `Patch` definition to update the given value with
|
|
188
|
+
* @param source - the value to use the given `patchItem` on.
|
|
189
|
+
* @example
|
|
190
|
+
* ```ts
|
|
191
|
+
* const value = { a: 1, b: 'a' };
|
|
192
|
+
* const upd = Deep.withType<typeof value>().patch([{ a: v => v + 1 }]);
|
|
193
|
+
* upd(value);
|
|
194
|
+
* // => { a: 2, b: 'a' }
|
|
195
|
+
* ```
|
|
196
|
+
*/
|
|
197
|
+
patchWith<TE extends T = T, TT = T>(patchItem: Patch<TT, TE>): (source: TE) => T;
|
|
198
|
+
/**
|
|
199
|
+
* Returns a function that patches a given `value` with the given `patchItems` at the given `path`.
|
|
200
|
+
* @typeparam P - the string literal path type in the object
|
|
201
|
+
* @typeparam TT - utility type
|
|
202
|
+
* @param path - the string path in the object
|
|
203
|
+
* @param patchItem - the `Patch` definition to update the given value with
|
|
204
|
+
* @param source - the value to use the given `patchItem` on at the given `path`.
|
|
205
|
+
* @example
|
|
206
|
+
* ```ts
|
|
207
|
+
* const value = { a: { b: 1, c: 'a' } };
|
|
208
|
+
* const upd = Deep.withType<typeof value>().patchAtWith('a', [{ b: (v) => v + 1 }])
|
|
209
|
+
* upd(value);
|
|
210
|
+
* // => { a: { b: 2, c: 'a' } }
|
|
211
|
+
* ```
|
|
212
|
+
*/
|
|
213
|
+
patchAtWith<P extends Path.Set<T>, TT = T>(path: P, patchItem: Patch<Path.Result<T, P>, Path.Result<TT, P>>): (source: T) => T;
|
|
214
|
+
/**
|
|
215
|
+
* Returns a function that matches a given `value` with the given `matcher`.
|
|
216
|
+
* @param matcher - a matcher object that matches input values.
|
|
217
|
+
* @param source - the value to use the given `matcher` on.
|
|
218
|
+
* @example
|
|
219
|
+
* ```ts
|
|
220
|
+
* const value = { a: 1, b: 'a' };
|
|
221
|
+
* const m = Deep.withType<typeof value>().matchWith({ a: 1 });
|
|
222
|
+
* m(value);
|
|
223
|
+
* // => true
|
|
224
|
+
* ```
|
|
225
|
+
*/
|
|
226
|
+
matchWith(matcher: Match<T>): (source: T) => boolean;
|
|
227
|
+
/**
|
|
228
|
+
* Returns a function that matches a given `value` with the given `matcher` at the given string `path`.
|
|
229
|
+
* @typeparam P - the string literal path type in the object
|
|
230
|
+
* @param path - the string path in the object
|
|
231
|
+
* @param matcher - a matcher object that matches input values.
|
|
232
|
+
* @param source - the value to use the given `matcher` on at the given `path`.
|
|
233
|
+
* @example
|
|
234
|
+
* ```ts
|
|
235
|
+
* const items = [{ a: { b: 1, c: 'a' } }, { a: { b: 2, c: 'b' } }];
|
|
236
|
+
* items.filter(Deep.matchAtWith('a.b', 2));
|
|
237
|
+
* // => [{ a: 2, b: 'b' }]
|
|
238
|
+
* ```
|
|
239
|
+
*/
|
|
240
|
+
matchAtWith<P extends Path.Get<T>>(path: P, matcher: Match<Path.Result<T, P>>): (source: T) => boolean;
|
|
241
|
+
/**
|
|
242
|
+
* Returns a function that selects a certain shape from a given `value` with the given `selector`.
|
|
243
|
+
* @typeparam SL - the selector shape type
|
|
244
|
+
* @param selector - a shape indicating the selection from the source values
|
|
245
|
+
* @param source - the value to use the given `selector` on.
|
|
246
|
+
* @example
|
|
247
|
+
* ```ts
|
|
248
|
+
* const value = { a: { b: 1, c: 'a' } };
|
|
249
|
+
* const sel = Deep.withType<typeof value>().selectWith({ q: 'a.b' });
|
|
250
|
+
* sel(value);
|
|
251
|
+
* // => { q: 1 }
|
|
252
|
+
* ```
|
|
253
|
+
*/
|
|
254
|
+
selectWith<SL extends Selector<T>>(selector: Selector.Shape<SL>): (source: T) => Selector.Result<T, SL>;
|
|
255
|
+
/**
|
|
256
|
+
* Returns a function that selects a certain shape from a given `value` with the given `selector` at the given string `path`.
|
|
257
|
+
* @typeparam P - the string literal path type in the object
|
|
258
|
+
* @typeparam SL - the selector shape type
|
|
259
|
+
* @param path - the string path in the object
|
|
260
|
+
* @param selector - a shape indicating the selection from the source values
|
|
261
|
+
* @param source - the value to use the given `selector` on at the given `path`.
|
|
262
|
+
* @example
|
|
263
|
+
* ```ts
|
|
264
|
+
* const value = { a: { b: 1, c: 'a' } };
|
|
265
|
+
* const sel = Deep.withType<typeof value>().selectAtWith('a', { q: 'b' });
|
|
266
|
+
* sel(value);
|
|
267
|
+
* // => { q: 1 }
|
|
268
|
+
* ```
|
|
269
|
+
*/
|
|
270
|
+
selectAtWith<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>;
|
|
271
|
+
}
|
|
272
|
+
/**
|
|
273
|
+
* Returns a curried API with a known target type. This can be useful for using the methods in
|
|
274
|
+
* contexts where the target type can be inferred from the usage.
|
|
275
|
+
* @typeparam T - the target type
|
|
276
|
+
* @example
|
|
277
|
+
* ```ts
|
|
278
|
+
* const s = { a: 1, b: { c: 'a', d: true }}
|
|
279
|
+
* const upd = Deep.withType<typeof s>().patchWith([{ d: (v) => !v }])
|
|
280
|
+
* upd(s)
|
|
281
|
+
* // => { a: 1, b: { c: 'a', d: false }}
|
|
282
|
+
* ```
|
|
283
|
+
*/
|
|
284
|
+
export declare function withType<T>(): WithType<T>;
|
package/dist/types/index.d.ts
CHANGED
|
@@ -5,5 +5,14 @@
|
|
|
5
5
|
* <br/>
|
|
6
6
|
* See the [Rimbu docs Deep overview page](/docs/deep/overview) for more information.
|
|
7
7
|
*/
|
|
8
|
-
export { patch, patchNested, Patch, match, Match, Path, Protected, } from './internal';
|
|
9
8
|
export { Tuple } from './tuple';
|
|
9
|
+
export type { Protected, Patch } from './internal';
|
|
10
|
+
export { Path, type Selector, type Match } from './internal';
|
|
11
|
+
export * from './deep';
|
|
12
|
+
import * as Deep from './deep';
|
|
13
|
+
export {
|
|
14
|
+
/**
|
|
15
|
+
* Convenience namespace offering access to most common functions used in the `@rimbu/deep` package.
|
|
16
|
+
* These are mainly utilities to patch and match plain JavaScript objects.
|
|
17
|
+
*/
|
|
18
|
+
Deep, };
|
package/dist/types/internal.d.ts
CHANGED
|
@@ -1,4 +1,7 @@
|
|
|
1
|
-
export
|
|
2
|
-
export
|
|
3
|
-
export
|
|
4
|
-
export
|
|
1
|
+
export type { Protected } from './protected';
|
|
2
|
+
export { Path } from './path';
|
|
3
|
+
export { type Match } from './match';
|
|
4
|
+
export type { Patch } from './patch';
|
|
5
|
+
export type { Selector } from './selector';
|
|
6
|
+
import * as Deep from './deep';
|
|
7
|
+
export { Deep };
|
package/dist/types/match.d.ts
CHANGED
|
@@ -1,124 +1,118 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { IsAnyFunc, IsArray, IsPlainObj, NotIterable } from '@rimbu/base';
|
|
2
2
|
import type { Protected } from './internal';
|
|
3
|
+
import type { Tuple } from './tuple';
|
|
3
4
|
/**
|
|
4
|
-
* The type to determine the allowed input values for the `match`
|
|
5
|
+
* The type to determine the allowed input values for the `match` function.
|
|
5
6
|
* @typeparam T - the type of value to match
|
|
7
|
+
* @typeparam C - utility type
|
|
6
8
|
*/
|
|
7
|
-
export declare type Match<T> = Match.
|
|
9
|
+
export declare type Match<T, C extends Partial<T> = Partial<T>> = Match.Entry<T, C, T, T>;
|
|
8
10
|
export declare namespace Match {
|
|
9
11
|
/**
|
|
10
|
-
*
|
|
11
|
-
* @typeparam T - the
|
|
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 parant type
|
|
12
16
|
* @typeparam R - the root object type
|
|
13
17
|
*/
|
|
14
|
-
type
|
|
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 ? // determine allowed match values for array or tuple
|
|
19
|
+
Match.Arr<T, C, P, R> | Match.Func<T, P, R, Match.Arr<T, C, P, R>> : Match.WithResult<T, P, R, {
|
|
20
|
+
[K in keyof C]: C[K & keyof T];
|
|
21
|
+
}>;
|
|
15
22
|
/**
|
|
16
|
-
* The type
|
|
17
|
-
* @typeparam T - the
|
|
23
|
+
* The type that determines allowed matchers for objects.
|
|
24
|
+
* @typeparam T - the input value type
|
|
25
|
+
* @typeparam C - utility type
|
|
26
|
+
* @typeparam P - the parant type
|
|
18
27
|
* @typeparam R - the root object type
|
|
19
28
|
*/
|
|
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
|
-
};
|
|
29
|
+
type Obj<T, C, P, R> = Match.ObjProps<T, C, R> | Match.CompoundForObj<T, C, P, R>;
|
|
23
30
|
/**
|
|
24
31
|
* The type to determine allowed matchers for object properties.
|
|
25
|
-
* @typeparam T - the
|
|
32
|
+
* @typeparam T - the input value type
|
|
33
|
+
* @typeparam C - utility type
|
|
26
34
|
* @typeparam R - the root object type
|
|
27
35
|
*/
|
|
28
|
-
type
|
|
36
|
+
type ObjProps<T, C, R> = {
|
|
37
|
+
[K in keyof C]?: K extends keyof T ? Match.Entry<T[K], C[K], T, R> : never;
|
|
38
|
+
};
|
|
29
39
|
/**
|
|
30
|
-
*
|
|
31
|
-
* @typeparam T - the
|
|
40
|
+
* The type that determines allowed matchers for arrays/tuples.
|
|
41
|
+
* @typeparam T - the input value type
|
|
42
|
+
* @typeparam C - utility type
|
|
43
|
+
* @typeparam P - the parant type
|
|
32
44
|
* @typeparam R - the root object type
|
|
33
|
-
* @typeparam Q - a utility type for the matcher
|
|
34
|
-
* @param matchItems - the match specifications to test
|
|
35
|
-
* @example
|
|
36
|
-
* ```ts
|
|
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
|
|
40
|
-
* ```
|
|
41
45
|
*/
|
|
42
|
-
|
|
46
|
+
type Arr<T, C, P, R> = C | Match.CompoundForArr<T, C, P, R> | (Match.TupIndices<T, C, R> & {
|
|
47
|
+
[K in Match.CompoundType]?: never;
|
|
48
|
+
});
|
|
49
|
+
type WithResult<T, P, R, S> = S | Match.Func<T, P, R, S>;
|
|
43
50
|
/**
|
|
44
|
-
*
|
|
45
|
-
* @typeparam T - the
|
|
51
|
+
* Type used to determine the allowed function types. Always includes booleans.
|
|
52
|
+
* @typeparam T - the input value type
|
|
53
|
+
* @typeparam P - the parant type
|
|
46
54
|
* @typeparam R - the root object type
|
|
47
|
-
* @typeparam
|
|
48
|
-
* @param matchItems - the match specifications to test
|
|
49
|
-
* @example
|
|
50
|
-
* ```ts
|
|
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
|
|
54
|
-
* ```
|
|
55
|
+
* @typeparam S - the allowed return value type
|
|
55
56
|
*/
|
|
56
|
-
|
|
57
|
+
type Func<T, P, R, S> = (current: Protected<T>, parent: Protected<P>, root: Protected<R>) => boolean | S;
|
|
57
58
|
/**
|
|
58
|
-
*
|
|
59
|
-
* @typeparam T - the
|
|
59
|
+
* Type used to indicate an object containing matches for tuple indices.
|
|
60
|
+
* @typeparam T - the input value type
|
|
61
|
+
* @typeparam C - utility type
|
|
60
62
|
* @typeparam R - the root object type
|
|
61
|
-
* @typeparam Q - a utility type for the matcher
|
|
62
|
-
* @param matchItems - the match specifications to test
|
|
63
|
-
* @example
|
|
64
|
-
* ```ts
|
|
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
|
|
68
|
-
* ```
|
|
69
63
|
*/
|
|
70
|
-
|
|
64
|
+
type TupIndices<T, C, R> = {
|
|
65
|
+
[K in Tuple.KeysOf<C>]?: Match.Entry<T[K & keyof T], C[K], T, R>;
|
|
66
|
+
} & NotIterable;
|
|
67
|
+
/**
|
|
68
|
+
* Compound keys used to indicate the type of compound.
|
|
69
|
+
*/
|
|
70
|
+
type CompoundType = 'every' | 'some' | 'none' | 'single';
|
|
71
71
|
/**
|
|
72
|
-
*
|
|
73
|
-
* @typeparam T - the
|
|
72
|
+
* Compount matcher for objects, can only be an array staring with a compound type keyword.
|
|
73
|
+
* @typeparam T - the input value type
|
|
74
|
+
* @typeparam C - utility type
|
|
75
|
+
* @typeparam P - the parent type
|
|
74
76
|
* @typeparam R - the root object type
|
|
75
|
-
* @typeparam Q - a utility type for the matcher
|
|
76
|
-
* @param matchItems - the match specifications to test
|
|
77
|
-
* @example
|
|
78
|
-
* ```ts
|
|
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
|
|
82
|
-
* ```
|
|
83
77
|
*/
|
|
84
|
-
|
|
78
|
+
type CompoundForObj<T, C, P, R> = [
|
|
79
|
+
Match.CompoundType,
|
|
80
|
+
...Match.Entry<T, C, P, R>[]
|
|
81
|
+
];
|
|
85
82
|
/**
|
|
86
|
-
*
|
|
83
|
+
* Defines an object containing exactly one `CompoundType` key, having an array of matchers.
|
|
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
|
|
87
88
|
*/
|
|
88
|
-
type
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
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>[]);
|
|
89
|
+
type CompoundForArr<T, C, P, R> = {
|
|
90
|
+
[K in CompoundType]: {
|
|
91
|
+
[K2 in CompoundType]?: K2 extends K ? Match.Entry<T, C, P, R>[] : never;
|
|
92
|
+
};
|
|
93
|
+
}[CompoundType];
|
|
94
|
+
/**
|
|
95
|
+
* Utility type for collecting errors
|
|
96
|
+
*/
|
|
97
|
+
type ErrorCollector = string[] | undefined;
|
|
105
98
|
}
|
|
106
99
|
/**
|
|
107
100
|
* Returns true if the given `value` object matches the given `matcher`, false otherwise.
|
|
108
101
|
* @typeparam T - the input value type
|
|
109
|
-
* @
|
|
102
|
+
* @typeparam C - utility type
|
|
103
|
+
* @param source - the value to match (should be a plain object)
|
|
110
104
|
* @param matcher - a matcher object or a function taking the matcher API and returning a match object
|
|
105
|
+
* @param errorCollector - (optional) a string array that can be passed to collect reasons why the match failed
|
|
111
106
|
* @example
|
|
112
107
|
* ```ts
|
|
113
108
|
* const input = { a: 1, b: { c: true, d: 'a' } }
|
|
114
109
|
* match(input, { a: 1 }) // => true
|
|
115
110
|
* match(input, { a: 2 }) // => false
|
|
116
|
-
* match(input, { a: v => v > 10 }) // => false
|
|
111
|
+
* match(input, { a: (v) => v > 10 }) // => false
|
|
117
112
|
* match(input, { b: { c: true }}) // => true
|
|
118
|
-
* match(input, (
|
|
113
|
+
* match(input, (['every', { a: (v) => v > 0 }, { b: { c: true } }]) // => true
|
|
119
114
|
* match(input, { b: { c: (v, parent, root) => v && parent.d.length > 0 && root.a > 0 } })
|
|
120
115
|
* // => true
|
|
121
116
|
* ```
|
|
122
117
|
*/
|
|
123
|
-
export declare function match<T
|
|
124
|
-
export {};
|
|
118
|
+
export declare function match<T, C extends Partial<T> = Partial<T>>(source: T, matcher: Match<T, C>, errorCollector?: Match.ErrorCollector): boolean;
|
package/dist/types/patch.d.ts
CHANGED
|
@@ -1,82 +1,89 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { IsAnyFunc, IsArray, IsPlainObj } from '@rimbu/base';
|
|
2
2
|
import type { Protected } from './internal';
|
|
3
|
+
import type { Tuple } from './tuple';
|
|
3
4
|
/**
|
|
4
5
|
* A type to determine the allowed input type for the `patch` function.
|
|
5
6
|
* @typeparam T - the input type to be patched
|
|
6
7
|
*/
|
|
7
|
-
export declare type Patch<T> = Patch.Entry<T, T>;
|
|
8
|
+
export declare type Patch<T, C = T> = Patch.Entry<T, C, T, T>;
|
|
8
9
|
export declare namespace Patch {
|
|
9
10
|
/**
|
|
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.
|
|
11
12
|
* @typeparam T - the input value type
|
|
13
|
+
* @typeparam C - a utility type
|
|
14
|
+
* @typeparam P - the parent type
|
|
12
15
|
* @typeparam R - the root object type
|
|
13
16
|
*/
|
|
14
|
-
type Entry<T, R> = Patch.Obj<T, R> |
|
|
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>;
|
|
15
18
|
/**
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
* @typeparam
|
|
19
|
-
* @typeparam R - the root
|
|
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.
|
|
20
46
|
*/
|
|
21
|
-
type
|
|
22
|
-
[
|
|
47
|
+
type NotIterable = {
|
|
48
|
+
[Symbol.iterator]?: never;
|
|
23
49
|
};
|
|
24
50
|
/**
|
|
25
|
-
* A
|
|
51
|
+
* A type defining the allowed patch values for objects.
|
|
26
52
|
* @typeparam T - the input value type
|
|
53
|
+
* @typeparam C - a utility type
|
|
27
54
|
* @typeparam R - the root object type
|
|
28
55
|
*/
|
|
29
|
-
type
|
|
30
|
-
/**
|
|
31
|
-
* The function type to create a nested Patch object.
|
|
32
|
-
*/
|
|
33
|
-
type Nested = typeof patchNested;
|
|
56
|
+
type Obj<T, C, R> = T | Patch.ObjProps<T, C, R>[];
|
|
34
57
|
/**
|
|
35
|
-
*
|
|
36
|
-
* @typeparam T - the
|
|
37
|
-
* @typeparam
|
|
38
|
-
* @
|
|
39
|
-
* @example
|
|
40
|
-
* ```ts
|
|
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' }]
|
|
44
|
-
* ```
|
|
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
|
|
45
62
|
*/
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
readonly patchDataItems: Patch.Obj<Q, R>[];
|
|
50
|
-
constructor(patchDataItems: Patch.Obj<Q, R>[]);
|
|
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
|
+
};
|
|
51
66
|
}
|
|
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
|
/**
|
|
67
68
|
* Returns an immutably updated version of the given `value` where the given `patchItems` have been
|
|
68
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
|
|
69
77
|
* @param value - the input value to patch
|
|
70
|
-
* @param
|
|
78
|
+
* @param patchItem - the `Patch` value to apply to the input value
|
|
71
79
|
* @example
|
|
72
80
|
* ```ts
|
|
73
81
|
* const input = { a: 1, b: { c: true, d: 'a' } }
|
|
74
|
-
* patch(input, { a: 2 }) // => { a: 2, b: { c: true, d: 'a' } }
|
|
75
|
-
* patch(input
|
|
82
|
+
* patch(input, [{ a: 2 }]) // => { a: 2, b: { c: true, d: 'a' } }
|
|
83
|
+
* patch(input, [{ b: [{ c: (v) => !v }] }] )
|
|
76
84
|
* // => { a: 1, b: { c: false, d: 'a' } }
|
|
77
|
-
* patch(input:
|
|
85
|
+
* patch(input: [{ a: (v) => v + 1, b: [{ d: 'q' }] }] )
|
|
78
86
|
* // => { a: 2, b: { c: true, d: 'q' } }
|
|
79
87
|
* ```
|
|
80
88
|
*/
|
|
81
|
-
export declare function patch<T>(value: T
|
|
82
|
-
export {};
|
|
89
|
+
export declare function patch<T, TE extends T = T, TT = T>(value: T, patchItem: Patch<TE, T & TT>): T;
|