@diphyx/harlemify 5.1.0 → 5.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.
- package/dist/module.d.mts +3 -3
- package/dist/module.d.ts +3 -3
- package/dist/module.json +1 -1
- package/dist/runtime/composables/action.d.ts +5 -5
- package/dist/runtime/composables/action.js +3 -1
- package/dist/runtime/composables/model.d.ts +3 -3
- package/dist/runtime/core/layers/action.js +52 -32
- package/dist/runtime/core/layers/model.js +8 -21
- package/dist/runtime/core/layers/view.js +5 -19
- package/dist/runtime/core/types/action.d.ts +63 -27
- package/dist/runtime/core/types/action.js +5 -0
- package/dist/runtime/core/types/base.d.ts +1 -2
- package/dist/runtime/core/types/model.d.ts +37 -19
- package/dist/runtime/core/types/model.js +10 -5
- package/dist/runtime/core/types/store.d.ts +3 -3
- package/dist/runtime/core/types/view.d.ts +3 -3
- package/dist/runtime/core/utils/action.js +37 -16
- package/dist/runtime/core/utils/base.d.ts +3 -0
- package/dist/runtime/core/utils/base.js +18 -0
- package/dist/runtime/core/utils/model.js +117 -23
- package/dist/runtime/core/utils/store.js +14 -6
- package/dist/runtime/index.d.ts +3 -3
- package/dist/runtime/index.js +2 -2
- package/package.json +1 -1
package/dist/module.d.mts
CHANGED
|
@@ -4,13 +4,13 @@ interface RuntimeModelConfig {
|
|
|
4
4
|
identifier?: string;
|
|
5
5
|
}
|
|
6
6
|
|
|
7
|
+
interface RuntimeViewConfig {
|
|
8
|
+
clone?: ViewClone;
|
|
9
|
+
}
|
|
7
10
|
declare enum ViewClone {
|
|
8
11
|
SHALLOW = "shallow",
|
|
9
12
|
DEEP = "deep"
|
|
10
13
|
}
|
|
11
|
-
interface RuntimeViewConfig {
|
|
12
|
-
clone?: ViewClone;
|
|
13
|
-
}
|
|
14
14
|
|
|
15
15
|
interface RuntimeActionConfig {
|
|
16
16
|
endpoint?: string;
|
package/dist/module.d.ts
CHANGED
|
@@ -4,13 +4,13 @@ interface RuntimeModelConfig {
|
|
|
4
4
|
identifier?: string;
|
|
5
5
|
}
|
|
6
6
|
|
|
7
|
+
interface RuntimeViewConfig {
|
|
8
|
+
clone?: ViewClone;
|
|
9
|
+
}
|
|
7
10
|
declare enum ViewClone {
|
|
8
11
|
SHALLOW = "shallow",
|
|
9
12
|
DEEP = "deep"
|
|
10
13
|
}
|
|
11
|
-
interface RuntimeViewConfig {
|
|
12
|
-
clone?: ViewClone;
|
|
13
|
-
}
|
|
14
14
|
|
|
15
15
|
interface RuntimeActionConfig {
|
|
16
16
|
endpoint?: string;
|
package/dist/module.json
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { type ComputedRef, type Ref } from "vue";
|
|
2
|
-
import { ActionStatus, type ActionCall, type ActionCallOptions } from "../core/types/action.js";
|
|
2
|
+
import { ActionStatus, type ActionCall, type ActionApiCall, type ActionHandlerCall, type ActionCallOptions, type ActionApiCallOptions, type ActionHandlerCallOptions } from "../core/types/action.js";
|
|
3
3
|
export interface UseStoreActionOptions {
|
|
4
4
|
isolated?: boolean;
|
|
5
5
|
}
|
|
6
|
-
export type UseStoreAction<T> = {
|
|
7
|
-
execute: (options?:
|
|
6
|
+
export type UseStoreAction<T, O = ActionCallOptions> = {
|
|
7
|
+
execute: (options?: Omit<O, "bind">) => Promise<T>;
|
|
8
8
|
error: Readonly<Ref<Error | null>>;
|
|
9
9
|
status: Readonly<Ref<ActionStatus>>;
|
|
10
10
|
loading: ComputedRef<boolean>;
|
|
@@ -12,6 +12,6 @@ export type UseStoreAction<T> = {
|
|
|
12
12
|
};
|
|
13
13
|
export declare function useIsolatedActionError(): Ref<Error | null>;
|
|
14
14
|
export declare function useIsolatedActionStatus(): Ref<ActionStatus>;
|
|
15
|
-
export declare function useStoreAction<A extends Record<string, ActionCall
|
|
15
|
+
export declare function useStoreAction<A extends Record<string, ActionCall<any>>, K extends keyof A & string, T = Awaited<ReturnType<A[K]>>>(store: {
|
|
16
16
|
action: A;
|
|
17
|
-
}, key: K, options?: UseStoreActionOptions): UseStoreAction<T>;
|
|
17
|
+
}, key: K, options?: UseStoreActionOptions): UseStoreAction<T, A[K] extends ActionHandlerCall<infer P, any> ? ActionHandlerCallOptions<P> : A[K] extends ActionApiCall<any> ? ActionApiCallOptions : ActionCallOptions>;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { ModelCall, ModelOneCall, ModelManyCall, ModelOneCommit, ModelManyCommit, StoreModel, ModelDefinitions } from "../core/types/model.js";
|
|
1
|
+
import type { ModelCall, ModelOneCall, ModelManyCall, ModelOneCommit, ModelManyListCommit, ModelManyRecordCommit, ModelManyCommit, StoreModel, ModelDefinitions } from "../core/types/model.js";
|
|
2
2
|
export interface UseStoreModelOptions {
|
|
3
3
|
debounce?: number;
|
|
4
4
|
throttle?: number;
|
|
@@ -8,14 +8,14 @@ type UseStoreModelOne<C extends ModelOneCommit<any>> = {
|
|
|
8
8
|
reset: C["reset"];
|
|
9
9
|
patch: C["patch"];
|
|
10
10
|
};
|
|
11
|
-
type UseStoreModelMany<C extends
|
|
11
|
+
type UseStoreModelMany<C extends ModelManyListCommit<any, any> | ModelManyRecordCommit<any>> = {
|
|
12
12
|
set: C["set"];
|
|
13
13
|
reset: C["reset"];
|
|
14
14
|
patch: C["patch"];
|
|
15
15
|
add: C["add"];
|
|
16
16
|
remove: C["remove"];
|
|
17
17
|
};
|
|
18
|
-
export type UseStoreModel<M extends ModelCall<any> = ModelCall<any>> = M extends ModelManyCall<infer S> ? UseStoreModelMany<ModelManyCommit<S>> : M extends ModelOneCall<infer S> ? UseStoreModelOne<ModelOneCommit<S>> : never;
|
|
18
|
+
export type UseStoreModel<M extends ModelCall<any> = ModelCall<any>> = M extends ModelManyCall<infer S, infer I, infer T> ? UseStoreModelMany<ModelManyCommit<S, I, T>> : M extends ModelOneCall<infer S> ? UseStoreModelOne<ModelOneCommit<S>> : never;
|
|
19
19
|
export declare function useStoreModel<M extends StoreModel<ModelDefinitions>, K extends keyof M & string>(store: {
|
|
20
20
|
model: M;
|
|
21
21
|
}, key: K, options?: UseStoreModelOptions): UseStoreModel<M[K]>;
|
|
@@ -1,46 +1,69 @@
|
|
|
1
|
+
import { wrapBaseDefinition } from "../utils/base.js";
|
|
1
2
|
import {
|
|
2
3
|
ActionApiMethod
|
|
3
4
|
} from "../types/action.js";
|
|
4
5
|
export function createActionFactory(config, logger) {
|
|
5
6
|
function apiCall(request, commit) {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
let key = "";
|
|
15
|
-
return {
|
|
16
|
-
get key() {
|
|
17
|
-
return key;
|
|
7
|
+
return wrapBaseDefinition({
|
|
8
|
+
request: {
|
|
9
|
+
endpoint: config?.endpoint,
|
|
10
|
+
headers: config?.headers,
|
|
11
|
+
query: config?.query,
|
|
12
|
+
timeout: config?.timeout,
|
|
13
|
+
concurrent: config?.concurrent,
|
|
14
|
+
...request
|
|
18
15
|
},
|
|
19
|
-
setKey(value) {
|
|
20
|
-
key = value;
|
|
21
|
-
},
|
|
22
|
-
request: mergedRequest,
|
|
23
16
|
commit,
|
|
24
17
|
logger
|
|
25
|
-
};
|
|
18
|
+
});
|
|
26
19
|
}
|
|
27
20
|
function apiGet(request, commit) {
|
|
28
21
|
return apiCall({ ...request, method: ActionApiMethod.GET }, commit);
|
|
29
22
|
}
|
|
30
23
|
function apiHead(request, commit) {
|
|
31
|
-
return apiCall(
|
|
24
|
+
return apiCall(
|
|
25
|
+
{
|
|
26
|
+
...request,
|
|
27
|
+
method: ActionApiMethod.HEAD
|
|
28
|
+
},
|
|
29
|
+
commit
|
|
30
|
+
);
|
|
32
31
|
}
|
|
33
32
|
function apiPost(request, commit) {
|
|
34
|
-
return apiCall(
|
|
33
|
+
return apiCall(
|
|
34
|
+
{
|
|
35
|
+
...request,
|
|
36
|
+
method: ActionApiMethod.POST
|
|
37
|
+
},
|
|
38
|
+
commit
|
|
39
|
+
);
|
|
35
40
|
}
|
|
36
41
|
function apiPut(request, commit) {
|
|
37
|
-
return apiCall(
|
|
42
|
+
return apiCall(
|
|
43
|
+
{
|
|
44
|
+
...request,
|
|
45
|
+
method: ActionApiMethod.PUT
|
|
46
|
+
},
|
|
47
|
+
commit
|
|
48
|
+
);
|
|
38
49
|
}
|
|
39
50
|
function apiPatch(request, commit) {
|
|
40
|
-
return apiCall(
|
|
51
|
+
return apiCall(
|
|
52
|
+
{
|
|
53
|
+
...request,
|
|
54
|
+
method: ActionApiMethod.PATCH
|
|
55
|
+
},
|
|
56
|
+
commit
|
|
57
|
+
);
|
|
41
58
|
}
|
|
42
59
|
function apiDelete(request, commit) {
|
|
43
|
-
return apiCall(
|
|
60
|
+
return apiCall(
|
|
61
|
+
{
|
|
62
|
+
...request,
|
|
63
|
+
method: ActionApiMethod.DELETE
|
|
64
|
+
},
|
|
65
|
+
commit
|
|
66
|
+
);
|
|
44
67
|
}
|
|
45
68
|
const api = Object.assign(apiCall, {
|
|
46
69
|
get: apiGet,
|
|
@@ -50,18 +73,15 @@ export function createActionFactory(config, logger) {
|
|
|
50
73
|
patch: apiPatch,
|
|
51
74
|
delete: apiDelete
|
|
52
75
|
});
|
|
53
|
-
function handler(callback) {
|
|
54
|
-
|
|
55
|
-
return {
|
|
56
|
-
get key() {
|
|
57
|
-
return key;
|
|
58
|
-
},
|
|
59
|
-
setKey(value) {
|
|
60
|
-
key = value;
|
|
61
|
-
},
|
|
76
|
+
function handler(callback, options) {
|
|
77
|
+
return wrapBaseDefinition({
|
|
62
78
|
callback,
|
|
79
|
+
options: {
|
|
80
|
+
concurrent: config?.concurrent,
|
|
81
|
+
...options
|
|
82
|
+
},
|
|
63
83
|
logger
|
|
64
|
-
};
|
|
84
|
+
});
|
|
65
85
|
}
|
|
66
86
|
return {
|
|
67
87
|
api,
|
|
@@ -1,42 +1,29 @@
|
|
|
1
|
+
import { wrapBaseDefinition } from "../utils/base.js";
|
|
1
2
|
import {
|
|
2
|
-
|
|
3
|
+
ModelType
|
|
3
4
|
} from "../types/model.js";
|
|
4
5
|
export function createModelFactory(config, logger) {
|
|
5
6
|
function one(shape, options) {
|
|
6
|
-
|
|
7
|
-
return {
|
|
8
|
-
get key() {
|
|
9
|
-
return key;
|
|
10
|
-
},
|
|
11
|
-
setKey(value) {
|
|
12
|
-
key = value;
|
|
13
|
-
},
|
|
7
|
+
return wrapBaseDefinition({
|
|
14
8
|
shape,
|
|
15
|
-
|
|
9
|
+
type: ModelType.ONE,
|
|
16
10
|
options: {
|
|
17
11
|
identifier: config?.identifier,
|
|
18
12
|
...options
|
|
19
13
|
},
|
|
20
14
|
logger
|
|
21
|
-
};
|
|
15
|
+
});
|
|
22
16
|
}
|
|
23
17
|
function many(shape, options) {
|
|
24
|
-
|
|
25
|
-
return {
|
|
26
|
-
get key() {
|
|
27
|
-
return key;
|
|
28
|
-
},
|
|
29
|
-
setKey(value) {
|
|
30
|
-
key = value;
|
|
31
|
-
},
|
|
18
|
+
return wrapBaseDefinition({
|
|
32
19
|
shape,
|
|
33
|
-
|
|
20
|
+
type: ModelType.MANY,
|
|
34
21
|
options: {
|
|
35
22
|
identifier: config?.identifier,
|
|
36
23
|
...options
|
|
37
24
|
},
|
|
38
25
|
logger
|
|
39
|
-
};
|
|
26
|
+
});
|
|
40
27
|
}
|
|
41
28
|
return {
|
|
42
29
|
one,
|
|
@@ -1,13 +1,7 @@
|
|
|
1
|
+
import { wrapBaseDefinition } from "../utils/base.js";
|
|
1
2
|
export function createViewFactory(config, logger) {
|
|
2
3
|
function from(model, resolver, options) {
|
|
3
|
-
|
|
4
|
-
const definition = {
|
|
5
|
-
get key() {
|
|
6
|
-
return key;
|
|
7
|
-
},
|
|
8
|
-
setKey(value) {
|
|
9
|
-
key = value;
|
|
10
|
-
},
|
|
4
|
+
return wrapBaseDefinition({
|
|
11
5
|
model: [model],
|
|
12
6
|
resolver,
|
|
13
7
|
options: {
|
|
@@ -15,18 +9,10 @@ export function createViewFactory(config, logger) {
|
|
|
15
9
|
...options
|
|
16
10
|
},
|
|
17
11
|
logger
|
|
18
|
-
};
|
|
19
|
-
return definition;
|
|
12
|
+
});
|
|
20
13
|
}
|
|
21
14
|
function merge(models, resolver, options) {
|
|
22
|
-
|
|
23
|
-
return {
|
|
24
|
-
get key() {
|
|
25
|
-
return key;
|
|
26
|
-
},
|
|
27
|
-
setKey(value) {
|
|
28
|
-
key = value;
|
|
29
|
-
},
|
|
15
|
+
return wrapBaseDefinition({
|
|
30
16
|
models,
|
|
31
17
|
resolver,
|
|
32
18
|
options: {
|
|
@@ -34,7 +20,7 @@ export function createViewFactory(config, logger) {
|
|
|
34
20
|
...options
|
|
35
21
|
},
|
|
36
22
|
logger
|
|
37
|
-
};
|
|
23
|
+
});
|
|
38
24
|
}
|
|
39
25
|
return {
|
|
40
26
|
from,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { ComputedRef, DeepReadonly, MaybeRefOrGetter, Ref } from "vue";
|
|
2
2
|
import type { BaseDefinition } from "./base.js";
|
|
3
|
-
import type { ModelDefinitions, ModelOneCommitOptions, ModelManyCommitOptions, StoreModel } from "./model.js";
|
|
3
|
+
import type { ModelDefinitions, ModelDefinitionInfer, ModelOneCommitOptions, ModelManyCommitOptions, StoreModel } from "./model.js";
|
|
4
4
|
import { ModelOneMode, ModelManyMode } from "./model.js";
|
|
5
5
|
import type { ViewDefinitions, StoreView } from "./view.js";
|
|
6
6
|
export interface RuntimeActionConfig {
|
|
@@ -22,6 +22,10 @@ export declare enum ActionConcurrent {
|
|
|
22
22
|
CANCEL = "cancel",
|
|
23
23
|
ALLOW = "allow"
|
|
24
24
|
}
|
|
25
|
+
export declare enum ActionType {
|
|
26
|
+
API = "api",
|
|
27
|
+
HANDLER = "handler"
|
|
28
|
+
}
|
|
25
29
|
export declare enum ActionApiMethod {
|
|
26
30
|
GET = "GET",
|
|
27
31
|
HEAD = "HEAD",
|
|
@@ -42,39 +46,49 @@ export interface ActionApiRequest<MD extends ModelDefinitions, VD extends ViewDe
|
|
|
42
46
|
concurrent?: ActionConcurrent;
|
|
43
47
|
}
|
|
44
48
|
export type ActionApiRequestShortcut<MD extends ModelDefinitions, VD extends ViewDefinitions<MD>> = Omit<ActionApiRequest<MD, VD>, "method">;
|
|
45
|
-
export interface ActionApiCommit<MD extends ModelDefinitions> {
|
|
46
|
-
model:
|
|
49
|
+
export interface ActionApiCommit<MD extends ModelDefinitions, K extends keyof MD = keyof MD> {
|
|
50
|
+
model: K;
|
|
47
51
|
mode: ModelOneMode | ModelManyMode;
|
|
48
52
|
value?: (data: unknown) => unknown;
|
|
49
53
|
options?: ModelOneCommitOptions | ModelManyCommitOptions;
|
|
50
54
|
}
|
|
51
|
-
export interface ActionApiDefinition<MD extends ModelDefinitions, VD extends ViewDefinitions<MD
|
|
55
|
+
export interface ActionApiDefinition<MD extends ModelDefinitions, VD extends ViewDefinitions<MD>, K extends keyof MD = keyof MD> extends BaseDefinition {
|
|
52
56
|
request: ActionApiRequest<MD, VD>;
|
|
53
|
-
commit?: ActionApiCommit<MD>;
|
|
57
|
+
commit?: ActionApiCommit<MD, K>;
|
|
58
|
+
}
|
|
59
|
+
export interface ActionHandlerOptions<P = unknown> {
|
|
60
|
+
payload?: P;
|
|
61
|
+
concurrent?: ActionConcurrent;
|
|
54
62
|
}
|
|
55
|
-
export type ActionHandlerCallback<MD extends ModelDefinitions, VD extends ViewDefinitions<MD>, R = void> = (context: {
|
|
63
|
+
export type ActionHandlerCallback<MD extends ModelDefinitions, VD extends ViewDefinitions<MD>, P = unknown, R = void> = (context: {
|
|
56
64
|
model: StoreModel<MD>;
|
|
57
65
|
view: StoreView<MD, VD>;
|
|
66
|
+
payload: P;
|
|
58
67
|
}) => Promise<R>;
|
|
59
|
-
export interface ActionHandlerDefinition<MD extends ModelDefinitions, VD extends ViewDefinitions<MD>, R = void> extends BaseDefinition {
|
|
60
|
-
callback: ActionHandlerCallback<MD, VD, R>;
|
|
68
|
+
export interface ActionHandlerDefinition<MD extends ModelDefinitions, VD extends ViewDefinitions<MD>, P = unknown, R = void> extends BaseDefinition {
|
|
69
|
+
callback: ActionHandlerCallback<MD, VD, P, R>;
|
|
70
|
+
options?: ActionHandlerOptions<P>;
|
|
61
71
|
}
|
|
62
|
-
export type ActionDefinition<MD extends ModelDefinitions, VD extends ViewDefinitions<MD>> = ActionApiDefinition<MD, VD> | ActionHandlerDefinition<MD, VD,
|
|
72
|
+
export type ActionDefinition<MD extends ModelDefinitions, VD extends ViewDefinitions<MD>> = ActionApiDefinition<MD, VD> | ActionHandlerDefinition<MD, VD, any, any>;
|
|
63
73
|
export type ActionDefinitions<MD extends ModelDefinitions, VD extends ViewDefinitions<MD>> = Record<string, ActionDefinition<MD, VD>>;
|
|
64
|
-
export type StoreAction<MD extends ModelDefinitions, VD extends ViewDefinitions<MD>, AD extends ActionDefinitions<MD, VD>> = {
|
|
65
|
-
[K in keyof AD]: ActionCall;
|
|
66
|
-
};
|
|
67
74
|
export interface ActionApiFactory<MD extends ModelDefinitions, VD extends ViewDefinitions<MD>> {
|
|
68
|
-
(request: ActionApiRequest<MD, VD>, commit
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
+
<K extends keyof MD>(request: ActionApiRequest<MD, VD>, commit: ActionApiCommit<MD, K>): ActionApiDefinition<MD, VD, K>;
|
|
76
|
+
(request: ActionApiRequest<MD, VD>): ActionApiDefinition<MD, VD>;
|
|
77
|
+
get<K extends keyof MD>(request: ActionApiRequestShortcut<MD, VD>, commit: ActionApiCommit<MD, K>): ActionApiDefinition<MD, VD, K>;
|
|
78
|
+
get(request: ActionApiRequestShortcut<MD, VD>): ActionApiDefinition<MD, VD>;
|
|
79
|
+
head<K extends keyof MD>(request: ActionApiRequestShortcut<MD, VD>, commit: ActionApiCommit<MD, K>): ActionApiDefinition<MD, VD, K>;
|
|
80
|
+
head(request: ActionApiRequestShortcut<MD, VD>): ActionApiDefinition<MD, VD>;
|
|
81
|
+
post<K extends keyof MD>(request: ActionApiRequestShortcut<MD, VD>, commit: ActionApiCommit<MD, K>): ActionApiDefinition<MD, VD, K>;
|
|
82
|
+
post(request: ActionApiRequestShortcut<MD, VD>): ActionApiDefinition<MD, VD>;
|
|
83
|
+
put<K extends keyof MD>(request: ActionApiRequestShortcut<MD, VD>, commit: ActionApiCommit<MD, K>): ActionApiDefinition<MD, VD, K>;
|
|
84
|
+
put(request: ActionApiRequestShortcut<MD, VD>): ActionApiDefinition<MD, VD>;
|
|
85
|
+
patch<K extends keyof MD>(request: ActionApiRequestShortcut<MD, VD>, commit: ActionApiCommit<MD, K>): ActionApiDefinition<MD, VD, K>;
|
|
86
|
+
patch(request: ActionApiRequestShortcut<MD, VD>): ActionApiDefinition<MD, VD>;
|
|
87
|
+
delete<K extends keyof MD>(request: ActionApiRequestShortcut<MD, VD>, commit: ActionApiCommit<MD, K>): ActionApiDefinition<MD, VD, K>;
|
|
88
|
+
delete(request: ActionApiRequestShortcut<MD, VD>): ActionApiDefinition<MD, VD>;
|
|
75
89
|
}
|
|
76
90
|
export interface ActionHandlerFactory<MD extends ModelDefinitions, VD extends ViewDefinitions<MD>> {
|
|
77
|
-
<R>(callback: ActionHandlerCallback<MD, VD, R>): ActionHandlerDefinition<MD, VD, R>;
|
|
91
|
+
<P = unknown, R = void>(callback: ActionHandlerCallback<MD, VD, P, R>, options?: ActionHandlerOptions<P>): ActionHandlerDefinition<MD, VD, P, R>;
|
|
78
92
|
}
|
|
79
93
|
export interface ActionFactory<MD extends ModelDefinitions, VD extends ViewDefinitions<MD>> {
|
|
80
94
|
api: ActionApiFactory<MD, VD>;
|
|
@@ -84,8 +98,9 @@ export interface ActionCallBindOptions {
|
|
|
84
98
|
status?: Ref<ActionStatus>;
|
|
85
99
|
error?: Ref<Error | null>;
|
|
86
100
|
}
|
|
87
|
-
export interface
|
|
88
|
-
|
|
101
|
+
export interface ActionCallBaseOptions {
|
|
102
|
+
concurrent?: ActionConcurrent;
|
|
103
|
+
bind?: ActionCallBindOptions;
|
|
89
104
|
}
|
|
90
105
|
export interface ActionResolvedApi {
|
|
91
106
|
url: string;
|
|
@@ -100,7 +115,10 @@ export interface ActionCallTransformerOptions {
|
|
|
100
115
|
request?: (api: ActionResolvedApi) => ActionResolvedApi;
|
|
101
116
|
response?: (data: unknown) => unknown;
|
|
102
117
|
}
|
|
103
|
-
export interface
|
|
118
|
+
export interface ActionCallCommitOptions {
|
|
119
|
+
mode?: ModelOneMode | ModelManyMode;
|
|
120
|
+
}
|
|
121
|
+
export interface ActionApiCallOptions extends ActionCallBaseOptions {
|
|
104
122
|
params?: Record<string, string>;
|
|
105
123
|
headers?: Record<string, string>;
|
|
106
124
|
query?: Record<string, unknown>;
|
|
@@ -108,14 +126,32 @@ export interface ActionCallOptions {
|
|
|
108
126
|
timeout?: number;
|
|
109
127
|
signal?: AbortSignal;
|
|
110
128
|
transformer?: ActionCallTransformerOptions;
|
|
111
|
-
concurrent?: ActionConcurrent;
|
|
112
|
-
bind?: ActionCallBindOptions;
|
|
113
129
|
commit?: ActionCallCommitOptions;
|
|
114
130
|
}
|
|
115
|
-
export interface
|
|
116
|
-
|
|
131
|
+
export interface ActionResolvedHandler<MD extends ModelDefinitions, VD extends ViewDefinitions<MD>, P = unknown> {
|
|
132
|
+
model: StoreModel<MD>;
|
|
133
|
+
view: StoreView<MD, VD>;
|
|
134
|
+
payload: P;
|
|
135
|
+
}
|
|
136
|
+
export interface ActionHandlerCallOptions<P = unknown> extends ActionCallBaseOptions {
|
|
137
|
+
payload?: P;
|
|
138
|
+
}
|
|
139
|
+
export type ActionCallOptions = ActionApiCallOptions | ActionHandlerCallOptions;
|
|
140
|
+
export interface ActionCallBase {
|
|
117
141
|
readonly error: Readonly<Ref<Error | null>>;
|
|
118
142
|
readonly status: Readonly<Ref<ActionStatus>>;
|
|
119
143
|
readonly loading: ComputedRef<boolean>;
|
|
120
144
|
reset: () => void;
|
|
121
145
|
}
|
|
146
|
+
export interface ActionApiCall<T = void> extends ActionCallBase {
|
|
147
|
+
readonly actionType: ActionType.API;
|
|
148
|
+
(options?: ActionApiCallOptions): Promise<T>;
|
|
149
|
+
}
|
|
150
|
+
export interface ActionHandlerCall<P = unknown, T = void> extends ActionCallBase {
|
|
151
|
+
readonly actionType: ActionType.HANDLER;
|
|
152
|
+
(options?: ActionHandlerCallOptions<P>): Promise<T>;
|
|
153
|
+
}
|
|
154
|
+
export type ActionCall<T = void> = ActionApiCall<T> | ActionHandlerCall<any, T>;
|
|
155
|
+
export type StoreAction<MD extends ModelDefinitions, VD extends ViewDefinitions<MD>, AD extends ActionDefinitions<MD, VD>> = {
|
|
156
|
+
[K in keyof AD]: AD[K] extends ActionApiDefinition<MD, VD, infer MK> ? MK extends keyof MD ? ActionApiCall<ModelDefinitionInfer<MD, MK>> : ActionApiCall : AD[K] extends ActionHandlerDefinition<MD, VD, infer P, infer R> ? ActionHandlerCall<P, R> : never;
|
|
157
|
+
};
|
|
@@ -12,6 +12,11 @@ export var ActionConcurrent = /* @__PURE__ */ ((ActionConcurrent2) => {
|
|
|
12
12
|
ActionConcurrent2["ALLOW"] = "allow";
|
|
13
13
|
return ActionConcurrent2;
|
|
14
14
|
})(ActionConcurrent || {});
|
|
15
|
+
export var ActionType = /* @__PURE__ */ ((ActionType2) => {
|
|
16
|
+
ActionType2["API"] = "api";
|
|
17
|
+
ActionType2["HANDLER"] = "handler";
|
|
18
|
+
return ActionType2;
|
|
19
|
+
})(ActionType || {});
|
|
15
20
|
export var ActionApiMethod = /* @__PURE__ */ ((ActionApiMethod2) => {
|
|
16
21
|
ActionApiMethod2["GET"] = "GET";
|
|
17
22
|
ActionApiMethod2["HEAD"] = "HEAD";
|
|
@@ -3,9 +3,13 @@ import type { Shape, ShapeType } from "./shape.js";
|
|
|
3
3
|
export interface RuntimeModelConfig {
|
|
4
4
|
identifier?: string;
|
|
5
5
|
}
|
|
6
|
-
export declare enum
|
|
7
|
-
|
|
8
|
-
|
|
6
|
+
export declare enum ModelType {
|
|
7
|
+
ONE = "one",
|
|
8
|
+
MANY = "many"
|
|
9
|
+
}
|
|
10
|
+
export declare enum ModelManyKind {
|
|
11
|
+
LIST = "list",
|
|
12
|
+
RECORD = "record"
|
|
9
13
|
}
|
|
10
14
|
export declare enum ModelOneMode {
|
|
11
15
|
SET = "set",
|
|
@@ -19,27 +23,33 @@ export declare enum ModelManyMode {
|
|
|
19
23
|
REMOVE = "remove",
|
|
20
24
|
ADD = "add"
|
|
21
25
|
}
|
|
26
|
+
export type ModelDefaultIdentifier<S extends Shape> = "id" extends keyof S ? "id" : keyof S;
|
|
27
|
+
export type AtLeastOne<S extends Shape> = {
|
|
28
|
+
[K in keyof S]: Pick<S, K>;
|
|
29
|
+
}[keyof S];
|
|
22
30
|
export interface ModelOneDefinitionOptions<S extends Shape> {
|
|
23
31
|
identifier?: keyof S;
|
|
24
32
|
default?: S;
|
|
25
33
|
}
|
|
26
|
-
export
|
|
27
|
-
|
|
28
|
-
default?: S[]
|
|
29
|
-
}
|
|
34
|
+
export type ModelManyDefinitionOptions<S extends Shape, I extends keyof S = ModelDefaultIdentifier<S>, T extends ModelManyKind = ModelManyKind.LIST> = {
|
|
35
|
+
kind?: T;
|
|
36
|
+
default?: [T] extends [ModelManyKind.LIST] ? S[] : Record<string, S[]>;
|
|
37
|
+
} & ([T] extends [ModelManyKind.LIST] ? {
|
|
38
|
+
identifier?: I;
|
|
39
|
+
} : {});
|
|
30
40
|
export interface ModelOneDefinition<S extends Shape> extends BaseDefinition {
|
|
31
41
|
shape: ShapeType<S>;
|
|
32
|
-
|
|
42
|
+
type: ModelType.ONE;
|
|
33
43
|
options?: ModelOneDefinitionOptions<S>;
|
|
34
44
|
}
|
|
35
|
-
export interface ModelManyDefinition<S extends Shape> extends BaseDefinition {
|
|
45
|
+
export interface ModelManyDefinition<S extends Shape, I extends keyof S = ModelDefaultIdentifier<S>, T extends ModelManyKind = ModelManyKind.LIST> extends BaseDefinition {
|
|
36
46
|
shape: ShapeType<S>;
|
|
37
|
-
|
|
38
|
-
options?: ModelManyDefinitionOptions<S>;
|
|
47
|
+
type: ModelType.MANY;
|
|
48
|
+
options?: ModelManyDefinitionOptions<S, I, T>;
|
|
39
49
|
}
|
|
40
|
-
export type ModelDefinition<S extends Shape> = ModelOneDefinition<S> | ModelManyDefinition<S>;
|
|
50
|
+
export type ModelDefinition<S extends Shape> = ModelOneDefinition<S> | ModelManyDefinition<S, any, any>;
|
|
41
51
|
export type ModelDefinitions = Record<string, ModelDefinition<any>>;
|
|
42
|
-
export type ModelDefinitionInfer<MD extends ModelDefinitions, K extends keyof MD> = MD[K] extends ModelOneDefinition<infer S> ? S | null : MD[K] extends ModelManyDefinition<infer S> ? S[] : never;
|
|
52
|
+
export type ModelDefinitionInfer<MD extends ModelDefinitions, K extends keyof MD> = MD[K] extends ModelOneDefinition<infer S> ? S | null : MD[K] extends ModelManyDefinition<infer S, any, infer T> ? [T] extends [ModelManyKind.LIST] ? S[] : Record<string, S[]> : never;
|
|
43
53
|
export type ModelDefinitionInferTuple<MD extends ModelDefinitions, K extends readonly (keyof MD)[]> = {
|
|
44
54
|
[I in keyof K]: K[I] extends keyof MD ? ModelDefinitionInfer<MD, K[I]> : never;
|
|
45
55
|
};
|
|
@@ -48,7 +58,7 @@ export type ModelDefinitionsInfer<MD extends ModelDefinitions> = {
|
|
|
48
58
|
};
|
|
49
59
|
export interface ModelFactory {
|
|
50
60
|
one<S extends Shape>(shape: ShapeType<S>, options?: ModelOneDefinitionOptions<S>): ModelOneDefinition<S>;
|
|
51
|
-
many<S extends Shape>(shape: ShapeType<S>, options?: ModelManyDefinitionOptions<S>): ModelManyDefinition<S>;
|
|
61
|
+
many<S extends Shape, I extends keyof S = ModelDefaultIdentifier<S>, T extends ModelManyKind = ModelManyKind.LIST>(shape: ShapeType<S>, options?: ModelManyDefinitionOptions<S, I, T>): ModelManyDefinition<S, I, T>;
|
|
52
62
|
}
|
|
53
63
|
export interface ModelOneCommitOptions {
|
|
54
64
|
deep?: boolean;
|
|
@@ -64,22 +74,30 @@ export interface ModelOneCommit<S extends Shape> {
|
|
|
64
74
|
reset: () => void;
|
|
65
75
|
patch: (value: Partial<S>, options?: ModelOneCommitOptions) => void;
|
|
66
76
|
}
|
|
67
|
-
export interface
|
|
77
|
+
export interface ModelManyListCommit<S extends Shape, I extends keyof S = ModelDefaultIdentifier<S>> {
|
|
68
78
|
set: (value: S[]) => void;
|
|
69
79
|
reset: () => void;
|
|
70
80
|
patch: (value: Partial<S> | Partial<S>[], options?: ModelManyCommitOptions) => void;
|
|
71
|
-
remove: (value: S | S[]
|
|
81
|
+
remove: (value: Pick<S, I> | Pick<S, I>[] | AtLeastOne<S> | AtLeastOne<S>[]) => void;
|
|
72
82
|
add: (value: S | S[], options?: ModelManyCommitOptions) => void;
|
|
73
83
|
}
|
|
84
|
+
export interface ModelManyRecordCommit<S extends Shape> {
|
|
85
|
+
set: (value: Record<string, S[]>) => void;
|
|
86
|
+
reset: () => void;
|
|
87
|
+
patch: (value: Record<string, S[]>, options?: ModelOneCommitOptions) => void;
|
|
88
|
+
remove: (key: string) => void;
|
|
89
|
+
add: (key: string, value: S[]) => void;
|
|
90
|
+
}
|
|
91
|
+
export type ModelManyCommit<S extends Shape, I extends keyof S = ModelDefaultIdentifier<S>, T extends ModelManyKind = ModelManyKind.LIST> = [T] extends [ModelManyKind.LIST] ? ModelManyListCommit<S, I> : ModelManyRecordCommit<S>;
|
|
74
92
|
export type ModelOneCall<S extends Shape> = ModelOneCommit<S> & {
|
|
75
93
|
commit(mode: string, value?: unknown, options?: unknown): void;
|
|
76
94
|
aliases(): Record<string, string>;
|
|
77
95
|
};
|
|
78
|
-
export type ModelManyCall<S extends Shape> = ModelManyCommit<S> & {
|
|
96
|
+
export type ModelManyCall<S extends Shape, I extends keyof S = ModelDefaultIdentifier<S>, T extends ModelManyKind = ModelManyKind.LIST> = ModelManyCommit<S, I, T> & {
|
|
79
97
|
commit(mode: string, value?: unknown, options?: unknown): void;
|
|
80
98
|
aliases(): Record<string, string>;
|
|
81
99
|
};
|
|
82
|
-
export type ModelCall<S extends Shape> = ModelOneCall<S> | ModelManyCall<S>;
|
|
100
|
+
export type ModelCall<S extends Shape> = ModelOneCall<S> | ModelManyCall<S, any, any>;
|
|
83
101
|
export type StoreModel<MD extends ModelDefinitions> = {
|
|
84
|
-
[K in keyof MD]: MD[K] extends ModelOneDefinition<infer S> ? ModelOneCall<S> : MD[K] extends ModelManyDefinition<infer S> ? ModelManyCall<S> : never;
|
|
102
|
+
[K in keyof MD]: MD[K] extends ModelOneDefinition<infer S> ? ModelOneCall<S> : MD[K] extends ModelManyDefinition<infer S, infer I, infer T> ? ModelManyCall<S, I, T> : never;
|
|
85
103
|
};
|
|
@@ -1,8 +1,13 @@
|
|
|
1
|
-
export var
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
return
|
|
5
|
-
})(
|
|
1
|
+
export var ModelType = /* @__PURE__ */ ((ModelType2) => {
|
|
2
|
+
ModelType2["ONE"] = "one";
|
|
3
|
+
ModelType2["MANY"] = "many";
|
|
4
|
+
return ModelType2;
|
|
5
|
+
})(ModelType || {});
|
|
6
|
+
export var ModelManyKind = /* @__PURE__ */ ((ModelManyKind2) => {
|
|
7
|
+
ModelManyKind2["LIST"] = "list";
|
|
8
|
+
ModelManyKind2["RECORD"] = "record";
|
|
9
|
+
return ModelManyKind2;
|
|
10
|
+
})(ModelManyKind || {});
|
|
6
11
|
export var ModelOneMode = /* @__PURE__ */ ((ModelOneMode2) => {
|
|
7
12
|
ModelOneMode2["SET"] = "set";
|
|
8
13
|
ModelOneMode2["RESET"] = "reset";
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import type { ModelDefinitions, ModelFactory, StoreModel } from "./model.js";
|
|
2
2
|
import type { ViewDefinitions, ViewFactory, StoreView } from "./view.js";
|
|
3
|
-
import type {
|
|
4
|
-
export interface StoreConfig<MD extends ModelDefinitions, VD extends ViewDefinitions<MD>,
|
|
3
|
+
import type { ActionDefinitions, ActionFactory, StoreAction } from "./action.js";
|
|
4
|
+
export interface StoreConfig<MD extends ModelDefinitions, VD extends ViewDefinitions<MD>, AD extends ActionDefinitions<MD, VD>> {
|
|
5
5
|
name: string;
|
|
6
6
|
model: (factory: ModelFactory) => MD;
|
|
7
7
|
view: (factory: ViewFactory<MD>) => VD;
|
|
8
|
-
action: (factory: ActionFactory<MD, VD>) =>
|
|
8
|
+
action: (factory: ActionFactory<MD, VD>) => AD;
|
|
9
9
|
}
|
|
10
10
|
export interface Store<MD extends ModelDefinitions, VD extends ViewDefinitions<MD>, AD extends ActionDefinitions<MD, VD>> {
|
|
11
11
|
model: StoreModel<MD>;
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import type { ComputedRef } from "vue";
|
|
2
2
|
import type { BaseDefinition } from "./base.js";
|
|
3
3
|
import type { ModelDefinitions, ModelDefinitionInfer, ModelDefinitionInferTuple } from "./model.js";
|
|
4
|
+
export interface RuntimeViewConfig {
|
|
5
|
+
clone?: ViewClone;
|
|
6
|
+
}
|
|
4
7
|
export declare enum ViewClone {
|
|
5
8
|
SHALLOW = "shallow",
|
|
6
9
|
DEEP = "deep"
|
|
7
10
|
}
|
|
8
|
-
export interface RuntimeViewConfig {
|
|
9
|
-
clone?: ViewClone;
|
|
10
|
-
}
|
|
11
11
|
export interface ViewDefinitionOptions {
|
|
12
12
|
clone?: ViewClone;
|
|
13
13
|
}
|
|
@@ -2,6 +2,7 @@ import { defu } from "defu";
|
|
|
2
2
|
import { ref, computed, readonly, toValue, nextTick } from "vue";
|
|
3
3
|
import {
|
|
4
4
|
ActionApiMethod,
|
|
5
|
+
ActionType,
|
|
5
6
|
ActionStatus,
|
|
6
7
|
ActionConcurrent
|
|
7
8
|
} from "../types/action.js";
|
|
@@ -77,13 +78,22 @@ function resolveApiSignal(options, abortController) {
|
|
|
77
78
|
}
|
|
78
79
|
return abortController.signal;
|
|
79
80
|
}
|
|
80
|
-
function
|
|
81
|
+
function resolveHandlerPayload(definition, options) {
|
|
82
|
+
if (options?.payload !== void 0) {
|
|
83
|
+
return options.payload;
|
|
84
|
+
}
|
|
85
|
+
if (definition.options?.payload !== void 0) {
|
|
86
|
+
return definition.options.payload;
|
|
87
|
+
}
|
|
88
|
+
return void 0;
|
|
89
|
+
}
|
|
90
|
+
function resolveApiCommitTarget(commit, model) {
|
|
81
91
|
if (commit) {
|
|
82
92
|
return model[commit.model];
|
|
83
93
|
}
|
|
84
94
|
return void 0;
|
|
85
95
|
}
|
|
86
|
-
function
|
|
96
|
+
function resolveApiCommitMode(commit, options) {
|
|
87
97
|
if (commit) {
|
|
88
98
|
if (options?.commit?.mode) {
|
|
89
99
|
return options.commit.mode;
|
|
@@ -92,14 +102,17 @@ function resolveCommitMode(commit, options) {
|
|
|
92
102
|
}
|
|
93
103
|
return void 0;
|
|
94
104
|
}
|
|
95
|
-
function
|
|
105
|
+
function resolveApiCommitValue(commit, data) {
|
|
96
106
|
if (typeof commit.value === "function") {
|
|
97
107
|
return commit.value(data);
|
|
98
108
|
}
|
|
99
109
|
return data;
|
|
100
110
|
}
|
|
101
111
|
function isApiDefinition(definition) {
|
|
102
|
-
return "
|
|
112
|
+
return !("callback" in definition);
|
|
113
|
+
}
|
|
114
|
+
function isHandlerDefinition(definition) {
|
|
115
|
+
return "callback" in definition;
|
|
103
116
|
}
|
|
104
117
|
function resolveConcurrent(definition, options) {
|
|
105
118
|
if (options?.concurrent) {
|
|
@@ -108,6 +121,9 @@ function resolveConcurrent(definition, options) {
|
|
|
108
121
|
if (isApiDefinition(definition) && definition.request.concurrent) {
|
|
109
122
|
return definition.request.concurrent;
|
|
110
123
|
}
|
|
124
|
+
if (isHandlerDefinition(definition) && definition.options?.concurrent) {
|
|
125
|
+
return definition.options.concurrent;
|
|
126
|
+
}
|
|
111
127
|
return ActionConcurrent.BLOCK;
|
|
112
128
|
}
|
|
113
129
|
async function executeApi(definition, api, options) {
|
|
@@ -147,15 +163,13 @@ async function executeApi(definition, api, options) {
|
|
|
147
163
|
throw fetchError;
|
|
148
164
|
}
|
|
149
165
|
}
|
|
150
|
-
async function executeHandler(definition,
|
|
166
|
+
async function executeHandler(definition, handler) {
|
|
151
167
|
try {
|
|
152
168
|
definition.logger?.debug("Action handler phase", {
|
|
153
169
|
action: definition.key
|
|
154
170
|
});
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
view
|
|
158
|
-
});
|
|
171
|
+
const data = await definition.callback(handler);
|
|
172
|
+
return data;
|
|
159
173
|
} catch (error) {
|
|
160
174
|
if (isError(error, ActionApiError, ActionHandlerError)) {
|
|
161
175
|
throw error;
|
|
@@ -186,7 +200,7 @@ function executeCommit(definition, target, mode, data) {
|
|
|
186
200
|
if (!isEmptyRecord(target.aliases())) {
|
|
187
201
|
data = resolveAliasInbound(data, target.aliases());
|
|
188
202
|
}
|
|
189
|
-
const value =
|
|
203
|
+
const value = resolveApiCommitValue(definition.commit, data);
|
|
190
204
|
target.commit(mode, value, definition.commit.options);
|
|
191
205
|
} catch (error) {
|
|
192
206
|
const commitError = toError(error, ActionCommitError);
|
|
@@ -198,9 +212,10 @@ function executeCommit(definition, target, mode, data) {
|
|
|
198
212
|
}
|
|
199
213
|
}
|
|
200
214
|
export function createAction(definition, model, view) {
|
|
215
|
+
const actionType = isApiDefinition(definition) ? ActionType.API : ActionType.HANDLER;
|
|
201
216
|
definition.logger?.debug("Registering action", {
|
|
202
217
|
action: definition.key,
|
|
203
|
-
type:
|
|
218
|
+
type: actionType
|
|
204
219
|
});
|
|
205
220
|
let currentController = null;
|
|
206
221
|
let abortController = null;
|
|
@@ -241,10 +256,10 @@ export function createAction(definition, model, view) {
|
|
|
241
256
|
activeError.value = null;
|
|
242
257
|
currentController = (async () => {
|
|
243
258
|
try {
|
|
244
|
-
let data;
|
|
259
|
+
let data = void 0;
|
|
245
260
|
if (isApiDefinition(definition)) {
|
|
246
|
-
const target =
|
|
247
|
-
const mode =
|
|
261
|
+
const target = resolveApiCommitTarget(definition.commit, model);
|
|
262
|
+
const mode = resolveApiCommitMode(definition.commit, options);
|
|
248
263
|
const url = resolveApiUrl(definition, view, options);
|
|
249
264
|
const method = resolveApiMethod(definition, view);
|
|
250
265
|
const headers = resolveApiHeaders(definition, view, options);
|
|
@@ -266,8 +281,13 @@ export function createAction(definition, model, view) {
|
|
|
266
281
|
options
|
|
267
282
|
);
|
|
268
283
|
executeCommit(definition, target, mode, data);
|
|
269
|
-
} else {
|
|
270
|
-
|
|
284
|
+
} else if (isHandlerDefinition(definition)) {
|
|
285
|
+
const payload = resolveHandlerPayload(definition, options);
|
|
286
|
+
data = await executeHandler(definition, {
|
|
287
|
+
model,
|
|
288
|
+
view,
|
|
289
|
+
payload
|
|
290
|
+
});
|
|
271
291
|
}
|
|
272
292
|
activeStatus.value = ActionStatus.SUCCESS;
|
|
273
293
|
definition.logger?.debug("Action success", {
|
|
@@ -286,6 +306,7 @@ export function createAction(definition, model, view) {
|
|
|
286
306
|
return currentController;
|
|
287
307
|
}
|
|
288
308
|
const action = Object.assign(execute, {
|
|
309
|
+
actionType,
|
|
289
310
|
get error() {
|
|
290
311
|
return readonly(globalError);
|
|
291
312
|
},
|
|
@@ -1,5 +1,8 @@
|
|
|
1
|
+
import type { BaseDefinition } from "../types/base.js";
|
|
2
|
+
export declare function wrapBaseDefinition<T extends Omit<BaseDefinition, "key">>(definition: T): T & BaseDefinition;
|
|
1
3
|
export declare function trimStart(value: string, char: string): string;
|
|
2
4
|
export declare function trimEnd(value: string, char: string): string;
|
|
5
|
+
export declare function ensureArray<T>(value: T | T[]): T[];
|
|
3
6
|
export declare function isObject(value: unknown): value is object;
|
|
4
7
|
export declare function isPlainObject(value: unknown): value is Record<string, unknown>;
|
|
5
8
|
export declare function isEmptyRecord(record: Record<string, unknown> | undefined): record is undefined;
|
|
@@ -1,9 +1,27 @@
|
|
|
1
|
+
export function wrapBaseDefinition(definition) {
|
|
2
|
+
let key = "";
|
|
3
|
+
return Object.defineProperties(definition, {
|
|
4
|
+
key: {
|
|
5
|
+
get() {
|
|
6
|
+
return key;
|
|
7
|
+
},
|
|
8
|
+
set(value) {
|
|
9
|
+
key = value;
|
|
10
|
+
},
|
|
11
|
+
enumerable: true,
|
|
12
|
+
configurable: true
|
|
13
|
+
}
|
|
14
|
+
});
|
|
15
|
+
}
|
|
1
16
|
export function trimStart(value, char) {
|
|
2
17
|
return value.replace(new RegExp(`^${char}+`), "");
|
|
3
18
|
}
|
|
4
19
|
export function trimEnd(value, char) {
|
|
5
20
|
return value.replace(new RegExp(`${char}+$`), "");
|
|
6
21
|
}
|
|
22
|
+
export function ensureArray(value) {
|
|
23
|
+
return Array.isArray(value) ? value : [value];
|
|
24
|
+
}
|
|
7
25
|
export function isObject(value) {
|
|
8
26
|
return value != null && typeof value === "object";
|
|
9
27
|
}
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import { defu } from "defu";
|
|
2
|
+
import { ensureArray } from "./base.js";
|
|
2
3
|
import { resolveShape } from "./shape.js";
|
|
3
4
|
import {
|
|
4
|
-
|
|
5
|
+
ModelType,
|
|
6
|
+
ModelManyKind,
|
|
5
7
|
ModelOneMode,
|
|
6
8
|
ModelManyMode
|
|
7
9
|
} from "../types/model.js";
|
|
@@ -64,7 +66,7 @@ function createOneCommit(definition, source) {
|
|
|
64
66
|
patch
|
|
65
67
|
};
|
|
66
68
|
}
|
|
67
|
-
function
|
|
69
|
+
function createManyListCommit(definition, shape, source) {
|
|
68
70
|
const identifier = resolveIdentifier(definition, shape);
|
|
69
71
|
const setOperation = source.mutation(`${definition.key}:set`, (state, value) => {
|
|
70
72
|
state[definition.key] = value;
|
|
@@ -75,11 +77,11 @@ function createManyCommit(definition, shape, source) {
|
|
|
75
77
|
const patchOperation = source.mutation(
|
|
76
78
|
`${definition.key}:patch`,
|
|
77
79
|
(state, payload) => {
|
|
78
|
-
const items =
|
|
80
|
+
const items = ensureArray(payload.value);
|
|
79
81
|
const by = payload.options?.by ?? identifier;
|
|
80
82
|
state[definition.key] = state[definition.key].map((item) => {
|
|
81
|
-
const found = items.find((
|
|
82
|
-
return
|
|
83
|
+
const found = items.find((partial) => {
|
|
84
|
+
return partial[by] === item[by];
|
|
83
85
|
});
|
|
84
86
|
if (!found) {
|
|
85
87
|
return item;
|
|
@@ -96,23 +98,25 @@ function createManyCommit(definition, shape, source) {
|
|
|
96
98
|
);
|
|
97
99
|
const removeOperation = source.mutation(
|
|
98
100
|
`${definition.key}:remove`,
|
|
99
|
-
(state,
|
|
100
|
-
const items =
|
|
101
|
-
const by = payload.options?.by ?? identifier;
|
|
102
|
-
const ids = new Set(
|
|
103
|
-
items.map((item) => {
|
|
104
|
-
return item[by];
|
|
105
|
-
})
|
|
106
|
-
);
|
|
101
|
+
(state, value) => {
|
|
102
|
+
const items = ensureArray(value);
|
|
107
103
|
state[definition.key] = state[definition.key].filter((item) => {
|
|
108
|
-
return !
|
|
104
|
+
return !items.some((match) => {
|
|
105
|
+
let keys = Object.keys(match);
|
|
106
|
+
if (identifier in match) {
|
|
107
|
+
keys = [identifier];
|
|
108
|
+
}
|
|
109
|
+
return keys.every((key) => {
|
|
110
|
+
return item[key] === match[key];
|
|
111
|
+
});
|
|
112
|
+
});
|
|
109
113
|
});
|
|
110
114
|
}
|
|
111
115
|
);
|
|
112
116
|
const addOperation = source.mutation(
|
|
113
117
|
`${definition.key}:add`,
|
|
114
118
|
(state, payload) => {
|
|
115
|
-
let items =
|
|
119
|
+
let items = ensureArray(payload.value);
|
|
116
120
|
if (payload.options?.unique) {
|
|
117
121
|
const by = payload.options.by ?? identifier;
|
|
118
122
|
const existingIds = new Set(
|
|
@@ -155,15 +159,12 @@ function createManyCommit(definition, shape, source) {
|
|
|
155
159
|
options
|
|
156
160
|
});
|
|
157
161
|
}
|
|
158
|
-
function remove(value
|
|
162
|
+
function remove(value) {
|
|
159
163
|
definition.logger?.debug("Model mutation", {
|
|
160
164
|
model: definition.key,
|
|
161
165
|
mutation: "remove"
|
|
162
166
|
});
|
|
163
|
-
removeOperation(
|
|
164
|
-
value,
|
|
165
|
-
options
|
|
166
|
-
});
|
|
167
|
+
removeOperation(value);
|
|
167
168
|
}
|
|
168
169
|
function add(value, options) {
|
|
169
170
|
definition.logger?.debug("Model mutation", {
|
|
@@ -183,19 +184,112 @@ function createManyCommit(definition, shape, source) {
|
|
|
183
184
|
add
|
|
184
185
|
};
|
|
185
186
|
}
|
|
187
|
+
function createManyRecordCommit(definition, source) {
|
|
188
|
+
const setOperation = source.mutation(
|
|
189
|
+
`${definition.key}:set`,
|
|
190
|
+
(state, value) => {
|
|
191
|
+
state[definition.key] = value;
|
|
192
|
+
}
|
|
193
|
+
);
|
|
194
|
+
const resetOperation = source.mutation(`${definition.key}:reset`, (state) => {
|
|
195
|
+
state[definition.key] = definition.options?.default ?? {};
|
|
196
|
+
});
|
|
197
|
+
const patchOperation = source.mutation(
|
|
198
|
+
`${definition.key}:patch`,
|
|
199
|
+
(state, payload) => {
|
|
200
|
+
if (payload.options?.deep) {
|
|
201
|
+
state[definition.key] = defu(payload.value, state[definition.key]);
|
|
202
|
+
return;
|
|
203
|
+
}
|
|
204
|
+
state[definition.key] = {
|
|
205
|
+
...state[definition.key],
|
|
206
|
+
...payload.value
|
|
207
|
+
};
|
|
208
|
+
}
|
|
209
|
+
);
|
|
210
|
+
const removeOperation = source.mutation(`${definition.key}:remove`, (state, key) => {
|
|
211
|
+
const record = {};
|
|
212
|
+
for (const entry of Object.keys(state[definition.key])) {
|
|
213
|
+
if (entry !== key) {
|
|
214
|
+
record[entry] = state[definition.key][entry];
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
state[definition.key] = record;
|
|
218
|
+
});
|
|
219
|
+
const addOperation = source.mutation(
|
|
220
|
+
`${definition.key}:add`,
|
|
221
|
+
(state, payload) => {
|
|
222
|
+
state[definition.key] = {
|
|
223
|
+
...state[definition.key],
|
|
224
|
+
[payload.key]: payload.value
|
|
225
|
+
};
|
|
226
|
+
}
|
|
227
|
+
);
|
|
228
|
+
function set(value) {
|
|
229
|
+
definition.logger?.debug("Model mutation", {
|
|
230
|
+
model: definition.key,
|
|
231
|
+
mutation: "set"
|
|
232
|
+
});
|
|
233
|
+
setOperation(value);
|
|
234
|
+
}
|
|
235
|
+
function reset() {
|
|
236
|
+
definition.logger?.debug("Model mutation", {
|
|
237
|
+
model: definition.key,
|
|
238
|
+
mutation: "reset"
|
|
239
|
+
});
|
|
240
|
+
resetOperation();
|
|
241
|
+
}
|
|
242
|
+
function patch(value, options) {
|
|
243
|
+
definition.logger?.debug("Model mutation", {
|
|
244
|
+
model: definition.key,
|
|
245
|
+
mutation: "patch"
|
|
246
|
+
});
|
|
247
|
+
patchOperation({ value, options });
|
|
248
|
+
}
|
|
249
|
+
function remove(key) {
|
|
250
|
+
definition.logger?.debug("Model mutation", {
|
|
251
|
+
model: definition.key,
|
|
252
|
+
mutation: "remove"
|
|
253
|
+
});
|
|
254
|
+
removeOperation(key);
|
|
255
|
+
}
|
|
256
|
+
function add(key, value) {
|
|
257
|
+
definition.logger?.debug("Model mutation", {
|
|
258
|
+
model: definition.key,
|
|
259
|
+
mutation: "add"
|
|
260
|
+
});
|
|
261
|
+
addOperation({ key, value });
|
|
262
|
+
}
|
|
263
|
+
return {
|
|
264
|
+
set,
|
|
265
|
+
reset,
|
|
266
|
+
patch,
|
|
267
|
+
remove,
|
|
268
|
+
add
|
|
269
|
+
};
|
|
270
|
+
}
|
|
186
271
|
function isOneDefinition(definition) {
|
|
187
|
-
return definition.
|
|
272
|
+
return definition.type === ModelType.ONE;
|
|
273
|
+
}
|
|
274
|
+
function isManyRecordDefinition(definition) {
|
|
275
|
+
return definition.options?.kind === ModelManyKind.RECORD;
|
|
276
|
+
}
|
|
277
|
+
function resolveManyCommit(definition, shape, source) {
|
|
278
|
+
if (isManyRecordDefinition(definition)) {
|
|
279
|
+
return createManyRecordCommit(definition, source);
|
|
280
|
+
}
|
|
281
|
+
return createManyListCommit(definition, shape, source);
|
|
188
282
|
}
|
|
189
283
|
function resolveCommit(definition, shape, source) {
|
|
190
284
|
if (isOneDefinition(definition)) {
|
|
191
285
|
return createOneCommit(definition, source);
|
|
192
286
|
}
|
|
193
|
-
return
|
|
287
|
+
return resolveManyCommit(definition, shape, source);
|
|
194
288
|
}
|
|
195
289
|
export function createModel(definition, source) {
|
|
196
290
|
definition.logger?.debug("Registering model", {
|
|
197
291
|
model: definition.key,
|
|
198
|
-
|
|
292
|
+
type: definition.type
|
|
199
293
|
});
|
|
200
294
|
const shape = resolveShape(definition.shape);
|
|
201
295
|
const commit = resolveCommit(definition, shape, source);
|
|
@@ -1,18 +1,26 @@
|
|
|
1
1
|
import { createModel } from "./model.js";
|
|
2
2
|
import { createView } from "./view.js";
|
|
3
3
|
import { createAction } from "./action.js";
|
|
4
|
-
import {
|
|
4
|
+
import {
|
|
5
|
+
ModelType,
|
|
6
|
+
ModelManyKind
|
|
7
|
+
} from "../types/model.js";
|
|
5
8
|
export function createStoreState(modelDefinitions) {
|
|
6
9
|
const output = {};
|
|
7
|
-
for (const [key, { options,
|
|
8
|
-
|
|
10
|
+
for (const [key, { options, type }] of Object.entries(modelDefinitions)) {
|
|
11
|
+
if (type === ModelType.ONE) {
|
|
12
|
+
output[key] = options?.default ?? null;
|
|
13
|
+
} else {
|
|
14
|
+
const manyDefault = options?.kind === ModelManyKind.RECORD ? {} : [];
|
|
15
|
+
output[key] = options?.default ?? manyDefault;
|
|
16
|
+
}
|
|
9
17
|
}
|
|
10
18
|
return output;
|
|
11
19
|
}
|
|
12
20
|
export function createStoreModel(modelDefinitions, source) {
|
|
13
21
|
const output = {};
|
|
14
22
|
for (const [key, definition] of Object.entries(modelDefinitions)) {
|
|
15
|
-
definition.
|
|
23
|
+
definition.key = key;
|
|
16
24
|
output[key] = createModel(definition, source);
|
|
17
25
|
}
|
|
18
26
|
return output;
|
|
@@ -20,7 +28,7 @@ export function createStoreModel(modelDefinitions, source) {
|
|
|
20
28
|
export function createStoreView(viewDefinitions, source) {
|
|
21
29
|
const output = {};
|
|
22
30
|
for (const [key, definition] of Object.entries(viewDefinitions)) {
|
|
23
|
-
definition.
|
|
31
|
+
definition.key = key;
|
|
24
32
|
output[key] = createView(definition, source);
|
|
25
33
|
}
|
|
26
34
|
return output;
|
|
@@ -28,7 +36,7 @@ export function createStoreView(viewDefinitions, source) {
|
|
|
28
36
|
export function createStoreAction(actionDefinitions, model, view) {
|
|
29
37
|
const output = {};
|
|
30
38
|
for (const [key, definition] of Object.entries(actionDefinitions)) {
|
|
31
|
-
definition.
|
|
39
|
+
definition.key = key;
|
|
32
40
|
output[key] = createAction(definition, model, view);
|
|
33
41
|
}
|
|
34
42
|
return output;
|
package/dist/runtime/index.d.ts
CHANGED
|
@@ -2,12 +2,12 @@ export { createStore } from "./core/store.js";
|
|
|
2
2
|
export type { Store, StoreConfig } from "./core/types/store.js";
|
|
3
3
|
export { shape } from "./core/layers/shape.js";
|
|
4
4
|
export type { ShapeInfer } from "./core/types/shape.js";
|
|
5
|
-
export {
|
|
5
|
+
export { ModelType, ModelManyKind, ModelOneMode, ModelManyMode } from "./core/types/model.js";
|
|
6
6
|
export type { ModelOneCommitOptions, ModelManyCommitOptions } from "./core/types/model.js";
|
|
7
7
|
export { ViewClone } from "./core/types/view.js";
|
|
8
8
|
export type { ViewDefinitionOptions } from "./core/types/view.js";
|
|
9
|
-
export { ActionStatus, ActionConcurrent, ActionApiMethod } from "./core/types/action.js";
|
|
10
|
-
export type { ActionCall, ActionCallOptions, ActionCallTransformerOptions, ActionCallBindOptions, ActionCallCommitOptions, ActionResolvedApi, } from "./core/types/action.js";
|
|
9
|
+
export { ActionStatus, ActionConcurrent, ActionType, ActionApiMethod } from "./core/types/action.js";
|
|
10
|
+
export type { ActionCall, ActionApiCall, ActionHandlerCall, ActionCallOptions, ActionCallBaseOptions, ActionApiCallOptions, ActionHandlerCallOptions, ActionCallTransformerOptions, ActionCallBindOptions, ActionCallCommitOptions, ActionHandlerOptions, ActionResolvedApi, } from "./core/types/action.js";
|
|
11
11
|
export { ActionApiError, ActionHandlerError, ActionCommitError, ActionConcurrentError } from "./core/utils/error.js";
|
|
12
12
|
export { useIsolatedActionStatus, useIsolatedActionError, useStoreAction } from "./composables/action.js";
|
|
13
13
|
export type { UseStoreActionOptions, UseStoreAction } from "./composables/action.js";
|
package/dist/runtime/index.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
export { createStore } from "./core/store.js";
|
|
2
2
|
export { shape } from "./core/layers/shape.js";
|
|
3
|
-
export {
|
|
3
|
+
export { ModelType, ModelManyKind, ModelOneMode, ModelManyMode } from "./core/types/model.js";
|
|
4
4
|
export { ViewClone } from "./core/types/view.js";
|
|
5
|
-
export { ActionStatus, ActionConcurrent, ActionApiMethod } from "./core/types/action.js";
|
|
5
|
+
export { ActionStatus, ActionConcurrent, ActionType, ActionApiMethod } from "./core/types/action.js";
|
|
6
6
|
export { ActionApiError, ActionHandlerError, ActionCommitError, ActionConcurrentError } from "./core/utils/error.js";
|
|
7
7
|
export { useIsolatedActionStatus, useIsolatedActionError, useStoreAction } from "./composables/action.js";
|
|
8
8
|
export { useStoreModel } from "./composables/model.js";
|