@diphyx/harlemify 4.0.1 → 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 +30 -44
- package/dist/module.d.mts +5 -0
- package/dist/module.d.ts +5 -0
- package/dist/module.json +1 -1
- package/dist/runtime/composables/action.d.ts +16 -3
- package/dist/runtime/composables/action.js +47 -3
- package/dist/runtime/composables/model.d.ts +22 -0
- package/dist/runtime/composables/model.js +32 -0
- package/dist/runtime/composables/view.d.ts +33 -0
- package/dist/runtime/composables/view.js +54 -0
- package/dist/runtime/core/layers/action.d.ts +3 -2
- package/dist/runtime/core/layers/action.js +37 -69
- package/dist/runtime/core/layers/model.js +14 -0
- package/dist/runtime/core/layers/shape.d.ts +2 -2
- package/dist/runtime/core/layers/shape.js +3 -2
- package/dist/runtime/core/layers/view.d.ts +2 -2
- package/dist/runtime/core/layers/view.js +27 -5
- package/dist/runtime/core/store.d.ts +5 -23
- package/dist/runtime/core/store.js +8 -28
- package/dist/runtime/core/types/action.d.ts +79 -121
- package/dist/runtime/core/types/action.js +0 -16
- package/dist/runtime/core/types/base.d.ts +6 -0
- package/dist/runtime/core/types/base.js +0 -0
- package/dist/runtime/core/types/model.d.ts +47 -32
- package/dist/runtime/core/types/model.js +14 -0
- package/dist/runtime/core/types/shape.d.ts +30 -5
- package/dist/runtime/core/types/store.d.ts +14 -0
- package/dist/runtime/core/types/store.js +0 -0
- package/dist/runtime/core/types/view.d.ts +35 -24
- package/dist/runtime/core/types/view.js +5 -0
- package/dist/runtime/core/utils/action.d.ts +4 -4
- package/dist/runtime/core/utils/action.js +217 -207
- package/dist/runtime/core/utils/base.d.ts +14 -0
- package/dist/runtime/core/utils/base.js +109 -0
- package/dist/runtime/core/utils/error.d.ts +21 -0
- package/dist/runtime/core/utils/error.js +36 -0
- package/dist/runtime/core/utils/model.d.ts +3 -11
- package/dist/runtime/core/utils/model.js +104 -110
- package/dist/runtime/core/utils/shape.d.ts +6 -3
- package/dist/runtime/core/utils/shape.js +218 -14
- package/dist/runtime/core/utils/store.d.ts +8 -0
- package/dist/runtime/core/utils/store.js +35 -0
- package/dist/runtime/core/utils/view.d.ts +3 -4
- package/dist/runtime/core/utils/view.js +35 -14
- package/dist/runtime/index.d.ts +14 -5
- package/dist/runtime/index.js +7 -10
- package/package.json +2 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type
|
|
2
|
-
import type {
|
|
3
|
-
|
|
4
|
-
export declare function createAction<
|
|
1
|
+
import { type StoreModel, type ModelDefinitions } from "../types/model.js";
|
|
2
|
+
import type { StoreView, ViewDefinitions } from "../types/view.js";
|
|
3
|
+
import { type ActionCall, type ActionDefinition } from "../types/action.js";
|
|
4
|
+
export declare function createAction<MD extends ModelDefinitions, VD extends ViewDefinitions<MD>, R>(definition: ActionDefinition<MD, VD>, model: StoreModel<MD>, view: StoreView<MD, VD>): ActionCall<R>;
|
|
@@ -3,263 +3,277 @@ import { ref, computed, readonly, toValue, nextTick } from "vue";
|
|
|
3
3
|
import {
|
|
4
4
|
ActionApiMethod,
|
|
5
5
|
ActionStatus,
|
|
6
|
-
ActionConcurrent
|
|
7
|
-
DEFINITION
|
|
6
|
+
ActionConcurrent
|
|
8
7
|
} from "../types/action.js";
|
|
9
|
-
import {
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
8
|
+
import { trimStart, trimEnd, isEmptyRecord, isPlainObject } from "./base.js";
|
|
9
|
+
import {
|
|
10
|
+
ActionApiError,
|
|
11
|
+
ActionHandlerError,
|
|
12
|
+
ActionCommitError,
|
|
13
|
+
ActionConcurrentError,
|
|
14
|
+
isError,
|
|
15
|
+
toError
|
|
16
|
+
} from "./error.js";
|
|
17
|
+
import { resolveAliasInbound, resolveAliasOutbound } from "./shape.js";
|
|
18
|
+
function resolveValue(value, view, fallback) {
|
|
19
|
+
if (typeof value === "function") {
|
|
20
|
+
return value(view) || fallback;
|
|
17
21
|
}
|
|
22
|
+
return toValue(value) || fallback;
|
|
18
23
|
}
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
+
function resolveApiUrl(definition, view, options) {
|
|
25
|
+
const endpoint = trimEnd(definition.request.endpoint ?? "", "/");
|
|
26
|
+
let path = resolveValue(definition.request.url, view);
|
|
27
|
+
if (options?.params) {
|
|
28
|
+
for (const [key, value] of Object.entries(options.params)) {
|
|
29
|
+
path = path.replace(`:${key}`, encodeURIComponent(value));
|
|
30
|
+
}
|
|
24
31
|
}
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
name = "ActionCommitError";
|
|
28
|
-
constructor(cause) {
|
|
29
|
-
super(cause.message);
|
|
30
|
-
this.cause = cause;
|
|
32
|
+
if (endpoint) {
|
|
33
|
+
return `${endpoint}/${trimStart(path, "/")}`;
|
|
31
34
|
}
|
|
35
|
+
return path;
|
|
32
36
|
}
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
+
function resolveApiHeaders(definition, view, options) {
|
|
38
|
+
const initial = resolveValue(definition.request.headers, view, {});
|
|
39
|
+
const custom = options?.headers ?? {};
|
|
40
|
+
return defu(custom, initial);
|
|
41
|
+
}
|
|
42
|
+
function resolveApiQuery(definition, view, options) {
|
|
43
|
+
const initial = resolveValue(definition.request.query, view, {});
|
|
44
|
+
const custom = options?.query ?? {};
|
|
45
|
+
return defu(custom, initial);
|
|
46
|
+
}
|
|
47
|
+
function resolveApiBody(definition, view, target, options) {
|
|
48
|
+
if (definition.request.method === ActionApiMethod.GET || definition.request.method === ActionApiMethod.HEAD) {
|
|
49
|
+
return void 0;
|
|
50
|
+
}
|
|
51
|
+
const initial = resolveValue(definition.request.body, view, {});
|
|
52
|
+
const custom = options?.body ?? {};
|
|
53
|
+
const body = defu(custom, initial);
|
|
54
|
+
if (!isPlainObject(body)) {
|
|
55
|
+
return body;
|
|
37
56
|
}
|
|
57
|
+
if (!isEmptyRecord(target?.aliases())) {
|
|
58
|
+
return resolveAliasOutbound(body, target.aliases());
|
|
59
|
+
}
|
|
60
|
+
return body;
|
|
38
61
|
}
|
|
39
|
-
function
|
|
40
|
-
return
|
|
62
|
+
function resolveApiMethod(definition, view) {
|
|
63
|
+
return resolveValue(definition.request.method, view, ActionApiMethod.GET);
|
|
41
64
|
}
|
|
42
|
-
function
|
|
43
|
-
|
|
65
|
+
function resolveApiTimeout(definition, view, options) {
|
|
66
|
+
if (options?.timeout) {
|
|
67
|
+
return options.timeout;
|
|
68
|
+
}
|
|
69
|
+
if (definition.request.timeout) {
|
|
70
|
+
return resolveValue(definition.request.timeout, view);
|
|
71
|
+
}
|
|
72
|
+
return void 0;
|
|
44
73
|
}
|
|
45
|
-
function
|
|
46
|
-
|
|
74
|
+
function resolveApiSignal(options, abortController) {
|
|
75
|
+
if (options?.signal) {
|
|
76
|
+
return options.signal;
|
|
77
|
+
}
|
|
78
|
+
return abortController.signal;
|
|
47
79
|
}
|
|
48
|
-
function
|
|
49
|
-
|
|
80
|
+
function resolveCommitTarget(commit, model) {
|
|
81
|
+
if (commit) {
|
|
82
|
+
return model[commit.model];
|
|
83
|
+
}
|
|
84
|
+
return void 0;
|
|
50
85
|
}
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
model,
|
|
58
|
-
mode,
|
|
59
|
-
value,
|
|
60
|
-
options
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
};
|
|
86
|
+
function resolveCommitMode(commit, options) {
|
|
87
|
+
if (commit) {
|
|
88
|
+
if (options?.commit?.mode) {
|
|
89
|
+
return options.commit.mode;
|
|
90
|
+
}
|
|
91
|
+
return commit.mode;
|
|
64
92
|
}
|
|
65
|
-
return
|
|
93
|
+
return void 0;
|
|
66
94
|
}
|
|
67
|
-
function
|
|
68
|
-
if (typeof value === "function") {
|
|
69
|
-
|
|
70
|
-
return handler(view) || fallback;
|
|
95
|
+
function resolveCommitValue(commit, data) {
|
|
96
|
+
if (typeof commit.value === "function") {
|
|
97
|
+
return commit.value(data);
|
|
71
98
|
}
|
|
72
|
-
return
|
|
99
|
+
return data;
|
|
73
100
|
}
|
|
74
|
-
function
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
101
|
+
function isApiDefinition(definition) {
|
|
102
|
+
return "request" in definition;
|
|
103
|
+
}
|
|
104
|
+
function resolveConcurrent(definition, options) {
|
|
105
|
+
if (options?.concurrent) {
|
|
106
|
+
return options.concurrent;
|
|
79
107
|
}
|
|
80
|
-
|
|
108
|
+
if (isApiDefinition(definition) && definition.request.concurrent) {
|
|
109
|
+
return definition.request.concurrent;
|
|
110
|
+
}
|
|
111
|
+
return ActionConcurrent.BLOCK;
|
|
81
112
|
}
|
|
82
|
-
function
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
113
|
+
async function executeApi(definition, api, options) {
|
|
114
|
+
try {
|
|
115
|
+
definition.logger?.debug("Action API request", {
|
|
116
|
+
action: definition.key,
|
|
117
|
+
method: api.method,
|
|
118
|
+
url: api.url
|
|
119
|
+
});
|
|
120
|
+
if (options?.transformer?.request) {
|
|
121
|
+
api = options.transformer.request(api);
|
|
122
|
+
}
|
|
123
|
+
const response = await $fetch(api.url, {
|
|
124
|
+
method: api.method,
|
|
125
|
+
headers: api.headers,
|
|
126
|
+
query: api.query,
|
|
127
|
+
body: api.body,
|
|
128
|
+
timeout: api.timeout,
|
|
129
|
+
signal: api.signal,
|
|
130
|
+
responseType: "json"
|
|
131
|
+
});
|
|
132
|
+
definition.logger?.debug("Action API response received", {
|
|
133
|
+
action: definition.key,
|
|
134
|
+
method: api.method,
|
|
135
|
+
url: api.url
|
|
136
|
+
});
|
|
137
|
+
if (options?.transformer?.response) {
|
|
138
|
+
return options.transformer.response(response);
|
|
139
|
+
}
|
|
140
|
+
return response;
|
|
141
|
+
} catch (error) {
|
|
142
|
+
const fetchError = toError(error, ActionApiError);
|
|
143
|
+
definition.logger?.error("Action API error", {
|
|
144
|
+
action: definition.key,
|
|
145
|
+
error: fetchError.message
|
|
146
|
+
});
|
|
147
|
+
throw fetchError;
|
|
148
|
+
}
|
|
86
149
|
}
|
|
87
|
-
function
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
150
|
+
async function executeHandler(definition, model, view) {
|
|
151
|
+
try {
|
|
152
|
+
definition.logger?.debug("Action handler phase", {
|
|
153
|
+
action: definition.key
|
|
154
|
+
});
|
|
155
|
+
return await definition.callback({
|
|
156
|
+
model,
|
|
157
|
+
view
|
|
158
|
+
});
|
|
159
|
+
} catch (error) {
|
|
160
|
+
if (isError(error, ActionApiError, ActionHandlerError)) {
|
|
161
|
+
throw error;
|
|
162
|
+
}
|
|
163
|
+
const handlerError = toError(error, ActionHandlerError);
|
|
164
|
+
definition.logger?.error("Action handler error", {
|
|
165
|
+
action: definition.key,
|
|
166
|
+
error: handlerError.message
|
|
167
|
+
});
|
|
168
|
+
throw handlerError;
|
|
169
|
+
}
|
|
91
170
|
}
|
|
92
|
-
function
|
|
93
|
-
if (definition.
|
|
94
|
-
return
|
|
171
|
+
function executeCommit(definition, target, mode, data) {
|
|
172
|
+
if (!definition.commit) {
|
|
173
|
+
return;
|
|
174
|
+
}
|
|
175
|
+
if (!target || !mode) {
|
|
176
|
+
throw new ActionCommitError({
|
|
177
|
+
message: `Model "${definition.commit.model}" is not defined`
|
|
178
|
+
});
|
|
179
|
+
}
|
|
180
|
+
try {
|
|
181
|
+
definition.logger?.debug("Action commit phase", {
|
|
182
|
+
action: definition.key,
|
|
183
|
+
target,
|
|
184
|
+
mode
|
|
185
|
+
});
|
|
186
|
+
if (!isEmptyRecord(target.aliases())) {
|
|
187
|
+
data = resolveAliasInbound(data, target.aliases());
|
|
188
|
+
}
|
|
189
|
+
const value = resolveCommitValue(definition.commit, data);
|
|
190
|
+
target.commit(mode, value, definition.commit.options);
|
|
191
|
+
} catch (error) {
|
|
192
|
+
const commitError = toError(error, ActionCommitError);
|
|
193
|
+
definition.logger?.error("Action commit error", {
|
|
194
|
+
action: definition.key,
|
|
195
|
+
error: commitError.message
|
|
196
|
+
});
|
|
197
|
+
throw commitError;
|
|
95
198
|
}
|
|
96
|
-
const initial = resolveApiValue(definition.body, view, {});
|
|
97
|
-
const custom = resolveApiValue(payload?.body, view, {});
|
|
98
|
-
return defu(custom, initial);
|
|
99
199
|
}
|
|
100
|
-
export function createAction(definition,
|
|
200
|
+
export function createAction(definition, model, view) {
|
|
201
|
+
definition.logger?.debug("Registering action", {
|
|
202
|
+
action: definition.key,
|
|
203
|
+
type: isApiDefinition(definition) ? "api" : "handler"
|
|
204
|
+
});
|
|
205
|
+
let currentController = null;
|
|
206
|
+
let abortController = null;
|
|
101
207
|
const globalError = ref(null);
|
|
102
208
|
const globalStatus = ref(ActionStatus.IDLE);
|
|
103
209
|
const loading = computed(() => {
|
|
104
210
|
return globalStatus.value === ActionStatus.PENDING;
|
|
105
211
|
});
|
|
106
|
-
|
|
107
|
-
let currentController = null;
|
|
108
|
-
let abortController = null;
|
|
109
|
-
async function execute(payload) {
|
|
212
|
+
async function execute(options) {
|
|
110
213
|
await nextTick();
|
|
214
|
+
const concurrent = resolveConcurrent(definition, options);
|
|
111
215
|
if (loading.value) {
|
|
112
|
-
const concurrent = payload?.concurrent ?? definition.api?.concurrent ?? ActionConcurrent.BLOCK;
|
|
113
216
|
switch (concurrent) {
|
|
114
217
|
case ActionConcurrent.BLOCK: {
|
|
115
218
|
definition.logger?.error("Action blocked by concurrent guard", {
|
|
116
|
-
action: key
|
|
219
|
+
action: definition.key
|
|
117
220
|
});
|
|
118
|
-
throw
|
|
221
|
+
throw new ActionConcurrentError();
|
|
119
222
|
}
|
|
120
223
|
case ActionConcurrent.SKIP: {
|
|
121
224
|
definition.logger?.warn("Action skipped by concurrent guard", {
|
|
122
|
-
action: key
|
|
225
|
+
action: definition.key
|
|
123
226
|
});
|
|
124
227
|
return currentController;
|
|
125
228
|
}
|
|
126
229
|
case ActionConcurrent.CANCEL: {
|
|
127
230
|
definition.logger?.warn("Action cancelling previous execution", {
|
|
128
|
-
action: key
|
|
231
|
+
action: definition.key
|
|
129
232
|
});
|
|
130
233
|
abortController?.abort();
|
|
131
234
|
}
|
|
132
235
|
}
|
|
133
236
|
}
|
|
134
237
|
abortController = new AbortController();
|
|
135
|
-
const activeStatus =
|
|
136
|
-
const activeError =
|
|
238
|
+
const activeStatus = options?.bind?.status ?? globalStatus;
|
|
239
|
+
const activeError = options?.bind?.error ?? globalError;
|
|
137
240
|
activeStatus.value = ActionStatus.PENDING;
|
|
138
241
|
activeError.value = null;
|
|
139
242
|
currentController = (async () => {
|
|
140
243
|
try {
|
|
141
|
-
let
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
method: definition.api.method,
|
|
167
|
-
url
|
|
168
|
-
});
|
|
169
|
-
} catch (error) {
|
|
170
|
-
const errorMessage = error?.message ?? "API request failed";
|
|
171
|
-
const errorOptions = {
|
|
172
|
-
status: error?.status ?? error?.response?.status,
|
|
173
|
-
statusText: error?.statusText ?? error?.response?.statusText,
|
|
174
|
-
data: error?.data ?? error?.response?._data
|
|
175
|
-
};
|
|
176
|
-
definition.logger?.error("Action API error", {
|
|
177
|
-
action: key,
|
|
178
|
-
error: errorMessage
|
|
179
|
-
});
|
|
180
|
-
throw createApiError(errorMessage, errorOptions);
|
|
181
|
-
}
|
|
182
|
-
if (definition.handle) {
|
|
183
|
-
const handler = definition.handle;
|
|
184
|
-
try {
|
|
185
|
-
definition.logger?.debug("Action handle phase", {
|
|
186
|
-
action: key
|
|
187
|
-
});
|
|
188
|
-
result = await handler({
|
|
189
|
-
view,
|
|
190
|
-
commit: committer,
|
|
191
|
-
async api() {
|
|
192
|
-
return response;
|
|
193
|
-
}
|
|
194
|
-
});
|
|
195
|
-
} catch (handleError) {
|
|
196
|
-
if (handleError instanceof ApiError || handleError instanceof HandleError) {
|
|
197
|
-
throw handleError;
|
|
198
|
-
}
|
|
199
|
-
definition.logger?.error("Action handle error", {
|
|
200
|
-
action: key,
|
|
201
|
-
error: handleError?.message
|
|
202
|
-
});
|
|
203
|
-
throw createHandleError(handleError);
|
|
204
|
-
}
|
|
205
|
-
} else {
|
|
206
|
-
result = response;
|
|
207
|
-
}
|
|
208
|
-
} else if (definition.handle) {
|
|
209
|
-
const handler = definition.handle;
|
|
210
|
-
try {
|
|
211
|
-
definition.logger?.debug("Action handle phase", {
|
|
212
|
-
action: key
|
|
213
|
-
});
|
|
214
|
-
result = await handler({
|
|
215
|
-
view,
|
|
216
|
-
commit: committer
|
|
217
|
-
});
|
|
218
|
-
} catch (handleError) {
|
|
219
|
-
if (handleError instanceof HandleError) {
|
|
220
|
-
throw handleError;
|
|
221
|
-
}
|
|
222
|
-
definition.logger?.error("Action handle error", {
|
|
223
|
-
action: key,
|
|
224
|
-
error: handleError?.message
|
|
225
|
-
});
|
|
226
|
-
throw createHandleError(handleError);
|
|
227
|
-
}
|
|
244
|
+
let data;
|
|
245
|
+
if (isApiDefinition(definition)) {
|
|
246
|
+
const target = resolveCommitTarget(definition.commit, model);
|
|
247
|
+
const mode = resolveCommitMode(definition.commit, options);
|
|
248
|
+
const url = resolveApiUrl(definition, view, options);
|
|
249
|
+
const method = resolveApiMethod(definition, view);
|
|
250
|
+
const headers = resolveApiHeaders(definition, view, options);
|
|
251
|
+
const query = resolveApiQuery(definition, view, options);
|
|
252
|
+
const body = resolveApiBody(definition, view, target, options);
|
|
253
|
+
const timeout = resolveApiTimeout(definition, view, options);
|
|
254
|
+
const signal = resolveApiSignal(options, abortController);
|
|
255
|
+
data = await executeApi(
|
|
256
|
+
definition,
|
|
257
|
+
{
|
|
258
|
+
url,
|
|
259
|
+
method,
|
|
260
|
+
headers,
|
|
261
|
+
query,
|
|
262
|
+
body,
|
|
263
|
+
timeout,
|
|
264
|
+
signal
|
|
265
|
+
},
|
|
266
|
+
options
|
|
267
|
+
);
|
|
268
|
+
executeCommit(definition, target, mode, data);
|
|
228
269
|
} else {
|
|
229
|
-
|
|
230
|
-
}
|
|
231
|
-
if (payload?.transformer) {
|
|
232
|
-
result = payload.transformer(result);
|
|
270
|
+
data = await executeHandler(definition, model, view);
|
|
233
271
|
}
|
|
234
|
-
if (definition.commit) {
|
|
235
|
-
try {
|
|
236
|
-
definition.logger?.debug("Action commit phase", {
|
|
237
|
-
action: key,
|
|
238
|
-
model: definition.commit.model,
|
|
239
|
-
mode: definition.commit.mode
|
|
240
|
-
});
|
|
241
|
-
executeCommit(
|
|
242
|
-
{
|
|
243
|
-
...definition.commit,
|
|
244
|
-
mode: payload?.commit?.mode ?? definition.commit.mode
|
|
245
|
-
},
|
|
246
|
-
mutations,
|
|
247
|
-
result
|
|
248
|
-
);
|
|
249
|
-
} catch (commitError) {
|
|
250
|
-
definition.logger?.error("Action commit error", {
|
|
251
|
-
action: key,
|
|
252
|
-
error: commitError?.message
|
|
253
|
-
});
|
|
254
|
-
throw createCommitError(commitError);
|
|
255
|
-
}
|
|
256
|
-
}
|
|
257
|
-
data = result;
|
|
258
272
|
activeStatus.value = ActionStatus.SUCCESS;
|
|
259
273
|
definition.logger?.debug("Action success", {
|
|
260
|
-
action: key
|
|
274
|
+
action: definition.key
|
|
261
275
|
});
|
|
262
|
-
return
|
|
276
|
+
return data;
|
|
263
277
|
} catch (actionError) {
|
|
264
278
|
activeError.value = actionError;
|
|
265
279
|
activeStatus.value = ActionStatus.ERROR;
|
|
@@ -272,22 +286,18 @@ export function createAction(definition, mutations, view, key) {
|
|
|
272
286
|
return currentController;
|
|
273
287
|
}
|
|
274
288
|
const action = Object.assign(execute, {
|
|
275
|
-
get loading() {
|
|
276
|
-
return loading;
|
|
277
|
-
},
|
|
278
289
|
get error() {
|
|
279
290
|
return readonly(globalError);
|
|
280
291
|
},
|
|
281
292
|
get status() {
|
|
282
293
|
return readonly(globalStatus);
|
|
283
294
|
},
|
|
284
|
-
get
|
|
285
|
-
return
|
|
295
|
+
get loading() {
|
|
296
|
+
return loading;
|
|
286
297
|
},
|
|
287
298
|
reset() {
|
|
288
299
|
globalError.value = null;
|
|
289
300
|
globalStatus.value = ActionStatus.IDLE;
|
|
290
|
-
data = null;
|
|
291
301
|
}
|
|
292
302
|
});
|
|
293
303
|
return action;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export declare function trimStart(value: string, char: string): string;
|
|
2
|
+
export declare function trimEnd(value: string, char: string): string;
|
|
3
|
+
export declare function isObject(value: unknown): value is object;
|
|
4
|
+
export declare function isPlainObject(value: unknown): value is Record<string, unknown>;
|
|
5
|
+
export declare function isEmptyRecord(record: Record<string, unknown> | undefined): record is undefined;
|
|
6
|
+
type ReferenceProxy<T> = {
|
|
7
|
+
value: T;
|
|
8
|
+
} & Record<string | symbol, unknown>;
|
|
9
|
+
export declare function toReactiveProxy<T>(reference: {
|
|
10
|
+
value: T;
|
|
11
|
+
}): ReferenceProxy<T>;
|
|
12
|
+
export declare function debounce<T extends (...args: any[]) => any>(callback: T, delay: number): T;
|
|
13
|
+
export declare function throttle<T extends (...args: any[]) => any>(callback: T, delay: number): T;
|
|
14
|
+
export {};
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
export function trimStart(value, char) {
|
|
2
|
+
return value.replace(new RegExp(`^${char}+`), "");
|
|
3
|
+
}
|
|
4
|
+
export function trimEnd(value, char) {
|
|
5
|
+
return value.replace(new RegExp(`${char}+$`), "");
|
|
6
|
+
}
|
|
7
|
+
export function isObject(value) {
|
|
8
|
+
return value != null && typeof value === "object";
|
|
9
|
+
}
|
|
10
|
+
export function isPlainObject(value) {
|
|
11
|
+
if (!isObject(value)) {
|
|
12
|
+
return false;
|
|
13
|
+
}
|
|
14
|
+
if (Array.isArray(value)) {
|
|
15
|
+
return false;
|
|
16
|
+
}
|
|
17
|
+
return true;
|
|
18
|
+
}
|
|
19
|
+
export function isEmptyRecord(record) {
|
|
20
|
+
if (!record) {
|
|
21
|
+
return true;
|
|
22
|
+
}
|
|
23
|
+
if (Object.keys(record).length === 0) {
|
|
24
|
+
return true;
|
|
25
|
+
}
|
|
26
|
+
return false;
|
|
27
|
+
}
|
|
28
|
+
export function toReactiveProxy(reference) {
|
|
29
|
+
function get(_target, prop) {
|
|
30
|
+
if (prop === "value") {
|
|
31
|
+
return reference.value;
|
|
32
|
+
}
|
|
33
|
+
if (!isObject(reference.value)) {
|
|
34
|
+
return void 0;
|
|
35
|
+
}
|
|
36
|
+
return reference.value[prop];
|
|
37
|
+
}
|
|
38
|
+
function has(_target, prop) {
|
|
39
|
+
if (prop === "value") {
|
|
40
|
+
return true;
|
|
41
|
+
}
|
|
42
|
+
if (!isObject(reference.value)) {
|
|
43
|
+
return false;
|
|
44
|
+
}
|
|
45
|
+
return prop in reference.value;
|
|
46
|
+
}
|
|
47
|
+
function ownKeys() {
|
|
48
|
+
if (!isObject(reference.value)) {
|
|
49
|
+
return [];
|
|
50
|
+
}
|
|
51
|
+
return Reflect.ownKeys(reference.value);
|
|
52
|
+
}
|
|
53
|
+
function getOwnPropertyDescriptor(_target, prop) {
|
|
54
|
+
if (!isObject(reference.value) || !(prop in reference.value)) {
|
|
55
|
+
return void 0;
|
|
56
|
+
}
|
|
57
|
+
return {
|
|
58
|
+
configurable: true,
|
|
59
|
+
enumerable: true,
|
|
60
|
+
value: reference.value[prop]
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
return new Proxy(
|
|
64
|
+
{},
|
|
65
|
+
{
|
|
66
|
+
get,
|
|
67
|
+
has,
|
|
68
|
+
ownKeys,
|
|
69
|
+
getOwnPropertyDescriptor
|
|
70
|
+
}
|
|
71
|
+
);
|
|
72
|
+
}
|
|
73
|
+
export function debounce(callback, delay) {
|
|
74
|
+
let timer = null;
|
|
75
|
+
return (...args) => {
|
|
76
|
+
if (timer) {
|
|
77
|
+
clearTimeout(timer);
|
|
78
|
+
}
|
|
79
|
+
timer = setTimeout(() => {
|
|
80
|
+
timer = null;
|
|
81
|
+
callback(...args);
|
|
82
|
+
}, delay);
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
export function throttle(callback, delay) {
|
|
86
|
+
let lastCall = 0;
|
|
87
|
+
let timer = null;
|
|
88
|
+
return (...args) => {
|
|
89
|
+
const now = Date.now();
|
|
90
|
+
const remaining = delay - (now - lastCall);
|
|
91
|
+
if (remaining <= 0) {
|
|
92
|
+
if (timer) {
|
|
93
|
+
clearTimeout(timer);
|
|
94
|
+
timer = null;
|
|
95
|
+
}
|
|
96
|
+
lastCall = now;
|
|
97
|
+
callback(...args);
|
|
98
|
+
return;
|
|
99
|
+
}
|
|
100
|
+
if (timer) {
|
|
101
|
+
return;
|
|
102
|
+
}
|
|
103
|
+
timer = setTimeout(() => {
|
|
104
|
+
lastCall = Date.now();
|
|
105
|
+
timer = null;
|
|
106
|
+
callback(...args);
|
|
107
|
+
}, remaining);
|
|
108
|
+
};
|
|
109
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
export declare class ActionApiError extends Error {
|
|
2
|
+
name: "ActionApiError";
|
|
3
|
+
status: number;
|
|
4
|
+
statusText: string;
|
|
5
|
+
data: unknown;
|
|
6
|
+
constructor(source: any);
|
|
7
|
+
}
|
|
8
|
+
export declare class ActionHandlerError extends Error {
|
|
9
|
+
name: "ActionHandlerError";
|
|
10
|
+
constructor(source: any);
|
|
11
|
+
}
|
|
12
|
+
export declare class ActionCommitError extends Error {
|
|
13
|
+
name: "ActionCommitError";
|
|
14
|
+
constructor(source: any);
|
|
15
|
+
}
|
|
16
|
+
export declare class ActionConcurrentError extends Error {
|
|
17
|
+
name: "ActionConcurrentError";
|
|
18
|
+
constructor();
|
|
19
|
+
}
|
|
20
|
+
export declare function isError(error: unknown, ...types: (abstract new (...args: never[]) => Error)[]): error is Error;
|
|
21
|
+
export declare function toError<T extends Error = Error>(error: unknown, ErrorType?: new (source: unknown) => T): T;
|