@fgv/ts-utils 4.4.0 → 4.5.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.
- package/dist/ts-utils.d.ts +4247 -3635
- package/dist/tsdoc-metadata.json +1 -1
- package/lib/index.d.ts +3 -2
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +6 -3
- package/lib/index.js.map +1 -1
- package/lib/packlets/base/utils.d.ts.map +1 -1
- package/lib/packlets/base/utils.js +0 -1
- package/lib/packlets/base/utils.js.map +1 -1
- package/lib/packlets/collections/collectible.d.ts +49 -7
- package/lib/packlets/collections/collectible.d.ts.map +1 -1
- package/lib/packlets/collections/collectible.js +0 -9
- package/lib/packlets/collections/collectible.js.map +1 -1
- package/lib/packlets/collections/collector.d.ts +70 -135
- package/lib/packlets/collections/collector.d.ts.map +1 -1
- package/lib/packlets/collections/collector.js +80 -91
- package/lib/packlets/collections/collector.js.map +1 -1
- package/lib/packlets/collections/collectorValidator.d.ts +89 -0
- package/lib/packlets/collections/collectorValidator.d.ts.map +1 -0
- package/lib/packlets/collections/collectorValidator.js +98 -0
- package/lib/packlets/collections/collectorValidator.js.map +1 -0
- package/lib/packlets/collections/convertingCollector.d.ts +80 -45
- package/lib/packlets/collections/convertingCollector.d.ts.map +1 -1
- package/lib/packlets/collections/convertingCollector.js +74 -19
- package/lib/packlets/collections/convertingCollector.js.map +1 -1
- package/lib/packlets/collections/convertingCollectorValidator.d.ts +69 -0
- package/lib/packlets/collections/convertingCollectorValidator.d.ts.map +1 -0
- package/lib/packlets/collections/{collectorConverter.js → convertingCollectorValidator.js} +10 -9
- package/lib/packlets/collections/convertingCollectorValidator.js.map +1 -0
- package/lib/packlets/collections/index.d.ts +7 -5
- package/lib/packlets/collections/index.d.ts.map +1 -1
- package/lib/packlets/collections/index.js +7 -5
- package/lib/packlets/collections/index.js.map +1 -1
- package/lib/packlets/collections/readonlyResultMap.d.ts +0 -4
- package/lib/packlets/collections/readonlyResultMap.d.ts.map +1 -1
- package/lib/packlets/collections/readonlyResultMap.js.map +1 -1
- package/lib/packlets/collections/resultMap.d.ts +0 -4
- package/lib/packlets/collections/resultMap.d.ts.map +1 -1
- package/lib/packlets/collections/resultMap.js +0 -6
- package/lib/packlets/collections/resultMap.js.map +1 -1
- package/lib/packlets/collections/{resultMapConverter.d.ts → resultMapValidator.d.ts} +11 -11
- package/lib/packlets/collections/{resultMapConverter.d.ts.map → resultMapValidator.d.ts.map} +1 -1
- package/lib/packlets/collections/{resultMapConverter.js → resultMapValidator.js} +6 -6
- package/lib/packlets/collections/{resultMapConverter.js.map → resultMapValidator.js.map} +1 -1
- package/lib/packlets/collections/validatingCollector.d.ts +69 -0
- package/lib/packlets/collections/validatingCollector.d.ts.map +1 -0
- package/lib/packlets/collections/validatingCollector.js +67 -0
- package/lib/packlets/collections/validatingCollector.js.map +1 -0
- package/lib/packlets/collections/validatingConvertingCollector.d.ts +59 -0
- package/lib/packlets/collections/validatingConvertingCollector.d.ts.map +1 -0
- package/lib/packlets/collections/validatingConvertingCollector.js +68 -0
- package/lib/packlets/collections/validatingConvertingCollector.js.map +1 -0
- package/lib/packlets/collections/{convertingResultMap.d.ts → validatingResultMap.d.ts} +16 -16
- package/lib/packlets/collections/{convertingResultMap.d.ts.map → validatingResultMap.d.ts.map} +1 -1
- package/lib/packlets/collections/{convertingResultMap.js → validatingResultMap.js} +11 -11
- package/lib/packlets/collections/{convertingResultMap.js.map → validatingResultMap.js.map} +1 -1
- package/lib/packlets/file-tree/directoryItem.d.ts +47 -0
- package/lib/packlets/file-tree/directoryItem.d.ts.map +1 -0
- package/lib/packlets/file-tree/directoryItem.js +71 -0
- package/lib/packlets/file-tree/directoryItem.js.map +1 -0
- package/lib/packlets/file-tree/fileItem.d.ts +64 -0
- package/lib/packlets/file-tree/fileItem.d.ts.map +1 -0
- package/lib/packlets/file-tree/fileItem.js +93 -0
- package/lib/packlets/file-tree/fileItem.js.map +1 -0
- package/lib/packlets/file-tree/fileTree.d.ts +84 -0
- package/lib/packlets/file-tree/fileTree.d.ts.map +1 -0
- package/lib/packlets/file-tree/fileTree.js +135 -0
- package/lib/packlets/file-tree/fileTree.js.map +1 -0
- package/lib/packlets/file-tree/fileTreeAccessors.d.ts +134 -0
- package/lib/packlets/file-tree/fileTreeAccessors.d.ts.map +1 -0
- package/lib/packlets/file-tree/fileTreeAccessors.js +24 -0
- package/lib/packlets/file-tree/fileTreeAccessors.js.map +1 -0
- package/lib/packlets/file-tree/fsTree.d.ts +45 -0
- package/lib/packlets/file-tree/fsTree.d.ts.map +1 -0
- package/lib/packlets/file-tree/fsTree.js +116 -0
- package/lib/packlets/file-tree/fsTree.js.map +1 -0
- package/lib/packlets/file-tree/in-memory/inMemoryTree.d.ts +67 -0
- package/lib/packlets/file-tree/in-memory/inMemoryTree.d.ts.map +1 -0
- package/lib/packlets/file-tree/in-memory/inMemoryTree.js +150 -0
- package/lib/packlets/file-tree/in-memory/inMemoryTree.js.map +1 -0
- package/lib/packlets/file-tree/in-memory/index.d.ts +2 -0
- package/lib/packlets/file-tree/in-memory/index.d.ts.map +1 -0
- package/lib/packlets/file-tree/in-memory/index.js +39 -0
- package/lib/packlets/file-tree/in-memory/index.js.map +1 -0
- package/lib/packlets/file-tree/in-memory/treeBuilder.d.ts +106 -0
- package/lib/packlets/file-tree/in-memory/treeBuilder.d.ts.map +1 -0
- package/lib/packlets/file-tree/in-memory/treeBuilder.js +170 -0
- package/lib/packlets/file-tree/in-memory/treeBuilder.js.map +1 -0
- package/lib/packlets/file-tree/index.d.ts +8 -0
- package/lib/packlets/file-tree/index.d.ts.map +1 -0
- package/lib/packlets/file-tree/index.js +46 -0
- package/lib/packlets/file-tree/index.js.map +1 -0
- package/lib/packlets/hash/crcNormalizer.js +1 -1
- package/lib/packlets/hash/crcNormalizer.js.map +1 -1
- package/package.json +15 -15
- package/lib/packlets/collections/collectorConverter.d.ts +0 -86
- package/lib/packlets/collections/collectorConverter.d.ts.map +0 -1
- package/lib/packlets/collections/collectorConverter.js.map +0 -1
- package/lib/packlets/collections/collectors.d.ts +0 -31
- package/lib/packlets/collections/collectors.d.ts.map +0 -1
- package/lib/packlets/collections/collectors.js +0 -54
- package/lib/packlets/collections/collectors.js.map +0 -1
|
@@ -1,194 +1,129 @@
|
|
|
1
1
|
import { DetailedResult, Result } from '../base';
|
|
2
|
-
import {
|
|
2
|
+
import { CollectibleFactoryCallback, CollectibleKey, ICollectible } from './collectible';
|
|
3
3
|
import { KeyValueEntry } from './common';
|
|
4
4
|
import { IReadOnlyResultMap, ResultMapForEachCb, ResultMapResultDetail } from './readonlyResultMap';
|
|
5
5
|
/**
|
|
6
|
-
* Additional success or failure details for mutating
|
|
6
|
+
* Additional success or failure details for mutating collector calls.
|
|
7
7
|
* @public
|
|
8
8
|
*/
|
|
9
9
|
export type CollectorResultDetail = ResultMapResultDetail | 'invalid-index';
|
|
10
10
|
/**
|
|
11
|
-
* A read-only interface exposing non-mutating methods of a {@link Collections.
|
|
11
|
+
* A read-only interface exposing only the non-mutating methods of a {@link Collections.Collector | ICollector}.
|
|
12
12
|
* @public
|
|
13
13
|
*/
|
|
14
|
-
export interface IReadOnlyCollector<
|
|
14
|
+
export interface IReadOnlyCollector<TITEM extends ICollectible<any, any>> extends IReadOnlyResultMap<CollectibleKey<TITEM>, TITEM> {
|
|
15
15
|
/**
|
|
16
16
|
* Gets the item at a specified index.
|
|
17
17
|
* @param index - The index of the item to retrieve.
|
|
18
|
-
* @returns Returns {@link Success | Success} with the item if it exists, or {@link Failure | Failure}
|
|
18
|
+
* @returns Returns {@link Success | Success} with the item if it exists, or {@link Failure | Failure}
|
|
19
|
+
* with an error if the index is out of range.
|
|
19
20
|
*/
|
|
20
21
|
getAt(index: number): Result<TITEM>;
|
|
21
22
|
}
|
|
22
23
|
/**
|
|
23
|
-
*
|
|
24
|
-
* time of addition. Items are immutable once added.
|
|
24
|
+
* Parameters for constructing a {@link Collections.Collector | ICollector}.
|
|
25
25
|
* @public
|
|
26
26
|
*/
|
|
27
|
-
export interface
|
|
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
|
|
36
|
-
*/
|
|
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>;
|
|
47
|
-
/**
|
|
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.
|
|
49
|
-
* @param key - The key of the item to retrieve.
|
|
50
|
-
* @param item - The source representation of the item to be added if it does not exist.
|
|
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
|
|
52
|
-
* item cannot be created and indexed.
|
|
53
|
-
*/
|
|
54
|
-
getOrAdd(key: TKEY, item: TSRC): DetailedResult<TITEM, CollectorResultDetail>;
|
|
55
|
-
/**
|
|
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.
|
|
57
|
-
* @param key - The key of the item to retrieve.
|
|
58
|
-
* @param callback - The factory callback to create the item if it does not exist.
|
|
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.
|
|
60
|
-
*/
|
|
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>;
|
|
70
|
-
/**
|
|
71
|
-
* Gets a {@link IReadOnlyResultMap | read-only map} which can access the items in the collector.
|
|
72
|
-
*/
|
|
73
|
-
toReadOnly(): IReadOnlyCollector<TKEY, TINDEX, TITEM>;
|
|
74
|
-
}
|
|
75
|
-
/**
|
|
76
|
-
* A simple {@link ICollector | ICollector} with non-branded `string` key and `number` index, and no transformation of source items.
|
|
77
|
-
* @public
|
|
78
|
-
*/
|
|
79
|
-
export type ISimpleCollector<TITEM extends ICollectible<string, number>> = ICollector<string, number, TITEM, TITEM>;
|
|
80
|
-
/**
|
|
81
|
-
* A {@link ICollector | Collector} with non-branded `string` key and `number` index, and transformation of source items.
|
|
82
|
-
* @public
|
|
83
|
-
*/
|
|
84
|
-
export type IConvertingCollector<TITEM extends ICollectible<string, number>, TSRC> = ICollector<string, number, TITEM, TSRC>;
|
|
85
|
-
/**
|
|
86
|
-
* Parameters for constructing a {@link ICollector | Collector}.
|
|
87
|
-
* @public
|
|
88
|
-
*/
|
|
89
|
-
export interface ICollectorConstructorParams<TKEY extends string = string, TINDEX extends number = number, TITEM extends ICollectible<TKEY, TINDEX> = ICollectible<TKEY, TINDEX>, TSRC = TITEM> {
|
|
90
|
-
/**
|
|
91
|
-
* The default {@link Collections.CollectibleFactory | factory} to create items.
|
|
92
|
-
*/
|
|
93
|
-
factory: CollectibleFactory<TKEY, TINDEX, TITEM, TSRC>;
|
|
94
|
-
/**
|
|
95
|
-
* An optional array of entries to add to the collector.
|
|
96
|
-
*/
|
|
97
|
-
entries?: KeyValueEntry<TKEY, TSRC>[];
|
|
27
|
+
export interface ICollectorConstructorParams<TITEM extends ICollectible<any, any>> {
|
|
28
|
+
items?: TITEM[];
|
|
98
29
|
}
|
|
99
30
|
/**
|
|
100
|
-
* A {@link
|
|
101
|
-
*
|
|
31
|
+
* A {@link Collections.Collector | Collector} that is a specialized collection
|
|
32
|
+
* which contains items of type {@link Collections.ICollectible | ICollectible},
|
|
33
|
+
* which have a unique key and a write-once index.
|
|
34
|
+
*
|
|
35
|
+
* Items are assigned an index sequentially as they are added to the collection.
|
|
36
|
+
* Once added, items are immutable - they cannot be removed or replaced.
|
|
102
37
|
* @public
|
|
103
38
|
*/
|
|
104
|
-
export declare class Collector<
|
|
105
|
-
private _byKey;
|
|
106
|
-
private _byIndex;
|
|
107
|
-
private _factory;
|
|
39
|
+
export declare class Collector<TITEM extends ICollectible<any, any>> implements IReadOnlyCollector<TITEM> {
|
|
40
|
+
private readonly _byKey;
|
|
41
|
+
private readonly _byIndex;
|
|
108
42
|
/**
|
|
109
|
-
* {@inheritdoc
|
|
43
|
+
* {@inheritdoc Collections.ResultMap.size}
|
|
110
44
|
*/
|
|
111
|
-
get
|
|
45
|
+
get size(): number;
|
|
112
46
|
/**
|
|
113
|
-
*
|
|
114
|
-
* @param params -
|
|
47
|
+
* Constructs a new {@link Collections.Collector | Collector}.
|
|
48
|
+
* @param params - Optional {@link Collections.ICollectorConstructorParams | initialization parameters} used
|
|
49
|
+
* to construct the collector.
|
|
115
50
|
*/
|
|
116
|
-
|
|
51
|
+
constructor(params?: ICollectorConstructorParams<TITEM>);
|
|
117
52
|
/**
|
|
118
|
-
* {@
|
|
53
|
+
* Creates a new {@link Collections.Collector | Collector} instance.
|
|
54
|
+
* @param params - Optional {@link Collections.ICollectorConstructorParams | initialization parameters} used
|
|
55
|
+
* to create the collector.
|
|
56
|
+
* @returns Returns {@link Success | Success} with the new collector if it was created successfully,
|
|
57
|
+
* or {@link Failure | Failure} with an error if the collector could not be created.
|
|
119
58
|
*/
|
|
120
|
-
|
|
59
|
+
static createCollector<TITEM extends ICollectible<any, any>>(params?: ICollectorConstructorParams<TITEM>): Result<Collector<TITEM>>;
|
|
121
60
|
/**
|
|
122
|
-
*
|
|
61
|
+
* Adds an item to the collection, failing if a different item with the same key already exists. Note
|
|
62
|
+
* that adding an object that is already in the collection again will succeed without updating the collection.
|
|
63
|
+
* @param item - The item to add.
|
|
64
|
+
* @returns Returns {@link DetailedSuccess | Success} with the item and detail `added` if it was added
|
|
65
|
+
* or detail `exists` if the item was already in the map. Returns {@link DetailedFailure | Failure} with
|
|
66
|
+
* an error message and appropriate detail if the item could not be added.
|
|
123
67
|
*/
|
|
124
|
-
|
|
68
|
+
add(item: TITEM): DetailedResult<TITEM, CollectorResultDetail>;
|
|
125
69
|
/**
|
|
126
|
-
* {@inheritdoc
|
|
70
|
+
* {@inheritdoc Collections.ResultMap.entries}
|
|
127
71
|
*/
|
|
128
|
-
|
|
72
|
+
entries(): MapIterator<KeyValueEntry<CollectibleKey<TITEM>, TITEM>>;
|
|
129
73
|
/**
|
|
130
|
-
* {@inheritdoc
|
|
74
|
+
* {@inheritdoc Collections.ResultMap.forEach}
|
|
131
75
|
*/
|
|
132
|
-
|
|
76
|
+
forEach(callback: ResultMapForEachCb<CollectibleKey<TITEM>, TITEM>, arg?: unknown): void;
|
|
133
77
|
/**
|
|
134
|
-
* {@inheritdoc
|
|
78
|
+
* {@inheritdoc Collections.ResultMap.get}
|
|
135
79
|
*/
|
|
136
|
-
|
|
137
|
-
/**
|
|
138
|
-
* {@inheritdoc IReadOnlyResultMap.get}
|
|
139
|
-
*/
|
|
140
|
-
get(key: TKEY): DetailedResult<TITEM, ResultMapResultDetail>;
|
|
80
|
+
get(key: CollectibleKey<TITEM>): DetailedResult<TITEM, ResultMapResultDetail>;
|
|
141
81
|
/**
|
|
142
82
|
* {@inheritdoc Collections.IReadOnlyCollector.getAt}
|
|
143
83
|
*/
|
|
144
84
|
getAt(index: number): Result<TITEM>;
|
|
145
85
|
/**
|
|
146
|
-
*
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
*
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
/**
|
|
154
|
-
* {@inheritdoc ICollector.addItem}
|
|
86
|
+
* Gets an existing item with a key matching that of a supplied item, or adds the supplied
|
|
87
|
+
* item to the collector if no item with that key exists.
|
|
88
|
+
* @param item - The item to get or add.
|
|
89
|
+
* @returns Returns {@link DetailedSuccess | Success} with the item stored in the collector -
|
|
90
|
+
* detail `exists` indicates that an existing item return and detail `added` indicates that the
|
|
91
|
+
* item was added. Returns {@link DetailedFailure | Failure} with an error and appropriate
|
|
92
|
+
* detail if the item could not be added.
|
|
155
93
|
*/
|
|
156
|
-
|
|
94
|
+
getOrAdd(item: TITEM): DetailedResult<TITEM, CollectorResultDetail>;
|
|
157
95
|
/**
|
|
158
|
-
*
|
|
96
|
+
* Gets an existing item with a key matching the supplied key, or adds a new item to the collector
|
|
97
|
+
* using a factory callback if no item with that key exists.
|
|
98
|
+
* @param key - The key of the item to add.
|
|
99
|
+
* @param callback - The factory callback to create the item.
|
|
100
|
+
* @returns Returns {@link DetailedSuccess | Success} with the item stored in the collector -
|
|
101
|
+
* detail `exists` indicates that an existing item return and detail `added` indicates that the
|
|
102
|
+
* item was added. Returns {@link DetailedFailure | Failure} with an error and appropriate
|
|
103
|
+
* detail if the item could not be added.
|
|
159
104
|
*/
|
|
160
|
-
getOrAdd(key:
|
|
105
|
+
getOrAdd(key: CollectibleKey<TITEM>, factory: CollectibleFactoryCallback<TITEM>): DetailedResult<TITEM, CollectorResultDetail>;
|
|
161
106
|
/**
|
|
162
|
-
* {@inheritdoc
|
|
107
|
+
* {@inheritdoc Collections.ResultMap.has}
|
|
163
108
|
*/
|
|
164
|
-
|
|
109
|
+
has(key: CollectibleKey<TITEM>): boolean;
|
|
165
110
|
/**
|
|
166
|
-
* {@inheritdoc
|
|
111
|
+
* {@inheritdoc Collections.ResultMap.keys}
|
|
167
112
|
*/
|
|
168
|
-
|
|
113
|
+
keys(): IterableIterator<CollectibleKey<TITEM>>;
|
|
169
114
|
/**
|
|
170
|
-
* {@inheritdoc
|
|
115
|
+
* {@inheritdoc Collections.ResultMap.values}
|
|
171
116
|
*/
|
|
172
|
-
|
|
117
|
+
values(): IterableIterator<TITEM>;
|
|
173
118
|
/**
|
|
174
|
-
*
|
|
119
|
+
* Gets a read-only version of this collector.
|
|
175
120
|
*/
|
|
176
|
-
toReadOnly(): IReadOnlyCollector<
|
|
121
|
+
toReadOnly(): IReadOnlyCollector<TITEM>;
|
|
177
122
|
/**
|
|
178
123
|
* Gets an iterator over the map entries.
|
|
179
124
|
* @returns An iterator over the map entries.
|
|
180
125
|
*/
|
|
181
|
-
[Symbol.iterator](): IterableIterator<KeyValueEntry<
|
|
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>;
|
|
192
|
-
protected _isFactoryCB(item: TSRC | CollectibleFactoryCallback<TKEY, TINDEX, TITEM>): item is CollectibleFactoryCallback<TKEY, TINDEX, TITEM>;
|
|
126
|
+
[Symbol.iterator](): IterableIterator<KeyValueEntry<CollectibleKey<TITEM>, TITEM>>;
|
|
127
|
+
protected _isItem(keyOrItem: CollectibleKey<TITEM> | TITEM): keyOrItem is TITEM;
|
|
193
128
|
}
|
|
194
129
|
//# sourceMappingURL=collector.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"collector.d.ts","sourceRoot":"","sources":["../../../src/packlets/collections/collector.ts"],"names":[],"mappings":"AAsBA,OAAO,
|
|
1
|
+
{"version":3,"file":"collector.d.ts","sourceRoot":"","sources":["../../../src/packlets/collections/collector.ts"],"names":[],"mappings":"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"}
|
|
@@ -24,56 +24,79 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
24
24
|
exports.Collector = void 0;
|
|
25
25
|
const base_1 = require("../base");
|
|
26
26
|
/**
|
|
27
|
-
* A {@link
|
|
28
|
-
*
|
|
27
|
+
* A {@link Collections.Collector | Collector} that is a specialized collection
|
|
28
|
+
* which contains items of type {@link Collections.ICollectible | ICollectible},
|
|
29
|
+
* which have a unique key and a write-once index.
|
|
30
|
+
*
|
|
31
|
+
* Items are assigned an index sequentially as they are added to the collection.
|
|
32
|
+
* Once added, items are immutable - they cannot be removed or replaced.
|
|
29
33
|
* @public
|
|
30
34
|
*/
|
|
31
35
|
class Collector {
|
|
32
36
|
/**
|
|
33
|
-
* {@inheritdoc
|
|
37
|
+
* {@inheritdoc Collections.ResultMap.size}
|
|
34
38
|
*/
|
|
35
|
-
get
|
|
36
|
-
return this.
|
|
39
|
+
get size() {
|
|
40
|
+
return this._byIndex.length;
|
|
37
41
|
}
|
|
38
42
|
/**
|
|
39
|
-
*
|
|
40
|
-
* @param params -
|
|
43
|
+
* Constructs a new {@link Collections.Collector | Collector}.
|
|
44
|
+
* @param params - Optional {@link Collections.ICollectorConstructorParams | initialization parameters} used
|
|
45
|
+
* to construct the collector.
|
|
41
46
|
*/
|
|
42
47
|
constructor(params) {
|
|
43
48
|
var _a;
|
|
44
49
|
this._byKey = new Map();
|
|
45
50
|
this._byIndex = [];
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
});
|
|
50
|
-
}
|
|
51
|
-
/**
|
|
52
|
-
* {@inheritdoc IReadOnlyResultMap.size}
|
|
53
|
-
*/
|
|
54
|
-
get size() {
|
|
55
|
-
return this._byKey.size;
|
|
51
|
+
for (const item of (_a = params === null || params === void 0 ? void 0 : params.items) !== null && _a !== void 0 ? _a : []) {
|
|
52
|
+
this.add(item).orThrow();
|
|
53
|
+
}
|
|
56
54
|
}
|
|
57
55
|
/**
|
|
58
|
-
* {@
|
|
56
|
+
* Creates a new {@link Collections.Collector | Collector} instance.
|
|
57
|
+
* @param params - Optional {@link Collections.ICollectorConstructorParams | initialization parameters} used
|
|
58
|
+
* to create the collector.
|
|
59
|
+
* @returns Returns {@link Success | Success} with the new collector if it was created successfully,
|
|
60
|
+
* or {@link Failure | Failure} with an error if the collector could not be created.
|
|
59
61
|
*/
|
|
60
|
-
|
|
61
|
-
return
|
|
62
|
+
static createCollector(params) {
|
|
63
|
+
return (0, base_1.captureResult)(() => new Collector(params));
|
|
62
64
|
}
|
|
63
65
|
/**
|
|
64
|
-
*
|
|
66
|
+
* Adds an item to the collection, failing if a different item with the same key already exists. Note
|
|
67
|
+
* that adding an object that is already in the collection again will succeed without updating the collection.
|
|
68
|
+
* @param item - The item to add.
|
|
69
|
+
* @returns Returns {@link DetailedSuccess | Success} with the item and detail `added` if it was added
|
|
70
|
+
* or detail `exists` if the item was already in the map. Returns {@link DetailedFailure | Failure} with
|
|
71
|
+
* an error message and appropriate detail if the item could not be added.
|
|
65
72
|
*/
|
|
66
|
-
|
|
67
|
-
|
|
73
|
+
add(item) {
|
|
74
|
+
const existing = this._byKey.get(item.key);
|
|
75
|
+
if (existing === item) {
|
|
76
|
+
return (0, base_1.succeedWithDetail)(item, 'exists');
|
|
77
|
+
}
|
|
78
|
+
else if (existing) {
|
|
79
|
+
return (0, base_1.failWithDetail)(`${item.key}: already exists`, 'exists');
|
|
80
|
+
}
|
|
81
|
+
const indexResult = item.setIndex(this._byIndex.length);
|
|
82
|
+
if (indexResult.isFailure()) {
|
|
83
|
+
return (0, base_1.failWithDetail)(`${item.key}: ${indexResult.message}`, 'invalid-index');
|
|
84
|
+
}
|
|
85
|
+
else if (item.index !== this._byIndex.length) {
|
|
86
|
+
return (0, base_1.failWithDetail)(`${item.key}: index mismatch - built item has ${item.index}`, 'invalid-index');
|
|
87
|
+
}
|
|
88
|
+
this._byKey.set(item.key, item);
|
|
89
|
+
this._byIndex.push(item);
|
|
90
|
+
return (0, base_1.succeedWithDetail)(item, 'added');
|
|
68
91
|
}
|
|
69
92
|
/**
|
|
70
|
-
* {@inheritdoc
|
|
93
|
+
* {@inheritdoc Collections.ResultMap.entries}
|
|
71
94
|
*/
|
|
72
95
|
entries() {
|
|
73
96
|
return this._byKey.entries();
|
|
74
97
|
}
|
|
75
98
|
/**
|
|
76
|
-
* {@inheritdoc
|
|
99
|
+
* {@inheritdoc Collections.ResultMap.forEach}
|
|
77
100
|
*/
|
|
78
101
|
forEach(callback, arg) {
|
|
79
102
|
for (const [key, value] of this._byKey.entries()) {
|
|
@@ -81,14 +104,11 @@ class Collector {
|
|
|
81
104
|
}
|
|
82
105
|
}
|
|
83
106
|
/**
|
|
84
|
-
* {@inheritdoc
|
|
107
|
+
* {@inheritdoc Collections.ResultMap.get}
|
|
85
108
|
*/
|
|
86
109
|
get(key) {
|
|
87
110
|
const item = this._byKey.get(key);
|
|
88
|
-
|
|
89
|
-
return (0, base_1.failWithDetail)(`${key}: not found.`, 'not-found');
|
|
90
|
-
}
|
|
91
|
-
return (0, base_1.succeedWithDetail)(item, 'success');
|
|
111
|
+
return item ? (0, base_1.succeedWithDetail)(item, 'exists') : (0, base_1.failWithDetail)(`${key}: not found`, 'not-found');
|
|
92
112
|
}
|
|
93
113
|
/**
|
|
94
114
|
* {@inheritdoc Collections.IReadOnlyCollector.getAt}
|
|
@@ -99,65 +119,46 @@ class Collector {
|
|
|
99
119
|
}
|
|
100
120
|
return (0, base_1.succeed)(this._byIndex[index]);
|
|
101
121
|
}
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
122
|
+
getOrAdd(keyOrItem, factory) {
|
|
123
|
+
const key = !this._isItem(keyOrItem) ? keyOrItem : keyOrItem.key;
|
|
124
|
+
const existing = this._byKey.get(key);
|
|
125
|
+
if (existing) {
|
|
126
|
+
return (0, base_1.succeedWithDetail)(existing, 'exists');
|
|
127
|
+
}
|
|
128
|
+
const itemResult = !this._isItem(keyOrItem)
|
|
129
|
+
? factory(keyOrItem, this._byIndex.length)
|
|
130
|
+
: (0, base_1.succeed)(keyOrItem);
|
|
131
|
+
if (itemResult.isFailure()) {
|
|
132
|
+
return (0, base_1.failWithDetail)(`${key}: ${itemResult.message}`, 'invalid-value');
|
|
105
133
|
}
|
|
106
|
-
|
|
134
|
+
const item = itemResult.value;
|
|
135
|
+
if (item.key !== key) {
|
|
136
|
+
return (0, base_1.failWithDetail)(`${key}: key mismatch - built item has ${key}`, 'invalid-key');
|
|
137
|
+
}
|
|
138
|
+
return itemResult.withFailureDetail('invalid-index').onSuccess((item) => {
|
|
139
|
+
return this.add(item);
|
|
140
|
+
});
|
|
107
141
|
}
|
|
108
142
|
/**
|
|
109
|
-
* {@inheritdoc
|
|
143
|
+
* {@inheritdoc Collections.ResultMap.has}
|
|
110
144
|
*/
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
return (0, base_1.failWithDetail)(`${item.key}: already exists.`, 'exists');
|
|
114
|
-
}
|
|
115
|
-
return this.getOrAddItem(item);
|
|
116
|
-
}
|
|
117
|
-
getOrAdd(key, itemOrCb) {
|
|
118
|
-
if (this._byKey.has(key)) {
|
|
119
|
-
return (0, base_1.succeedWithDetail)(this._byKey.get(key), 'exists');
|
|
120
|
-
}
|
|
121
|
-
const build = this._isFactoryCB(itemOrCb)
|
|
122
|
-
? itemOrCb(key, this._byIndex.length)
|
|
123
|
-
: this._factory(key, this._byIndex.length, itemOrCb);
|
|
124
|
-
if (build.isFailure()) {
|
|
125
|
-
return (0, base_1.failWithDetail)(build.message, 'invalid-value');
|
|
126
|
-
}
|
|
127
|
-
const newItem = build.value;
|
|
128
|
-
if (newItem.key !== key) {
|
|
129
|
-
return (0, base_1.failWithDetail)(`$[key}: key mismatch in created item - ${newItem.key} !== ${key}`, 'invalid-key');
|
|
130
|
-
}
|
|
131
|
-
if (newItem.index !== this._byIndex.length) {
|
|
132
|
-
return (0, base_1.failWithDetail)(`$[key}: index mismatch in created item - ${newItem.index} !== ${this._byIndex.length}`, 'invalid-index');
|
|
133
|
-
}
|
|
134
|
-
this._byKey.set(key, newItem);
|
|
135
|
-
this._byIndex.push(newItem);
|
|
136
|
-
return (0, base_1.succeedWithDetail)(newItem, 'added');
|
|
145
|
+
has(key) {
|
|
146
|
+
return this._byKey.has(key);
|
|
137
147
|
}
|
|
138
148
|
/**
|
|
139
|
-
* {@inheritdoc
|
|
149
|
+
* {@inheritdoc Collections.ResultMap.keys}
|
|
140
150
|
*/
|
|
141
|
-
|
|
142
|
-
|
|
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');
|
|
151
|
+
keys() {
|
|
152
|
+
return this._byKey.keys();
|
|
152
153
|
}
|
|
153
154
|
/**
|
|
154
|
-
* {@inheritdoc
|
|
155
|
+
* {@inheritdoc Collections.ResultMap.values}
|
|
155
156
|
*/
|
|
156
|
-
|
|
157
|
-
return this._byKey.
|
|
157
|
+
values() {
|
|
158
|
+
return this._byKey.values();
|
|
158
159
|
}
|
|
159
160
|
/**
|
|
160
|
-
*
|
|
161
|
+
* Gets a read-only version of this collector.
|
|
161
162
|
*/
|
|
162
163
|
toReadOnly() {
|
|
163
164
|
return this;
|
|
@@ -169,20 +170,8 @@ class Collector {
|
|
|
169
170
|
[Symbol.iterator]() {
|
|
170
171
|
return this._byKey[Symbol.iterator]();
|
|
171
172
|
}
|
|
172
|
-
|
|
173
|
-
|
|
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
|
-
}
|
|
184
|
-
_isFactoryCB(item) {
|
|
185
|
-
return typeof item === 'function';
|
|
173
|
+
_isItem(keyOrItem) {
|
|
174
|
+
return typeof keyOrItem !== 'string';
|
|
186
175
|
}
|
|
187
176
|
}
|
|
188
177
|
exports.Collector = Collector;
|
|
@@ -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 * 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"]}
|
|
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 {\n captureResult,\n DetailedResult,\n failWithDetail,\n Result,\n fail,\n succeed,\n succeedWithDetail\n} from '../base';\nimport { CollectibleFactoryCallback, CollectibleKey, ICollectible } from './collectible';\nimport { KeyValueEntry } from './common';\nimport { IReadOnlyResultMap, ResultMapForEachCb, ResultMapResultDetail } from './readonlyResultMap';\n\n/**\n * Additional success or failure details for mutating collector calls.\n * @public\n */\nexport type CollectorResultDetail = ResultMapResultDetail | 'invalid-index';\n\n/**\n * A read-only interface exposing only the non-mutating methods of a {@link Collections.Collector | ICollector}.\n * @public\n */\nexport interface IReadOnlyCollector<\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n TITEM extends ICollectible<any, any>\n> extends IReadOnlyResultMap<CollectibleKey<TITEM>, 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}\n * with an error if the index is out of range.\n */\n getAt(index: number): Result<TITEM>;\n}\n\n/**\n * Parameters for constructing a {@link Collections.Collector | ICollector}.\n * @public\n */\nexport interface ICollectorConstructorParams<\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n TITEM extends ICollectible<any, any>\n> {\n items?: TITEM[];\n}\n\n/**\n * A {@link Collections.Collector | Collector} that is a specialized collection\n * which contains items of type {@link Collections.ICollectible | ICollectible},\n * which have a unique key and a write-once index.\n *\n * Items are assigned an index sequentially as they are added to the collection.\n * Once added, items are immutable - they cannot be removed or replaced.\n * @public\n */\nexport class Collector<\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n TITEM extends ICollectible<any, any>\n> implements IReadOnlyCollector<TITEM>\n{\n private readonly _byKey: Map<CollectibleKey<TITEM>, TITEM>;\n private readonly _byIndex: TITEM[];\n\n /**\n * {@inheritdoc Collections.ResultMap.size}\n */\n public get size(): number {\n return this._byIndex.length;\n }\n\n /**\n * Constructs a new {@link Collections.Collector | Collector}.\n * @param params - Optional {@link Collections.ICollectorConstructorParams | initialization parameters} used\n * to construct the collector.\n */\n public constructor(params?: ICollectorConstructorParams<TITEM>) {\n this._byKey = new Map<CollectibleKey<TITEM>, TITEM>();\n this._byIndex = [];\n for (const item of params?.items ?? []) {\n this.add(item).orThrow();\n }\n }\n\n /**\n * Creates a new {@link Collections.Collector | Collector} instance.\n * @param params - Optional {@link Collections.ICollectorConstructorParams | initialization parameters} used\n * to create the collector.\n * @returns Returns {@link Success | Success} with the new collector if it was created successfully,\n * or {@link Failure | Failure} with an error if the collector could not be created.\n */\n public static createCollector<\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n TITEM extends ICollectible<any, any>\n >(params?: ICollectorConstructorParams<TITEM>): Result<Collector<TITEM>> {\n return captureResult(() => new Collector(params));\n }\n\n /**\n * Adds an item to the collection, failing if a different item with the same key already exists. Note\n * that adding an object that is already in the collection again will succeed without updating the collection.\n * @param item - The item to add.\n * @returns Returns {@link DetailedSuccess | Success} with the item and detail `added` if it was added\n * or detail `exists` if the item was already in the map. Returns {@link DetailedFailure | Failure} with\n * an error message and appropriate detail if the item could not be added.\n */\n public add(item: TITEM): DetailedResult<TITEM, CollectorResultDetail> {\n const existing = this._byKey.get(item.key);\n if (existing === item) {\n return succeedWithDetail(item, 'exists');\n } else if (existing) {\n return failWithDetail(`${item.key}: already exists`, 'exists');\n }\n const indexResult = item.setIndex(this._byIndex.length);\n if (indexResult.isFailure()) {\n return failWithDetail(`${item.key}: ${indexResult.message}`, 'invalid-index');\n } else if (item.index !== this._byIndex.length) {\n return failWithDetail(`${item.key}: index mismatch - built item has ${item.index}`, '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 Collections.ResultMap.entries}\n */\n public entries(): MapIterator<KeyValueEntry<CollectibleKey<TITEM>, TITEM>> {\n return this._byKey.entries();\n }\n\n /**\n * {@inheritdoc Collections.ResultMap.forEach}\n */\n public forEach(callback: ResultMapForEachCb<CollectibleKey<TITEM>, 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 Collections.ResultMap.get}\n */\n public get(key: CollectibleKey<TITEM>): DetailedResult<TITEM, ResultMapResultDetail> {\n const item = this._byKey.get(key);\n return item ? succeedWithDetail(item, 'exists') : failWithDetail(`${key}: not found`, 'not-found');\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 * 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 get or add.\n * @returns Returns {@link DetailedSuccess | Success} with the item stored in the collector -\n * detail `exists` indicates that an existing item return and detail `added` indicates that the\n * item was added. Returns {@link DetailedFailure | Failure} with an error and appropriate\n * detail if the item could not be added.\n */\n public getOrAdd(item: TITEM): DetailedResult<TITEM, CollectorResultDetail>;\n\n /**\n * Gets an existing item with a key matching the supplied key, or adds a new item to the collector\n * using a factory callback if no item with that key exists.\n * @param key - The key of the item to add.\n * @param callback - The factory callback to create the item.\n * @returns Returns {@link DetailedSuccess | Success} with the item stored in the collector -\n * detail `exists` indicates that an existing item return and detail `added` indicates that the\n * item was added. Returns {@link DetailedFailure | Failure} with an error and appropriate\n * detail if the item could not be added.\n */\n public getOrAdd(\n key: CollectibleKey<TITEM>,\n factory: CollectibleFactoryCallback<TITEM>\n ): DetailedResult<TITEM, CollectorResultDetail>;\n\n public getOrAdd(\n keyOrItem: CollectibleKey<TITEM> | TITEM,\n factory?: CollectibleFactoryCallback<TITEM>\n ): DetailedResult<TITEM, CollectorResultDetail> {\n const key = !this._isItem(keyOrItem) ? keyOrItem : keyOrItem.key;\n const existing = this._byKey.get(key);\n if (existing) {\n return succeedWithDetail(existing, 'exists');\n }\n\n const itemResult = !this._isItem(keyOrItem)\n ? factory!(keyOrItem, this._byIndex.length)\n : succeed(keyOrItem);\n if (itemResult.isFailure()) {\n return failWithDetail(`${key}: ${itemResult.message}`, 'invalid-value');\n }\n const item = itemResult.value;\n\n if (item.key !== key) {\n return failWithDetail(`${key}: key mismatch - built item has ${key}`, 'invalid-key');\n }\n\n return itemResult.withFailureDetail<CollectorResultDetail>('invalid-index').onSuccess((item) => {\n return this.add(item);\n });\n }\n\n /**\n * {@inheritdoc Collections.ResultMap.has}\n */\n public has(key: CollectibleKey<TITEM>): boolean {\n return this._byKey.has(key);\n }\n\n /**\n * {@inheritdoc Collections.ResultMap.keys}\n */\n public keys(): IterableIterator<CollectibleKey<TITEM>> {\n return this._byKey.keys();\n }\n\n /**\n * {@inheritdoc Collections.ResultMap.values}\n */\n public values(): IterableIterator<TITEM> {\n return this._byKey.values();\n }\n\n /**\n * Gets a read-only version of this collector.\n */\n public toReadOnly(): IReadOnlyCollector<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<CollectibleKey<TITEM>, TITEM>> {\n return this._byKey[Symbol.iterator]();\n }\n\n protected _isItem(keyOrItem: CollectibleKey<TITEM> | TITEM): keyOrItem is TITEM {\n return typeof keyOrItem !== 'string';\n }\n}\n"]}
|