@fgv/ts-utils 5.0.2 → 5.1.0-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.
Files changed (104) hide show
  1. package/README.md +152 -84
  2. package/dist/index.js +2 -2
  3. package/dist/packlets/base/messageAggregator.js +6 -6
  4. package/dist/packlets/base/result.js +39 -39
  5. package/dist/packlets/base/utils.js +47 -0
  6. package/dist/packlets/collections/aggregatedResultMap.js +722 -0
  7. package/dist/packlets/collections/collector.js +9 -9
  8. package/dist/packlets/collections/collectorValidator.js +4 -4
  9. package/dist/packlets/collections/converters.js +39 -0
  10. package/dist/packlets/collections/convertingCollectorValidator.js +3 -3
  11. package/dist/packlets/collections/convertingResultMap.js +208 -0
  12. package/dist/packlets/collections/index.js +4 -0
  13. package/dist/packlets/collections/keyValueConverters.js +1 -4
  14. package/dist/packlets/collections/readOnlyConvertingResultMap.js +193 -0
  15. package/dist/packlets/collections/resultMapValidator.js +50 -6
  16. package/dist/packlets/collections/validatingConvertingResultMap.js +78 -0
  17. package/dist/packlets/conversion/advancedConverters.js +249 -0
  18. package/dist/packlets/conversion/baseConverter.js +23 -16
  19. package/dist/packlets/conversion/basicConverters.js +571 -0
  20. package/dist/packlets/conversion/converters.js +3 -617
  21. package/dist/packlets/conversion/defaultingConverter.js +21 -15
  22. package/dist/packlets/logging/bootLogger.js +122 -0
  23. package/dist/packlets/logging/index.js +1 -0
  24. package/dist/packlets/logging/logReporter.js +32 -1
  25. package/dist/packlets/logging/logger.js +25 -5
  26. package/dist/packlets/validation/classes.js +1 -0
  27. package/dist/packlets/validation/compositeId.js +60 -0
  28. package/dist/packlets/validation/field.js +1 -1
  29. package/dist/packlets/validation/genericValidator.js +24 -10
  30. package/dist/packlets/validation/object.js +3 -6
  31. package/dist/packlets/validation/validators.js +12 -0
  32. package/dist/ts-utils.d.ts +1633 -200
  33. package/dist/tsdoc-metadata.json +1 -1
  34. package/lib/index.d.ts +2 -2
  35. package/lib/index.js +2 -1
  36. package/lib/packlets/base/mapResults.d.ts +3 -3
  37. package/lib/packlets/base/messageAggregator.d.ts +6 -6
  38. package/lib/packlets/base/messageAggregator.js +6 -6
  39. package/lib/packlets/base/result.d.ts +74 -51
  40. package/lib/packlets/base/result.js +39 -39
  41. package/lib/packlets/base/utils.d.ts +42 -0
  42. package/lib/packlets/base/utils.js +52 -0
  43. package/lib/packlets/collections/aggregatedResultMap.d.ts +433 -0
  44. package/lib/packlets/collections/aggregatedResultMap.js +728 -0
  45. package/lib/packlets/collections/collector.d.ts +11 -10
  46. package/lib/packlets/collections/collector.js +9 -9
  47. package/lib/packlets/collections/collectorValidator.d.ts +12 -10
  48. package/lib/packlets/collections/collectorValidator.js +4 -4
  49. package/lib/packlets/collections/converters.d.ts +18 -0
  50. package/lib/packlets/collections/converters.js +42 -0
  51. package/lib/packlets/collections/convertingCollector.d.ts +4 -4
  52. package/lib/packlets/collections/convertingCollectorValidator.d.ts +10 -7
  53. package/lib/packlets/collections/convertingCollectorValidator.js +3 -3
  54. package/lib/packlets/collections/convertingResultMap.d.ts +176 -0
  55. package/lib/packlets/collections/convertingResultMap.js +213 -0
  56. package/lib/packlets/collections/index.d.ts +4 -0
  57. package/lib/packlets/collections/index.js +4 -0
  58. package/lib/packlets/collections/keyValueConverters.d.ts +1 -4
  59. package/lib/packlets/collections/keyValueConverters.js +1 -4
  60. package/lib/packlets/collections/readOnlyConvertingResultMap.d.ts +153 -0
  61. package/lib/packlets/collections/readOnlyConvertingResultMap.js +197 -0
  62. package/lib/packlets/collections/readonlyResultMap.d.ts +7 -7
  63. package/lib/packlets/collections/resultMap.d.ts +108 -2
  64. package/lib/packlets/collections/resultMapValidator.d.ts +45 -11
  65. package/lib/packlets/collections/resultMapValidator.js +52 -7
  66. package/lib/packlets/collections/validatingCollector.d.ts +5 -5
  67. package/lib/packlets/collections/validatingConvertingCollector.d.ts +3 -3
  68. package/lib/packlets/collections/validatingConvertingResultMap.d.ts +102 -0
  69. package/lib/packlets/collections/validatingConvertingResultMap.js +83 -0
  70. package/lib/packlets/collections/validatingResultMap.d.ts +1 -1
  71. package/lib/packlets/conversion/advancedConverters.d.ts +170 -0
  72. package/lib/packlets/conversion/advancedConverters.js +258 -0
  73. package/lib/packlets/conversion/baseConverter.d.ts +39 -23
  74. package/lib/packlets/conversion/baseConverter.js +23 -16
  75. package/lib/packlets/conversion/basicConverters.d.ts +470 -0
  76. package/lib/packlets/conversion/basicConverters.js +595 -0
  77. package/lib/packlets/conversion/converter.d.ts +7 -0
  78. package/lib/packlets/conversion/converters.d.ts +2 -535
  79. package/lib/packlets/conversion/converters.js +17 -639
  80. package/lib/packlets/conversion/defaultingConverter.d.ts +20 -16
  81. package/lib/packlets/conversion/defaultingConverter.js +21 -15
  82. package/lib/packlets/logging/bootLogger.d.ts +84 -0
  83. package/lib/packlets/logging/bootLogger.js +126 -0
  84. package/lib/packlets/logging/index.d.ts +1 -0
  85. package/lib/packlets/logging/index.js +1 -0
  86. package/lib/packlets/logging/logReporter.d.ts +18 -3
  87. package/lib/packlets/logging/logReporter.js +31 -0
  88. package/lib/packlets/logging/logger.d.ts +39 -6
  89. package/lib/packlets/logging/logger.js +26 -5
  90. package/lib/packlets/validation/classes.d.ts +1 -0
  91. package/lib/packlets/validation/classes.js +3 -1
  92. package/lib/packlets/validation/compositeId.d.ts +29 -0
  93. package/lib/packlets/validation/compositeId.js +64 -0
  94. package/lib/packlets/validation/field.d.ts +1 -1
  95. package/lib/packlets/validation/field.js +1 -1
  96. package/lib/packlets/validation/genericValidator.d.ts +15 -11
  97. package/lib/packlets/validation/genericValidator.js +24 -10
  98. package/lib/packlets/validation/object.d.ts +3 -6
  99. package/lib/packlets/validation/object.js +3 -6
  100. package/lib/packlets/validation/traits.d.ts +3 -3
  101. package/lib/packlets/validation/validator.d.ts +7 -0
  102. package/lib/packlets/validation/validators.d.ts +10 -0
  103. package/lib/packlets/validation/validators.js +13 -0
  104. package/package.json +27 -27
@@ -0,0 +1,213 @@
1
+ "use strict";
2
+ /*
3
+ * Copyright (c) 2025 Erik Fortune
4
+ *
5
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ * of this software and associated documentation files (the "Software"), to deal
7
+ * in the Software without restriction, including without limitation the rights
8
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ * copies of the Software, and to permit persons to whom the Software is
10
+ * furnished to do so, subject to the following conditions:
11
+ *
12
+ * The above copyright notice and this permission notice shall be included in all
13
+ * copies or substantial portions of the Software.
14
+ *
15
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ * SOFTWARE.
22
+ */
23
+ Object.defineProperty(exports, "__esModule", { value: true });
24
+ exports.ConvertingResultMap = exports.CacheInvalidatingResultMapWrapper = void 0;
25
+ const base_1 = require("../base");
26
+ const readOnlyConvertingResultMap_1 = require("./readOnlyConvertingResultMap");
27
+ /**
28
+ * A wrapper around a mutable result map that invalidates cache entries
29
+ * in the parent {@link Collections.ConvertingResultMap | ConvertingResultMap} when mutations occur.
30
+ * @public
31
+ */
32
+ class CacheInvalidatingResultMapWrapper {
33
+ /**
34
+ * Constructs a new cache-invalidating wrapper.
35
+ * @param inner - The inner map to wrap.
36
+ * @param parent - The parent converting map whose cache should be invalidated.
37
+ */
38
+ constructor(inner, parent) {
39
+ this._inner = inner;
40
+ this._parent = parent;
41
+ }
42
+ /**
43
+ * The number of entries in the map.
44
+ */
45
+ get size() {
46
+ return this._inner.size;
47
+ }
48
+ /**
49
+ * Adds a key/value pair to the map if the key does not already exist.
50
+ * Invalidates the cache entry for the key.
51
+ * @param key - The key to add.
52
+ * @param value - The value to add.
53
+ * @returns The result of the add operation.
54
+ */
55
+ add(key, value) {
56
+ this._parent._clearCacheEntry(key);
57
+ return this._inner.add(key, value);
58
+ }
59
+ /**
60
+ * Sets a key/value pair in the map.
61
+ * Invalidates the cache entry for the key.
62
+ * @param key - The key to set.
63
+ * @param value - The value to set.
64
+ * @returns The result of the set operation.
65
+ */
66
+ set(key, value) {
67
+ this._parent._clearCacheEntry(key);
68
+ return this._inner.set(key, value);
69
+ }
70
+ /**
71
+ * Updates an existing key in the map.
72
+ * Invalidates the cache entry for the key.
73
+ * @param key - The key to update.
74
+ * @param value - The new value.
75
+ * @returns The result of the update operation.
76
+ */
77
+ update(key, value) {
78
+ this._parent._clearCacheEntry(key);
79
+ return this._inner.update(key, value);
80
+ }
81
+ /**
82
+ * Deletes a key from the map.
83
+ * Invalidates the cache entry for the key.
84
+ * @param key - The key to delete.
85
+ * @returns The result of the delete operation.
86
+ */
87
+ delete(key) {
88
+ this._parent._clearCacheEntry(key);
89
+ return this._inner.delete(key);
90
+ }
91
+ /**
92
+ * Gets a value from the map.
93
+ * @param key - The key to retrieve.
94
+ * @returns The result of the get operation.
95
+ */
96
+ get(key) {
97
+ return this._inner.get(key);
98
+ }
99
+ getOrAdd(key, valueOrFactory) {
100
+ const result = typeof valueOrFactory === 'function'
101
+ ? this._inner.getOrAdd(key, valueOrFactory)
102
+ : this._inner.getOrAdd(key, valueOrFactory);
103
+ if (result.isSuccess() && result.detail === 'added') {
104
+ this._parent._clearCacheEntry(key);
105
+ }
106
+ return result;
107
+ }
108
+ /**
109
+ * Checks if the map contains a key.
110
+ * @param key - The key to check.
111
+ * @returns `true` if the key exists, `false` otherwise.
112
+ */
113
+ has(key) {
114
+ return this._inner.has(key);
115
+ }
116
+ /**
117
+ * Clears all entries from the map.
118
+ * Clears the entire cache.
119
+ */
120
+ clear() {
121
+ this._parent._clearCache();
122
+ this._inner.clear();
123
+ }
124
+ /**
125
+ * Returns an iterator over the map entries.
126
+ * @returns An iterator over the map entries.
127
+ */
128
+ entries() {
129
+ return this._inner.entries();
130
+ }
131
+ /**
132
+ * Returns an iterator over the map keys.
133
+ * @returns An iterator over the map keys.
134
+ */
135
+ keys() {
136
+ return this._inner.keys();
137
+ }
138
+ /**
139
+ * Returns an iterator over the map values.
140
+ * @returns An iterator over the map values.
141
+ */
142
+ values() {
143
+ return this._inner.values();
144
+ }
145
+ /**
146
+ * Calls a callback for each entry in the map.
147
+ * @param cb - The callback to call for each entry.
148
+ * @param thisArg - Optional `this` argument for the callback.
149
+ */
150
+ forEach(cb, thisArg) {
151
+ this._inner.forEach(cb, thisArg);
152
+ }
153
+ /**
154
+ * Gets an iterator over the map entries.
155
+ * @returns An iterator over the map entries.
156
+ */
157
+ [Symbol.iterator]() {
158
+ return this._inner[Symbol.iterator]();
159
+ }
160
+ /**
161
+ * Gets a read-only version of this map.
162
+ * @returns A read-only version of this map.
163
+ */
164
+ toReadOnly() {
165
+ return this._inner.toReadOnly();
166
+ }
167
+ }
168
+ exports.CacheInvalidatingResultMapWrapper = CacheInvalidatingResultMapWrapper;
169
+ /**
170
+ * A result map that wraps an inner {@link Collections.IResultMap | IResultMap} of source type
171
+ * and returns lazily-converted, cached values of a target type. Exposes the inner map
172
+ * via a {@link Collections.CacheInvalidatingResultMapWrapper | source} property that
173
+ * invalidates cache entries when mutations occur.
174
+ * @public
175
+ */
176
+ class ConvertingResultMap extends readOnlyConvertingResultMap_1.ReadOnlyConvertingResultMap {
177
+ /**
178
+ * Constructs a new {@link Collections.ConvertingResultMap | ConvertingResultMap}.
179
+ * @param params - Parameters for constructing the map.
180
+ */
181
+ constructor(params) {
182
+ super(params);
183
+ this._typedInner = params.inner;
184
+ this.source = new CacheInvalidatingResultMapWrapper(params.inner, this);
185
+ }
186
+ /**
187
+ * Creates a new {@link Collections.ConvertingResultMap | ConvertingResultMap}.
188
+ * @param params - Parameters for constructing the map.
189
+ * @returns `Success` with the new map, or `Failure` with error details if an error occurred.
190
+ */
191
+ static create(params) {
192
+ return (0, base_1.captureResult)(() => new ConvertingResultMap(params));
193
+ }
194
+ /**
195
+ * Clears a single entry from the cache.
196
+ * This method is public to allow the cache-invalidating wrapper to call it.
197
+ * @param key - The key to clear from the cache.
198
+ * @internal
199
+ */
200
+ _clearCacheEntry(key) {
201
+ super._clearCacheEntry(key);
202
+ }
203
+ /**
204
+ * Clears all entries from the cache.
205
+ * This method is public to allow the cache-invalidating wrapper to call it.
206
+ * @internal
207
+ */
208
+ _clearCache() {
209
+ super._clearCache();
210
+ }
211
+ }
212
+ exports.ConvertingResultMap = ConvertingResultMap;
213
+ //# sourceMappingURL=convertingResultMap.js.map
@@ -1,6 +1,7 @@
1
1
  import * as Utils from './utils';
2
2
  export * from './collectible';
3
3
  export * from './convertingCollector';
4
+ export * from './convertingResultMap';
4
5
  export * from './collector';
5
6
  export * from './collectorValidator';
6
7
  export * from './convertingCollectorValidator';
@@ -8,9 +9,12 @@ export * from './validatingConvertingCollector';
8
9
  export * from './common';
9
10
  export * from './keyValueConverters';
10
11
  export * from './readonlyResultMap';
12
+ export * from './readOnlyConvertingResultMap';
11
13
  export * from './resultMap';
12
14
  export * from './resultMapValidator';
13
15
  export * from './validatingCollector';
16
+ export * from './validatingConvertingResultMap';
14
17
  export * from './validatingResultMap';
18
+ export * from './aggregatedResultMap';
15
19
  export { Utils };
16
20
  //# sourceMappingURL=index.d.ts.map
@@ -62,6 +62,7 @@ const Utils = __importStar(require("./utils"));
62
62
  exports.Utils = Utils;
63
63
  __exportStar(require("./collectible"), exports);
64
64
  __exportStar(require("./convertingCollector"), exports);
65
+ __exportStar(require("./convertingResultMap"), exports);
65
66
  __exportStar(require("./collector"), exports);
66
67
  __exportStar(require("./collectorValidator"), exports);
67
68
  __exportStar(require("./convertingCollectorValidator"), exports);
@@ -69,8 +70,11 @@ __exportStar(require("./validatingConvertingCollector"), exports);
69
70
  __exportStar(require("./common"), exports);
70
71
  __exportStar(require("./keyValueConverters"), exports);
71
72
  __exportStar(require("./readonlyResultMap"), exports);
73
+ __exportStar(require("./readOnlyConvertingResultMap"), exports);
72
74
  __exportStar(require("./resultMap"), exports);
73
75
  __exportStar(require("./resultMapValidator"), exports);
74
76
  __exportStar(require("./validatingCollector"), exports);
77
+ __exportStar(require("./validatingConvertingResultMap"), exports);
75
78
  __exportStar(require("./validatingResultMap"), exports);
79
+ __exportStar(require("./aggregatedResultMap"), exports);
76
80
  //# sourceMappingURL=index.js.map
@@ -35,10 +35,7 @@ export declare class KeyValueConverters<TK extends string = string, TV = unknown
35
35
  readonly value: Validator<TV, unknown> | Converter<TV, unknown>;
36
36
  /**
37
37
  * Constructs a new key-value validator.
38
- * @param key - Required key {@link Validator | validator}, {@link Converter | converter},
39
- * or {@link Conversion.ConverterFunc | converter function}.
40
- * @param value - Required value {@link Validator | validator}, {@link Converter | converter},
41
- * or {@link Conversion.ConverterFunc | converter function}.
38
+ * @param params - Key and value converters or validators.
42
39
  */
43
40
  constructor({ key, value }: IKeyValueConverterConstructorParams<TK, TV>);
44
41
  /**
@@ -32,10 +32,7 @@ const conversion_1 = require("../conversion");
32
32
  class KeyValueConverters {
33
33
  /**
34
34
  * Constructs a new key-value validator.
35
- * @param key - Required key {@link Validator | validator}, {@link Converter | converter},
36
- * or {@link Conversion.ConverterFunc | converter function}.
37
- * @param value - Required value {@link Validator | validator}, {@link Converter | converter},
38
- * or {@link Conversion.ConverterFunc | converter function}.
35
+ * @param params - Key and value converters or validators.
39
36
  */
40
37
  constructor({ key, value }) {
41
38
  this.key = typeof key === 'function' ? conversion_1.Converters.generic(key) : key;
@@ -0,0 +1,153 @@
1
+ import { DetailedResult, Result } from '../base';
2
+ import { ILogger } from '../logging';
3
+ import { KeyValueEntry } from './common';
4
+ import { IReadOnlyResultMap, ResultMapForEachCb, ResultMapResultDetail } from './readonlyResultMap';
5
+ /**
6
+ * A function that converts a source value to a target value.
7
+ * @public
8
+ */
9
+ export type ConvertingResultMapValueConverter<TK extends string, TSRC, TTARGET> = (src: TSRC, key: TK) => Result<TTARGET>;
10
+ /**
11
+ * Error handling behavior for conversion failures during iteration.
12
+ * - `'ignore'`: Silently skip failed conversions (default behavior)
13
+ * - `'warn'`: Log warning and skip failed conversions
14
+ * - `'fail'`: Throw error on first conversion failure
15
+ * @public
16
+ */
17
+ export type ConversionErrorHandling = 'ignore' | 'warn' | 'fail';
18
+ /**
19
+ * Parameters for constructing a {@link Collections.ReadOnlyConvertingResultMap | ReadOnlyConvertingResultMap}.
20
+ * @public
21
+ */
22
+ export interface IReadOnlyConvertingResultMapConstructorParams<TK extends string, TSRC, TTARGET> {
23
+ /**
24
+ * The inner map containing source values.
25
+ */
26
+ inner: IReadOnlyResultMap<TK, TSRC>;
27
+ /**
28
+ * The converter function to transform source values to target values.
29
+ */
30
+ converter: ConvertingResultMapValueConverter<TK, TSRC, TTARGET>;
31
+ /**
32
+ * Error handling behavior for conversion failures during iteration.
33
+ * Defaults to `'ignore'` (silently skip failed conversions).
34
+ */
35
+ onConversionError?: ConversionErrorHandling;
36
+ /**
37
+ * Optional logger for warnings when `onConversionError` is `'warn'`.
38
+ */
39
+ logger?: ILogger;
40
+ }
41
+ /**
42
+ * A read-only result map that wraps an inner {@link Collections.IReadOnlyResultMap | IReadOnlyResultMap}
43
+ * of source type and returns lazily-converted, cached values of a target type.
44
+ * @public
45
+ */
46
+ export declare class ReadOnlyConvertingResultMap<TK extends string, TSRC, TTARGET> implements IReadOnlyResultMap<TK, TTARGET> {
47
+ /**
48
+ * The inner map containing source values.
49
+ */
50
+ protected readonly _inner: IReadOnlyResultMap<TK, TSRC>;
51
+ /**
52
+ * The converter function to transform source values to target values.
53
+ */
54
+ protected readonly _converter: ConvertingResultMapValueConverter<TK, TSRC, TTARGET>;
55
+ /**
56
+ * Cache of converted target values.
57
+ */
58
+ protected readonly _cache: Map<TK, TTARGET>;
59
+ /**
60
+ * Error handling behavior for conversion failures during iteration.
61
+ */
62
+ protected readonly _onConversionError: ConversionErrorHandling;
63
+ /**
64
+ * Optional logger for warnings.
65
+ */
66
+ protected readonly _logger?: ILogger;
67
+ /**
68
+ * Constructs a new {@link Collections.ReadOnlyConvertingResultMap | ReadOnlyConvertingResultMap}.
69
+ * @param params - Parameters for constructing the map.
70
+ */
71
+ constructor(params: IReadOnlyConvertingResultMapConstructorParams<TK, TSRC, TTARGET>);
72
+ /**
73
+ * Creates a new {@link Collections.ReadOnlyConvertingResultMap | ReadOnlyConvertingResultMap}.
74
+ * @param params - Parameters for constructing the map.
75
+ * @returns `Success` with the new map, or `Failure` with error details if an error occurred.
76
+ */
77
+ static create<TK extends string, TSRC, TTARGET>(params: IReadOnlyConvertingResultMapConstructorParams<TK, TSRC, TTARGET>): Result<ReadOnlyConvertingResultMap<TK, TSRC, TTARGET>>;
78
+ /**
79
+ * The number of entries in the map.
80
+ */
81
+ get size(): number;
82
+ /**
83
+ * Gets a converted value from the map by key.
84
+ * @param key - The key to retrieve.
85
+ * @returns `Success` with the converted value and detail `exists` if the key was found,
86
+ * `Failure` with detail `not-found` if the key was not found, or `Failure` with
87
+ * detail `invalid-value` if conversion failed.
88
+ */
89
+ get(key: TK): DetailedResult<TTARGET, ResultMapResultDetail>;
90
+ /**
91
+ * Checks if the map contains a key.
92
+ * @param key - The key to check.
93
+ * @returns `true` if the key exists, `false` otherwise.
94
+ */
95
+ has(key: TK): boolean;
96
+ /**
97
+ * Returns an iterator over the map entries with converted values.
98
+ * @returns An iterator over the map entries.
99
+ */
100
+ entries(): IterableIterator<KeyValueEntry<TK, TTARGET>>;
101
+ /**
102
+ * Returns an iterator over the map keys.
103
+ * @returns An iterator over the map keys.
104
+ */
105
+ keys(): IterableIterator<TK>;
106
+ /**
107
+ * Returns an iterator over the converted map values.
108
+ * @returns An iterator over the map values.
109
+ */
110
+ values(): IterableIterator<TTARGET>;
111
+ /**
112
+ * Calls a callback for each entry in the map with converted values.
113
+ * @param cb - The callback to call for each entry.
114
+ * @param thisArg - Optional `this` argument for the callback.
115
+ */
116
+ forEach(cb: ResultMapForEachCb<TK, TTARGET>, thisArg?: unknown): void;
117
+ /**
118
+ * Gets an iterator over the map entries.
119
+ * @returns An iterator over the map entries.
120
+ */
121
+ [Symbol.iterator](): IterableIterator<KeyValueEntry<TK, TTARGET>>;
122
+ /**
123
+ * Gets a read-only version of this map.
124
+ * @returns A read-only version of this map.
125
+ */
126
+ toReadOnly(): IReadOnlyResultMap<TK, TTARGET>;
127
+ /**
128
+ * Converts a source value to a target value and caches the result.
129
+ * @param key - The key of the value.
130
+ * @param src - The source value to convert.
131
+ * @returns `Success` with the converted value if successful, `Failure` otherwise.
132
+ */
133
+ protected _convertAndCache(key: TK, src: TSRC): DetailedResult<TTARGET, ResultMapResultDetail>;
134
+ /**
135
+ * Gets a cached value or converts and caches a source value.
136
+ * Used by iterators. Handles conversion failures according to `_onConversionError`.
137
+ * @param key - The key of the value.
138
+ * @param src - The source value to convert if not cached.
139
+ * @returns The converted value, or `undefined` if conversion failed.
140
+ * @throws Error if `_onConversionError` is `'fail'` and conversion fails.
141
+ */
142
+ protected _getOrConvert(key: TK, src: TSRC): TTARGET | undefined;
143
+ /**
144
+ * Clears a single entry from the cache.
145
+ * @param key - The key to clear from the cache.
146
+ */
147
+ protected _clearCacheEntry(key: TK): void;
148
+ /**
149
+ * Clears all entries from the cache.
150
+ */
151
+ protected _clearCache(): void;
152
+ }
153
+ //# sourceMappingURL=readOnlyConvertingResultMap.d.ts.map
@@ -0,0 +1,197 @@
1
+ "use strict";
2
+ /*
3
+ * Copyright (c) 2026 Erik Fortune
4
+ *
5
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ * of this software and associated documentation files (the "Software"), to deal
7
+ * in the Software without restriction, including without limitation the rights
8
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ * copies of the Software, and to permit persons to whom the Software is
10
+ * furnished to do so, subject to the following conditions:
11
+ *
12
+ * The above copyright notice and this permission notice shall be included in all
13
+ * copies or substantial portions of the Software.
14
+ *
15
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ * SOFTWARE.
22
+ */
23
+ Object.defineProperty(exports, "__esModule", { value: true });
24
+ exports.ReadOnlyConvertingResultMap = void 0;
25
+ const base_1 = require("../base");
26
+ /**
27
+ * A read-only result map that wraps an inner {@link Collections.IReadOnlyResultMap | IReadOnlyResultMap}
28
+ * of source type and returns lazily-converted, cached values of a target type.
29
+ * @public
30
+ */
31
+ class ReadOnlyConvertingResultMap {
32
+ /**
33
+ * Constructs a new {@link Collections.ReadOnlyConvertingResultMap | ReadOnlyConvertingResultMap}.
34
+ * @param params - Parameters for constructing the map.
35
+ */
36
+ constructor(params) {
37
+ var _a;
38
+ this._inner = params.inner;
39
+ this._converter = params.converter;
40
+ this._cache = new Map();
41
+ this._onConversionError = (_a = params.onConversionError) !== null && _a !== void 0 ? _a : 'ignore';
42
+ this._logger = params.logger;
43
+ }
44
+ /**
45
+ * Creates a new {@link Collections.ReadOnlyConvertingResultMap | ReadOnlyConvertingResultMap}.
46
+ * @param params - Parameters for constructing the map.
47
+ * @returns `Success` with the new map, or `Failure` with error details if an error occurred.
48
+ */
49
+ static create(params) {
50
+ return (0, base_1.captureResult)(() => new ReadOnlyConvertingResultMap(params));
51
+ }
52
+ /**
53
+ * The number of entries in the map.
54
+ */
55
+ get size() {
56
+ return this._inner.size;
57
+ }
58
+ /**
59
+ * Gets a converted value from the map by key.
60
+ * @param key - The key to retrieve.
61
+ * @returns `Success` with the converted value and detail `exists` if the key was found,
62
+ * `Failure` with detail `not-found` if the key was not found, or `Failure` with
63
+ * detail `invalid-value` if conversion failed.
64
+ */
65
+ get(key) {
66
+ const cached = this._cache.get(key);
67
+ if (cached !== undefined) {
68
+ return (0, base_1.succeedWithDetail)(cached, 'exists');
69
+ }
70
+ return this._inner.get(key).onSuccess((src) => {
71
+ return this._convertAndCache(key, src);
72
+ });
73
+ }
74
+ /**
75
+ * Checks if the map contains a key.
76
+ * @param key - The key to check.
77
+ * @returns `true` if the key exists, `false` otherwise.
78
+ */
79
+ has(key) {
80
+ return this._inner.has(key);
81
+ }
82
+ /**
83
+ * Returns an iterator over the map entries with converted values.
84
+ * @returns An iterator over the map entries.
85
+ */
86
+ *entries() {
87
+ for (const [key, src] of this._inner.entries()) {
88
+ const target = this._getOrConvert(key, src);
89
+ if (target !== undefined) {
90
+ yield [key, target];
91
+ }
92
+ }
93
+ }
94
+ /**
95
+ * Returns an iterator over the map keys.
96
+ * @returns An iterator over the map keys.
97
+ */
98
+ keys() {
99
+ return this._inner.keys();
100
+ }
101
+ /**
102
+ * Returns an iterator over the converted map values.
103
+ * @returns An iterator over the map values.
104
+ */
105
+ *values() {
106
+ for (const [key, src] of this._inner.entries()) {
107
+ const target = this._getOrConvert(key, src);
108
+ if (target !== undefined) {
109
+ yield target;
110
+ }
111
+ }
112
+ }
113
+ /**
114
+ * Calls a callback for each entry in the map with converted values.
115
+ * @param cb - The callback to call for each entry.
116
+ * @param thisArg - Optional `this` argument for the callback.
117
+ */
118
+ forEach(cb, thisArg) {
119
+ for (const [key, src] of this._inner.entries()) {
120
+ const target = this._getOrConvert(key, src);
121
+ if (target !== undefined) {
122
+ cb.call(thisArg, target, key, this);
123
+ }
124
+ }
125
+ }
126
+ /**
127
+ * Gets an iterator over the map entries.
128
+ * @returns An iterator over the map entries.
129
+ */
130
+ [Symbol.iterator]() {
131
+ return this.entries();
132
+ }
133
+ /**
134
+ * Gets a read-only version of this map.
135
+ * @returns A read-only version of this map.
136
+ */
137
+ toReadOnly() {
138
+ return this;
139
+ }
140
+ /**
141
+ * Converts a source value to a target value and caches the result.
142
+ * @param key - The key of the value.
143
+ * @param src - The source value to convert.
144
+ * @returns `Success` with the converted value if successful, `Failure` otherwise.
145
+ */
146
+ _convertAndCache(key, src) {
147
+ const result = this._converter(src, key);
148
+ if (result.isFailure()) {
149
+ return (0, base_1.failWithDetail)(result.message, 'invalid-value');
150
+ }
151
+ this._cache.set(key, result.value);
152
+ return (0, base_1.succeedWithDetail)(result.value, 'exists');
153
+ }
154
+ /**
155
+ * Gets a cached value or converts and caches a source value.
156
+ * Used by iterators. Handles conversion failures according to `_onConversionError`.
157
+ * @param key - The key of the value.
158
+ * @param src - The source value to convert if not cached.
159
+ * @returns The converted value, or `undefined` if conversion failed.
160
+ * @throws Error if `_onConversionError` is `'fail'` and conversion fails.
161
+ */
162
+ _getOrConvert(key, src) {
163
+ var _a;
164
+ const cached = this._cache.get(key);
165
+ if (cached !== undefined) {
166
+ return cached;
167
+ }
168
+ const result = this._converter(src, key);
169
+ if (result.isSuccess()) {
170
+ this._cache.set(key, result.value);
171
+ return result.value;
172
+ }
173
+ switch (this._onConversionError) {
174
+ case 'fail':
175
+ throw new Error(`Conversion failed for key '${key}': ${result.message}`);
176
+ case 'warn':
177
+ (_a = this._logger) === null || _a === void 0 ? void 0 : _a.log('warning', `Conversion failed for key '${key}': ${result.message}`);
178
+ break;
179
+ }
180
+ return undefined;
181
+ }
182
+ /**
183
+ * Clears a single entry from the cache.
184
+ * @param key - The key to clear from the cache.
185
+ */
186
+ _clearCacheEntry(key) {
187
+ this._cache.delete(key);
188
+ }
189
+ /**
190
+ * Clears all entries from the cache.
191
+ */
192
+ _clearCache() {
193
+ this._cache.clear();
194
+ }
195
+ }
196
+ exports.ReadOnlyConvertingResultMap = ReadOnlyConvertingResultMap;
197
+ //# sourceMappingURL=readOnlyConvertingResultMap.js.map
@@ -18,31 +18,31 @@ export type ResultMapForEachCb<TK extends string = string, TE = unknown> = (valu
18
18
  */
19
19
  export interface IReadOnlyResultMap<TK extends string = string, TV = unknown> {
20
20
  /**
21
- * {@inheritdoc Collections.ResultMap.size}
21
+ * {@inheritDoc Collections.ResultMap.size}
22
22
  */
23
23
  readonly size: number;
24
24
  /**
25
- * {@inheritdoc Collections.ResultMap.entries}
25
+ * {@inheritDoc Collections.ResultMap.entries}
26
26
  */
27
27
  entries(): IterableIterator<KeyValueEntry<TK, TV>>;
28
28
  /**
29
- * {@inheritdoc Collections.ResultMap.forEach}
29
+ * {@inheritDoc Collections.ResultMap.forEach}
30
30
  */
31
31
  forEach(cb: ResultMapForEachCb, arg?: unknown): void;
32
32
  /**
33
- * {@inheritdoc Collections.ResultMap.get}
33
+ * {@inheritDoc Collections.ResultMap.get}
34
34
  */
35
35
  get(key: TK): DetailedResult<TV, ResultMapResultDetail>;
36
36
  /**
37
- * {@inheritdoc Collections.ResultMap.has}
37
+ * {@inheritDoc Collections.ResultMap.has}
38
38
  */
39
39
  has(key: TK): boolean;
40
40
  /**
41
- * {@inheritdoc Collections.ResultMap.keys}
41
+ * {@inheritDoc Collections.ResultMap.keys}
42
42
  */
43
43
  keys(): IterableIterator<TK>;
44
44
  /**
45
- * {@inheritdoc Collections.ResultMap.values}
45
+ * {@inheritDoc Collections.ResultMap.values}
46
46
  */
47
47
  values(): IterableIterator<TV>;
48
48
  /**