@azure-net/kit 1.2.6 → 1.3.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.
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { type AppError, createErrorParser } from './ErrorHandler.js';
|
|
2
2
|
export interface AsyncActionResponse<T, D = unknown, CustomErrorField = never> {
|
|
3
3
|
success: boolean;
|
|
4
4
|
response: T;
|
|
@@ -9,7 +9,7 @@ export declare const createAsyncHelpers: <Custom = unknown>(opts?: {
|
|
|
9
9
|
parseError?: ReturnType<typeof createErrorParser<Custom>>;
|
|
10
10
|
}) => {
|
|
11
11
|
createAsyncAction: <Res = unknown, Req = unknown>(action: ActionOrThunk<Res>, args?: {
|
|
12
|
-
beforeSend?: (abort: () => void) => void | Promise<void>;
|
|
12
|
+
beforeSend?: (next: () => void, abort: () => void) => void | Promise<void>;
|
|
13
13
|
onSuccess?: (result: AsyncActionResponse<Res, undefined, Custom>) => Promise<unknown> | unknown;
|
|
14
14
|
onError?: (result: AsyncActionResponse<never, Req, Custom>) => Promise<unknown> | unknown;
|
|
15
15
|
reject?: boolean;
|
|
@@ -20,7 +20,7 @@ export declare const createAsyncHelpers: <Custom = unknown>(opts?: {
|
|
|
20
20
|
fallbackResponse?: Res;
|
|
21
21
|
}) => Promise<AsyncActionResponse<Res, Req, Custom>>;
|
|
22
22
|
createAsyncResource: <Res, Req_1 = unknown>(action: ActionOrThunk<Res>, args?: {
|
|
23
|
-
beforeSend?: (abort: () => void) => void | Promise<void>;
|
|
23
|
+
beforeSend?: (next: () => void, abort: () => void) => void | Promise<void>;
|
|
24
24
|
onSuccess?: (result: Res) => Promise<unknown> | unknown;
|
|
25
25
|
onError?: (error: AppError<Req_1, Custom>) => Promise<unknown> | unknown;
|
|
26
26
|
reject?: boolean;
|
|
@@ -19,27 +19,28 @@ export const createAsyncHelpers = (opts) => {
|
|
|
19
19
|
};
|
|
20
20
|
}
|
|
21
21
|
if (args?.beforeSend) {
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
]).catch((err) => {
|
|
22
|
+
const beforeSendResult = await new Promise((resolve) => {
|
|
23
|
+
const next = () => resolve('next');
|
|
24
|
+
const abort = () => resolve('abort');
|
|
25
|
+
Promise.resolve(args.beforeSend(next, abort)).catch((err) => {
|
|
26
|
+
console.error('Error in beforeSend:', err);
|
|
27
|
+
resolve('abort');
|
|
28
|
+
});
|
|
29
|
+
});
|
|
30
|
+
if (beforeSendResult === 'abort') {
|
|
32
31
|
const abortError = {
|
|
33
32
|
type: 'abort',
|
|
34
33
|
message: 'Aborted in beforeSend',
|
|
35
|
-
original:
|
|
34
|
+
original: new Error('Aborted in beforeSend')
|
|
36
35
|
};
|
|
36
|
+
if (args?.reject)
|
|
37
|
+
throw abortError;
|
|
37
38
|
return {
|
|
38
39
|
success: false,
|
|
39
40
|
error: abortError,
|
|
40
41
|
response: args?.fallbackResponse
|
|
41
42
|
};
|
|
42
|
-
}
|
|
43
|
+
}
|
|
43
44
|
}
|
|
44
45
|
try {
|
|
45
46
|
const response = await Promise.resolve(typeof action === 'function' ? action() : action);
|
|
@@ -64,27 +65,25 @@ export const createAsyncHelpers = (opts) => {
|
|
|
64
65
|
return args.fallbackResponse;
|
|
65
66
|
}
|
|
66
67
|
if (args?.beforeSend) {
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
})
|
|
76
|
-
]).catch((err) => {
|
|
77
|
-
const abortError = {
|
|
78
|
-
type: 'abort',
|
|
79
|
-
message: 'Aborted in beforeSend',
|
|
80
|
-
original: err
|
|
81
|
-
};
|
|
82
|
-
return {
|
|
83
|
-
success: false,
|
|
84
|
-
error: abortError,
|
|
85
|
-
response: args?.fallbackResponse
|
|
86
|
-
};
|
|
68
|
+
const beforeSendResult = await new Promise((resolve) => {
|
|
69
|
+
const next = () => resolve('next');
|
|
70
|
+
const abort = () => resolve('abort');
|
|
71
|
+
Promise.resolve(args.beforeSend(next, abort)).catch((err) => {
|
|
72
|
+
console.error('Error in beforeSend:', err);
|
|
73
|
+
// If beforeSend throws, treat it as abort
|
|
74
|
+
resolve('abort');
|
|
75
|
+
});
|
|
87
76
|
});
|
|
77
|
+
if (beforeSendResult === 'abort') {
|
|
78
|
+
if (args?.reject) {
|
|
79
|
+
throw {
|
|
80
|
+
type: 'abort',
|
|
81
|
+
message: 'Aborted in beforeSend',
|
|
82
|
+
original: new Error('Aborted in beforeSend')
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
return args.fallbackResponse;
|
|
86
|
+
}
|
|
88
87
|
}
|
|
89
88
|
try {
|
|
90
89
|
const response = await Promise.resolve(typeof action === 'function' ? action() : action);
|
|
@@ -11,9 +11,11 @@ export interface ProviderWithType<T extends ServiceMap> {
|
|
|
11
11
|
type ProviderFactory<T extends ServiceMap, D extends Record<string, ProviderWithType<ServiceMap>>> = (context: {
|
|
12
12
|
[K in keyof D]: InferProviderType<D[K]>;
|
|
13
13
|
}) => T;
|
|
14
|
-
interface
|
|
14
|
+
export interface ProviderSettings<T extends ServiceMap, D extends Record<string, ProviderWithType<ServiceMap>>> {
|
|
15
15
|
dependsOn?: D;
|
|
16
|
+
boot?: (services: ResolvedServices<T>) => void | Promise<void>;
|
|
17
|
+
register: ProviderFactory<T, D>;
|
|
16
18
|
}
|
|
17
|
-
export declare const createBoundaryProvider: <T extends ServiceMap, D extends Record<string, ProviderWithType<ServiceMap>>>(name: string,
|
|
19
|
+
export declare const createBoundaryProvider: <T extends ServiceMap, D extends Record<string, ProviderWithType<ServiceMap>>>(name: string, settings: ProviderSettings<T, D>) => ProviderWithType<T>;
|
|
18
20
|
export declare function cleanupProvider(name: string): void;
|
|
19
21
|
export {};
|
|
@@ -3,6 +3,7 @@ import { EnvironmentUtil } from 'azure-net-tools';
|
|
|
3
3
|
const clientCache = new Map();
|
|
4
4
|
const factoriesCache = new WeakMap();
|
|
5
5
|
const providerProxyCache = new Map();
|
|
6
|
+
const clientBootFlags = new Map();
|
|
6
7
|
const getProviderCache = (providerName) => {
|
|
7
8
|
if (EnvironmentUtil.isBrowser) {
|
|
8
9
|
if (!clientCache.has(providerName)) {
|
|
@@ -26,8 +27,34 @@ const getProviderCache = (providerName) => {
|
|
|
26
27
|
return providers.get(providerName);
|
|
27
28
|
}
|
|
28
29
|
};
|
|
29
|
-
|
|
30
|
-
|
|
30
|
+
const getBootFlag = (providerName) => {
|
|
31
|
+
if (EnvironmentUtil.isBrowser) {
|
|
32
|
+
return clientBootFlags.get(providerName) ?? false;
|
|
33
|
+
}
|
|
34
|
+
else {
|
|
35
|
+
const context = RequestContext.current();
|
|
36
|
+
if (!context.data.bootFlags) {
|
|
37
|
+
context.data.bootFlags = new Map();
|
|
38
|
+
}
|
|
39
|
+
const bootFlags = context.data.bootFlags;
|
|
40
|
+
return bootFlags.get(providerName) ?? false;
|
|
41
|
+
}
|
|
42
|
+
};
|
|
43
|
+
const setBootFlag = (providerName, value) => {
|
|
44
|
+
if (EnvironmentUtil.isBrowser) {
|
|
45
|
+
clientBootFlags.set(providerName, value);
|
|
46
|
+
}
|
|
47
|
+
else {
|
|
48
|
+
const context = RequestContext.current();
|
|
49
|
+
if (!context.data.bootFlags) {
|
|
50
|
+
context.data.bootFlags = new Map();
|
|
51
|
+
}
|
|
52
|
+
const bootFlags = context.data.bootFlags;
|
|
53
|
+
bootFlags.set(providerName, value);
|
|
54
|
+
}
|
|
55
|
+
};
|
|
56
|
+
export const createBoundaryProvider = (name, settings) => {
|
|
57
|
+
const { dependsOn = {}, boot, register } = settings;
|
|
31
58
|
const providerFn = () => {
|
|
32
59
|
if (EnvironmentUtil.isBrowser && providerProxyCache.has(name)) {
|
|
33
60
|
return providerProxyCache.get(name);
|
|
@@ -37,8 +64,8 @@ export const createBoundaryProvider = (name, services, options) => {
|
|
|
37
64
|
const getFactories = () => {
|
|
38
65
|
if (factories)
|
|
39
66
|
return factories;
|
|
40
|
-
if (factoriesCache.has(
|
|
41
|
-
factories = factoriesCache.get(
|
|
67
|
+
if (factoriesCache.has(register)) {
|
|
68
|
+
factories = factoriesCache.get(register);
|
|
42
69
|
return factories;
|
|
43
70
|
}
|
|
44
71
|
const deps = {};
|
|
@@ -54,9 +81,9 @@ export const createBoundaryProvider = (name, services, options) => {
|
|
|
54
81
|
}
|
|
55
82
|
});
|
|
56
83
|
}
|
|
57
|
-
factories =
|
|
84
|
+
factories = register(deps);
|
|
58
85
|
if (EnvironmentUtil.isBrowser) {
|
|
59
|
-
factoriesCache.set(
|
|
86
|
+
factoriesCache.set(register, factories);
|
|
60
87
|
}
|
|
61
88
|
return factories;
|
|
62
89
|
};
|
|
@@ -90,6 +117,14 @@ export const createBoundaryProvider = (name, services, options) => {
|
|
|
90
117
|
if (EnvironmentUtil.isBrowser) {
|
|
91
118
|
providerProxyCache.set(name, providerProxy);
|
|
92
119
|
}
|
|
120
|
+
if (boot && !getBootFlag(name)) {
|
|
121
|
+
setBootFlag(name, true);
|
|
122
|
+
getFactories();
|
|
123
|
+
const bootResult = boot(providerProxy);
|
|
124
|
+
if (bootResult instanceof Promise) {
|
|
125
|
+
bootResult.catch((err) => console.error(`Error in boot for provider '${name}':`, err));
|
|
126
|
+
}
|
|
127
|
+
}
|
|
93
128
|
return providerProxy;
|
|
94
129
|
};
|
|
95
130
|
return providerFn;
|
|
@@ -114,6 +149,7 @@ export function cleanupProvider(name) {
|
|
|
114
149
|
void cleanupCache(cache);
|
|
115
150
|
}
|
|
116
151
|
providerProxyCache.delete(name);
|
|
152
|
+
clientBootFlags.delete(name);
|
|
117
153
|
}
|
|
118
154
|
else {
|
|
119
155
|
const context = RequestContext.current();
|