applesauce-loaders 5.0.2 → 5.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/helpers/async-map.d.ts +24 -0
- package/dist/helpers/async-map.js +64 -0
- package/dist/helpers/index.d.ts +3 -2
- package/dist/helpers/index.js +3 -2
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
A collection of functional loading methods to make common event loading patterns easier.
|
|
4
4
|
|
|
5
|
-
[Documentation](https://
|
|
5
|
+
[Documentation](https://applesauce.build/loaders/package.html) [typedoc](https://applesauce.build/typedoc/modules/applesauce-loaders.html)
|
|
6
6
|
|
|
7
7
|
## Address Loader
|
|
8
8
|
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Resolves multiple promises concurrently, similar to RxJS combineLatest but for async operations.
|
|
3
|
+
* Each promise races against the provided timeout. If a promise doesn't resolve within the timeout,
|
|
4
|
+
* its value will be `undefined` in the returned object.
|
|
5
|
+
*
|
|
6
|
+
* @param map - An object where each value is a Promise
|
|
7
|
+
* @param timeout - Global timeout in milliseconds for all fields. If a field doesn't resolve within this time, it will be `undefined`
|
|
8
|
+
* @returns A promise that resolves to an object with the same keys, where each value is either the resolved value or `undefined`
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
* ```ts
|
|
12
|
+
* const { profile, mailboxes, notes } = await loadAsyncMap(
|
|
13
|
+
* {
|
|
14
|
+
* profile: user.profile$.$first(),
|
|
15
|
+
* mailboxes: user.mailboxes$.$first(1000),
|
|
16
|
+
* notes: lastValueFrom(someObservable),
|
|
17
|
+
* },
|
|
18
|
+
* 30 * 1000, // 30 second timeout
|
|
19
|
+
* );
|
|
20
|
+
* ```
|
|
21
|
+
*/
|
|
22
|
+
export declare function loadAsyncMap<T extends Record<string, Promise<any>>>(map: T, timeout: number): Promise<{
|
|
23
|
+
[K in keyof T]: Awaited<T[K]> | undefined;
|
|
24
|
+
}>;
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Resolves multiple promises concurrently, similar to RxJS combineLatest but for async operations.
|
|
3
|
+
* Each promise races against the provided timeout. If a promise doesn't resolve within the timeout,
|
|
4
|
+
* its value will be `undefined` in the returned object.
|
|
5
|
+
*
|
|
6
|
+
* @param map - An object where each value is a Promise
|
|
7
|
+
* @param timeout - Global timeout in milliseconds for all fields. If a field doesn't resolve within this time, it will be `undefined`
|
|
8
|
+
* @returns A promise that resolves to an object with the same keys, where each value is either the resolved value or `undefined`
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
* ```ts
|
|
12
|
+
* const { profile, mailboxes, notes } = await loadAsyncMap(
|
|
13
|
+
* {
|
|
14
|
+
* profile: user.profile$.$first(),
|
|
15
|
+
* mailboxes: user.mailboxes$.$first(1000),
|
|
16
|
+
* notes: lastValueFrom(someObservable),
|
|
17
|
+
* },
|
|
18
|
+
* 30 * 1000, // 30 second timeout
|
|
19
|
+
* );
|
|
20
|
+
* ```
|
|
21
|
+
*/
|
|
22
|
+
export async function loadAsyncMap(map, timeout) {
|
|
23
|
+
// Create a timeout promise that resolves with a special marker after the timeout
|
|
24
|
+
const TIMEOUT_MARKER = Symbol("timeout");
|
|
25
|
+
const createTimeoutPromise = () => {
|
|
26
|
+
return new Promise((resolve) => {
|
|
27
|
+
setTimeout(() => resolve(TIMEOUT_MARKER), timeout);
|
|
28
|
+
});
|
|
29
|
+
};
|
|
30
|
+
// Race each promise against the timeout
|
|
31
|
+
// If the promise resolves first, use its value
|
|
32
|
+
// If the timeout happens first, use undefined
|
|
33
|
+
// If the promise rejects, catch it and return undefined
|
|
34
|
+
const entries = Object.entries(map);
|
|
35
|
+
const results = await Promise.allSettled(entries.map(async ([key, promise]) => {
|
|
36
|
+
// Wrap promise to handle rejections gracefully and prevent unhandled rejections
|
|
37
|
+
const safePromise = promise
|
|
38
|
+
.then((value) => ({ type: "resolved", value }))
|
|
39
|
+
.catch(() => ({ type: "rejected" }));
|
|
40
|
+
const result = await Promise.race([
|
|
41
|
+
safePromise,
|
|
42
|
+
createTimeoutPromise().then(() => ({ type: "timeout" })),
|
|
43
|
+
]);
|
|
44
|
+
if (result.type === "timeout" || result.type === "rejected") {
|
|
45
|
+
return [key, undefined];
|
|
46
|
+
}
|
|
47
|
+
else {
|
|
48
|
+
return [key, result.value];
|
|
49
|
+
}
|
|
50
|
+
}));
|
|
51
|
+
// Extract values from settled results, defaulting to undefined if anything went wrong
|
|
52
|
+
const extractedResults = results.map((settled, index) => {
|
|
53
|
+
if (settled.status === "fulfilled") {
|
|
54
|
+
return settled.value;
|
|
55
|
+
}
|
|
56
|
+
else {
|
|
57
|
+
// If the outer promise somehow rejected, return undefined for that key
|
|
58
|
+
const key = entries[index][0];
|
|
59
|
+
return [key, undefined];
|
|
60
|
+
}
|
|
61
|
+
});
|
|
62
|
+
// Reconstruct the object with the same keys
|
|
63
|
+
return Object.fromEntries(extractedResults);
|
|
64
|
+
}
|
package/dist/helpers/index.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
export * from "./
|
|
1
|
+
export * from "./address-pointer.js";
|
|
2
|
+
export * from "./async-map.js";
|
|
2
3
|
export * from "./cache.js";
|
|
4
|
+
export * from "./dns-identity.js";
|
|
3
5
|
export * from "./event-pointer.js";
|
|
4
|
-
export * from "./address-pointer.js";
|
|
5
6
|
export * from "./loaders.js";
|
|
6
7
|
export * from "./upstream.js";
|
package/dist/helpers/index.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
export * from "./
|
|
1
|
+
export * from "./address-pointer.js";
|
|
2
|
+
export * from "./async-map.js";
|
|
2
3
|
export * from "./cache.js";
|
|
4
|
+
export * from "./dns-identity.js";
|
|
3
5
|
export * from "./event-pointer.js";
|
|
4
|
-
export * from "./address-pointer.js";
|
|
5
6
|
export * from "./loaders.js";
|
|
6
7
|
export * from "./upstream.js";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "applesauce-loaders",
|
|
3
|
-
"version": "5.0
|
|
3
|
+
"version": "5.1.0",
|
|
4
4
|
"description": "A collection of observable based loaders built on rx-nostr",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -52,13 +52,13 @@
|
|
|
52
52
|
}
|
|
53
53
|
},
|
|
54
54
|
"dependencies": {
|
|
55
|
-
"applesauce-core": "^5.
|
|
55
|
+
"applesauce-core": "^5.1.0",
|
|
56
56
|
"nanoid": "^5.0.9",
|
|
57
57
|
"rxjs": "^7.8.1"
|
|
58
58
|
},
|
|
59
59
|
"devDependencies": {
|
|
60
60
|
"@hirez_io/observer-spy": "^2.2.0",
|
|
61
|
-
"applesauce-signers": "^5.
|
|
61
|
+
"applesauce-signers": "^5.1.0",
|
|
62
62
|
"rimraf": "^6.0.1",
|
|
63
63
|
"typescript": "^5.8.3",
|
|
64
64
|
"vitest": "^4.0.15",
|