@webreflection/utils 0.2.9 → 0.2.11
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/README.md +1 -0
- package/package.json +8 -1
- package/src/README.md +27 -0
- package/src/all.js +41 -0
- package/types/all.d.ts +7 -0
package/README.md
CHANGED
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
|
|
8
8
|
A [collection](./src/) of utility functions:
|
|
9
9
|
|
|
10
|
+
* **[all](https://github.com/WebReflection/utils/tree/main/src#all)** - `Promise.all` via object destructuring
|
|
10
11
|
* **[bound-once](https://github.com/WebReflection/utils/tree/main/src#bound-once)** - to retrieve unique bound methods per realm
|
|
11
12
|
* **[bound](https://github.com/WebReflection/utils/tree/main/src#bound)** - to retrieve one-off bound methods
|
|
12
13
|
* **[shared-array-buffer](https://github.com/WebReflection/utils/tree/main/src#shared-array-buffer)** - to simulate *SAB* when not available
|
package/package.json
CHANGED
|
@@ -1,14 +1,20 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@webreflection/utils",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.11",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"types": {
|
|
6
|
+
"./all": "./types/all.d.ts",
|
|
6
7
|
"./bound-once": "./types/bound-once.d.ts",
|
|
7
8
|
"./bound": "./types/bound.d.ts",
|
|
8
9
|
"./shared-array-buffer": "./types/shared-array-buffer.d.ts",
|
|
10
|
+
"./sticky": "./types/sticky.d.ts",
|
|
9
11
|
"./with-resolvers": "./types/with-resolvers.d.ts"
|
|
10
12
|
},
|
|
11
13
|
"exports": {
|
|
14
|
+
"./all": {
|
|
15
|
+
"types": "./types/all.d.ts",
|
|
16
|
+
"import": "./src/all.js"
|
|
17
|
+
},
|
|
12
18
|
"./bound-once": {
|
|
13
19
|
"types": "./types/bound-once.d.ts",
|
|
14
20
|
"import": "./src/bound-once.js"
|
|
@@ -32,6 +38,7 @@
|
|
|
32
38
|
"./package.json": "./package.json"
|
|
33
39
|
},
|
|
34
40
|
"tests": [
|
|
41
|
+
"all",
|
|
35
42
|
"bound-once",
|
|
36
43
|
"bound",
|
|
37
44
|
"shared-array-buffer",
|
package/src/README.md
CHANGED
|
@@ -5,12 +5,36 @@ Each utility can be loaded from a *CDN* via either `https://esm.run/@webreflecti
|
|
|
5
5
|
|
|
6
6
|
This document describes each utility separately.
|
|
7
7
|
|
|
8
|
+
|
|
9
|
+
## all
|
|
10
|
+
|
|
11
|
+
A `Promise.all` companion with one extra convenience: when called with a
|
|
12
|
+
single object literal, it resolves each value and returns an object with the
|
|
13
|
+
same keys.
|
|
14
|
+
|
|
15
|
+
```js
|
|
16
|
+
import all from '@webreflection/all';
|
|
17
|
+
|
|
18
|
+
const user = await all({
|
|
19
|
+
name: fetchName(),
|
|
20
|
+
age: fetchAge()
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
// { name: 'Ada', age: 36 }
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
This preserves the shape and names of object-literal work, avoiding the
|
|
27
|
+
positional array juggling required by `Promise.all`. For arrays, or for two or
|
|
28
|
+
more arguments, it behaves like `Promise.all` and resolves to an array.
|
|
29
|
+
|
|
30
|
+
|
|
8
31
|
## bound-once
|
|
9
32
|
|
|
10
33
|
This is equivalent to **bound**, except each bound method is created only once. It is useful when bound method identity must be preserved across multiple calls.
|
|
11
34
|
|
|
12
35
|
This variant uses **sticky** to ensure that weakly referenced targets always produce the same bound method within the same realm.
|
|
13
36
|
|
|
37
|
+
|
|
14
38
|
## bound
|
|
15
39
|
|
|
16
40
|
This utility provides an object-destructuring syntax shortcut for binding methods.
|
|
@@ -33,6 +57,7 @@ This class can be used to simulate *SAB* capabilities.
|
|
|
33
57
|
|
|
34
58
|
The module exports both `SharedArrayBuffer` and `native`. The `native` *boolean* indicates whether the returned constructor is the platform implementation or the shim.
|
|
35
59
|
|
|
60
|
+
|
|
36
61
|
## sticky
|
|
37
62
|
|
|
38
63
|
Based on `Symbol.for(name)`, this utility helps modules that might be embedded multiple times across projects avoid conflicts in their internal logic. It preserves the assumption that a module is imported only *once* per application.
|
|
@@ -63,6 +88,8 @@ if (known) console.warn('embedded multiple times');
|
|
|
63
88
|
export default module;
|
|
64
89
|
```
|
|
65
90
|
|
|
91
|
+
Because the sticky logic is intentionally simple, using a "*first come, first served*" global symbol lookup, avoid storing sensitive values there directly when secrecy or module-level isolation matters.
|
|
92
|
+
|
|
66
93
|
|
|
67
94
|
## with-resolvers
|
|
68
95
|
|
package/src/all.js
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
// @ts-check
|
|
2
|
+
|
|
3
|
+
import bound from './bound.js';
|
|
4
|
+
|
|
5
|
+
const { isArray } = Array;
|
|
6
|
+
const { entries, fromEntries } = Object;
|
|
7
|
+
|
|
8
|
+
const { all, resolve } = bound(Promise);
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* @typedef {{
|
|
12
|
+
* <T extends object>(obj: T): Promise<{ [K in keyof T]: Awaited<T[K]> }>;
|
|
13
|
+
* <T extends unknown[]>(values: T): Promise<{ [K in keyof T]: Awaited<T[K]> }>;
|
|
14
|
+
* <T extends [unknown, unknown, ...unknown[]]>(...values: T): Promise<{ [K in keyof T]: Awaited<T[K]> }>;
|
|
15
|
+
* }} All
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* @param {unknown} obj
|
|
20
|
+
* @param {...unknown} rest
|
|
21
|
+
* @returns {Promise<unknown>}
|
|
22
|
+
*/
|
|
23
|
+
const values = (obj, ...rest) => {
|
|
24
|
+
// resolve all arguments passed along as array
|
|
25
|
+
if (rest.length)
|
|
26
|
+
return all([obj, ...rest]);
|
|
27
|
+
|
|
28
|
+
// resolve all entries in the array
|
|
29
|
+
if (isArray(obj))
|
|
30
|
+
return all(obj);
|
|
31
|
+
|
|
32
|
+
// resolve the object literal values re-mapping
|
|
33
|
+
// them as key-value pairs
|
|
34
|
+
for (const [k, v] of entries(/** @type {object} */ (obj)))
|
|
35
|
+
/** @type {Promise<[string, unknown]>[]} */(rest).push(resolve(v).then(v => [k, v]));
|
|
36
|
+
|
|
37
|
+
// return the object literal with the resolved values
|
|
38
|
+
return all(/** @type {Promise<[string, unknown]>[]} */(rest)).then(fromEntries);
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
export default /** @type {All} */(values);
|
package/types/all.d.ts
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
declare const _default: All;
|
|
2
|
+
export default _default;
|
|
3
|
+
export type All = {
|
|
4
|
+
<T extends object>(obj: T): Promise<{ [K in keyof T]: Awaited<T[K]>; }>;
|
|
5
|
+
<T extends unknown[]>(values: T): Promise<{ [K in keyof T]: Awaited<T[K]>; }>;
|
|
6
|
+
<T extends [unknown, unknown, ...unknown[]]>(...values: T): Promise<{ [K in keyof T]: Awaited<T[K]>; }>;
|
|
7
|
+
};
|