@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.
Files changed (56) hide show
  1. package/README.md +37 -27
  2. package/dist/bun/deep.mts +2 -2
  3. package/dist/bun/match.mts +27 -25
  4. package/dist/bun/patch.mts +10 -9
  5. package/dist/bun/path.mts +94 -95
  6. package/dist/bun/protected.mts +18 -17
  7. package/dist/bun/selector.mts +22 -20
  8. package/dist/bun/tuple.mts +1 -1
  9. package/dist/cjs/deep.cjs +197 -576
  10. package/dist/cjs/deep.cjs.map +1 -0
  11. package/dist/cjs/deep.d.cts +284 -0
  12. package/dist/cjs/index.cjs +18 -662
  13. package/dist/cjs/index.cjs.map +1 -0
  14. package/dist/cjs/index.d.cts +18 -0
  15. package/dist/cjs/internal.cjs +8 -582
  16. package/dist/cjs/internal.cjs.map +1 -0
  17. package/dist/cjs/internal.d.cts +7 -0
  18. package/dist/cjs/match.cjs +250 -343
  19. package/dist/cjs/match.cjs.map +1 -0
  20. package/dist/cjs/match.d.cts +140 -0
  21. package/dist/cjs/patch.cjs +120 -93
  22. package/dist/cjs/patch.cjs.map +1 -0
  23. package/dist/cjs/patch.d.cts +89 -0
  24. package/dist/cjs/path.cjs +114 -573
  25. package/dist/cjs/path.cjs.map +1 -0
  26. package/dist/cjs/path.d.cts +199 -0
  27. package/dist/cjs/protected.cjs +2 -17
  28. package/dist/cjs/protected.cjs.map +1 -0
  29. package/dist/cjs/selector.cjs +32 -574
  30. package/dist/cjs/selector.cjs.map +1 -0
  31. package/dist/cjs/selector.d.cts +47 -0
  32. package/dist/cjs/tuple.cjs +162 -71
  33. package/dist/cjs/tuple.cjs.map +1 -0
  34. package/dist/esm/match.mjs.map +1 -1
  35. package/dist/esm/patch.mjs.map +1 -1
  36. package/dist/{types → esm}/path.d.mts +4 -1
  37. package/dist/esm/path.mjs.map +1 -1
  38. package/dist/esm/protected.d.mts +17 -0
  39. package/dist/esm/selector.mjs.map +1 -1
  40. package/dist/esm/tuple.d.mts +142 -0
  41. package/package.json +20 -14
  42. package/src/deep.mts +2 -2
  43. package/src/match.mts +27 -25
  44. package/src/patch.mts +10 -9
  45. package/src/path.mts +94 -95
  46. package/src/protected.mts +18 -17
  47. package/src/selector.mts +22 -20
  48. package/src/tuple.mts +1 -1
  49. /package/dist/{types/protected.d.mts → cjs/protected.d.cts} +0 -0
  50. /package/dist/{types/tuple.d.mts → cjs/tuple.d.cts} +0 -0
  51. /package/dist/{types → esm}/deep.d.mts +0 -0
  52. /package/dist/{types → esm}/index.d.mts +0 -0
  53. /package/dist/{types → esm}/internal.d.mts +0 -0
  54. /package/dist/{types → esm}/match.d.mts +0 -0
  55. /package/dist/{types → esm}/patch.d.mts +0 -0
  56. /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;
@@ -1,105 +1,132 @@
1
1
  "use strict";
2
- var __defProp = Object.defineProperty;
3
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
- var __getOwnPropNames = Object.getOwnPropertyNames;
5
- var __hasOwnProp = Object.prototype.hasOwnProperty;
6
- var __export = (target, all) => {
7
- for (var name in all)
8
- __defProp(target, name, { get: all[name], enumerable: true });
9
- };
10
- var __copyProps = (to, from, except, desc) => {
11
- if (from && typeof from === "object" || typeof from === "function") {
12
- for (let key of __getOwnPropNames(from))
13
- if (!__hasOwnProp.call(to, key) && key !== except)
14
- __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
- }
16
- return to;
17
- };
18
- var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
-
20
- // src/patch.mts
21
- var patch_exports = {};
22
- __export(patch_exports, {
23
- patch: () => patch
24
- });
25
- module.exports = __toCommonJS(patch_exports);
26
- var import_base = require("@rimbu/base");
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
- return patchEntry(value, value, value, patchItem);
29
+ return patchEntry(value, value, value, patchItem);
29
30
  }
30
31
  function patchEntry(value, parent, root, patchItem) {
31
- if (Object.is(value, patchItem)) {
32
- return value;
33
- }
34
- if (typeof value === "function") {
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
- if (!Array.isArray(patchItem)) {
51
- return patchItem;
52
- }
53
- const result = { ...value };
54
- let anyChange = false;
55
- for (const entry of patchItem) {
56
- const currentRoot = value === root ? { ...result } : root;
57
- const parent = { ...result };
58
- for (const key in entry) {
59
- const currentValue = result[key];
60
- const newValue = patchEntry(
61
- currentValue,
62
- parent,
63
- currentRoot,
64
- entry[key]
65
- );
66
- if (!Object.is(currentValue, newValue)) {
67
- anyChange = true;
68
- result[key] = newValue;
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
- if (anyChange) {
73
- return result;
74
- }
75
- return value;
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
- if (Array.isArray(patchItem)) {
79
- return patchItem;
80
- }
81
- const result = [...value];
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
- if (anyChange) {
98
- return result;
99
- }
100
- return value;
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
- // Annotate the CommonJS export names for ESM import in node:
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;