@fgv/ts-utils 4.3.0 → 4.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (36) hide show
  1. package/CHANGELOG.json +6 -0
  2. package/CHANGELOG.md +6 -1
  3. package/dist/ts-utils.d.ts +175 -70
  4. package/lib/index.d.ts +2 -2
  5. package/lib/index.d.ts.map +1 -1
  6. package/lib/index.js +2 -1
  7. package/lib/index.js.map +1 -1
  8. package/lib/packlets/collections/collectible.d.ts +37 -5
  9. package/lib/packlets/collections/collectible.d.ts.map +1 -1
  10. package/lib/packlets/collections/collectible.js +42 -8
  11. package/lib/packlets/collections/collectible.js.map +1 -1
  12. package/lib/packlets/collections/collector.d.ts +77 -13
  13. package/lib/packlets/collections/collector.d.ts.map +1 -1
  14. package/lib/packlets/collections/collector.js +44 -2
  15. package/lib/packlets/collections/collector.js.map +1 -1
  16. package/lib/packlets/collections/collectorConverter.d.ts +31 -4
  17. package/lib/packlets/collections/collectorConverter.d.ts.map +1 -1
  18. package/lib/packlets/collections/collectorConverter.js +18 -6
  19. package/lib/packlets/collections/collectorConverter.js.map +1 -1
  20. package/lib/packlets/collections/collectors.d.ts +0 -1
  21. package/lib/packlets/collections/collectors.d.ts.map +1 -1
  22. package/lib/packlets/collections/collectors.js +1 -4
  23. package/lib/packlets/collections/collectors.js.map +1 -1
  24. package/lib/packlets/collections/convertingCollector.d.ts +19 -13
  25. package/lib/packlets/collections/convertingCollector.d.ts.map +1 -1
  26. package/lib/packlets/collections/convertingCollector.js +0 -10
  27. package/lib/packlets/collections/convertingCollector.js.map +1 -1
  28. package/lib/packlets/collections/convertingResultMap.d.ts +4 -24
  29. package/lib/packlets/collections/convertingResultMap.d.ts.map +1 -1
  30. package/lib/packlets/collections/convertingResultMap.js +0 -41
  31. package/lib/packlets/collections/convertingResultMap.js.map +1 -1
  32. package/lib/packlets/collections/keyValueConverters.d.ts +1 -17
  33. package/lib/packlets/collections/keyValueConverters.d.ts.map +1 -1
  34. package/lib/packlets/collections/keyValueConverters.js +1 -8
  35. package/lib/packlets/collections/keyValueConverters.js.map +1 -1
  36. package/package.json +1 -1
@@ -23,6 +23,7 @@
23
23
  Object.defineProperty(exports, "__esModule", { value: true });
24
24
  exports.Collectible = void 0;
25
25
  const base_1 = require("../base");
26
+ const conversion_1 = require("../conversion");
26
27
  /**
27
28
  * Simple implementation of {@link Collections.ICollectible | ICollectible} which does not allow the index to be
28
29
  * changed once set.
@@ -37,22 +38,55 @@ class Collectible {
37
38
  }
38
39
  /**
39
40
  * Constructs a new {@link Collections.Collectible | Collectible} instance.
40
- * @param key - The key of the item to be collected.
41
- * @param index - Optional index of the item to be collected.
41
+ * @param params - Required parameters for constructing the collectible.
42
42
  */
43
- constructor(key, index) {
44
- this.key = key;
45
- this._index = index;
43
+ constructor(params) {
44
+ this.key = params.key;
45
+ if ('indexConverter' in params) {
46
+ this._indexConverter =
47
+ typeof params.indexConverter === 'function'
48
+ ? conversion_1.Converters.generic(params.indexConverter)
49
+ : params.indexConverter;
50
+ if (params.index !== undefined) {
51
+ this._index = this._indexConverter.convert(params.index).orThrow();
52
+ }
53
+ }
54
+ else {
55
+ this._index = params.index;
56
+ }
57
+ }
58
+ /**
59
+ * Creates a new {@link Collections.Collectible | Collectible} instance from the supplied parameters.
60
+ * @param params - Required parameters for constructing the collectible.
61
+ * @returns `Success` with the new collectible if successful, or `Failure` with an error message if not.
62
+ */
63
+ static createCollectible(params) {
64
+ return (0, base_1.captureResult)(() => new Collectible(params));
46
65
  }
47
66
  /**
48
67
  * {@link Collections.ICollectible.setIndex}
49
68
  */
50
69
  setIndex(index) {
51
- if (this._index !== undefined && index !== this.index) {
70
+ let converted;
71
+ if (this._indexConverter) {
72
+ const { value, message } = this._indexConverter.convert(index);
73
+ if (message) {
74
+ return (0, base_1.fail)(message);
75
+ }
76
+ converted = value;
77
+ }
78
+ if (index === this.index) {
79
+ return (0, base_1.succeed)(this.index);
80
+ }
81
+ else if (this._index !== undefined) {
52
82
  return (0, base_1.fail)(`index ${this.index} is immutable and cannot be changed to ${index}`);
53
83
  }
54
- this._index = index;
55
- return (0, base_1.succeed)(this._index);
84
+ /* c8 ignore next 3 - should be impossible */
85
+ if (converted === undefined) {
86
+ return (0, base_1.fail)(`index ${index} cannot be set on a Collectible without an index converter`);
87
+ }
88
+ this._index = converted;
89
+ return (0, base_1.succeed)(converted);
56
90
  }
57
91
  }
58
92
  exports.Collectible = Collectible;
@@ -1 +1 @@
1
- {"version":3,"file":"collectible.js","sourceRoot":"","sources":["../../../src/packlets/collections/collectible.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;;;AAEH,kCAAgD;AAkChD;;;;GAIG;AACH,MAAa,WAAW;IAQtB;;OAEG;IACH,IAAW,KAAK;QACd,OAAO,IAAI,CAAC,MAAM,CAAC;IACrB,CAAC;IAID;;;;OAIG;IACH,YAAmB,GAAS,EAAE,KAAc;QAC1C,IAAI,CAAC,GAAG,GAAG,GAAG,CAAC;QACf,IAAI,CAAC,MAAM,GAAG,KAAK,CAAC;IACtB,CAAC;IAED;;OAEG;IACI,QAAQ,CAAC,KAAa;QAC3B,IAAI,IAAI,CAAC,MAAM,KAAK,SAAS,IAAI,KAAK,KAAK,IAAI,CAAC,KAAK,EAAE,CAAC;YACtD,OAAO,IAAA,WAAI,EAAC,SAAS,IAAI,CAAC,KAAK,0CAA0C,KAAK,EAAE,CAAC,CAAC;QACpF,CAAC;QACD,IAAI,CAAC,MAAM,GAAG,KAAK,CAAC;QACpB,OAAO,IAAA,cAAO,EAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IAC9B,CAAC;CACF;AArCD,kCAqCC","sourcesContent":["/*\n * Copyright (c) 2025 Erik Fortune\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in all\n * copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n * SOFTWARE.\n */\n\nimport { Result, fail, succeed } from '../base';\n\n/**\n * An item that can be collected by some {@link Collector | Collector}.\n * @public\n */\nexport interface ICollectible<TKEY extends string = string, TINDEX extends number = number> {\n readonly key: TKEY;\n readonly index: TINDEX | undefined;\n setIndex(index: TINDEX): Result<TINDEX>;\n}\n\n/**\n * Factory function for creating a new {@link Collections.ICollectible | ICollectible} instance given a key, an index and a source representation\n * of the item to be added.\n * @public\n */\nexport type CollectibleFactory<\n TKEY extends string = string,\n TINDEX extends number = number,\n TITEM extends ICollectible<TKEY, TINDEX> = ICollectible<TKEY, TINDEX>,\n TSRC = TITEM\n> = (key: TKEY, index: number, item: TSRC) => Result<TITEM>;\n\n/**\n * Factory function for creating a new {@link Collections.ICollectible | ICollectible} instance given a key and an index.\n * @public\n */\nexport type CollectibleFactoryCallback<\n TKEY extends string = string,\n TINDEX extends number = number,\n TITEM extends ICollectible<TKEY, TINDEX> = ICollectible<TKEY, TINDEX>\n> = (key: TKEY, index: number) => Result<TITEM>;\n\n/**\n * Simple implementation of {@link Collections.ICollectible | ICollectible} which does not allow the index to be\n * changed once set.\n * @public\n */\nexport class Collectible<TKEY extends string = string, TINDEX extends number = number>\n implements ICollectible<TKEY, TINDEX>\n{\n /**\n * {@link Collections.ICollectible.key}\n */\n public readonly key: TKEY;\n\n /**\n * {@link Collections.ICollectible.index}\n */\n public get index(): TINDEX | undefined {\n return this._index;\n }\n\n protected _index: TINDEX | undefined;\n\n /**\n * Constructs a new {@link Collections.Collectible | Collectible} instance.\n * @param key - The key of the item to be collected.\n * @param index - Optional index of the item to be collected.\n */\n public constructor(key: TKEY, index?: TINDEX) {\n this.key = key;\n this._index = index;\n }\n\n /**\n * {@link Collections.ICollectible.setIndex}\n */\n public setIndex(index: TINDEX): Result<TINDEX> {\n if (this._index !== undefined && index !== this.index) {\n return fail(`index ${this.index} is immutable and cannot be changed to ${index}`);\n }\n this._index = index;\n return succeed(this._index);\n }\n}\n"]}
1
+ {"version":3,"file":"collectible.js","sourceRoot":"","sources":["../../../src/packlets/collections/collectible.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;;;AAEH,kCAA+D;AAC/D,8CAAqE;AAsErE;;;;GAIG;AACH,MAAa,WAAW;IAQtB;;OAEG;IACH,IAAW,KAAK;QACd,OAAO,IAAI,CAAC,MAAM,CAAC;IACrB,CAAC;IAKD;;;OAGG;IACH,YAAmB,MAAmD;QACpE,IAAI,CAAC,GAAG,GAAG,MAAM,CAAC,GAAG,CAAC;QACtB,IAAI,gBAAgB,IAAI,MAAM,EAAE,CAAC;YAC/B,IAAI,CAAC,eAAe;gBAClB,OAAO,MAAM,CAAC,cAAc,KAAK,UAAU;oBACzC,CAAC,CAAC,uBAAU,CAAC,OAAO,CAAC,MAAM,CAAC,cAAc,CAAC;oBAC3C,CAAC,CAAC,MAAM,CAAC,cAAc,CAAC;YAC5B,IAAI,MAAM,CAAC,KAAK,KAAK,SAAS,EAAE,CAAC;gBAC/B,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,eAAe,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,OAAO,EAAE,CAAC;YACrE,CAAC;QACH,CAAC;aAAM,CAAC;YACN,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC;QAC7B,CAAC;IACH,CAAC;IAED;;;;OAIG;IACI,MAAM,CAAC,iBAAiB,CAC7B,MAAmD;QAEnD,OAAO,IAAA,oBAAa,EAAC,GAAG,EAAE,CAAC,IAAI,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC;IACtD,CAAC;IAED;;OAEG;IACI,QAAQ,CAAC,KAAa;QAC3B,IAAI,SAA6B,CAAC;QAClC,IAAI,IAAI,CAAC,eAAe,EAAE,CAAC;YACzB,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC,eAAe,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;YAC/D,IAAI,OAAO,EAAE,CAAC;gBACZ,OAAO,IAAA,WAAI,EAAC,OAAO,CAAC,CAAC;YACvB,CAAC;YACD,SAAS,GAAG,KAAK,CAAC;QACpB,CAAC;QAED,IAAI,KAAK,KAAK,IAAI,CAAC,KAAK,EAAE,CAAC;YACzB,OAAO,IAAA,cAAO,EAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAC7B,CAAC;aAAM,IAAI,IAAI,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;YACrC,OAAO,IAAA,WAAI,EAAC,SAAS,IAAI,CAAC,KAAK,0CAA0C,KAAK,EAAE,CAAC,CAAC;QACpF,CAAC;QAED,6CAA6C;QAC7C,IAAI,SAAS,KAAK,SAAS,EAAE,CAAC;YAC5B,OAAO,IAAA,WAAI,EAAC,SAAS,KAAK,4DAA4D,CAAC,CAAC;QAC1F,CAAC;QAED,IAAI,CAAC,MAAM,GAAG,SAAS,CAAC;QACxB,OAAO,IAAA,cAAO,EAAC,SAAS,CAAC,CAAC;IAC5B,CAAC;CACF;AA3ED,kCA2EC","sourcesContent":["/*\n * Copyright (c) 2025 Erik Fortune\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in all\n * copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n * SOFTWARE.\n */\n\nimport { Result, captureResult, fail, succeed } from '../base';\nimport { Converter, ConverterFunc, Converters } from '../conversion';\nimport { Validator } from '../validation';\n\n/**\n * An item that can be collected by some {@link Collector | Collector}.\n * @public\n */\nexport interface ICollectible<TKEY extends string = string, TINDEX extends number = number> {\n readonly key: TKEY;\n readonly index: TINDEX | undefined;\n setIndex(index: number): Result<TINDEX>;\n}\n\n/**\n * Factory function for creating a new {@link Collections.ICollectible | ICollectible} instance given a key, an index and a source representation\n * of the item to be added.\n * @public\n */\nexport type CollectibleFactory<\n TKEY extends string = string,\n TINDEX extends number = number,\n TITEM extends ICollectible<TKEY, TINDEX> = ICollectible<TKEY, TINDEX>,\n TSRC = TITEM\n> = (key: TKEY, index: number, item: TSRC) => Result<TITEM>;\n\n/**\n * Factory function for creating a new {@link Collections.ICollectible | ICollectible} instance given a key and an index.\n * @public\n */\nexport type CollectibleFactoryCallback<\n TKEY extends string = string,\n TINDEX extends number = number,\n TITEM extends ICollectible<TKEY, TINDEX> = ICollectible<TKEY, TINDEX>\n> = (key: TKEY, index: number) => Result<TITEM>;\n\n/**\n * Parameters for constructing a new {@link Collections.ICollectible | ICollectible} instance with\n * a defined, strongly-typed index.\n * @public\n */\nexport interface ICollectibleConstructorParamsWithIndex<\n TKEY extends string = string,\n TINDEX extends number = number\n> {\n key: TKEY;\n index: TINDEX;\n}\n\n/**\n * Parameters for constructing a new {@link Collections.ICollectible | ICollectible} instance with an\n * index converter.\n * @public\n */\nexport interface ICollectibleConstructorParamsWithConverter<\n TKEY extends string = string,\n TINDEX extends number = number\n> {\n key: TKEY;\n index?: number;\n indexConverter: Validator<TINDEX, unknown> | Converter<TINDEX, unknown> | ConverterFunc<TINDEX, undefined>;\n}\n\n/**\n * Parameters for constructing a new {@link Collections.ICollectible | ICollectible} instance.\n * @public\n */\nexport type ICollectibleConstructorParams<TKEY extends string = string, TINDEX extends number = number> =\n | ICollectibleConstructorParamsWithIndex<TKEY, TINDEX>\n | ICollectibleConstructorParamsWithConverter<TKEY, TINDEX>;\n\n/**\n * Simple implementation of {@link Collections.ICollectible | ICollectible} which does not allow the index to be\n * changed once set.\n * @public\n */\nexport class Collectible<TKEY extends string = string, TINDEX extends number = number>\n implements ICollectible<TKEY, TINDEX>\n{\n /**\n * {@link Collections.ICollectible.key}\n */\n public readonly key: TKEY;\n\n /**\n * {@link Collections.ICollectible.index}\n */\n public get index(): TINDEX | undefined {\n return this._index;\n }\n\n protected _index: TINDEX | undefined;\n protected readonly _indexConverter?: Validator<TINDEX, unknown> | Converter<TINDEX, unknown>;\n\n /**\n * Constructs a new {@link Collections.Collectible | Collectible} instance.\n * @param params - Required parameters for constructing the collectible.\n */\n public constructor(params: ICollectibleConstructorParams<TKEY, TINDEX>) {\n this.key = params.key;\n if ('indexConverter' in params) {\n this._indexConverter =\n typeof params.indexConverter === 'function'\n ? Converters.generic(params.indexConverter)\n : params.indexConverter;\n if (params.index !== undefined) {\n this._index = this._indexConverter.convert(params.index).orThrow();\n }\n } else {\n this._index = params.index;\n }\n }\n\n /**\n * Creates a new {@link Collections.Collectible | Collectible} instance from the supplied parameters.\n * @param params - Required parameters for constructing the collectible.\n * @returns `Success` with the new collectible if successful, or `Failure` with an error message if not.\n */\n public static createCollectible<TKEY extends string = string, TINDEX extends number = number>(\n params: ICollectibleConstructorParams<TKEY, TINDEX>\n ): Result<Collectible<TKEY, TINDEX>> {\n return captureResult(() => new Collectible(params));\n }\n\n /**\n * {@link Collections.ICollectible.setIndex}\n */\n public setIndex(index: number): Result<TINDEX> {\n let converted: TINDEX | undefined;\n if (this._indexConverter) {\n const { value, message } = this._indexConverter.convert(index);\n if (message) {\n return fail(message);\n }\n converted = value;\n }\n\n if (index === this.index) {\n return succeed(this.index);\n } else if (this._index !== undefined) {\n return fail(`index ${this.index} is immutable and cannot be changed to ${index}`);\n }\n\n /* c8 ignore next 3 - should be impossible */\n if (converted === undefined) {\n return fail(`index ${index} cannot be set on a Collectible without an index converter`);\n }\n\n this._index = converted;\n return succeed(converted);\n }\n}\n"]}
@@ -3,17 +3,47 @@ import { ICollectible, CollectibleFactoryCallback, CollectibleFactory } from './
3
3
  import { KeyValueEntry } from './common';
4
4
  import { IReadOnlyResultMap, ResultMapForEachCb, ResultMapResultDetail } from './readonlyResultMap';
5
5
  /**
6
- * Collects {@link Collections.ICollectible | ICollectible} items. Items in a collector are created by key and are assigned an index at the
7
- * time of addition. Items are immutable once added.
6
+ * Additional success or failure details for mutating {@link ICollector | Collector} calls.
8
7
  * @public
9
8
  */
10
- export interface ICollector<TKEY extends string = string, TINDEX extends number = number, TITEM extends ICollectible<TKEY, TINDEX> = ICollectible<TKEY, TINDEX>, TSRC = TITEM> extends IReadOnlyResultMap<TKEY, TITEM> {
9
+ export type CollectorResultDetail = ResultMapResultDetail | 'invalid-index';
10
+ /**
11
+ * A read-only interface exposing non-mutating methods of a {@link Collections.ICollector | Collector}.
12
+ * @public
13
+ */
14
+ export interface IReadOnlyCollector<TKEY extends string = string, TINDEX extends number = number, TITEM extends ICollectible<TKEY, TINDEX> = ICollectible<TKEY, TINDEX>> extends IReadOnlyResultMap<TKEY, TITEM> {
11
15
  /**
12
16
  * Gets the item at a specified index.
13
17
  * @param index - The index of the item to retrieve.
14
- * @returns Returs {@link Success | Success} with the item if it exists, or {@link Failure | Failure} with an error if the index is out of range.
18
+ * @returns Returns {@link Success | Success} with the item if it exists, or {@link Failure | Failure} with an error if the index is out of range.
19
+ */
20
+ getAt(index: number): Result<TITEM>;
21
+ }
22
+ /**
23
+ * Collects {@link Collections.ICollectible | ICollectible} items. Items in a collector are created by key and are assigned an index at the
24
+ * time of addition. Items are immutable once added.
25
+ * @public
26
+ */
27
+ export interface ICollector<TKEY extends string = string, TINDEX extends number = number, TITEM extends ICollectible<TKEY, TINDEX> = ICollectible<TKEY, TINDEX>, TSRC = TITEM> extends IReadOnlyCollector<TKEY, TINDEX, TITEM> {
28
+ /**
29
+ * Adds an item to the collector using the default {@link Collections.CollectibleFactory | factory}
30
+ * at a specified key, failing if an item with that key already exists.
31
+ * @param key - The key of the item to add.
32
+ * @param item - The source representation of the item to be added.
33
+ * @returns Returns {@link Success | Success} with the item if it is added, or {@link Failure | Failure} with
34
+ * an error if the item cannot be created and indexed.
35
+ * @public
15
36
  */
16
- getAt(index: TINDEX): Result<TITEM>;
37
+ add(key: TKEY, item: TSRC): DetailedResult<TITEM, CollectorResultDetail>;
38
+ add(key: TKEY, callback: CollectibleFactoryCallback<TKEY, TINDEX>): DetailedResult<TITEM, CollectorResultDetail>;
39
+ /**
40
+ * Adds an item to the collector using the default {@link Collections.CollectibleFactory | factory}
41
+ * at a specified key, failing if an item with that key already exists.
42
+ * @param item - The item to add.
43
+ * @returns Returns {@link Success | Success} with the item if it is added, or {@link Failure | Failure} with an
44
+ * error if the item cannot be created and indexed.
45
+ */
46
+ addItem(item: TITEM): DetailedResult<TITEM, CollectorResultDetail>;
17
47
  /**
18
48
  * Gets an item by key if it exists, or creates a new item and adds it using the default {@link Collections.CollectibleFactory | factory} if not.
19
49
  * @param key - The key of the item to retrieve.
@@ -21,18 +51,26 @@ export interface ICollector<TKEY extends string = string, TINDEX extends number
21
51
  * @returns Returns {@link Success | Success} with the item if it exists or could be created, or {@link Failure | Failure} with an error if the
22
52
  * item cannot be created and indexed.
23
53
  */
24
- getOrAdd(key: TKEY, item: TSRC): DetailedResult<TITEM, ResultMapResultDetail>;
54
+ getOrAdd(key: TKEY, item: TSRC): DetailedResult<TITEM, CollectorResultDetail>;
25
55
  /**
26
56
  * Gets an item by key if it exists, or creates a new item and adds it using the specified {@link Collections.CollectibleFactoryCallback | factory callback} if not.
27
57
  * @param key - The key of the item to retrieve.
28
58
  * @param callback - The factory callback to create the item if it does not exist.
29
59
  * @returns Returns {@link Success | Success} with the item if it exists, or {@link Failure | Failure} with an error if the item is not found.
30
60
  */
31
- getOrAdd(key: TKEY, callback: CollectibleFactoryCallback<TKEY, TINDEX>): DetailedResult<TITEM, ResultMapResultDetail>;
61
+ getOrAdd(key: TKEY, callback: CollectibleFactoryCallback<TKEY, TINDEX>): DetailedResult<TITEM, CollectorResultDetail>;
62
+ /**
63
+ * Gets an existing item with a key matching that of a supplied item, or adds the supplied
64
+ * item to the collector if no item with that key exists.
65
+ * @param item - The item to retrieve or add.
66
+ * @returns Returns {@link Success | Success} with the item stored in the collector
67
+ * or {@link Failure | Failure} with an error if the item cannot be created and indexed.
68
+ */
69
+ getOrAddItem(item: TITEM): DetailedResult<TITEM, CollectorResultDetail>;
32
70
  /**
33
71
  * Gets a {@link IReadOnlyResultMap | read-only map} which can access the items in the collector.
34
72
  */
35
- toReadOnly(): IReadOnlyResultMap<TKEY, TITEM>;
73
+ toReadOnly(): IReadOnlyCollector<TKEY, TINDEX, TITEM>;
36
74
  }
37
75
  /**
38
76
  * A simple {@link ICollector | ICollector} with non-branded `string` key and `number` index, and no transformation of source items.
@@ -101,17 +139,33 @@ export declare class Collector<TKEY extends string = string, TINDEX extends numb
101
139
  */
102
140
  get(key: TKEY): DetailedResult<TITEM, ResultMapResultDetail>;
103
141
  /**
104
- * {@inheritdoc ICollector.getAt}
142
+ * {@inheritdoc Collections.IReadOnlyCollector.getAt}
143
+ */
144
+ getAt(index: number): Result<TITEM>;
145
+ /**
146
+ * {@inheritdoc ICollector.(add:1)}
147
+ */
148
+ add(key: TKEY, item: TSRC): DetailedResult<TITEM, CollectorResultDetail>;
149
+ /**
150
+ * {@inheritdoc ICollector.(add:2)}
105
151
  */
106
- getAt(index: TINDEX): Result<TITEM>;
152
+ add(key: TKEY, cb: CollectibleFactoryCallback<TKEY, TINDEX, TITEM>): DetailedResult<TITEM, CollectorResultDetail>;
153
+ /**
154
+ * {@inheritdoc ICollector.addItem}
155
+ */
156
+ addItem(item: TITEM): DetailedResult<TITEM, CollectorResultDetail>;
107
157
  /**
108
158
  * {@inheritdoc ICollector.(getOrAdd:1)}
109
159
  */
110
- getOrAdd(key: TKEY, item: TSRC): DetailedResult<TITEM, ResultMapResultDetail>;
160
+ getOrAdd(key: TKEY, item: TSRC): DetailedResult<TITEM, CollectorResultDetail>;
111
161
  /**
112
162
  * {@inheritdoc ICollector.(getOrAdd:2)}
113
163
  */
114
- getOrAdd(key: TKEY, cb: CollectibleFactoryCallback<TKEY, TINDEX, TITEM>): DetailedResult<TITEM, ResultMapResultDetail>;
164
+ getOrAdd(key: TKEY, cb: CollectibleFactoryCallback<TKEY, TINDEX, TITEM>): DetailedResult<TITEM, CollectorResultDetail>;
165
+ /**
166
+ * {@inheritdoc ICollector.getOrAddItem}
167
+ */
168
+ getOrAddItem(item: TITEM): DetailedResult<TITEM, CollectorResultDetail>;
115
169
  /**
116
170
  * {@inheritdoc IReadOnlyResultMap.has}
117
171
  */
@@ -119,12 +173,22 @@ export declare class Collector<TKEY extends string = string, TINDEX extends numb
119
173
  /**
120
174
  * {@inheritdoc ICollector.toReadOnly}
121
175
  */
122
- toReadOnly(): IReadOnlyResultMap<TKEY, TITEM>;
176
+ toReadOnly(): IReadOnlyCollector<TKEY, TINDEX, TITEM>;
123
177
  /**
124
178
  * Gets an iterator over the map entries.
125
179
  * @returns An iterator over the map entries.
126
180
  */
127
181
  [Symbol.iterator](): IterableIterator<KeyValueEntry<TKEY, TITEM>>;
182
+ /**
183
+ * A simple factory method for derived classes which directly store the supplied
184
+ * object.
185
+ * @param key - The key of the item to create.
186
+ * @param index - The index of the item to create.
187
+ * @param item - The source item to create.
188
+ * @returns `Success` with the created item and a detail of 'success', or
189
+ * `Failure` with an error message and appropriate detail.
190
+ */
191
+ protected static _simpleFactory<TKEY extends string = string, TINDEX extends number = number, TITEM extends ICollectible<TKEY, TINDEX> = ICollectible<TKEY, TINDEX>>(key: TKEY, index: number, item: TITEM): Result<TITEM>;
128
192
  protected _isFactoryCB(item: TSRC | CollectibleFactoryCallback<TKEY, TINDEX, TITEM>): item is CollectibleFactoryCallback<TKEY, TINDEX, TITEM>;
129
193
  }
130
194
  //# sourceMappingURL=collector.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"collector.d.ts","sourceRoot":"","sources":["../../../src/packlets/collections/collector.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"collector.d.ts","sourceRoot":"","sources":["../../../src/packlets/collections/collector.ts"],"names":[],"mappings":"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"}
@@ -91,7 +91,7 @@ class Collector {
91
91
  return (0, base_1.succeedWithDetail)(item, 'success');
92
92
  }
93
93
  /**
94
- * {@inheritdoc ICollector.getAt}
94
+ * {@inheritdoc Collections.IReadOnlyCollector.getAt}
95
95
  */
96
96
  getAt(index) {
97
97
  if (index < 0 || index >= this._byIndex.length) {
@@ -99,6 +99,21 @@ class Collector {
99
99
  }
100
100
  return (0, base_1.succeed)(this._byIndex[index]);
101
101
  }
102
+ add(key, itemOrCb) {
103
+ if (this._byKey.has(key)) {
104
+ return (0, base_1.failWithDetail)(`${key}: already exists.`, 'exists');
105
+ }
106
+ return this.getOrAdd(key, itemOrCb);
107
+ }
108
+ /**
109
+ * {@inheritdoc ICollector.addItem}
110
+ */
111
+ addItem(item) {
112
+ if (this._byKey.has(item.key)) {
113
+ return (0, base_1.failWithDetail)(`${item.key}: already exists.`, 'exists');
114
+ }
115
+ return this.getOrAddItem(item);
116
+ }
102
117
  getOrAdd(key, itemOrCb) {
103
118
  if (this._byKey.has(key)) {
104
119
  return (0, base_1.succeedWithDetail)(this._byKey.get(key), 'exists');
@@ -114,12 +129,27 @@ class Collector {
114
129
  return (0, base_1.failWithDetail)(`$[key}: key mismatch in created item - ${newItem.key} !== ${key}`, 'invalid-key');
115
130
  }
116
131
  if (newItem.index !== this._byIndex.length) {
117
- return (0, base_1.failWithDetail)(`$[key}: index mismatch in created item - ${newItem.index} !== ${this._byIndex.length}`, 'invalid-value');
132
+ return (0, base_1.failWithDetail)(`$[key}: index mismatch in created item - ${newItem.index} !== ${this._byIndex.length}`, 'invalid-index');
118
133
  }
119
134
  this._byKey.set(key, newItem);
120
135
  this._byIndex.push(newItem);
121
136
  return (0, base_1.succeedWithDetail)(newItem, 'added');
122
137
  }
138
+ /**
139
+ * {@inheritdoc ICollector.getOrAddItem}
140
+ */
141
+ getOrAddItem(item) {
142
+ if (this._byKey.has(item.key)) {
143
+ return (0, base_1.succeedWithDetail)(this._byKey.get(item.key), 'exists');
144
+ }
145
+ const { message } = item.setIndex(this._byIndex.length);
146
+ if (message !== undefined) {
147
+ return (0, base_1.failWithDetail)(message, 'invalid-index');
148
+ }
149
+ this._byKey.set(item.key, item);
150
+ this._byIndex.push(item);
151
+ return (0, base_1.succeedWithDetail)(item, 'added');
152
+ }
123
153
  /**
124
154
  * {@inheritdoc IReadOnlyResultMap.has}
125
155
  */
@@ -139,6 +169,18 @@ class Collector {
139
169
  [Symbol.iterator]() {
140
170
  return this._byKey[Symbol.iterator]();
141
171
  }
172
+ /**
173
+ * A simple factory method for derived classes which directly store the supplied
174
+ * object.
175
+ * @param key - The key of the item to create.
176
+ * @param index - The index of the item to create.
177
+ * @param item - The source item to create.
178
+ * @returns `Success` with the created item and a detail of 'success', or
179
+ * `Failure` with an error message and appropriate detail.
180
+ */
181
+ static _simpleFactory(key, index, item) {
182
+ return item.setIndex(index).onSuccess(() => (0, base_1.succeed)(item));
183
+ }
142
184
  _isFactoryCB(item) {
143
185
  return typeof item === 'function';
144
186
  }
@@ -1 +1 @@
1
- {"version":3,"file":"collector.js","sourceRoot":"","sources":["../../../src/packlets/collections/collector.ts"],"names":[],"mappings":"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","sourcesContent":["/*\n * Copyright (c) 2025 Erik Fortune\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in all\n * copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n * SOFTWARE.\n */\n\nimport { DetailedResult, Result, fail, failWithDetail, succeed, succeedWithDetail } from '../base';\nimport { ICollectible, CollectibleFactoryCallback, CollectibleFactory } from './collectible';\nimport { KeyValueEntry } from './common';\nimport { IReadOnlyResultMap, ResultMapForEachCb, ResultMapResultDetail } from './readonlyResultMap';\n\n/**\n * Collects {@link Collections.ICollectible | ICollectible} items. Items in a collector are created by key and are assigned an index at the\n * time of addition. Items are immutable once added.\n * @public\n */\nexport interface ICollector<\n TKEY extends string = string,\n TINDEX extends number = number,\n TITEM extends ICollectible<TKEY, TINDEX> = ICollectible<TKEY, TINDEX>,\n TSRC = TITEM\n> extends IReadOnlyResultMap<TKEY, TITEM> {\n /**\n * Gets the item at a specified index.\n * @param index - The index of the item to retrieve.\n * @returns Returs {@link Success | Success} with the item if it exists, or {@link Failure | Failure} with an error if the index is out of range.\n */\n getAt(index: TINDEX): Result<TITEM>;\n\n /**\n * Gets an item by key if it exists, or creates a new item and adds it using the default {@link Collections.CollectibleFactory | factory} if not.\n * @param key - The key of the item to retrieve.\n * @param item - The source representation of the item to be added if it does not exist.\n * @returns Returns {@link Success | Success} with the item if it exists or could be created, or {@link Failure | Failure} with an error if the\n * item cannot be created and indexed.\n */\n getOrAdd(key: TKEY, item: TSRC): DetailedResult<TITEM, ResultMapResultDetail>;\n\n /**\n * Gets an item by key if it exists, or creates a new item and adds it using the specified {@link Collections.CollectibleFactoryCallback | factory callback} if not.\n * @param key - The key of the item to retrieve.\n * @param callback - The factory callback to create the item if it does not exist.\n * @returns Returns {@link Success | Success} with the item if it exists, or {@link Failure | Failure} with an error if the item is not found.\n */\n getOrAdd(\n key: TKEY,\n callback: CollectibleFactoryCallback<TKEY, TINDEX>\n ): DetailedResult<TITEM, ResultMapResultDetail>;\n\n /**\n * Gets a {@link IReadOnlyResultMap | read-only map} which can access the items in the collector.\n */\n toReadOnly(): IReadOnlyResultMap<TKEY, TITEM>;\n}\n\n/**\n * A simple {@link ICollector | ICollector} with non-branded `string` key and `number` index, and no transformation of source items.\n * @public\n */\nexport type ISimpleCollector<TITEM extends ICollectible<string, number>> = ICollector<\n string,\n number,\n TITEM,\n TITEM\n>;\n\n/**\n * A {@link ICollector | Collector} with non-branded `string` key and `number` index, and transformation of source items.\n * @public\n */\nexport type IConvertingCollector<TITEM extends ICollectible<string, number>, TSRC> = ICollector<\n string,\n number,\n TITEM,\n TSRC\n>;\n\n/**\n * Parameters for constructing a {@link ICollector | Collector}.\n * @public\n */\nexport interface ICollectorConstructorParams<\n TKEY extends string = string,\n TINDEX extends number = number,\n TITEM extends ICollectible<TKEY, TINDEX> = ICollectible<TKEY, TINDEX>,\n TSRC = TITEM\n> {\n /**\n * The default {@link Collections.CollectibleFactory | factory} to create items.\n */\n factory: CollectibleFactory<TKEY, TINDEX, TITEM, TSRC>;\n /**\n * An optional array of entries to add to the collector.\n */\n entries?: KeyValueEntry<TKEY, TSRC>[];\n}\n\n/**\n * A {@link ICollector | Collector} that collects {@link Collections.ICollectible | ICollectible} items. Items in a collector are created by key and are assigned an index at the\n * time of addition. Items are immutable once added. Keys and indexes might be branded types, and source items might be transformed on addition.\n * @public\n */\nexport class Collector<\n TKEY extends string = string,\n TINDEX extends number = number,\n TITEM extends ICollectible<TKEY, TINDEX> = ICollectible<TKEY, TINDEX>,\n TSRC = TITEM\n> implements ICollector<TKEY, TINDEX, TITEM, TSRC>\n{\n private _byKey: Map<TKEY, TITEM>;\n private _byIndex: TITEM[];\n private _factory: CollectibleFactory<TKEY, TINDEX, TITEM, TSRC>;\n\n /**\n * {@inheritdoc IReadOnlyResultMap.inner}\n */\n public get inner(): ReadonlyMap<TKEY, TITEM> {\n return this._byKey;\n }\n\n /**\n * Constructor for derived classes.\n * @param params - Parameters for constructing the collector.\n */\n protected constructor(params: ICollectorConstructorParams<TKEY, TINDEX, TITEM, TSRC>) {\n this._byKey = new Map<TKEY, TITEM>();\n this._byIndex = [];\n this._factory = params.factory;\n params.entries?.forEach((entry) => {\n this.getOrAdd(entry[0], entry[1]);\n });\n }\n\n /**\n * {@inheritdoc IReadOnlyResultMap.size}\n */\n public get size(): number {\n return this._byKey.size;\n }\n\n /**\n * {@inheritdoc IReadOnlyResultMap.keys}\n */\n public keys(): IterableIterator<TKEY> {\n return this._byKey.keys();\n }\n\n /**\n * {@inheritdoc IReadOnlyResultMap.values}\n */\n public values(): IterableIterator<TITEM> {\n return this._byKey.values();\n }\n\n /**\n * {@inheritdoc IReadOnlyResultMap.entries}\n */\n public entries(): IterableIterator<[TKEY, TITEM]> {\n return this._byKey.entries();\n }\n\n /**\n * {@inheritdoc IReadOnlyResultMap.forEach}\n */\n public forEach(callback: ResultMapForEachCb<TKEY, TITEM>, arg?: unknown): void {\n for (const [key, value] of this._byKey.entries()) {\n callback(value, key, this, arg);\n }\n }\n\n /**\n * {@inheritdoc IReadOnlyResultMap.get}\n */\n public get(key: TKEY): DetailedResult<TITEM, ResultMapResultDetail> {\n const item = this._byKey.get(key);\n if (item === undefined) {\n return failWithDetail<TITEM, ResultMapResultDetail>(`${key}: not found.`, 'not-found');\n }\n return succeedWithDetail(item, 'success');\n }\n\n /**\n * {@inheritdoc ICollector.getAt}\n */\n public getAt(index: TINDEX): Result<TITEM> {\n if (index < 0 || index >= this._byIndex.length) {\n return fail(`${index}: out of range.`);\n }\n return succeed(this._byIndex[index]);\n }\n\n /**\n * {@inheritdoc ICollector.(getOrAdd:1)}\n */\n public getOrAdd(key: TKEY, item: TSRC): DetailedResult<TITEM, ResultMapResultDetail>;\n /**\n * {@inheritdoc ICollector.(getOrAdd:2)}\n */\n public getOrAdd(\n key: TKEY,\n cb: CollectibleFactoryCallback<TKEY, TINDEX, TITEM>\n ): DetailedResult<TITEM, ResultMapResultDetail>;\n public getOrAdd(\n key: TKEY,\n itemOrCb: TSRC | CollectibleFactoryCallback<TKEY, TINDEX, TITEM>\n ): DetailedResult<TITEM, ResultMapResultDetail> {\n if (this._byKey.has(key)) {\n return succeedWithDetail(this._byKey.get(key)!, 'exists');\n }\n const build = this._isFactoryCB(itemOrCb)\n ? itemOrCb(key, this._byIndex.length)\n : this._factory(key, this._byIndex.length, itemOrCb);\n if (build.isFailure()) {\n return failWithDetail<TITEM, ResultMapResultDetail>(build.message, 'invalid-value');\n }\n const newItem = build.value;\n\n if (newItem.key !== key) {\n return failWithDetail(\n `$[key}: key mismatch in created item - ${newItem.key} !== ${key}`,\n 'invalid-key'\n );\n }\n if (newItem.index !== this._byIndex.length) {\n return failWithDetail(\n `$[key}: index mismatch in created item - ${newItem.index} !== ${this._byIndex.length}`,\n 'invalid-value'\n );\n }\n this._byKey.set(key, newItem);\n this._byIndex.push(newItem);\n return succeedWithDetail(newItem, 'added');\n }\n\n /**\n * {@inheritdoc IReadOnlyResultMap.has}\n */\n public has(key: TKEY): boolean {\n return this._byKey.has(key);\n }\n\n /**\n * {@inheritdoc ICollector.toReadOnly}\n */\n public toReadOnly(): IReadOnlyResultMap<TKEY, TITEM> {\n return this;\n }\n\n /**\n * Gets an iterator over the map entries.\n * @returns An iterator over the map entries.\n */\n public [Symbol.iterator](): IterableIterator<KeyValueEntry<TKEY, TITEM>> {\n return this._byKey[Symbol.iterator]();\n }\n\n protected _isFactoryCB(\n item: TSRC | CollectibleFactoryCallback<TKEY, TINDEX, TITEM>\n ): item is CollectibleFactoryCallback<TKEY, TINDEX, TITEM> {\n return typeof item === 'function';\n }\n}\n"]}
1
+ {"version":3,"file":"collector.js","sourceRoot":"","sources":["../../../src/packlets/collections/collector.ts"],"names":[],"mappings":"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","sourcesContent":["/*\n * Copyright (c) 2025 Erik Fortune\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in all\n * copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n * SOFTWARE.\n */\n\nimport { DetailedResult, Result, fail, failWithDetail, succeed, succeedWithDetail } from '../base';\nimport { ICollectible, CollectibleFactoryCallback, CollectibleFactory } from './collectible';\nimport { KeyValueEntry } from './common';\nimport { IReadOnlyResultMap, ResultMapForEachCb, ResultMapResultDetail } from './readonlyResultMap';\n\n/**\n * Additional success or failure details for mutating {@link ICollector | Collector} calls.\n * @public\n */\nexport type CollectorResultDetail = ResultMapResultDetail | 'invalid-index';\n\n/**\n * A read-only interface exposing non-mutating methods of a {@link Collections.ICollector | Collector}.\n * @public\n */\nexport interface IReadOnlyCollector<\n TKEY extends string = string,\n TINDEX extends number = number,\n TITEM extends ICollectible<TKEY, TINDEX> = ICollectible<TKEY, TINDEX>\n> extends IReadOnlyResultMap<TKEY, TITEM> {\n /**\n * Gets the item at a specified index.\n * @param index - The index of the item to retrieve.\n * @returns Returns {@link Success | Success} with the item if it exists, or {@link Failure | Failure} with an error if the index is out of range.\n */\n getAt(index: number): Result<TITEM>;\n}\n\n/**\n * Collects {@link Collections.ICollectible | ICollectible} items. Items in a collector are created by key and are assigned an index at the\n * time of addition. Items are immutable once added.\n * @public\n */\nexport interface ICollector<\n TKEY extends string = string,\n TINDEX extends number = number,\n TITEM extends ICollectible<TKEY, TINDEX> = ICollectible<TKEY, TINDEX>,\n TSRC = TITEM\n> extends IReadOnlyCollector<TKEY, TINDEX, TITEM> {\n /**\n * Adds an item to the collector using the default {@link Collections.CollectibleFactory | factory}\n * at a specified key, failing if an item with that key already exists.\n * @param key - The key of the item to add.\n * @param item - The source representation of the item to be added.\n * @returns Returns {@link Success | Success} with the item if it is added, or {@link Failure | Failure} with\n * an error if the item cannot be created and indexed.\n * @public\n */\n add(key: TKEY, item: TSRC): DetailedResult<TITEM, CollectorResultDetail>;\n add(\n key: TKEY,\n callback: CollectibleFactoryCallback<TKEY, TINDEX>\n ): DetailedResult<TITEM, CollectorResultDetail>;\n\n /**\n * Adds an item to the collector using the default {@link Collections.CollectibleFactory | factory}\n * at a specified key, failing if an item with that key already exists.\n * @param item - The item to add.\n * @returns Returns {@link Success | Success} with the item if it is added, or {@link Failure | Failure} with an\n * error if the item cannot be created and indexed.\n */\n addItem(item: TITEM): DetailedResult<TITEM, CollectorResultDetail>;\n\n /**\n * Gets an item by key if it exists, or creates a new item and adds it using the default {@link Collections.CollectibleFactory | factory} if not.\n * @param key - The key of the item to retrieve.\n * @param item - The source representation of the item to be added if it does not exist.\n * @returns Returns {@link Success | Success} with the item if it exists or could be created, or {@link Failure | Failure} with an error if the\n * item cannot be created and indexed.\n */\n getOrAdd(key: TKEY, item: TSRC): DetailedResult<TITEM, CollectorResultDetail>;\n\n /**\n * Gets an item by key if it exists, or creates a new item and adds it using the specified {@link Collections.CollectibleFactoryCallback | factory callback} if not.\n * @param key - The key of the item to retrieve.\n * @param callback - The factory callback to create the item if it does not exist.\n * @returns Returns {@link Success | Success} with the item if it exists, or {@link Failure | Failure} with an error if the item is not found.\n */\n getOrAdd(\n key: TKEY,\n callback: CollectibleFactoryCallback<TKEY, TINDEX>\n ): DetailedResult<TITEM, CollectorResultDetail>;\n\n /**\n * Gets an existing item with a key matching that of a supplied item, or adds the supplied\n * item to the collector if no item with that key exists.\n * @param item - The item to retrieve or add.\n * @returns Returns {@link Success | Success} with the item stored in the collector\n * or {@link Failure | Failure} with an error if the item cannot be created and indexed.\n */\n getOrAddItem(item: TITEM): DetailedResult<TITEM, CollectorResultDetail>;\n\n /**\n * Gets a {@link IReadOnlyResultMap | read-only map} which can access the items in the collector.\n */\n toReadOnly(): IReadOnlyCollector<TKEY, TINDEX, TITEM>;\n}\n\n/**\n * A simple {@link ICollector | ICollector} with non-branded `string` key and `number` index, and no transformation of source items.\n * @public\n */\nexport type ISimpleCollector<TITEM extends ICollectible<string, number>> = ICollector<\n string,\n number,\n TITEM,\n TITEM\n>;\n\n/**\n * A {@link ICollector | Collector} with non-branded `string` key and `number` index, and transformation of source items.\n * @public\n */\nexport type IConvertingCollector<TITEM extends ICollectible<string, number>, TSRC> = ICollector<\n string,\n number,\n TITEM,\n TSRC\n>;\n\n/**\n * Parameters for constructing a {@link ICollector | Collector}.\n * @public\n */\nexport interface ICollectorConstructorParams<\n TKEY extends string = string,\n TINDEX extends number = number,\n TITEM extends ICollectible<TKEY, TINDEX> = ICollectible<TKEY, TINDEX>,\n TSRC = TITEM\n> {\n /**\n * The default {@link Collections.CollectibleFactory | factory} to create items.\n */\n factory: CollectibleFactory<TKEY, TINDEX, TITEM, TSRC>;\n /**\n * An optional array of entries to add to the collector.\n */\n entries?: KeyValueEntry<TKEY, TSRC>[];\n}\n\n/**\n * A {@link ICollector | Collector} that collects {@link Collections.ICollectible | ICollectible} items. Items in a collector are created by key and are assigned an index at the\n * time of addition. Items are immutable once added. Keys and indexes might be branded types, and source items might be transformed on addition.\n * @public\n */\nexport class Collector<\n TKEY extends string = string,\n TINDEX extends number = number,\n TITEM extends ICollectible<TKEY, TINDEX> = ICollectible<TKEY, TINDEX>,\n TSRC = TITEM\n> implements ICollector<TKEY, TINDEX, TITEM, TSRC>\n{\n private _byKey: Map<TKEY, TITEM>;\n private _byIndex: TITEM[];\n private _factory: CollectibleFactory<TKEY, TINDEX, TITEM, TSRC>;\n\n /**\n * {@inheritdoc IReadOnlyResultMap.inner}\n */\n public get inner(): ReadonlyMap<TKEY, TITEM> {\n return this._byKey;\n }\n\n /**\n * Constructor for derived classes.\n * @param params - Parameters for constructing the collector.\n */\n protected constructor(params: ICollectorConstructorParams<TKEY, TINDEX, TITEM, TSRC>) {\n this._byKey = new Map<TKEY, TITEM>();\n this._byIndex = [];\n this._factory = params.factory;\n params.entries?.forEach((entry) => {\n this.getOrAdd(entry[0], entry[1]);\n });\n }\n\n /**\n * {@inheritdoc IReadOnlyResultMap.size}\n */\n public get size(): number {\n return this._byKey.size;\n }\n\n /**\n * {@inheritdoc IReadOnlyResultMap.keys}\n */\n public keys(): IterableIterator<TKEY> {\n return this._byKey.keys();\n }\n\n /**\n * {@inheritdoc IReadOnlyResultMap.values}\n */\n public values(): IterableIterator<TITEM> {\n return this._byKey.values();\n }\n\n /**\n * {@inheritdoc IReadOnlyResultMap.entries}\n */\n public entries(): IterableIterator<[TKEY, TITEM]> {\n return this._byKey.entries();\n }\n\n /**\n * {@inheritdoc IReadOnlyResultMap.forEach}\n */\n public forEach(callback: ResultMapForEachCb<TKEY, TITEM>, arg?: unknown): void {\n for (const [key, value] of this._byKey.entries()) {\n callback(value, key, this, arg);\n }\n }\n\n /**\n * {@inheritdoc IReadOnlyResultMap.get}\n */\n public get(key: TKEY): DetailedResult<TITEM, ResultMapResultDetail> {\n const item = this._byKey.get(key);\n if (item === undefined) {\n return failWithDetail<TITEM, ResultMapResultDetail>(`${key}: not found.`, 'not-found');\n }\n return succeedWithDetail(item, 'success');\n }\n\n /**\n * {@inheritdoc Collections.IReadOnlyCollector.getAt}\n */\n public getAt(index: number): Result<TITEM> {\n if (index < 0 || index >= this._byIndex.length) {\n return fail(`${index}: out of range.`);\n }\n return succeed(this._byIndex[index]);\n }\n\n /**\n * {@inheritdoc ICollector.(add:1)}\n */\n public add(key: TKEY, item: TSRC): DetailedResult<TITEM, CollectorResultDetail>;\n /**\n * {@inheritdoc ICollector.(add:2)}\n */\n public add(\n key: TKEY,\n cb: CollectibleFactoryCallback<TKEY, TINDEX, TITEM>\n ): DetailedResult<TITEM, CollectorResultDetail>;\n public add(\n key: TKEY,\n itemOrCb: TSRC | CollectibleFactoryCallback<TKEY, TINDEX, TITEM>\n ): DetailedResult<TITEM, CollectorResultDetail> {\n if (this._byKey.has(key)) {\n return failWithDetail(`${key}: already exists.`, 'exists');\n }\n return this.getOrAdd(key, itemOrCb as TSRC);\n }\n\n /**\n * {@inheritdoc ICollector.addItem}\n */\n public addItem(item: TITEM): DetailedResult<TITEM, CollectorResultDetail> {\n if (this._byKey.has(item.key)) {\n return failWithDetail(`${item.key}: already exists.`, 'exists');\n }\n return this.getOrAddItem(item);\n }\n\n /**\n * {@inheritdoc ICollector.(getOrAdd:1)}\n */\n public getOrAdd(key: TKEY, item: TSRC): DetailedResult<TITEM, CollectorResultDetail>;\n /**\n * {@inheritdoc ICollector.(getOrAdd:2)}\n */\n public getOrAdd(\n key: TKEY,\n cb: CollectibleFactoryCallback<TKEY, TINDEX, TITEM>\n ): DetailedResult<TITEM, CollectorResultDetail>;\n\n public getOrAdd(\n key: TKEY,\n itemOrCb: TSRC | CollectibleFactoryCallback<TKEY, TINDEX, TITEM>\n ): DetailedResult<TITEM, CollectorResultDetail> {\n if (this._byKey.has(key)) {\n return succeedWithDetail(this._byKey.get(key)!, 'exists');\n }\n const build = this._isFactoryCB(itemOrCb)\n ? itemOrCb(key, this._byIndex.length)\n : this._factory(key, this._byIndex.length, itemOrCb);\n if (build.isFailure()) {\n return failWithDetail<TITEM, CollectorResultDetail>(build.message, 'invalid-value');\n }\n const newItem = build.value;\n\n if (newItem.key !== key) {\n return failWithDetail(\n `$[key}: key mismatch in created item - ${newItem.key} !== ${key}`,\n 'invalid-key'\n );\n }\n if (newItem.index !== this._byIndex.length) {\n return failWithDetail(\n `$[key}: index mismatch in created item - ${newItem.index} !== ${this._byIndex.length}`,\n 'invalid-index'\n );\n }\n this._byKey.set(key, newItem);\n this._byIndex.push(newItem);\n return succeedWithDetail(newItem, 'added');\n }\n\n /**\n * {@inheritdoc ICollector.getOrAddItem}\n */\n public getOrAddItem(item: TITEM): DetailedResult<TITEM, CollectorResultDetail> {\n if (this._byKey.has(item.key)) {\n return succeedWithDetail(this._byKey.get(item.key)!, 'exists');\n }\n const { message } = item.setIndex(this._byIndex.length);\n if (message !== undefined) {\n return failWithDetail(message, 'invalid-index');\n }\n this._byKey.set(item.key, item);\n this._byIndex.push(item);\n return succeedWithDetail(item, 'added');\n }\n\n /**\n * {@inheritdoc IReadOnlyResultMap.has}\n */\n public has(key: TKEY): boolean {\n return this._byKey.has(key);\n }\n\n /**\n * {@inheritdoc ICollector.toReadOnly}\n */\n public toReadOnly(): IReadOnlyCollector<TKEY, TINDEX, TITEM> {\n return this;\n }\n\n /**\n * Gets an iterator over the map entries.\n * @returns An iterator over the map entries.\n */\n public [Symbol.iterator](): IterableIterator<KeyValueEntry<TKEY, TITEM>> {\n return this._byKey[Symbol.iterator]();\n }\n\n /**\n * A simple factory method for derived classes which directly store the supplied\n * object.\n * @param key - The key of the item to create.\n * @param index - The index of the item to create.\n * @param item - The source item to create.\n * @returns `Success` with the created item and a detail of 'success', or\n * `Failure` with an error message and appropriate detail.\n */\n protected static _simpleFactory<\n TKEY extends string = string,\n TINDEX extends number = number,\n TITEM extends ICollectible<TKEY, TINDEX> = ICollectible<TKEY, TINDEX>\n >(key: TKEY, index: number, item: TITEM): Result<TITEM> {\n return item.setIndex(index).onSuccess(() => succeed(item));\n }\n\n protected _isFactoryCB(\n item: TSRC | CollectibleFactoryCallback<TKEY, TINDEX, TITEM>\n ): item is CollectibleFactoryCallback<TKEY, TINDEX, TITEM> {\n return typeof item === 'function';\n }\n}\n"]}
@@ -3,8 +3,27 @@ import { IReadOnlyResultMap, ResultMapResultDetail } from './readonlyResultMap';
3
3
  import { ResultMapValueFactory } from './resultMap';
4
4
  import { KeyValueConverters } from './keyValueConverters';
5
5
  import { CollectibleFactoryCallback, ICollectible } from './collectible';
6
- import { ICollector } from './collector';
6
+ import { CollectorResultDetail, ICollector } from './collector';
7
7
  import { IReadOnlyResultMapConverter } from './resultMapConverter';
8
+ /**
9
+ * A read-only interface exposing non-mutating methods of a
10
+ * {@link Collections.CollectorConverter | CollectorConverter}.
11
+ * @public
12
+ */
13
+ export interface IReadOnlyCollectorConverter<TKEY extends string = string, TINDEX extends number = number, TITEM extends ICollectible<TKEY> = ICollectible<TKEY, TINDEX>> extends IReadOnlyResultMapConverter<TKEY, TITEM> {
14
+ /**
15
+ * {@inheritdoc Collections.CollectorConverter.map}
16
+ */
17
+ readonly map: IReadOnlyResultMap<TKEY, TITEM>;
18
+ /**
19
+ * {@inheritdoc Collections.Collector.get}
20
+ */
21
+ get(key: string): DetailedResult<TITEM, ResultMapResultDetail>;
22
+ /**
23
+ * {@inheritdoc Collections.Collector.has}
24
+ */
25
+ has(key: string): boolean;
26
+ }
8
27
  /**
9
28
  * Parameters for constructing a {@link Collections.CollectorConverter | CollectorConverter}.
10
29
  * @public
@@ -27,6 +46,14 @@ export declare class CollectorConverter<TKEY extends string = string, TINDEX ext
27
46
  * @param params - Required parameters for constructing the collector converter.
28
47
  */
29
48
  constructor(params: ICollectorConverterCreateParams<TKEY, TINDEX, TITEM, TSRC>);
49
+ /**
50
+ * {@inheritdoc Collections.Collector.(add:1)}
51
+ */
52
+ add(key: string, value: unknown): DetailedResult<TITEM, CollectorResultDetail>;
53
+ /**
54
+ * {@inheritdoc Collections.Collector.(add:2)}
55
+ */
56
+ add(key: string, factory: ResultMapValueFactory<TKEY, TITEM>): DetailedResult<TITEM, CollectorResultDetail>;
30
57
  /**
31
58
  * {@inheritdoc Collections.Collector.get}
32
59
  */
@@ -34,11 +61,11 @@ export declare class CollectorConverter<TKEY extends string = string, TINDEX ext
34
61
  /**
35
62
  * {@inheritdoc Collections.Collector.(getOrAdd:1)}
36
63
  */
37
- getOrAdd(key: string, value: unknown): DetailedResult<TITEM, ResultMapResultDetail>;
64
+ getOrAdd(key: string, value: unknown): DetailedResult<TITEM, CollectorResultDetail>;
38
65
  /**
39
66
  * {@inheritdoc Collections.Collector.(getOrAdd:2)}
40
67
  */
41
- getOrAdd(key: string, factory: ResultMapValueFactory<TKEY, TITEM>): DetailedResult<TITEM, ResultMapResultDetail>;
68
+ getOrAdd(key: string, factory: ResultMapValueFactory<TKEY, TITEM>): DetailedResult<TITEM, CollectorResultDetail>;
42
69
  /**
43
70
  * {@inheritdoc Collections.Collector.has}
44
71
  */
@@ -46,7 +73,7 @@ export declare class CollectorConverter<TKEY extends string = string, TINDEX ext
46
73
  /**
47
74
  * {@inheritdoc Collections.Collector.toReadOnly}
48
75
  */
49
- toReadOnly(): IReadOnlyResultMapConverter<TKEY, TITEM>;
76
+ toReadOnly(): IReadOnlyCollectorConverter<TKEY, TINDEX, TITEM>;
50
77
  /**
51
78
  * Determines if a value is a {@link Collections.CollectibleFactoryCallback | CollectibleFactoryCallback}.
52
79
  * @param value - The value to check.
@@ -1 +1 @@
1
- {"version":3,"file":"collectorConverter.d.ts","sourceRoot":"","sources":["../../../src/packlets/collections/collectorConverter.ts"],"names":[],"mappings":"AAsBA,OAAO,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AACzC,OAAO,EAAE,kBAAkB,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAC;AAChF,OAAO,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAC;AACpD,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAC1D,OAAO,EAAE,0BAA0B,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AACzE,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,2BAA2B,EAAE,MAAM,sBAAsB,CAAC;AAEnE;;;GAGG;AACH,MAAM,WAAW,+BAA+B,CAC9C,IAAI,SAAS,MAAM,GAAG,MAAM,EAC5B,MAAM,SAAS,MAAM,GAAG,MAAM,EAC9B,KAAK,SAAS,YAAY,CAAC,IAAI,EAAE,MAAM,CAAC,GAAG,YAAY,CAAC,IAAI,EAAE,MAAM,CAAC,EACrE,IAAI,GAAG,KAAK;IAEZ,SAAS,EAAE,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,CAAC,CAAC;IACjD,UAAU,EAAE,kBAAkB,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;CAC5C;AAED;;;;GAIG;AACH,qBAAa,kBAAkB,CAC7B,IAAI,SAAS,MAAM,GAAG,MAAM,EAC5B,MAAM,SAAS,MAAM,GAAG,MAAM,EAC9B,KAAK,SAAS,YAAY,CAAC,IAAI,EAAE,MAAM,CAAC,GAAG,YAAY,CAAC,IAAI,EAAE,MAAM,CAAC,EACrE,IAAI,GAAG,KAAK,CACZ,YAAW,2BAA2B,CAAC,IAAI,EAAE,KAAK,CAAC;IAEnD,SAAgB,UAAU,EAAE,kBAAkB,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;IAE3D,IAAW,GAAG,IAAI,kBAAkB,CAAC,IAAI,EAAE,KAAK,CAAC,CAEhD;IAED,SAAS,CAAC,UAAU,EAAE,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,CAAC,CAAC;IAE5D;;;OAGG;gBACgB,MAAM,EAAE,+BAA+B,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,CAAC;IAKrF;;OAEG;IACI,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,cAAc,CAAC,KAAK,EAAE,qBAAqB,CAAC;IAMrE;;OAEG;IACI,QAAQ,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,GAAG,cAAc,CAAC,KAAK,EAAE,qBAAqB,CAAC;IAE1F;;OAEG;IACI,QAAQ,CACb,GAAG,EAAE,MAAM,EACX,OAAO,EAAE,qBAAqB,CAAC,IAAI,EAAE,KAAK,CAAC,GAC1C,cAAc,CAAC,KAAK,EAAE,qBAAqB,CAAC;IAgB/C;;OAEG;IACI,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO;IAIhC;;OAEG;IACI,UAAU,IAAI,2BAA2B,CAAC,IAAI,EAAE,KAAK,CAAC;IAI7D;;;;;;OAMG;IACH,SAAS,CAAC,6BAA6B,CACrC,KAAK,EAAE,OAAO,GAAG,0BAA0B,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,CAAC,GAC/D,KAAK,IAAI,0BAA0B,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,CAAC;CAG5D"}
1
+ {"version":3,"file":"collectorConverter.d.ts","sourceRoot":"","sources":["../../../src/packlets/collections/collectorConverter.ts"],"names":[],"mappings":"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"}
@@ -22,6 +22,7 @@
22
22
  */
23
23
  Object.defineProperty(exports, "__esModule", { value: true });
24
24
  exports.CollectorConverter = void 0;
25
+ const base_1 = require("../base");
25
26
  /**
26
27
  * A {@link Collections.Collector | Collector} wrapper which validates weakly-typed keys
27
28
  * and values before calling the wrapped collector.
@@ -39,6 +40,12 @@ class CollectorConverter {
39
40
  this._collector = params.collector;
40
41
  this.converters = params.converters;
41
42
  }
43
+ add(key, valueOrFactory) {
44
+ if (this.has(key)) {
45
+ return (0, base_1.failWithDetail)(`${key}: already exists`, 'exists');
46
+ }
47
+ return this.getOrAdd(key, valueOrFactory);
48
+ }
42
49
  /**
43
50
  * {@inheritdoc Collections.Collector.get}
44
51
  */
@@ -49,14 +56,19 @@ class CollectorConverter {
49
56
  }
50
57
  getOrAdd(key, valueOrFactory) {
51
58
  if (!this._isCollectibleFactoryCallback(valueOrFactory)) {
52
- return this.converters.convertEntry([key, valueOrFactory]).onSuccess(([vk, vs]) => {
53
- return this._collector.getOrAdd(vk, vs);
54
- });
59
+ const converted = this.converters.convertEntry([key, valueOrFactory]);
60
+ if (converted.isFailure()) {
61
+ return (0, base_1.failWithDetail)(converted.message, converted.detail);
62
+ }
63
+ const [vk, vs] = converted.value;
64
+ return this._collector.getOrAdd(vk, vs);
55
65
  }
56
66
  else {
57
- return this.converters.convertKey(key).onSuccess((k) => {
58
- return this._collector.getOrAdd(k, valueOrFactory);
59
- });
67
+ const converted = this.converters.convertKey(key);
68
+ if (converted.isFailure()) {
69
+ return (0, base_1.failWithDetail)(converted.message, converted.detail);
70
+ }
71
+ return this._collector.getOrAdd(converted.value, valueOrFactory);
60
72
  }
61
73
  }
62
74
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"collectorConverter.js","sourceRoot":"","sources":["../../../src/packlets/collections/collectorConverter.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;;;AAwBH;;;;GAIG;AACH,MAAa,kBAAkB;IAS7B,IAAW,GAAG;QACZ,OAAO,IAAI,CAAC,UAAU,CAAC,UAAU,EAAE,CAAC;IACtC,CAAC;IAID;;;OAGG;IACH,YAAmB,MAAkE;QACnF,IAAI,CAAC,UAAU,GAAG,MAAM,CAAC,SAAS,CAAC;QACnC,IAAI,CAAC,UAAU,GAAG,MAAM,CAAC,UAAU,CAAC;IACtC,CAAC;IAED;;OAEG;IACI,GAAG,CAAC,GAAW;QACpB,OAAO,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,EAAE;YACrD,OAAO,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;QAChC,CAAC,CAAC,CAAC;IACL,CAAC;IAcM,QAAQ,CACb,GAAW,EACX,cAAyE;QAEzE,IAAI,CAAC,IAAI,CAAC,6BAA6B,CAAC,cAAc,CAAC,EAAE,CAAC;YACxD,OAAO,IAAI,CAAC,UAAU,CAAC,YAAY,CAAC,CAAC,GAAG,EAAE,cAAc,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE;gBAChF,OAAO,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC;YAC1C,CAAC,CAAC,CAAC;QACL,CAAC;aAAM,CAAC;YACN,OAAO,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,EAAE;gBACrD,OAAO,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC,EAAE,cAAc,CAAC,CAAC;YACrD,CAAC,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED;;OAEG;IACI,GAAG,CAAC,GAAW;QACpB,OAAO,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,GAAW,CAAC,CAAC;IAC1C,CAAC;IAED;;OAEG;IACI,UAAU;QACf,OAAO,IAAI,CAAC;IACd,CAAC;IAED;;;;;;OAMG;IACO,6BAA6B,CACrC,KAAgE;QAEhE,OAAO,OAAO,KAAK,KAAK,UAAU,CAAC;IACrC,CAAC;CACF;AAtFD,gDAsFC","sourcesContent":["/*\n * Copyright (c) 2025 Erik Fortune\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in all\n * copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n * SOFTWARE.\n */\n\nimport { DetailedResult } from '../base';\nimport { IReadOnlyResultMap, ResultMapResultDetail } from './readonlyResultMap';\nimport { ResultMapValueFactory } from './resultMap';\nimport { KeyValueConverters } from './keyValueConverters';\nimport { CollectibleFactoryCallback, ICollectible } from './collectible';\nimport { ICollector } from './collector';\nimport { IReadOnlyResultMapConverter } from './resultMapConverter';\n\n/**\n * Parameters for constructing a {@link Collections.CollectorConverter | CollectorConverter}.\n * @public\n */\nexport interface ICollectorConverterCreateParams<\n TKEY extends string = string,\n TINDEX extends number = number,\n TITEM extends ICollectible<TKEY, TINDEX> = ICollectible<TKEY, TINDEX>,\n TSRC = TITEM\n> {\n collector: ICollector<TKEY, TINDEX, TITEM, TSRC>;\n converters: KeyValueConverters<TKEY, TSRC>;\n}\n\n/**\n * A {@link Collections.Collector | Collector} wrapper which validates weakly-typed keys\n * and values before calling the wrapped collector.\n * @public\n */\nexport class CollectorConverter<\n TKEY extends string = string,\n TINDEX extends number = number,\n TITEM extends ICollectible<TKEY, TINDEX> = ICollectible<TKEY, TINDEX>,\n TSRC = TITEM\n> implements IReadOnlyResultMapConverter<TKEY, TITEM>\n{\n public readonly converters: KeyValueConverters<TKEY, TSRC>;\n\n public get map(): IReadOnlyResultMap<TKEY, TITEM> {\n return this._collector.toReadOnly();\n }\n\n protected _collector: ICollector<TKEY, TINDEX, TITEM, TSRC>;\n\n /**\n * Constructs a new {@link Collections.CollectorConverter | CollectorConverter}.\n * @param params - Required parameters for constructing the collector converter.\n */\n public constructor(params: ICollectorConverterCreateParams<TKEY, TINDEX, TITEM, TSRC>) {\n this._collector = params.collector;\n this.converters = params.converters;\n }\n\n /**\n * {@inheritdoc Collections.Collector.get}\n */\n public get(key: string): DetailedResult<TITEM, ResultMapResultDetail> {\n return this.converters.convertKey(key).onSuccess((k) => {\n return this._collector.get(k);\n });\n }\n\n /**\n * {@inheritdoc Collections.Collector.(getOrAdd:1)}\n */\n public getOrAdd(key: string, value: unknown): DetailedResult<TITEM, ResultMapResultDetail>;\n\n /**\n * {@inheritdoc Collections.Collector.(getOrAdd:2)}\n */\n public getOrAdd(\n key: string,\n factory: ResultMapValueFactory<TKEY, TITEM>\n ): DetailedResult<TITEM, ResultMapResultDetail>;\n public getOrAdd(\n key: string,\n valueOrFactory: unknown | CollectibleFactoryCallback<TKEY, TINDEX, TITEM>\n ): DetailedResult<TITEM, ResultMapResultDetail> {\n if (!this._isCollectibleFactoryCallback(valueOrFactory)) {\n return this.converters.convertEntry([key, valueOrFactory]).onSuccess(([vk, vs]) => {\n return this._collector.getOrAdd(vk, vs);\n });\n } else {\n return this.converters.convertKey(key).onSuccess((k) => {\n return this._collector.getOrAdd(k, valueOrFactory);\n });\n }\n }\n\n /**\n * {@inheritdoc Collections.Collector.has}\n */\n public has(key: string): boolean {\n return this._collector.has(key as TKEY);\n }\n\n /**\n * {@inheritdoc Collections.Collector.toReadOnly}\n */\n public toReadOnly(): IReadOnlyResultMapConverter<TKEY, TITEM> {\n return this;\n }\n\n /**\n * Determines if a value is a {@link Collections.CollectibleFactoryCallback | CollectibleFactoryCallback}.\n * @param value - The value to check.\n * @returns `true` if the value is a {@link Collections.CollectibleFactoryCallback | CollectibleFactoryCallback},\n * `false` otherwise.\n * @public\n */\n protected _isCollectibleFactoryCallback(\n value: unknown | CollectibleFactoryCallback<TKEY, TINDEX, TITEM>\n ): value is CollectibleFactoryCallback<TKEY, TINDEX, TITEM> {\n return typeof value === 'function';\n }\n}\n"]}
1
+ {"version":3,"file":"collectorConverter.js","sourceRoot":"","sources":["../../../src/packlets/collections/collectorConverter.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;;;AAEH,kCAAyD;AAgDzD;;;;GAIG;AACH,MAAa,kBAAkB;IAS7B,IAAW,GAAG;QACZ,OAAO,IAAI,CAAC,UAAU,CAAC,UAAU,EAAE,CAAC;IACtC,CAAC;IAID;;;OAGG;IACH,YAAmB,MAAkE;QACnF,IAAI,CAAC,UAAU,GAAG,MAAM,CAAC,SAAS,CAAC;QACnC,IAAI,CAAC,UAAU,GAAG,MAAM,CAAC,UAAU,CAAC;IACtC,CAAC;IAcM,GAAG,CACR,GAAW,EACX,cAA4D;QAE5D,IAAI,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC;YAClB,OAAO,IAAA,qBAAc,EAAC,GAAG,GAAG,kBAAkB,EAAE,QAAQ,CAAC,CAAC;QAC5D,CAAC;QACD,OAAO,IAAI,CAAC,QAAQ,CAAC,GAAG,EAAE,cAAc,CAAC,CAAC;IAC5C,CAAC;IAED;;OAEG;IACI,GAAG,CAAC,GAAW;QACpB,OAAO,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,EAAE;YACrD,OAAO,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;QAChC,CAAC,CAAC,CAAC;IACL,CAAC;IAeM,QAAQ,CACb,GAAW,EACX,cAAyE;QAEzE,IAAI,CAAC,IAAI,CAAC,6BAA6B,CAAC,cAAc,CAAC,EAAE,CAAC;YACxD,MAAM,SAAS,GAAG,IAAI,CAAC,UAAU,CAAC,YAAY,CAAC,CAAC,GAAG,EAAE,cAAc,CAAC,CAAC,CAAC;YACtE,IAAI,SAAS,CAAC,SAAS,EAAE,EAAE,CAAC;gBAC1B,OAAO,IAAA,qBAAc,EAAC,SAAS,CAAC,OAAO,EAAE,SAAS,CAAC,MAAM,CAAC,CAAC;YAC7D,CAAC;YACD,MAAM,CAAC,EAAE,EAAE,EAAE,CAAC,GAAG,SAAS,CAAC,KAAK,CAAC;YACjC,OAAO,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC;QAC1C,CAAC;aAAM,CAAC;YACN,MAAM,SAAS,GAAG,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC;YAClD,IAAI,SAAS,CAAC,SAAS,EAAE,EAAE,CAAC;gBAC1B,OAAO,IAAA,qBAAc,EAAC,SAAS,CAAC,OAAO,EAAE,SAAS,CAAC,MAAM,CAAC,CAAC;YAC7D,CAAC;YACD,OAAO,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,SAAS,CAAC,KAAK,EAAE,cAAc,CAAC,CAAC;QACnE,CAAC;IACH,CAAC;IAED;;OAEG;IACI,GAAG,CAAC,GAAW;QACpB,OAAO,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,GAAW,CAAC,CAAC;IAC1C,CAAC;IAED;;OAEG;IACI,UAAU;QACf,OAAO,IAAI,CAAC;IACd,CAAC;IAED;;;;;;OAMG;IACO,6BAA6B,CACrC,KAAgE;QAEhE,OAAO,OAAO,KAAK,KAAK,UAAU,CAAC;IACrC,CAAC;CACF;AAlHD,gDAkHC","sourcesContent":["/*\n * Copyright (c) 2025 Erik Fortune\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in all\n * copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n * SOFTWARE.\n */\n\nimport { DetailedResult, failWithDetail } from '../base';\nimport { IReadOnlyResultMap, ResultMapResultDetail } from './readonlyResultMap';\nimport { ResultMapValueFactory } from './resultMap';\nimport { KeyValueConverters } from './keyValueConverters';\nimport { CollectibleFactoryCallback, ICollectible } from './collectible';\nimport { CollectorResultDetail, ICollector } from './collector';\nimport { IReadOnlyResultMapConverter } from './resultMapConverter';\n\n/**\n * A read-only interface exposing non-mutating methods of a\n * {@link Collections.CollectorConverter | CollectorConverter}.\n * @public\n */\nexport interface IReadOnlyCollectorConverter<\n TKEY extends string = string,\n TINDEX extends number = number,\n TITEM extends ICollectible<TKEY> = ICollectible<TKEY, TINDEX>\n> extends IReadOnlyResultMapConverter<TKEY, TITEM> {\n /**\n * {@inheritdoc Collections.CollectorConverter.map}\n */\n readonly map: IReadOnlyResultMap<TKEY, TITEM>;\n\n /**\n * {@inheritdoc Collections.Collector.get}\n */\n get(key: string): DetailedResult<TITEM, ResultMapResultDetail>;\n\n /**\n * {@inheritdoc Collections.Collector.has}\n */\n has(key: string): boolean;\n}\n\n/**\n * Parameters for constructing a {@link Collections.CollectorConverter | CollectorConverter}.\n * @public\n */\nexport interface ICollectorConverterCreateParams<\n TKEY extends string = string,\n TINDEX extends number = number,\n TITEM extends ICollectible<TKEY, TINDEX> = ICollectible<TKEY, TINDEX>,\n TSRC = TITEM\n> {\n collector: ICollector<TKEY, TINDEX, TITEM, TSRC>;\n converters: KeyValueConverters<TKEY, TSRC>;\n}\n\n/**\n * A {@link Collections.Collector | Collector} wrapper which validates weakly-typed keys\n * and values before calling the wrapped collector.\n * @public\n */\nexport class CollectorConverter<\n TKEY extends string = string,\n TINDEX extends number = number,\n TITEM extends ICollectible<TKEY, TINDEX> = ICollectible<TKEY, TINDEX>,\n TSRC = TITEM\n> implements IReadOnlyResultMapConverter<TKEY, TITEM>\n{\n public readonly converters: KeyValueConverters<TKEY, TSRC>;\n\n public get map(): IReadOnlyResultMap<TKEY, TITEM> {\n return this._collector.toReadOnly();\n }\n\n protected _collector: ICollector<TKEY, TINDEX, TITEM, TSRC>;\n\n /**\n * Constructs a new {@link Collections.CollectorConverter | CollectorConverter}.\n * @param params - Required parameters for constructing the collector converter.\n */\n public constructor(params: ICollectorConverterCreateParams<TKEY, TINDEX, TITEM, TSRC>) {\n this._collector = params.collector;\n this.converters = params.converters;\n }\n\n /**\n * {@inheritdoc Collections.Collector.(add:1)}\n */\n public add(key: string, value: unknown): DetailedResult<TITEM, CollectorResultDetail>;\n\n /**\n * {@inheritdoc Collections.Collector.(add:2)}\n */\n public add(\n key: string,\n factory: ResultMapValueFactory<TKEY, TITEM>\n ): DetailedResult<TITEM, CollectorResultDetail>;\n public add(\n key: string,\n valueOrFactory: unknown | ResultMapValueFactory<TKEY, TITEM>\n ): DetailedResult<TITEM, CollectorResultDetail> {\n if (this.has(key)) {\n return failWithDetail(`${key}: already exists`, 'exists');\n }\n return this.getOrAdd(key, valueOrFactory);\n }\n\n /**\n * {@inheritdoc Collections.Collector.get}\n */\n public get(key: string): DetailedResult<TITEM, ResultMapResultDetail> {\n return this.converters.convertKey(key).onSuccess((k) => {\n return this._collector.get(k);\n });\n }\n\n /**\n * {@inheritdoc Collections.Collector.(getOrAdd:1)}\n */\n public getOrAdd(key: string, value: unknown): DetailedResult<TITEM, CollectorResultDetail>;\n\n /**\n * {@inheritdoc Collections.Collector.(getOrAdd:2)}\n */\n public getOrAdd(\n key: string,\n factory: ResultMapValueFactory<TKEY, TITEM>\n ): DetailedResult<TITEM, CollectorResultDetail>;\n\n public getOrAdd(\n key: string,\n valueOrFactory: unknown | CollectibleFactoryCallback<TKEY, TINDEX, TITEM>\n ): DetailedResult<TITEM, CollectorResultDetail> {\n if (!this._isCollectibleFactoryCallback(valueOrFactory)) {\n const converted = this.converters.convertEntry([key, valueOrFactory]);\n if (converted.isFailure()) {\n return failWithDetail(converted.message, converted.detail);\n }\n const [vk, vs] = converted.value;\n return this._collector.getOrAdd(vk, vs);\n } else {\n const converted = this.converters.convertKey(key);\n if (converted.isFailure()) {\n return failWithDetail(converted.message, converted.detail);\n }\n return this._collector.getOrAdd(converted.value, valueOrFactory);\n }\n }\n\n /**\n * {@inheritdoc Collections.Collector.has}\n */\n public has(key: string): boolean {\n return this._collector.has(key as TKEY);\n }\n\n /**\n * {@inheritdoc Collections.Collector.toReadOnly}\n */\n public toReadOnly(): IReadOnlyCollectorConverter<TKEY, TINDEX, TITEM> {\n return this;\n }\n\n /**\n * Determines if a value is a {@link Collections.CollectibleFactoryCallback | CollectibleFactoryCallback}.\n * @param value - The value to check.\n * @returns `true` if the value is a {@link Collections.CollectibleFactoryCallback | CollectibleFactoryCallback},\n * `false` otherwise.\n * @public\n */\n protected _isCollectibleFactoryCallback(\n value: unknown | CollectibleFactoryCallback<TKEY, TINDEX, TITEM>\n ): value is CollectibleFactoryCallback<TKEY, TINDEX, TITEM> {\n return typeof value === 'function';\n }\n}\n"]}
@@ -27,6 +27,5 @@ export declare class SimpleCollector<TITEM extends ICollectible<string, number>>
27
27
  * @public
28
28
  */
29
29
  static createSimpleCollector<TITEM extends ICollectible<string, number>>(params?: ISimpleCollectorCreateParams<TITEM>): Result<SimpleCollector<TITEM>>;
30
- private static _factory;
31
30
  }
32
31
  //# sourceMappingURL=collectors.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"collectors.d.ts","sourceRoot":"","sources":["../../../src/packlets/collections/collectors.ts"],"names":[],"mappings":"AAsBA,OAAO,EAAE,MAAM,EAA0B,MAAM,SAAS,CAAC;AACzD,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAC7C,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAExC;;;GAGG;AACH,MAAM,WAAW,4BAA4B,CAAC,KAAK,SAAS,YAAY,CAAC,MAAM,EAAE,MAAM,CAAC;IACtF,KAAK,CAAC,EAAE,KAAK,EAAE,CAAC;CACjB;AAED;;;;;GAKG;AACH,qBAAa,eAAe,CAAC,KAAK,SAAS,YAAY,CAAC,MAAM,EAAE,MAAM,CAAC,CAAE,SAAQ,SAAS,CACxF,MAAM,EACN,MAAM,EACN,KAAK,EACL,KAAK,CACN;IACC;;;OAGG;gBACgB,MAAM,CAAC,EAAE,4BAA4B,CAAC,KAAK,CAAC;IAK/D;;;;;OAKG;WACW,qBAAqB,CAAC,KAAK,SAAS,YAAY,CAAC,MAAM,EAAE,MAAM,CAAC,EAC5E,MAAM,CAAC,EAAE,4BAA4B,CAAC,KAAK,CAAC,GAC3C,MAAM,CAAC,eAAe,CAAC,KAAK,CAAC,CAAC;IAIjC,OAAO,CAAC,MAAM,CAAC,QAAQ;CAOxB"}
1
+ {"version":3,"file":"collectors.d.ts","sourceRoot":"","sources":["../../../src/packlets/collections/collectors.ts"],"names":[],"mappings":"AAsBA,OAAO,EAAE,MAAM,EAAiB,MAAM,SAAS,CAAC;AAChD,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAC7C,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAExC;;;GAGG;AACH,MAAM,WAAW,4BAA4B,CAAC,KAAK,SAAS,YAAY,CAAC,MAAM,EAAE,MAAM,CAAC;IACtF,KAAK,CAAC,EAAE,KAAK,EAAE,CAAC;CACjB;AAED;;;;;GAKG;AACH,qBAAa,eAAe,CAAC,KAAK,SAAS,YAAY,CAAC,MAAM,EAAE,MAAM,CAAC,CAAE,SAAQ,SAAS,CACxF,MAAM,EACN,MAAM,EACN,KAAK,EACL,KAAK,CACN;IACC;;;OAGG;gBACgB,MAAM,CAAC,EAAE,4BAA4B,CAAC,KAAK,CAAC;IAK/D;;;;;OAKG;WACW,qBAAqB,CAAC,KAAK,SAAS,YAAY,CAAC,MAAM,EAAE,MAAM,CAAC,EAC5E,MAAM,CAAC,EAAE,4BAA4B,CAAC,KAAK,CAAC,GAC3C,MAAM,CAAC,eAAe,CAAC,KAAK,CAAC,CAAC;CAGlC"}