@azure-net/kit 3.0.4 → 3.0.5
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,15 +1,23 @@
|
|
|
1
1
|
import type { RequestErrors } from '../../delivery/schema/index.js';
|
|
2
2
|
import type { AsyncActionResponse } from '../../index.js';
|
|
3
|
-
type InitialData<FormData
|
|
4
|
-
|
|
5
|
-
|
|
3
|
+
type InitialData<FormData, Initial extends Partial<FormData>> = Initial | Promise<Initial> | (() => Initial | Promise<Initial>);
|
|
4
|
+
type PathRequiredShape<T, P extends string> = P extends `${infer Head}.${infer Tail}` ? Head extends keyof T ? {
|
|
5
|
+
[K in Head]-?: PathRequiredShape<NonNullable<T[K]>, Tail>;
|
|
6
|
+
} : unknown : P extends keyof T ? {
|
|
7
|
+
[K in P]-?: NonNullable<T[K]>;
|
|
8
|
+
} : unknown;
|
|
9
|
+
type UnionToIntersection<U> = (U extends unknown ? (arg: U) => void : never) extends (arg: infer I) => void ? I : never;
|
|
10
|
+
type RequiredByPaths<T, P extends string> = [P] extends [never] ? {} : UnionToIntersection<PathRequiredShape<T, P>>;
|
|
11
|
+
export interface FormConfig<FormData, Response, Initial extends Partial<FormData> = Partial<FormData>, RequiredPath extends string = never> {
|
|
12
|
+
initialData?: InitialData<FormData, Initial>;
|
|
13
|
+
required?: readonly RequiredPath[];
|
|
6
14
|
onSuccess?: (response: Response) => Promise<void> | void;
|
|
7
15
|
onError?: () => Promise<void> | void;
|
|
8
|
-
beforeSubmit?: (form: ActiveFormController<FormData>, abort: () => void) => Promise<void> | void;
|
|
16
|
+
beforeSubmit?: (form: ActiveFormController<FormData, RequiredPath>, abort: () => void) => Promise<void> | void;
|
|
9
17
|
waitForInitialData?: boolean;
|
|
10
18
|
}
|
|
11
|
-
export interface ActiveForm<FormData, Response, Custom> {
|
|
12
|
-
data: Partial<FormData>;
|
|
19
|
+
export interface ActiveForm<FormData, Response, Custom, RequiredPath extends string = never> {
|
|
20
|
+
data: Partial<FormData> & RequiredByPaths<FormData, RequiredPath>;
|
|
13
21
|
errors: RequestErrors<FormData>;
|
|
14
22
|
submit: () => Promise<AsyncActionResponse<Response, FormData, Custom>>;
|
|
15
23
|
reset: (toInitial?: boolean) => void;
|
|
@@ -17,8 +25,8 @@ export interface ActiveForm<FormData, Response, Custom> {
|
|
|
17
25
|
dirty: boolean;
|
|
18
26
|
ready: Promise<Partial<FormData>>;
|
|
19
27
|
}
|
|
20
|
-
export interface ActiveFormController<FormData> {
|
|
21
|
-
data: Partial<FormData>;
|
|
28
|
+
export interface ActiveFormController<FormData, RequiredPath extends string = never> {
|
|
29
|
+
data: Partial<FormData> & RequiredByPaths<FormData, RequiredPath>;
|
|
22
30
|
errors: RequestErrors<FormData>;
|
|
23
31
|
reset: (toInitial?: boolean) => void;
|
|
24
32
|
}
|
|
@@ -31,5 +39,5 @@ type ExtractFromSubmit<T> = {
|
|
|
31
39
|
formData: ExtractFormData<UnwrapPromise<T>>;
|
|
32
40
|
custom: ExtractCustom<UnwrapPromise<T>>;
|
|
33
41
|
};
|
|
34
|
-
export declare const createActiveForm: <SubmitReturn extends Promise<AsyncActionResponse<unknown, unknown, unknown
|
|
42
|
+
export declare const createActiveForm: <SubmitReturn extends Promise<AsyncActionResponse<unknown, unknown, unknown>>, RequiredPath extends string = never>(onSubmit: (formData: Partial<ExtractFromSubmit<SubmitReturn>["formData"]>) => SubmitReturn, config?: FormConfig<ExtractFromSubmit<SubmitReturn>["formData"], ExtractFromSubmit<SubmitReturn>["response"], Partial<ExtractFromSubmit<SubmitReturn>["formData"]>, RequiredPath>) => ActiveForm<ExtractFromSubmit<SubmitReturn>["formData"], ExtractFromSubmit<SubmitReturn>["response"], ExtractFromSubmit<SubmitReturn>["custom"], RequiredPath>;
|
|
35
43
|
export {};
|
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
export type AsyncStatus = 'idle' | 'pending' | 'success' | 'error';
|
|
2
|
+
export type AsyncSignalSource = 'auto' | 'manual' | 'global';
|
|
2
3
|
export interface AsyncSignalOptions<TData, TError = Error> {
|
|
3
4
|
server?: boolean;
|
|
4
5
|
immediate?: boolean;
|
|
5
6
|
watch?: (() => unknown)[];
|
|
6
|
-
initialData?: TData;
|
|
7
|
+
initialData?: TData | (() => TData);
|
|
7
8
|
beforeSend?: (meta: {
|
|
8
9
|
initial: boolean;
|
|
9
|
-
|
|
10
|
+
source: AsyncSignalSource;
|
|
10
11
|
}) => void | Promise<void>;
|
|
11
12
|
onSuccess?: (data: TData) => void | Promise<void>;
|
|
12
13
|
onError?: (error: TError) => void | Promise<void>;
|
|
@@ -25,7 +25,7 @@ const createAsyncSignalManager = () => {
|
|
|
25
25
|
if (instances) {
|
|
26
26
|
const instance = instances.get(key);
|
|
27
27
|
try {
|
|
28
|
-
await instance?.();
|
|
28
|
+
await instance?.('global');
|
|
29
29
|
}
|
|
30
30
|
catch {
|
|
31
31
|
return;
|
|
@@ -35,7 +35,7 @@ const createAsyncSignalManager = () => {
|
|
|
35
35
|
const refreshAll = async () => {
|
|
36
36
|
if (instances) {
|
|
37
37
|
try {
|
|
38
|
-
await Promise.all(instances.values().map((val) => val()));
|
|
38
|
+
await Promise.all(instances.values().map((val) => val('global')));
|
|
39
39
|
}
|
|
40
40
|
catch {
|
|
41
41
|
return;
|
|
@@ -47,7 +47,8 @@ const createAsyncSignalManager = () => {
|
|
|
47
47
|
const asyncSignalManager = createAsyncSignalManager();
|
|
48
48
|
export const createAsyncSignal = (handler, options = {}) => {
|
|
49
49
|
const { server = false, immediate = true, watch = [], initialData = undefined, key } = options;
|
|
50
|
-
|
|
50
|
+
const resolvedInitialData = typeof initialData === 'function' ? initialData() : initialData;
|
|
51
|
+
let data = $state(resolvedInitialData);
|
|
51
52
|
let error = $state();
|
|
52
53
|
let status = $state('idle');
|
|
53
54
|
const pending = $derived(status === 'pending');
|
|
@@ -55,7 +56,7 @@ export const createAsyncSignal = (handler, options = {}) => {
|
|
|
55
56
|
let currentPromise = null;
|
|
56
57
|
let currentRunId = 0;
|
|
57
58
|
let started = false;
|
|
58
|
-
const run = async (runId,
|
|
59
|
+
const run = async (runId, source) => {
|
|
59
60
|
const initial = !started;
|
|
60
61
|
started = true;
|
|
61
62
|
if (abortController) {
|
|
@@ -63,7 +64,7 @@ export const createAsyncSignal = (handler, options = {}) => {
|
|
|
63
64
|
}
|
|
64
65
|
abortController = new AbortController();
|
|
65
66
|
if (options.beforeSend) {
|
|
66
|
-
await options.beforeSend({ initial,
|
|
67
|
+
await options.beforeSend({ initial, source });
|
|
67
68
|
}
|
|
68
69
|
status = 'pending';
|
|
69
70
|
error = undefined;
|
|
@@ -96,12 +97,12 @@ export const createAsyncSignal = (handler, options = {}) => {
|
|
|
96
97
|
}
|
|
97
98
|
}
|
|
98
99
|
};
|
|
99
|
-
const start = (
|
|
100
|
+
const start = (source) => {
|
|
100
101
|
if (currentPromise) {
|
|
101
102
|
return currentPromise;
|
|
102
103
|
}
|
|
103
104
|
const runId = ++currentRunId;
|
|
104
|
-
const localPromise = run(runId,
|
|
105
|
+
const localPromise = run(runId, source);
|
|
105
106
|
currentPromise = localPromise;
|
|
106
107
|
return localPromise;
|
|
107
108
|
};
|
|
@@ -110,11 +111,13 @@ export const createAsyncSignal = (handler, options = {}) => {
|
|
|
110
111
|
await currentPromise;
|
|
111
112
|
return;
|
|
112
113
|
}
|
|
113
|
-
await start(
|
|
114
|
+
await start('manual');
|
|
114
115
|
};
|
|
115
116
|
if (EnvironmentUtil.isBrowser) {
|
|
116
117
|
const signalKey = key ?? asyncSignalManager.generateKey();
|
|
117
|
-
asyncSignalManager.register(signalKey, () =>
|
|
118
|
+
asyncSignalManager.register(signalKey, (source) => {
|
|
119
|
+
return start(source);
|
|
120
|
+
});
|
|
118
121
|
$effect(() => {
|
|
119
122
|
return () => {
|
|
120
123
|
asyncSignalManager.unregister(signalKey);
|
|
@@ -129,7 +132,7 @@ export const createAsyncSignal = (handler, options = {}) => {
|
|
|
129
132
|
return;
|
|
130
133
|
}
|
|
131
134
|
if (!isFirst) {
|
|
132
|
-
void start(
|
|
135
|
+
void start('auto');
|
|
133
136
|
}
|
|
134
137
|
isFirst = false;
|
|
135
138
|
});
|
|
@@ -138,11 +141,11 @@ export const createAsyncSignal = (handler, options = {}) => {
|
|
|
138
141
|
if (immediate) {
|
|
139
142
|
if (EnvironmentUtil.isServer && server) {
|
|
140
143
|
untrack(() => {
|
|
141
|
-
void start(
|
|
144
|
+
void start('auto');
|
|
142
145
|
});
|
|
143
146
|
}
|
|
144
147
|
else if (EnvironmentUtil.isBrowser) {
|
|
145
|
-
void start(
|
|
148
|
+
void start('auto');
|
|
146
149
|
}
|
|
147
150
|
}
|
|
148
151
|
return {
|
|
@@ -161,7 +164,7 @@ export const createAsyncSignal = (handler, options = {}) => {
|
|
|
161
164
|
get ready() {
|
|
162
165
|
if (currentPromise)
|
|
163
166
|
return currentPromise;
|
|
164
|
-
return start(
|
|
167
|
+
return start('auto');
|
|
165
168
|
},
|
|
166
169
|
execute,
|
|
167
170
|
refresh: execute,
|