@reykjavik/webtools 0.1.30 → 0.1.31

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/CHANGELOG.md CHANGED
@@ -4,6 +4,15 @@
4
4
 
5
5
  - ... <!-- Add new lines here. -->
6
6
 
7
+ ## 0.1.31
8
+
9
+ _2024-09-23_
10
+
11
+ - `@reykjavik/webtools/async`:
12
+ - feat: `maxWait` returns full `PromiseSettledResult` objects
13
+ - fix: `maxWait` result objects should remain stable
14
+ - fix: `maxWait` should distinguish between unresolved and rejected promises
15
+
7
16
  ## 0.1.30
8
17
 
9
18
  _2024-09-15_
package/README.md CHANGED
@@ -265,23 +265,21 @@ const { user, posts } = await promiseAllObject({
265
265
 
266
266
  **Syntax:** `maxWait(timeout: number, promises: Array<any>): Promise<void>`
267
267
  **Syntax:**
268
- `maxWait<T extends PlainObj>(timeout: number, promises: T): Promise<{ [K in keyof T]: { value: Awaited<T[K]> } | undefined }>`
268
+ `maxWait<T extends PlainObj>(timeout: number, promises: T): Promise<{ [K in keyof T]: PromiseSettledResult<T[K]> } | undefined }>`
269
269
 
270
- This somewhat esoteric helper resolves soon as all of the passed `promises`
271
- have resolved, or after `timeout` milliseconds — whichever comes first.
270
+ This somewhat esoteric helper resolves soon when all of the passed `promises`
271
+ have settled (resolved or rejected), OR after `timeout` milliseconds —
272
+ whichever comes first.
272
273
 
273
274
  If an object is passed, the resolved value will be an object with the same
274
- keys, with undefined values for any promises that didn't resolve in time, and
275
- the resolved values in a `value` container object.
276
-
277
- If any of the promises reject, their values become undefined in the returned
278
- object.
275
+ keys, and any settled values in a `PromiseSettledResult` object, and
276
+ `undefined` for any promises that didn't settle in time.
279
277
 
280
278
  ```ts
281
279
  import { maxWait } from '@reykjavik/webtools/async';
282
280
 
283
- const user = fetchUser();
284
- const posts = fetchPosts();
281
+ const user = fetchUser(); // Promise<User>
282
+ const posts = fetchPosts(); // Promise<Array<Post>>
285
283
 
286
284
  // Array of promises resolves to void
287
285
  await maxWait(500, [user, posts]);
@@ -291,6 +289,8 @@ const { user, posts } = await maxWait(500, { user, posts });
291
289
 
292
290
  console.log(user?.value); // undefined | User
293
291
  console.log(posts?.value); // undefined | Array<Post>
292
+ console.log(posts?.status); // 'fulfilled' | 'rejected'
293
+ console.log(posts?.reason); // undefined | unknown
294
294
  ```
295
295
 
296
296
  ---
@@ -333,11 +333,10 @@ detection test.)
333
333
 
334
334
  **`Intl.Collator` and `localeCompare`:**
335
335
 
336
- - It incorrectly treats `ð` and `d` as the same letter (most of the time), and
337
- the acute-accented characters `á`, `é`, `í`, `ó`, `ú` and `ý` get lumped in
338
- with their non-accented counterparts (unless the compared).
339
- We fix this only for the first letter in the string, but not for the rest of
340
- it.
336
+ - It sorts initial letters correctly but in the rest of the string, it
337
+ incorrectly treats `ð` and `d` as the same letter (most of the time), and
338
+ lumps the acute-accented characters `á`, `é`, `í`, `ó`, `ú` and `ý` in with
339
+ their non-accented counterparts.
341
340
 
342
341
  **`Intl.NumberFormat` and `toLocaleString`:**
343
342
 
package/async.d.ts CHANGED
@@ -1,3 +1,4 @@
1
+ import { EitherObj } from '@reykjavik/hanna-utils';
1
2
  type PlainObj = Record<string, unknown>;
2
3
  /**
3
4
  * Simple sleep function. Returns a promise that resolves after `length`
@@ -5,16 +6,19 @@ type PlainObj = Record<string, unknown>;
5
6
  */
6
7
  export declare const sleep: (length: number) => Promise<void>;
7
8
  /**
8
- * Resolves soon as all of the passed `promises` have resolved, or after
9
- * `timeout` milliseconds whichever comes first.
9
+ * Returns a function that adds lag/delay to a promise chain,
10
+ * passing the promise payload through.
11
+ */
12
+ export declare const addLag: (length: number) => <T>(res: T) => Promise<T>;
13
+ /**
14
+ * Resolves as soon as all of the passed `promises` have resolved/settled,
15
+ * or after `timeout` milliseconds — whichever comes first.
10
16
  *
11
17
  * @see https://github.com/reykjavikcity/webtools/blob/v0.1/README.md#maxwait
12
18
  */
13
19
  export declare function maxWait(timeout: number, promises: Array<unknown>): Promise<void>;
14
20
  export declare function maxWait<PromiseMap extends PlainObj>(timeout: number, promises: PromiseMap): Promise<{
15
- -readonly [K in keyof PromiseMap]: {
16
- value: Awaited<PromiseMap[K]>;
17
- } | undefined;
21
+ -readonly [K in keyof PromiseMap]: EitherObj<PromiseFulfilledResult<Awaited<PromiseMap[K]>>, PromiseRejectedResult> | undefined;
18
22
  }>;
19
23
  /**
20
24
  * A variation of `Promise.all()` that accepts an object with named promises
package/async.js CHANGED
@@ -1,12 +1,18 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.promiseAllObject = exports.maxWait = exports.sleep = void 0;
3
+ exports.promiseAllObject = exports.maxWait = exports.addLag = exports.sleep = void 0;
4
4
  /**
5
5
  * Simple sleep function. Returns a promise that resolves after `length`
6
6
  * milliseconds.
7
7
  */
8
8
  const sleep = (length) => new Promise((resolve) => setTimeout(resolve, length));
9
9
  exports.sleep = sleep;
10
+ /**
11
+ * Returns a function that adds lag/delay to a promise chain,
12
+ * passing the promise payload through.
13
+ */
14
+ const addLag = (length) => (res) => (0, exports.sleep)(length).then(() => res);
15
+ exports.addLag = addLag;
10
16
  function maxWait(timeout, promises) {
11
17
  if (Array.isArray(promises)) {
12
18
  return Promise.race([
@@ -19,17 +25,17 @@ function maxWait(timeout, promises) {
19
25
  Object.entries(promises).forEach(([key, value]) => {
20
26
  if (value instanceof Promise) {
21
27
  retObj[key] = undefined;
22
- value
23
- .then((value) => {
24
- retObj[key] = { value };
25
- })
26
- .catch(() => undefined);
28
+ value.then((value) => {
29
+ retObj[key] = { status: 'fulfilled', value };
30
+ }, (reason) => {
31
+ retObj[key] = { status: 'rejected', reason };
32
+ });
27
33
  }
28
34
  else {
29
- retObj[key] = { value };
35
+ retObj[key] = { status: 'fulfilled', value };
30
36
  }
31
37
  });
32
- return (0, exports.sleep)(0).then(() => retObj);
38
+ return Promise.resolve().then(() => ({ ...retObj }));
33
39
  });
34
40
  }
35
41
  exports.maxWait = maxWait;
package/esm/async.d.ts CHANGED
@@ -1,3 +1,4 @@
1
+ import { EitherObj } from '@reykjavik/hanna-utils';
1
2
  type PlainObj = Record<string, unknown>;
2
3
  /**
3
4
  * Simple sleep function. Returns a promise that resolves after `length`
@@ -5,16 +6,19 @@ type PlainObj = Record<string, unknown>;
5
6
  */
6
7
  export declare const sleep: (length: number) => Promise<void>;
7
8
  /**
8
- * Resolves soon as all of the passed `promises` have resolved, or after
9
- * `timeout` milliseconds whichever comes first.
9
+ * Returns a function that adds lag/delay to a promise chain,
10
+ * passing the promise payload through.
11
+ */
12
+ export declare const addLag: (length: number) => <T>(res: T) => Promise<T>;
13
+ /**
14
+ * Resolves as soon as all of the passed `promises` have resolved/settled,
15
+ * or after `timeout` milliseconds — whichever comes first.
10
16
  *
11
17
  * @see https://github.com/reykjavikcity/webtools/blob/v0.1/README.md#maxwait
12
18
  */
13
19
  export declare function maxWait(timeout: number, promises: Array<unknown>): Promise<void>;
14
20
  export declare function maxWait<PromiseMap extends PlainObj>(timeout: number, promises: PromiseMap): Promise<{
15
- -readonly [K in keyof PromiseMap]: {
16
- value: Awaited<PromiseMap[K]>;
17
- } | undefined;
21
+ -readonly [K in keyof PromiseMap]: EitherObj<PromiseFulfilledResult<Awaited<PromiseMap[K]>>, PromiseRejectedResult> | undefined;
18
22
  }>;
19
23
  /**
20
24
  * A variation of `Promise.all()` that accepts an object with named promises
package/esm/async.js CHANGED
@@ -3,6 +3,11 @@
3
3
  * milliseconds.
4
4
  */
5
5
  export const sleep = (length) => new Promise((resolve) => setTimeout(resolve, length));
6
+ /**
7
+ * Returns a function that adds lag/delay to a promise chain,
8
+ * passing the promise payload through.
9
+ */
10
+ export const addLag = (length) => (res) => sleep(length).then(() => res);
6
11
  export function maxWait(timeout, promises) {
7
12
  if (Array.isArray(promises)) {
8
13
  return Promise.race([
@@ -15,17 +20,17 @@ export function maxWait(timeout, promises) {
15
20
  Object.entries(promises).forEach(([key, value]) => {
16
21
  if (value instanceof Promise) {
17
22
  retObj[key] = undefined;
18
- value
19
- .then((value) => {
20
- retObj[key] = { value };
21
- })
22
- .catch(() => undefined);
23
+ value.then((value) => {
24
+ retObj[key] = { status: 'fulfilled', value };
25
+ }, (reason) => {
26
+ retObj[key] = { status: 'rejected', reason };
27
+ });
23
28
  }
24
29
  else {
25
- retObj[key] = { value };
30
+ retObj[key] = { status: 'fulfilled', value };
26
31
  }
27
32
  });
28
- return sleep(0).then(() => retObj);
33
+ return Promise.resolve().then(() => ({ ...retObj }));
29
34
  });
30
35
  }
31
36
  // ---------------------------------------------------------------------------
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@reykjavik/webtools",
3
- "version": "0.1.30",
3
+ "version": "0.1.31",
4
4
  "description": "Misc. JS/TS helpers used by Reykjavík City's web dev teams.",
5
5
  "main": "index.js",
6
6
  "repository": "ssh://git@github.com:reykjavikcity/webtools.git",