@nestia/e2e 14.0.1 → 14.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -25,27 +25,40 @@ exports.GaffComparator = void 0;
25
25
  * - Return > 0 if first element should come after second
26
26
  * - Return 0 if elements are equal
27
27
  *
28
+ * Processing cost: Each comparison extracts both key lists and visits their
29
+ * common prefix until the first difference; date keys additionally parse all
30
+ * supplied strings once per comparison. No sort or repeated scan is performed
31
+ * inside a comparison.
32
+ *
28
33
  * @author Jeongho Nam - https://github.com/samchon
29
34
  * @example
30
- * ```typescript
31
35
  * // Basic usage with single fields
32
- * users.sort(GaffComparator.strings(user => user.name));
33
- * posts.sort(GaffComparator.dates(post => post.createdAt));
34
- * products.sort(GaffComparator.numbers(product => product.price));
36
+ * users.sort(GaffComparator.strings((user) => user.name));
37
+ * posts.sort(GaffComparator.dates((post) => post.createdAt));
38
+ * products.sort(GaffComparator.numbers((product) => product.price));
35
39
  *
36
40
  * // Multi-field sorting with arrays
37
- * users.sort(GaffComparator.strings(user => [user.lastName, user.firstName]));
38
- * events.sort(GaffComparator.dates(event => [event.startDate, event.endDate]));
41
+ * users.sort(
42
+ * GaffComparator.strings((user) => [user.lastName, user.firstName]),
43
+ * );
44
+ * events.sort(
45
+ * GaffComparator.dates((event) => [event.startDate, event.endDate]),
46
+ * );
39
47
  *
40
48
  * // Integration with TestValidator's currying pattern
41
- * const validator = TestValidator.sort("user sorting",
42
- * (sortable) => api.getUsers({ sort: sortable })
43
- * )("name", "email")(
44
- * GaffComparator.strings(user => [user.name, user.email])
45
- * );
49
+ * const validator = TestValidator.sort("user sorting", (sortable) =>
50
+ * api.getUsers({ sort: sortable }),
51
+ * )(
52
+ * "name",
53
+ * "email",
54
+ * )(GaffComparator.strings((user) => [user.name, user.email]));
46
55
  * await validator("+"); // ascending
47
56
  * await validator("-"); // descending
48
- * ```;
57
+ *
58
+ * @evidence contracts/common.md#principled-implementation Each comparator maps both operands to arrays of comparable values and decides by the first position where they differ, then by array length, which is a lexicographic order that satisfies the sort contract for well-defined values; it is used to check server-side sorting from the client.
59
+ * @evidence contracts/common.md#clear-and-simple-design Three comparators share scalar-to-array wrapping. Strings compare each key by collation; dates and numbers use a shared strict mismatch search over their numeric keys.
60
+ * @evidence contracts/common.md#prohibited-implementation-shortcuts The ordering rule is generic in the getter, with no field, entity, or locale special case.
61
+ * @evidence contracts/common.md#meaningful-documentation The namespace prose lists the features and the sort contract with an example.
49
62
  */
50
63
  var GaffComparator;
51
64
  (function (GaffComparator) {
@@ -60,58 +73,99 @@ var GaffComparator;
60
73
  *
61
74
  * When comparing arrays, performs lexicographic ordering: compares the first
62
75
  * elements, then the second elements if the first are equal, and so on. This
63
- * enables complex sorting like "sort by last name, then by first name".
76
+ * enables complex sorting like "sort by last name, then by first name". Keys
77
+ * that compare equal under the runtime's collation, including different
78
+ * canonically equivalent Unicode spellings, continue to the next key. If the
79
+ * whole common prefix compares equal, the shorter key list sorts first.
80
+ *
81
+ * Processing cost: Both getters run once and a bounded loop visits only
82
+ * common keys until the first collation difference. Work depends on examined
83
+ * keys and string comparison cost; scalar wrapping adds constant space.
64
84
  *
65
85
  * @example
66
- * ```typescript
67
86
  * interface User {
68
87
  * id: string;
69
88
  * firstName: string;
70
89
  * lastName: string;
71
90
  * email: string;
72
- * status: 'active' | 'inactive';
91
+ * status: "active" | "inactive";
73
92
  * }
74
93
  *
75
94
  * const users: User[] = [
76
- * { id: '1', firstName: 'John', lastName: 'Doe', email: 'john@example.com', status: 'active' },
77
- * { id: '2', firstName: 'Jane', lastName: 'Doe', email: 'jane@example.com', status: 'inactive' },
78
- * { id: '3', firstName: 'Bob', lastName: 'Smith', email: 'bob@example.com', status: 'active' }
95
+ * {
96
+ * id: "1",
97
+ * firstName: "John",
98
+ * lastName: "Doe",
99
+ * email: "john@example.com",
100
+ * status: "active",
101
+ * },
102
+ * {
103
+ * id: "2",
104
+ * firstName: "Jane",
105
+ * lastName: "Doe",
106
+ * email: "jane@example.com",
107
+ * status: "inactive",
108
+ * },
109
+ * {
110
+ * id: "3",
111
+ * firstName: "Bob",
112
+ * lastName: "Smith",
113
+ * email: "bob@example.com",
114
+ * status: "active",
115
+ * },
79
116
  * ];
80
117
  *
81
118
  * // Single field sorting
82
- * users.sort(GaffComparator.strings(user => user.lastName));
119
+ * users.sort(GaffComparator.strings((user) => user.lastName));
83
120
  * // Result: Doe, Doe, Smith
84
121
  *
85
122
  * // Multi-field sorting: last name, then first name
86
- * users.sort(GaffComparator.strings(user => [user.lastName, user.firstName]));
123
+ * users.sort(
124
+ * GaffComparator.strings((user) => [user.lastName, user.firstName]),
125
+ * );
87
126
  * // Result: Doe Jane, Doe John, Smith Bob
88
127
  *
89
128
  * // Status-based sorting
90
- * users.sort(GaffComparator.strings(user => user.status));
129
+ * users.sort(GaffComparator.strings((user) => user.status));
91
130
  * // Result: active users first, then inactive
92
131
  *
93
132
  * // Complex multi-field: status, then last name, then first name
94
- * users.sort(GaffComparator.strings(user => [user.status, user.lastName, user.firstName]));
133
+ * users.sort(
134
+ * GaffComparator.strings((user) => [
135
+ * user.status,
136
+ * user.lastName,
137
+ * user.firstName,
138
+ * ]),
139
+ * );
95
140
  *
96
141
  * // Integration with TestValidator sorting validation
97
- * const sortValidator = TestValidator.sort("user name sorting",
98
- * (sortFields) => userApi.getUsers({ sort: sortFields })
99
- * )("lastName", "firstName")(
100
- * GaffComparator.strings(user => [user.lastName, user.firstName])
101
- * );
142
+ * const sortValidator = TestValidator.sort(
143
+ * "user name sorting",
144
+ * (sortFields) => userApi.getUsers({ sort: sortFields }),
145
+ * )(
146
+ * "lastName",
147
+ * "firstName",
148
+ * )(GaffComparator.strings((user) => [user.lastName, user.firstName]));
102
149
  * await sortValidator("+"); // test ascending order
103
150
  * await sortValidator("-"); // test descending order
104
- * ```;
105
151
  *
106
152
  * @template T - The type of objects being compared
107
153
  * @param getter - Function that extracts string value(s) from input objects
108
154
  * @returns A comparator function suitable for Array.sort()
155
+ * @evidence contracts/common.md#principled-implementation Each common key position is compared once with localeCompare; a nonzero result decides the order, while collation-equal spellings continue to later keys. Only an entirely equal common prefix falls through to array length, establishing lexicographic order under the runtime's actual collation without assuming strict string equality.
156
+ * @evidence contracts/common.md#clear-and-simple-design Shared wrapping accepts scalar or array keys; one bounded loop returns the first nonzero collation result or the length difference.
157
+ * @evidence contracts/common.md#prohibited-implementation-shortcuts The comparison is the platform's locale collation, not a hand-written ordering.
158
+ * @evidence contracts/common.md#meaningful-documentation The comment states the locale sensitivity, the multi-value rule, and the arguments, with examples.
109
159
  */
110
160
  GaffComparator.strings = (getter) => (x, y) => {
111
161
  const a = wrap(getter(x));
112
162
  const b = wrap(getter(y));
113
- const idx = mismatch(a, b);
114
- return idx !== -1 ? compare(a[idx], b[idx]) : a.length - b.length;
163
+ for (let index = 0; index < Math.min(a.length, b.length); ++index) {
164
+ const result = compare(a[index], b[index]);
165
+ if (result !== 0)
166
+ return result;
167
+ }
168
+ return a.length - b.length;
115
169
  };
116
170
  /**
117
171
  * Creates a comparator function for date-based sorting with automatic string
@@ -127,8 +181,11 @@ var GaffComparator;
127
181
  * The comparison is performed on millisecond timestamps for precise
128
182
  * ordering.
129
183
  *
184
+ * Processing cost: Both getters run once, each returned string is parsed
185
+ * once, and the bounded mismatch search visits at most the common key count.
186
+ * Numeric key arrays require space proportional to the two lists.
187
+ *
130
188
  * @example
131
- * ```typescript
132
189
  * interface Event {
133
190
  * id: string;
134
191
  * title: string;
@@ -140,53 +197,59 @@ var GaffComparator;
140
197
  *
141
198
  * const events: Event[] = [
142
199
  * {
143
- * id: '1',
144
- * title: 'Conference',
145
- * startDate: '2024-03-15T09:00:00Z',
146
- * endDate: '2024-03-15T17:00:00Z',
147
- * createdAt: '2024-01-10T10:00:00Z',
148
- * updatedAt: '2024-02-01T15:30:00Z'
200
+ * id: "1",
201
+ * title: "Conference",
202
+ * startDate: "2024-03-15T09:00:00Z",
203
+ * endDate: "2024-03-15T17:00:00Z",
204
+ * createdAt: "2024-01-10T10:00:00Z",
205
+ * updatedAt: "2024-02-01T15:30:00Z",
149
206
  * },
150
207
  * {
151
- * id: '2',
152
- * title: 'Workshop',
153
- * startDate: '2024-03-10T14:00:00Z',
154
- * endDate: '2024-03-10T16:00:00Z',
155
- * createdAt: '2024-01-15T11:00:00Z',
156
- * updatedAt: '2024-01-20T09:15:00Z'
157
- * }
208
+ * id: "2",
209
+ * title: "Workshop",
210
+ * startDate: "2024-03-10T14:00:00Z",
211
+ * endDate: "2024-03-10T16:00:00Z",
212
+ * createdAt: "2024-01-15T11:00:00Z",
213
+ * updatedAt: "2024-01-20T09:15:00Z",
214
+ * },
158
215
  * ];
159
216
  *
160
217
  * // Sort by start date (chronological order)
161
- * events.sort(GaffComparator.dates(event => event.startDate));
218
+ * events.sort(GaffComparator.dates((event) => event.startDate));
162
219
  *
163
220
  * // Sort by creation date (oldest first)
164
- * events.sort(GaffComparator.dates(event => event.createdAt));
221
+ * events.sort(GaffComparator.dates((event) => event.createdAt));
165
222
  *
166
223
  * // Multi-field: start date, then end date
167
- * events.sort(GaffComparator.dates(event => [event.startDate, event.endDate]));
224
+ * events.sort(
225
+ * GaffComparator.dates((event) => [event.startDate, event.endDate]),
226
+ * );
168
227
  *
169
228
  * // Sort by modification history: created date, then updated date
170
- * events.sort(GaffComparator.dates(event => [event.createdAt, event.updatedAt]));
229
+ * events.sort(
230
+ * GaffComparator.dates((event) => [event.createdAt, event.updatedAt]),
231
+ * );
171
232
  *
172
233
  * // Validate API date sorting with TestValidator
173
- * const dateValidator = TestValidator.sort("event chronological sorting",
174
- * (sortFields) => eventApi.getEvents({ sort: sortFields })
175
- * )("startDate")(
176
- * GaffComparator.dates(event => event.startDate)
177
- * );
234
+ * const dateValidator = TestValidator.sort(
235
+ * "event chronological sorting",
236
+ * (sortFields) => eventApi.getEvents({ sort: sortFields }),
237
+ * )("startDate")(GaffComparator.dates((event) => event.startDate));
178
238
  * await dateValidator("+", true); // ascending with trace logging
179
239
  *
180
240
  * // Test complex date-based sorting
181
- * const sortByEventSchedule = GaffComparator.dates(event => [
241
+ * const sortByEventSchedule = GaffComparator.dates((event) => [
182
242
  * event.startDate,
183
- * event.endDate
243
+ * event.endDate,
184
244
  * ]);
185
- * ```;
186
245
  *
187
246
  * @template T - The type of objects being compared
188
247
  * @param getter - Function that extracts date string(s) from input objects
189
248
  * @returns A comparator function suitable for Array.sort()
249
+ * @evidence contracts/common.md#principled-implementation Each value is parsed by the `Date` constructor and compared by its millisecond timestamp, so ISO 8601 and the other formats the constructor accepts order correctly; a string the constructor cannot parse yields NaN, and the comparator then returns NaN, which a sort treats as equality, a limit the caller must respect by giving valid dates.
250
+ * @evidence contracts/common.md#clear-and-simple-design It uses the shared `wrap` and `mismatch`, and adds only the parsing.
251
+ * @evidence contracts/common.md#prohibited-implementation-shortcuts Parsing is the standard constructor with no format special cases.
252
+ * @evidence contracts/common.md#meaningful-documentation The comment states the accepted formats and the millisecond comparison, with examples.
190
253
  */
191
254
  GaffComparator.dates = (getter) => (x, y) => {
192
255
  const take = (v) => wrap(getter(v)).map((str) => new Date(str).getTime());
@@ -209,8 +272,11 @@ var GaffComparator;
209
272
  * on. This enables sophisticated sorting like "sort by price ascending, then
210
273
  * by rating descending".
211
274
  *
275
+ * Processing cost: Both getters run once and mismatch visits only the common
276
+ * prefix until the first unequal key. Existing key arrays are reused, and
277
+ * scalar wrapping takes constant auxiliary space.
278
+ *
212
279
  * @example
213
- * ```typescript
214
280
  * interface Product {
215
281
  * id: string;
216
282
  * name: string;
@@ -222,49 +288,90 @@ var GaffComparator;
222
288
  * }
223
289
  *
224
290
  * const products: Product[] = [
225
- * { id: '1', name: 'Laptop', price: 999.99, rating: 4.5, stock: 15, categoryId: 1, salesCount: 150 },
226
- * { id: '2', name: 'Mouse', price: 29.99, rating: 4.2, stock: 50, categoryId: 1, salesCount: 300 },
227
- * { id: '3', name: 'Keyboard', price: 79.99, rating: 4.8, stock: 25, categoryId: 1, salesCount: 200 }
291
+ * {
292
+ * id: "1",
293
+ * name: "Laptop",
294
+ * price: 999.99,
295
+ * rating: 4.5,
296
+ * stock: 15,
297
+ * categoryId: 1,
298
+ * salesCount: 150,
299
+ * },
300
+ * {
301
+ * id: "2",
302
+ * name: "Mouse",
303
+ * price: 29.99,
304
+ * rating: 4.2,
305
+ * stock: 50,
306
+ * categoryId: 1,
307
+ * salesCount: 300,
308
+ * },
309
+ * {
310
+ * id: "3",
311
+ * name: "Keyboard",
312
+ * price: 79.99,
313
+ * rating: 4.8,
314
+ * stock: 25,
315
+ * categoryId: 1,
316
+ * salesCount: 200,
317
+ * },
228
318
  * ];
229
319
  *
230
320
  * // Sort by price (ascending)
231
- * products.sort(GaffComparator.numbers(product => product.price));
321
+ * products.sort(GaffComparator.numbers((product) => product.price));
232
322
  * // Result: Mouse ($29.99), Keyboard ($79.99), Laptop ($999.99)
233
323
  *
234
324
  * // Sort by rating (descending requires negation)
235
- * products.sort(GaffComparator.numbers(product => -product.rating));
325
+ * products.sort(GaffComparator.numbers((product) => -product.rating));
236
326
  * // Result: Keyboard (4.8), Laptop (4.5), Mouse (4.2)
237
327
  *
238
328
  * // Multi-field: category, then price
239
- * products.sort(GaffComparator.numbers(product => [product.categoryId, product.price]));
329
+ * products.sort(
330
+ * GaffComparator.numbers((product) => [
331
+ * product.categoryId,
332
+ * product.price,
333
+ * ]),
334
+ * );
240
335
  *
241
336
  * // Complex business logic: popularity (sales) then rating
242
- * products.sort(GaffComparator.numbers(product => [-product.salesCount, -product.rating]));
337
+ * products.sort(
338
+ * GaffComparator.numbers((product) => [
339
+ * -product.salesCount,
340
+ * -product.rating,
341
+ * ]),
342
+ * );
243
343
  * // Negative values for descending order
244
344
  *
245
345
  * // Sort by inventory priority: low stock first, then by sales
246
- * products.sort(GaffComparator.numbers(product => [product.stock, -product.salesCount]));
346
+ * products.sort(
347
+ * GaffComparator.numbers((product) => [
348
+ * product.stock,
349
+ * -product.salesCount,
350
+ * ]),
351
+ * );
247
352
  *
248
353
  * // Validate API numerical sorting with TestValidator
249
- * const priceValidator = TestValidator.sort("product price sorting",
250
- * (sortFields) => productApi.getProducts({ sort: sortFields })
251
- * )("price")(
252
- * GaffComparator.numbers(product => product.price)
253
- * );
354
+ * const priceValidator = TestValidator.sort(
355
+ * "product price sorting",
356
+ * (sortFields) => productApi.getProducts({ sort: sortFields }),
357
+ * )("price")(GaffComparator.numbers((product) => product.price));
254
358
  * await priceValidator("+"); // test ascending order
255
359
  * await priceValidator("-"); // test descending order
256
360
  *
257
361
  * // Test multi-criteria sorting
258
- * const sortByBusinessValue = GaffComparator.numbers(product => [
259
- * -product.salesCount, // High sales first
260
- * -product.rating, // High rating first
261
- * product.price // Low price first (for tie-breaking)
362
+ * const sortByBusinessValue = GaffComparator.numbers((product) => [
363
+ * -product.salesCount, // High sales first
364
+ * -product.rating, // High rating first
365
+ * product.price, // Low price first (for tie-breaking)
262
366
  * ]);
263
- * ```;
264
367
  *
265
368
  * @template T - The type of objects being compared
266
369
  * @param closure - Function that extracts number value(s) from input objects
267
370
  * @returns A comparator function suitable for Array.sort()
371
+ * @evidence contracts/common.md#principled-implementation The sign of subtraction at the first differing position orders finite numeric values, and a shorter equal prefix sorts first. Subtraction can round or overflow, so the result's magnitude is not an exact-distance guarantee; callers must supply ordered numeric values rather than NaN.
372
+ * @evidence contracts/common.md#clear-and-simple-design It uses the shared `wrap` and `mismatch`, and adds only the subtraction.
373
+ * @evidence contracts/common.md#prohibited-implementation-shortcuts The comparison is the arithmetic difference, with no rounding or thresholds.
374
+ * @evidence contracts/common.md#meaningful-documentation The comment states the multi-value rule and the arguments, with examples.
268
375
  */
269
376
  GaffComparator.numbers = (closure) => (x, y) => {
270
377
  const a = wrap(closure(x));
@@ -278,7 +385,13 @@ var GaffComparator;
278
385
  * or -1; beyond it a proper prefix orders before its extension, in both
279
386
  * argument orders.
280
387
  */
281
- const mismatch = (a, b) => a.findIndex((v, i) => i < b.length && v !== b[i]);
388
+ const mismatch = (a, b) => {
389
+ const length = Math.min(a.length, b.length);
390
+ for (let index = 0; index < length; ++index)
391
+ if (a[index] !== b[index])
392
+ return index;
393
+ return -1;
394
+ };
282
395
  const wrap = (elem) => (Array.isArray(elem) ? elem : [elem]);
283
396
  })(GaffComparator || (exports.GaffComparator = GaffComparator = {}));
284
397
  //# sourceMappingURL=GaffComparator.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"GaffComparator.js","sourceRoot":"","sources":["../src/GaffComparator.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"GaffComparator.js","sourceRoot":"","sources":["../src/GaffComparator.ts"],"names":[],"mappings":"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"}
package/lib/MapUtil.d.ts CHANGED
@@ -5,9 +5,21 @@
5
5
  * objects, providing convenient methods for common Map operations like
6
6
  * retrieving values with lazy initialization.
7
7
  *
8
+ * Processing cost: The get-or-create operation uses native Map membership and
9
+ * lookup, and calls the factory only for an absent key; its dominant extra cost
10
+ * is the caller factory.
11
+ *
12
+ * Reuse: Stored values, including promises and undefined, are reused while the
13
+ * supplied Map retains the key. The caller must key every relevant dependency
14
+ * and remove stale or rejected entries; this helper cannot establish
15
+ * external-data freshness or prevent reentrant factory calls.
16
+ *
17
+ * Resource ownership: New values are transferred into the caller-owned Map,
18
+ * whose growth and eviction remain the caller responsibility; the helper
19
+ * acquires no external handle or background task.
20
+ *
8
21
  * @author Jeongho Nam - https://github.com/samchon
9
22
  * @example
10
- * ```typescript
11
23
  * // Create a cache with lazy initialization
12
24
  * const cache = new Map<string, ExpensiveObject>();
13
25
  *
@@ -19,7 +31,11 @@
19
31
  * // Subsequent calls return cached value without re-creating
20
32
  * const sameObj = MapUtil.take(cache, "key1", () => new ExpensiveObject());
21
33
  * console.log(obj === sameObj); // true
22
- * ```;
34
+ *
35
+ * @evidence contracts/common.md#principled-implementation The namespace offers the get-or-create pattern over the native `Map`, whose `has` distinguishes an absent key from a stored `undefined`.
36
+ * @evidence contracts/common.md#clear-and-simple-design One function, without options or state.
37
+ * @evidence contracts/common.md#prohibited-implementation-shortcuts It uses only the public Map methods.
38
+ * @evidence contracts/common.md#meaningful-documentation The comment states the lazy initialization pattern with an example.
23
39
  */
24
40
  export declare namespace MapUtil {
25
41
  /**
@@ -32,8 +48,20 @@ export declare namespace MapUtil {
32
48
  * returns it. The factory function is only called when the key doesn't exist,
33
49
  * enabling lazy initialization and caching patterns.
34
50
  *
51
+ * Processing cost: One membership test and lookup, or one factory invocation
52
+ * and insertion, avoid a map scan; native Map access is sublinear on average
53
+ * and factory cost belongs to the supplied computation.
54
+ *
55
+ * Reuse: Stored values, including promises and undefined, are reused while
56
+ * the supplied Map retains the key. The caller must key every relevant
57
+ * dependency and remove stale or rejected entries; this helper cannot
58
+ * establish external-data freshness or prevent reentrant factory calls.
59
+ *
60
+ * Resource ownership: New values are transferred into the caller-owned Map,
61
+ * whose growth and eviction remain the caller responsibility; the helper
62
+ * acquires no external handle or background task.
63
+ *
35
64
  * @example
36
- * ```typescript
37
65
  * // Simple caching example
38
66
  * const userCache = new Map<number, User>();
39
67
  *
@@ -48,7 +76,7 @@ export declare namespace MapUtil {
48
76
  * const dbConfig = MapUtil.take(configs, "database", () => ({
49
77
  * host: "localhost",
50
78
  * port: 5432,
51
- * database: "myapp"
79
+ * database: "myapp",
52
80
  * }));
53
81
  *
54
82
  * // Lazy computation results
@@ -64,9 +92,8 @@ export declare namespace MapUtil {
64
92
  * const key: [number, number] = [rows, cols];
65
93
  *
66
94
  * const matrix = MapUtil.take(cache, key, () =>
67
- * generateIdentityMatrix(rows, cols)
95
+ * generateIdentityMatrix(rows, cols),
68
96
  * );
69
- * ```;
70
97
  *
71
98
  * @template K - The type of keys in the Map
72
99
  * @template V - The type of values in the Map
@@ -75,6 +102,10 @@ export declare namespace MapUtil {
75
102
  * @param value - A factory function that creates the value if key doesn't
76
103
  * exist
77
104
  * @returns The existing value if found, or the newly created value
105
+ * @evidence contracts/common.md#principled-implementation The key is looked up with `has`, so an existing value, even `undefined`, is returned without calling the factory; otherwise the factory is called once, its value is stored, and the same value is returned.
106
+ * @evidence contracts/common.md#clear-and-simple-design A single check, one factory call, and one store.
107
+ * @evidence contracts/common.md#prohibited-implementation-shortcuts The factory result is stored as returned, with no copying or expiry.
108
+ * @evidence contracts/common.md#meaningful-documentation The comment states when the factory runs and documents the parameters with several examples.
78
109
  */
79
110
  function take<K, V>(map: Map<K, V>, key: K, value: () => V): V;
80
111
  }
package/lib/MapUtil.js CHANGED
@@ -8,9 +8,21 @@ exports.MapUtil = void 0;
8
8
  * objects, providing convenient methods for common Map operations like
9
9
  * retrieving values with lazy initialization.
10
10
  *
11
+ * Processing cost: The get-or-create operation uses native Map membership and
12
+ * lookup, and calls the factory only for an absent key; its dominant extra cost
13
+ * is the caller factory.
14
+ *
15
+ * Reuse: Stored values, including promises and undefined, are reused while the
16
+ * supplied Map retains the key. The caller must key every relevant dependency
17
+ * and remove stale or rejected entries; this helper cannot establish
18
+ * external-data freshness or prevent reentrant factory calls.
19
+ *
20
+ * Resource ownership: New values are transferred into the caller-owned Map,
21
+ * whose growth and eviction remain the caller responsibility; the helper
22
+ * acquires no external handle or background task.
23
+ *
11
24
  * @author Jeongho Nam - https://github.com/samchon
12
25
  * @example
13
- * ```typescript
14
26
  * // Create a cache with lazy initialization
15
27
  * const cache = new Map<string, ExpensiveObject>();
16
28
  *
@@ -22,7 +34,11 @@ exports.MapUtil = void 0;
22
34
  * // Subsequent calls return cached value without re-creating
23
35
  * const sameObj = MapUtil.take(cache, "key1", () => new ExpensiveObject());
24
36
  * console.log(obj === sameObj); // true
25
- * ```;
37
+ *
38
+ * @evidence contracts/common.md#principled-implementation The namespace offers the get-or-create pattern over the native `Map`, whose `has` distinguishes an absent key from a stored `undefined`.
39
+ * @evidence contracts/common.md#clear-and-simple-design One function, without options or state.
40
+ * @evidence contracts/common.md#prohibited-implementation-shortcuts It uses only the public Map methods.
41
+ * @evidence contracts/common.md#meaningful-documentation The comment states the lazy initialization pattern with an example.
26
42
  */
27
43
  var MapUtil;
28
44
  (function (MapUtil) {
@@ -36,8 +52,20 @@ var MapUtil;
36
52
  * returns it. The factory function is only called when the key doesn't exist,
37
53
  * enabling lazy initialization and caching patterns.
38
54
  *
55
+ * Processing cost: One membership test and lookup, or one factory invocation
56
+ * and insertion, avoid a map scan; native Map access is sublinear on average
57
+ * and factory cost belongs to the supplied computation.
58
+ *
59
+ * Reuse: Stored values, including promises and undefined, are reused while
60
+ * the supplied Map retains the key. The caller must key every relevant
61
+ * dependency and remove stale or rejected entries; this helper cannot
62
+ * establish external-data freshness or prevent reentrant factory calls.
63
+ *
64
+ * Resource ownership: New values are transferred into the caller-owned Map,
65
+ * whose growth and eviction remain the caller responsibility; the helper
66
+ * acquires no external handle or background task.
67
+ *
39
68
  * @example
40
- * ```typescript
41
69
  * // Simple caching example
42
70
  * const userCache = new Map<number, User>();
43
71
  *
@@ -52,7 +80,7 @@ var MapUtil;
52
80
  * const dbConfig = MapUtil.take(configs, "database", () => ({
53
81
  * host: "localhost",
54
82
  * port: 5432,
55
- * database: "myapp"
83
+ * database: "myapp",
56
84
  * }));
57
85
  *
58
86
  * // Lazy computation results
@@ -68,9 +96,8 @@ var MapUtil;
68
96
  * const key: [number, number] = [rows, cols];
69
97
  *
70
98
  * const matrix = MapUtil.take(cache, key, () =>
71
- * generateIdentityMatrix(rows, cols)
99
+ * generateIdentityMatrix(rows, cols),
72
100
  * );
73
- * ```;
74
101
  *
75
102
  * @template K - The type of keys in the Map
76
103
  * @template V - The type of values in the Map
@@ -79,6 +106,10 @@ var MapUtil;
79
106
  * @param value - A factory function that creates the value if key doesn't
80
107
  * exist
81
108
  * @returns The existing value if found, or the newly created value
109
+ * @evidence contracts/common.md#principled-implementation The key is looked up with `has`, so an existing value, even `undefined`, is returned without calling the factory; otherwise the factory is called once, its value is stored, and the same value is returned.
110
+ * @evidence contracts/common.md#clear-and-simple-design A single check, one factory call, and one store.
111
+ * @evidence contracts/common.md#prohibited-implementation-shortcuts The factory result is stored as returned, with no copying or expiry.
112
+ * @evidence contracts/common.md#meaningful-documentation The comment states when the factory runs and documents the parameters with several examples.
82
113
  */
83
114
  function take(map, key, value) {
84
115
  if (map.has(key)) {
@@ -1 +1 @@
1
- {"version":3,"file":"MapUtil.js","sourceRoot":"","sources":["../src/MapUtil.ts"],"names":[],"mappings":";;;AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,IAAiB,OAAO,CA+DvB;AA/DD,WAAiB,OAAO;IACtB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAqDG;IACH,SAAgB,IAAI,CAAO,GAAc,EAAE,GAAM,EAAE,KAAc;QAC/D,IAAI,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC;YACjB,OAAO,GAAG,CAAC,GAAG,CAAC,GAAG,CAAM,CAAC;QAC3B,CAAC;QACD,MAAM,QAAQ,GAAG,KAAK,EAAE,CAAC;QACzB,GAAG,CAAC,GAAG,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC;QACvB,OAAO,QAAQ,CAAC;IAClB,CAAC;IAPe,QAAA,IAAI,OAOnB,CAAA;AACH,CAAC,EA/DgB,OAAO,aAAP,OAAO,GAAP,OAAO,QA+DvB"}
1
+ {"version":3,"file":"MapUtil.js","sourceRoot":"","sources":["../src/MapUtil.ts"],"names":[],"mappings":";;;AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsCG;AACH,IAAiB,OAAO,CA8EvB;AA9ED,WAAiB,OAAO;IACtB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAoEG;IACH,SAAgB,IAAI,CAAO,GAAc,EAAE,GAAM,EAAE,KAAc;QAC/D,IAAI,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC;YACjB,OAAO,GAAG,CAAC,GAAG,CAAC,GAAG,CAAM,CAAC;QAC3B,CAAC;QACD,MAAM,QAAQ,GAAG,KAAK,EAAE,CAAC;QACzB,GAAG,CAAC,GAAG,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC;QACvB,OAAO,QAAQ,CAAC;IAClB,CAAC;IAPe,QAAA,IAAI,OAOnB,CAAA;AACH,CAAC,EA9EgB,OAAO,aAAP,OAAO,GAAP,OAAO,QA8EvB"}