@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
package/README.md
CHANGED
|
@@ -2,14 +2,16 @@
|
|
|
2
2
|
|
|
3
3
|
> Factory-driven state management for Nuxt powered by [Harlem](https://harlemjs.com/)
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
Define your data **shape** once with Zod — get typed **models**, computed **views**, and async **actions** with a single `createStore` call.
|
|
6
6
|
|
|
7
|
-
- **
|
|
8
|
-
- **
|
|
9
|
-
- **
|
|
10
|
-
- **
|
|
11
|
-
- **
|
|
12
|
-
- **
|
|
7
|
+
- **Schema-first** — Define your data shape once, get TypeScript types and validation automatically
|
|
8
|
+
- **Reactive state** — Single items and collections with built-in mutations
|
|
9
|
+
- **Computed views** — Derived read-only state that updates when models change
|
|
10
|
+
- **API integration** — Declarative HTTP actions that fetch and commit data in one step
|
|
11
|
+
- **Status tracking** — Every action exposes loading, error, and status reactively
|
|
12
|
+
- **Concurrency control** — Block, skip, cancel, or allow parallel calls per action
|
|
13
|
+
- **Vue composables** — Reactive helpers for actions, models, and views in components
|
|
14
|
+
- **SSR ready** — Server-side rendering with automatic state hydration
|
|
13
15
|
|
|
14
16
|
## Install
|
|
15
17
|
|
|
@@ -17,37 +19,23 @@
|
|
|
17
19
|
npm install @diphyx/harlemify
|
|
18
20
|
```
|
|
19
21
|
|
|
20
|
-
## Setup
|
|
21
|
-
|
|
22
22
|
```typescript
|
|
23
23
|
// nuxt.config.ts
|
|
24
24
|
export default defineNuxtConfig({
|
|
25
25
|
modules: ["@diphyx/harlemify"],
|
|
26
|
-
harlemify: {
|
|
27
|
-
action: {
|
|
28
|
-
endpoint: "https://api.example.com",
|
|
29
|
-
},
|
|
30
|
-
},
|
|
31
26
|
});
|
|
32
27
|
```
|
|
33
28
|
|
|
34
29
|
## Usage
|
|
35
30
|
|
|
36
31
|
```typescript
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
}),
|
|
45
|
-
name: factory.string(),
|
|
46
|
-
email: factory.email(),
|
|
47
|
-
};
|
|
48
|
-
});
|
|
49
|
-
|
|
50
|
-
export type User = ShapeInfer<typeof userShape>;
|
|
32
|
+
const userShape = shape((factory) => ({
|
|
33
|
+
id: factory.number().meta({
|
|
34
|
+
identifier: true,
|
|
35
|
+
}),
|
|
36
|
+
name: factory.string(),
|
|
37
|
+
email: factory.email(),
|
|
38
|
+
}));
|
|
51
39
|
|
|
52
40
|
export const userStore = createStore({
|
|
53
41
|
name: "users",
|
|
@@ -63,19 +51,17 @@ export const userStore = createStore({
|
|
|
63
51
|
users: from("list"),
|
|
64
52
|
};
|
|
65
53
|
},
|
|
66
|
-
action({ api
|
|
54
|
+
action({ api }) {
|
|
67
55
|
return {
|
|
68
|
-
list: api
|
|
69
|
-
|
|
70
|
-
url: "/users",
|
|
71
|
-
})
|
|
72
|
-
.commit("list", ActionManyMode.SET),
|
|
73
|
-
create: api
|
|
74
|
-
.post({
|
|
56
|
+
list: api.get(
|
|
57
|
+
{
|
|
75
58
|
url: "/users",
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
|
|
59
|
+
},
|
|
60
|
+
{
|
|
61
|
+
model: "list",
|
|
62
|
+
mode: ModelManyMode.SET,
|
|
63
|
+
},
|
|
64
|
+
),
|
|
79
65
|
};
|
|
80
66
|
},
|
|
81
67
|
});
|
|
@@ -83,15 +69,15 @@ export const userStore = createStore({
|
|
|
83
69
|
|
|
84
70
|
```vue
|
|
85
71
|
<script setup>
|
|
86
|
-
const {
|
|
72
|
+
const { execute, loading } = useStoreAction(userStore, "list");
|
|
73
|
+
const { data } = useStoreView(userStore, "users");
|
|
87
74
|
|
|
88
|
-
await
|
|
75
|
+
await execute();
|
|
89
76
|
</script>
|
|
90
77
|
|
|
91
78
|
<template>
|
|
92
|
-
<
|
|
93
|
-
|
|
94
|
-
<li v-for="user in view.users.value" :key="user.id">{{ user.name }}</li>
|
|
79
|
+
<ul v-if="!loading">
|
|
80
|
+
<li v-for="user in data.value" :key="user.id">{{ user.name }}</li>
|
|
95
81
|
</ul>
|
|
96
82
|
</template>
|
|
97
83
|
```
|
package/dist/module.d.mts
CHANGED
package/dist/module.d.ts
CHANGED
package/dist/module.json
CHANGED
|
@@ -1,4 +1,17 @@
|
|
|
1
|
-
import { type Ref } from "vue";
|
|
2
|
-
import { type
|
|
1
|
+
import { type ComputedRef, type Ref } from "vue";
|
|
2
|
+
import { ActionStatus, type ActionCall, type ActionCallOptions } from "../core/types/action.js";
|
|
3
|
+
export interface UseStoreActionOptions {
|
|
4
|
+
isolated?: boolean;
|
|
5
|
+
}
|
|
6
|
+
export type UseStoreAction<T> = {
|
|
7
|
+
execute: (options?: ActionCallOptions) => Promise<T>;
|
|
8
|
+
error: Readonly<Ref<Error | null>>;
|
|
9
|
+
status: Readonly<Ref<ActionStatus>>;
|
|
10
|
+
loading: ComputedRef<boolean>;
|
|
11
|
+
reset: () => void;
|
|
12
|
+
};
|
|
13
|
+
export declare function useIsolatedActionError(): Ref<Error | null>;
|
|
3
14
|
export declare function useIsolatedActionStatus(): Ref<ActionStatus>;
|
|
4
|
-
export declare function
|
|
15
|
+
export declare function useStoreAction<A extends Record<string, ActionCall>, K extends keyof A & string, T = Awaited<ReturnType<A[K]>>>(store: {
|
|
16
|
+
action: A;
|
|
17
|
+
}, key: K, options?: UseStoreActionOptions): UseStoreAction<T>;
|
|
@@ -1,8 +1,52 @@
|
|
|
1
|
-
import { ref } from "vue";
|
|
1
|
+
import { ref, computed } from "vue";
|
|
2
2
|
import { ActionStatus } from "../core/types/action.js";
|
|
3
|
+
export function useIsolatedActionError() {
|
|
4
|
+
return ref(null);
|
|
5
|
+
}
|
|
3
6
|
export function useIsolatedActionStatus() {
|
|
4
7
|
return ref(ActionStatus.IDLE);
|
|
5
8
|
}
|
|
6
|
-
export function
|
|
7
|
-
|
|
9
|
+
export function useStoreAction(store, key, options) {
|
|
10
|
+
const action = store.action[key];
|
|
11
|
+
if (!action) {
|
|
12
|
+
throw new Error(`Action "${key}" not found in store`);
|
|
13
|
+
}
|
|
14
|
+
let error;
|
|
15
|
+
let status;
|
|
16
|
+
let loading;
|
|
17
|
+
let reset;
|
|
18
|
+
if (options?.isolated) {
|
|
19
|
+
const isolatedError = useIsolatedActionError();
|
|
20
|
+
const isolatedStatus = useIsolatedActionStatus();
|
|
21
|
+
error = isolatedError;
|
|
22
|
+
status = isolatedStatus;
|
|
23
|
+
loading = computed(() => {
|
|
24
|
+
return isolatedStatus.value === ActionStatus.PENDING;
|
|
25
|
+
});
|
|
26
|
+
reset = () => {
|
|
27
|
+
isolatedStatus.value = ActionStatus.IDLE;
|
|
28
|
+
isolatedError.value = null;
|
|
29
|
+
};
|
|
30
|
+
} else {
|
|
31
|
+
error = action.error;
|
|
32
|
+
status = action.status;
|
|
33
|
+
loading = action.loading;
|
|
34
|
+
reset = action.reset;
|
|
35
|
+
}
|
|
36
|
+
function execute(callOptions = {}) {
|
|
37
|
+
if (options?.isolated) {
|
|
38
|
+
callOptions.bind = {
|
|
39
|
+
status,
|
|
40
|
+
error
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
return action(callOptions);
|
|
44
|
+
}
|
|
45
|
+
return {
|
|
46
|
+
execute,
|
|
47
|
+
error,
|
|
48
|
+
status,
|
|
49
|
+
loading,
|
|
50
|
+
reset
|
|
51
|
+
};
|
|
8
52
|
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { ModelCall, ModelOneCall, ModelManyCall, ModelOneCommit, ModelManyCommit, StoreModel, ModelDefinitions } from "../core/types/model.js";
|
|
2
|
+
export interface UseStoreModelOptions {
|
|
3
|
+
debounce?: number;
|
|
4
|
+
throttle?: number;
|
|
5
|
+
}
|
|
6
|
+
type UseStoreModelOne<C extends ModelOneCommit<any>> = {
|
|
7
|
+
set: C["set"];
|
|
8
|
+
reset: C["reset"];
|
|
9
|
+
patch: C["patch"];
|
|
10
|
+
};
|
|
11
|
+
type UseStoreModelMany<C extends ModelManyCommit<any>> = {
|
|
12
|
+
set: C["set"];
|
|
13
|
+
reset: C["reset"];
|
|
14
|
+
patch: C["patch"];
|
|
15
|
+
add: C["add"];
|
|
16
|
+
remove: C["remove"];
|
|
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;
|
|
19
|
+
export declare function useStoreModel<M extends StoreModel<ModelDefinitions>, K extends keyof M & string>(store: {
|
|
20
|
+
model: M;
|
|
21
|
+
}, key: K, options?: UseStoreModelOptions): UseStoreModel<M[K]>;
|
|
22
|
+
export {};
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { debounce, throttle } from "../core/utils/base.js";
|
|
2
|
+
function isMany(model) {
|
|
3
|
+
return "add" in model && typeof model.add === "function";
|
|
4
|
+
}
|
|
5
|
+
function wrapCommit(commit, options) {
|
|
6
|
+
if (options?.debounce) {
|
|
7
|
+
return debounce(commit, options.debounce);
|
|
8
|
+
}
|
|
9
|
+
if (options?.throttle) {
|
|
10
|
+
return throttle(commit, options.throttle);
|
|
11
|
+
}
|
|
12
|
+
return commit;
|
|
13
|
+
}
|
|
14
|
+
export function useStoreModel(store, key, options) {
|
|
15
|
+
const model = store.model[key];
|
|
16
|
+
if (!model) {
|
|
17
|
+
throw new Error(`Model "${key}" not found in store`);
|
|
18
|
+
}
|
|
19
|
+
let output = {
|
|
20
|
+
set: wrapCommit(model.set.bind(model), options),
|
|
21
|
+
reset: wrapCommit(model.reset.bind(model), options),
|
|
22
|
+
patch: wrapCommit(model.patch.bind(model), options)
|
|
23
|
+
};
|
|
24
|
+
if (isMany(model)) {
|
|
25
|
+
output = {
|
|
26
|
+
...output,
|
|
27
|
+
add: wrapCommit(model.add.bind(model), options),
|
|
28
|
+
remove: wrapCommit(model.remove.bind(model), options)
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
return output;
|
|
32
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { type ComputedRef, type WatchStopHandle } from "vue";
|
|
2
|
+
import type { ViewCall } from "../core/types/view.js";
|
|
3
|
+
export interface UseStoreViewTrackOptions {
|
|
4
|
+
deep?: boolean;
|
|
5
|
+
immediate?: boolean;
|
|
6
|
+
debounce?: number;
|
|
7
|
+
throttle?: number;
|
|
8
|
+
}
|
|
9
|
+
export interface UseStoreViewOptions<T> {
|
|
10
|
+
proxy?: boolean;
|
|
11
|
+
default?: T;
|
|
12
|
+
}
|
|
13
|
+
export type UseStoreViewData<T> = {
|
|
14
|
+
value: T;
|
|
15
|
+
} & (T extends Record<string, unknown> ? {
|
|
16
|
+
[K in keyof T]: T[K];
|
|
17
|
+
} : Record<string, unknown>);
|
|
18
|
+
export type UseStoreViewProxy<T> = {
|
|
19
|
+
data: UseStoreViewData<T>;
|
|
20
|
+
track: (handler: (value: T) => void, options?: UseStoreViewTrackOptions) => WatchStopHandle;
|
|
21
|
+
};
|
|
22
|
+
export type UseStoreViewComputed<T> = {
|
|
23
|
+
data: ComputedRef<T>;
|
|
24
|
+
track: (handler: (value: T) => void, options?: UseStoreViewTrackOptions) => WatchStopHandle;
|
|
25
|
+
};
|
|
26
|
+
export declare function useStoreView<V extends Record<string, ViewCall>, K extends keyof V & string, T = V[K] extends ComputedRef<infer R> ? R : unknown>(store: {
|
|
27
|
+
view: V;
|
|
28
|
+
}, key: K, options: UseStoreViewOptions<T> & {
|
|
29
|
+
proxy: false;
|
|
30
|
+
}): UseStoreViewComputed<T>;
|
|
31
|
+
export declare function useStoreView<V extends Record<string, ViewCall>, K extends keyof V & string, T = V[K] extends ComputedRef<infer R> ? R : unknown>(store: {
|
|
32
|
+
view: V;
|
|
33
|
+
}, key: K, options?: UseStoreViewOptions<T>): UseStoreViewProxy<T>;
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { computed, watch } from "vue";
|
|
2
|
+
import { debounce, throttle, toReactiveProxy } from "../core/utils/base.js";
|
|
3
|
+
function resolveDefault(view, defaultValue) {
|
|
4
|
+
if (defaultValue === void 0) {
|
|
5
|
+
return view;
|
|
6
|
+
}
|
|
7
|
+
return computed(() => {
|
|
8
|
+
const value = view.value;
|
|
9
|
+
if (value == null) {
|
|
10
|
+
return defaultValue;
|
|
11
|
+
}
|
|
12
|
+
return value;
|
|
13
|
+
});
|
|
14
|
+
}
|
|
15
|
+
function resolveData(source, proxy) {
|
|
16
|
+
if (proxy !== false) {
|
|
17
|
+
return toReactiveProxy(source);
|
|
18
|
+
}
|
|
19
|
+
return source;
|
|
20
|
+
}
|
|
21
|
+
export function useStoreView(store, key, options) {
|
|
22
|
+
if (!store.view[key]) {
|
|
23
|
+
throw new Error(`View "${key}" not found in store`);
|
|
24
|
+
}
|
|
25
|
+
const source = resolveDefault(store.view[key], options?.default);
|
|
26
|
+
const data = resolveData(source, options?.proxy);
|
|
27
|
+
function resolveCallback(callback, callbackOptions) {
|
|
28
|
+
if (callbackOptions?.debounce) {
|
|
29
|
+
return debounce(callback, callbackOptions.debounce);
|
|
30
|
+
}
|
|
31
|
+
if (callbackOptions?.throttle) {
|
|
32
|
+
return throttle(callback, callbackOptions.throttle);
|
|
33
|
+
}
|
|
34
|
+
return callback;
|
|
35
|
+
}
|
|
36
|
+
function track(handler, trackOptions) {
|
|
37
|
+
const callback = resolveCallback(handler, trackOptions);
|
|
38
|
+
const stop = watch(
|
|
39
|
+
source,
|
|
40
|
+
(value) => {
|
|
41
|
+
callback(value);
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
deep: trackOptions?.deep,
|
|
45
|
+
immediate: trackOptions?.immediate
|
|
46
|
+
}
|
|
47
|
+
);
|
|
48
|
+
return stop;
|
|
49
|
+
}
|
|
50
|
+
return {
|
|
51
|
+
data,
|
|
52
|
+
track
|
|
53
|
+
};
|
|
54
|
+
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { ConsolaInstance } from "consola";
|
|
2
|
-
import type {
|
|
2
|
+
import type { ModelDefinitions } from "../types/model.js";
|
|
3
|
+
import type { ViewDefinitions } from "../types/view.js";
|
|
3
4
|
import { type RuntimeActionConfig, type ActionFactory } from "../types/action.js";
|
|
4
|
-
export declare function createActionFactory<
|
|
5
|
+
export declare function createActionFactory<MD extends ModelDefinitions, VD extends ViewDefinitions<MD>>(config?: RuntimeActionConfig, logger?: ConsolaInstance): ActionFactory<MD, VD>;
|
|
@@ -1,77 +1,46 @@
|
|
|
1
|
-
import { buildCommitMethod } from "../utils/action.js";
|
|
2
1
|
import {
|
|
3
|
-
ActionApiMethod
|
|
4
|
-
DEFINITION
|
|
2
|
+
ActionApiMethod
|
|
5
3
|
} from "../types/action.js";
|
|
6
|
-
export function createActionFactory(config, logger
|
|
7
|
-
function apiCall(
|
|
8
|
-
|
|
4
|
+
export function createActionFactory(config, logger) {
|
|
5
|
+
function apiCall(request, commit) {
|
|
6
|
+
const mergedRequest = {
|
|
9
7
|
endpoint: config?.endpoint,
|
|
10
8
|
headers: config?.headers,
|
|
11
9
|
query: config?.query,
|
|
12
10
|
timeout: config?.timeout,
|
|
13
11
|
concurrent: config?.concurrent,
|
|
14
|
-
...
|
|
15
|
-
};
|
|
16
|
-
const actionDefinition = {
|
|
17
|
-
api: apiDefinition,
|
|
18
|
-
logger
|
|
12
|
+
...request
|
|
19
13
|
};
|
|
14
|
+
let key = "";
|
|
20
15
|
return {
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
};
|
|
27
|
-
return {
|
|
28
|
-
commit: buildCommitMethod(handleDefinition),
|
|
29
|
-
get [DEFINITION]() {
|
|
30
|
-
return handleDefinition;
|
|
31
|
-
}
|
|
32
|
-
};
|
|
16
|
+
get key() {
|
|
17
|
+
return key;
|
|
18
|
+
},
|
|
19
|
+
setKey(value) {
|
|
20
|
+
key = value;
|
|
33
21
|
},
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
}
|
|
22
|
+
request: mergedRequest,
|
|
23
|
+
commit,
|
|
24
|
+
logger
|
|
38
25
|
};
|
|
39
26
|
}
|
|
40
|
-
function apiGet(
|
|
41
|
-
return apiCall({
|
|
42
|
-
...definition,
|
|
43
|
-
method: ActionApiMethod.GET
|
|
44
|
-
});
|
|
27
|
+
function apiGet(request, commit) {
|
|
28
|
+
return apiCall({ ...request, method: ActionApiMethod.GET }, commit);
|
|
45
29
|
}
|
|
46
|
-
function apiHead(
|
|
47
|
-
return apiCall({
|
|
48
|
-
...definition,
|
|
49
|
-
method: ActionApiMethod.HEAD
|
|
50
|
-
});
|
|
30
|
+
function apiHead(request, commit) {
|
|
31
|
+
return apiCall({ ...request, method: ActionApiMethod.HEAD }, commit);
|
|
51
32
|
}
|
|
52
|
-
function apiPost(
|
|
53
|
-
return apiCall({
|
|
54
|
-
...definition,
|
|
55
|
-
method: ActionApiMethod.POST
|
|
56
|
-
});
|
|
33
|
+
function apiPost(request, commit) {
|
|
34
|
+
return apiCall({ ...request, method: ActionApiMethod.POST }, commit);
|
|
57
35
|
}
|
|
58
|
-
function apiPut(
|
|
59
|
-
return apiCall({
|
|
60
|
-
...definition,
|
|
61
|
-
method: ActionApiMethod.PUT
|
|
62
|
-
});
|
|
36
|
+
function apiPut(request, commit) {
|
|
37
|
+
return apiCall({ ...request, method: ActionApiMethod.PUT }, commit);
|
|
63
38
|
}
|
|
64
|
-
function apiPatch(
|
|
65
|
-
return apiCall({
|
|
66
|
-
...definition,
|
|
67
|
-
method: ActionApiMethod.PATCH
|
|
68
|
-
});
|
|
39
|
+
function apiPatch(request, commit) {
|
|
40
|
+
return apiCall({ ...request, method: ActionApiMethod.PATCH }, commit);
|
|
69
41
|
}
|
|
70
|
-
function apiDelete(
|
|
71
|
-
return apiCall({
|
|
72
|
-
...definition,
|
|
73
|
-
method: ActionApiMethod.DELETE
|
|
74
|
-
});
|
|
42
|
+
function apiDelete(request, commit) {
|
|
43
|
+
return apiCall({ ...request, method: ActionApiMethod.DELETE }, commit);
|
|
75
44
|
}
|
|
76
45
|
const api = Object.assign(apiCall, {
|
|
77
46
|
get: apiGet,
|
|
@@ -81,22 +50,21 @@ export function createActionFactory(config, logger, _model, _view) {
|
|
|
81
50
|
patch: apiPatch,
|
|
82
51
|
delete: apiDelete
|
|
83
52
|
});
|
|
84
|
-
function
|
|
85
|
-
|
|
86
|
-
handle: callback,
|
|
87
|
-
logger
|
|
88
|
-
};
|
|
53
|
+
function handler(callback) {
|
|
54
|
+
let key = "";
|
|
89
55
|
return {
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
56
|
+
get key() {
|
|
57
|
+
return key;
|
|
58
|
+
},
|
|
59
|
+
setKey(value) {
|
|
60
|
+
key = value;
|
|
61
|
+
},
|
|
62
|
+
callback,
|
|
63
|
+
logger
|
|
94
64
|
};
|
|
95
65
|
}
|
|
96
|
-
const commit = buildCommitMethod({ logger });
|
|
97
66
|
return {
|
|
98
67
|
api,
|
|
99
|
-
|
|
100
|
-
commit
|
|
68
|
+
handler
|
|
101
69
|
};
|
|
102
70
|
}
|
|
@@ -3,7 +3,14 @@ import {
|
|
|
3
3
|
} from "../types/model.js";
|
|
4
4
|
export function createModelFactory(config, logger) {
|
|
5
5
|
function one(shape, options) {
|
|
6
|
+
let key = "";
|
|
6
7
|
return {
|
|
8
|
+
get key() {
|
|
9
|
+
return key;
|
|
10
|
+
},
|
|
11
|
+
setKey(value) {
|
|
12
|
+
key = value;
|
|
13
|
+
},
|
|
7
14
|
shape,
|
|
8
15
|
kind: ModelKind.OBJECT,
|
|
9
16
|
options: {
|
|
@@ -14,7 +21,14 @@ export function createModelFactory(config, logger) {
|
|
|
14
21
|
};
|
|
15
22
|
}
|
|
16
23
|
function many(shape, options) {
|
|
24
|
+
let key = "";
|
|
17
25
|
return {
|
|
26
|
+
get key() {
|
|
27
|
+
return key;
|
|
28
|
+
},
|
|
29
|
+
setKey(value) {
|
|
30
|
+
key = value;
|
|
31
|
+
},
|
|
18
32
|
shape,
|
|
19
33
|
kind: ModelKind.ARRAY,
|
|
20
34
|
options: {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
|
-
import type { ShapeFactory } from "../types/shape.js";
|
|
2
|
+
import type { ShapeFactory, ShapeRawDefinition } from "../types/shape.js";
|
|
3
3
|
export declare const primitiveField: {
|
|
4
4
|
string: typeof z.string;
|
|
5
5
|
number: typeof z.number;
|
|
@@ -42,4 +42,4 @@ export declare const specialField: {
|
|
|
42
42
|
nullable: typeof z.nullable;
|
|
43
43
|
optional: typeof z.optional;
|
|
44
44
|
};
|
|
45
|
-
export declare function shape<T extends
|
|
45
|
+
export declare function shape<T extends ShapeRawDefinition>(definition: T | ((factory: ShapeFactory) => T)): import("../types/shape").ShapeCall<T>;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
|
+
import { createShape } from "../utils/shape.js";
|
|
2
3
|
export const primitiveField = {
|
|
3
4
|
string: z.string,
|
|
4
5
|
number: z.number,
|
|
@@ -43,7 +44,7 @@ export const specialField = {
|
|
|
43
44
|
};
|
|
44
45
|
export function shape(definition) {
|
|
45
46
|
if (typeof definition === "function") {
|
|
46
|
-
return
|
|
47
|
+
return createShape(
|
|
47
48
|
definition({
|
|
48
49
|
...primitiveField,
|
|
49
50
|
...structureField,
|
|
@@ -52,5 +53,5 @@ export function shape(definition) {
|
|
|
52
53
|
})
|
|
53
54
|
);
|
|
54
55
|
}
|
|
55
|
-
return
|
|
56
|
+
return createShape(definition);
|
|
56
57
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import type { ConsolaInstance } from "consola";
|
|
2
|
-
import type {
|
|
2
|
+
import type { ModelDefinitions } from "../types/model.js";
|
|
3
3
|
import type { RuntimeViewConfig, ViewFactory } from "../types/view.js";
|
|
4
|
-
export declare function createViewFactory<
|
|
4
|
+
export declare function createViewFactory<MD extends ModelDefinitions>(config?: RuntimeViewConfig, logger?: ConsolaInstance): ViewFactory<MD>;
|
|
@@ -1,16 +1,38 @@
|
|
|
1
|
-
export function createViewFactory(config, logger
|
|
2
|
-
function from(
|
|
1
|
+
export function createViewFactory(config, logger) {
|
|
2
|
+
function from(model, resolver, options) {
|
|
3
|
+
let key = "";
|
|
3
4
|
const definition = {
|
|
4
|
-
|
|
5
|
+
get key() {
|
|
6
|
+
return key;
|
|
7
|
+
},
|
|
8
|
+
setKey(value) {
|
|
9
|
+
key = value;
|
|
10
|
+
},
|
|
11
|
+
model: [model],
|
|
5
12
|
resolver,
|
|
13
|
+
options: {
|
|
14
|
+
clone: config?.clone,
|
|
15
|
+
...options
|
|
16
|
+
},
|
|
6
17
|
logger
|
|
7
18
|
};
|
|
8
19
|
return definition;
|
|
9
20
|
}
|
|
10
|
-
function merge(
|
|
21
|
+
function merge(models, resolver, options) {
|
|
22
|
+
let key = "";
|
|
11
23
|
return {
|
|
12
|
-
|
|
24
|
+
get key() {
|
|
25
|
+
return key;
|
|
26
|
+
},
|
|
27
|
+
setKey(value) {
|
|
28
|
+
key = value;
|
|
29
|
+
},
|
|
30
|
+
models,
|
|
13
31
|
resolver,
|
|
32
|
+
options: {
|
|
33
|
+
clone: config?.clone,
|
|
34
|
+
...options
|
|
35
|
+
},
|
|
14
36
|
logger
|
|
15
37
|
};
|
|
16
38
|
}
|