@diphyx/harlemify 5.3.0 → 5.4.1
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 +11 -1
- package/dist/module.json +2 -2
- package/dist/module.mjs +5 -3
- package/dist/runtime/composables/compose.d.ts +9 -0
- package/dist/runtime/composables/compose.js +10 -0
- package/dist/runtime/composables/view.d.ts +2 -20
- package/dist/runtime/composables/view.js +5 -23
- package/dist/runtime/core/layers/model.js +34 -5
- package/dist/runtime/core/store.d.ts +2 -1
- package/dist/runtime/core/store.js +41 -24
- package/dist/runtime/core/types/action.d.ts +1 -1
- package/dist/runtime/core/types/compose.d.ts +18 -0
- package/dist/runtime/core/types/compose.js +0 -0
- package/dist/runtime/core/types/model.d.ts +40 -27
- package/dist/runtime/core/types/model.js +5 -0
- package/dist/runtime/core/types/shape.d.ts +0 -6
- package/dist/runtime/core/types/store.d.ts +6 -2
- package/dist/runtime/core/utils/base.d.ts +0 -7
- package/dist/runtime/core/utils/base.js +0 -45
- package/dist/runtime/core/utils/compose.d.ts +3 -0
- package/dist/runtime/core/utils/compose.js +37 -0
- package/dist/runtime/core/utils/model.js +156 -241
- package/dist/runtime/core/utils/shape.d.ts +4 -3
- package/dist/runtime/core/utils/shape.js +84 -124
- package/dist/runtime/core/utils/store.d.ts +1 -1
- package/dist/runtime/core/utils/store.js +2 -11
- package/dist/runtime/core/utils/view.js +1 -1
- package/dist/runtime/index.d.ts +5 -2
- package/dist/runtime/index.js +2 -1
- package/dist/runtime/plugin.js +3 -17
- package/dist/runtime/plugins/ssr.d.ts +9 -0
- package/dist/runtime/plugins/ssr.js +53 -0
- package/package.json +17 -18
package/README.md
CHANGED
|
@@ -77,11 +77,21 @@ await execute();
|
|
|
77
77
|
|
|
78
78
|
<template>
|
|
79
79
|
<ul v-if="!loading">
|
|
80
|
-
<li v-for="user in data
|
|
80
|
+
<li v-for="user in data" :key="user.id">{{ user.name }}</li>
|
|
81
81
|
</ul>
|
|
82
82
|
</template>
|
|
83
83
|
```
|
|
84
84
|
|
|
85
|
+
## Compatibility
|
|
86
|
+
|
|
87
|
+
| Dependency | Version |
|
|
88
|
+
| ---------- | --------------------- |
|
|
89
|
+
| Nuxt | `^3.14.0` or `^4.0.0` |
|
|
90
|
+
| Vue | `^3.5.0` |
|
|
91
|
+
| Zod | `^4.0.0` |
|
|
92
|
+
|
|
93
|
+
> **Note:** Early Nuxt 4 versions (e.g., 4.1.x) may have issues resolving the `#build` alias for module templates. If you encounter build errors related to `#build/harlemify.config`, upgrade to the latest Nuxt 4 release.
|
|
94
|
+
|
|
85
95
|
## Documentation
|
|
86
96
|
|
|
87
97
|
[https://diphyx.github.io/harlemify/](https://diphyx.github.io/harlemify/)
|
package/dist/module.json
CHANGED
package/dist/module.mjs
CHANGED
|
@@ -1,17 +1,18 @@
|
|
|
1
|
-
import { defineNuxtModule, createResolver, addTemplate, addPlugin, addImportsDir, addImports } from '@nuxt/kit';
|
|
1
|
+
import { useLogger, defineNuxtModule, createResolver, addTemplate, addPlugin, addImportsDir, addImports } from '@nuxt/kit';
|
|
2
2
|
|
|
3
|
+
const logger = useLogger("harlemify");
|
|
3
4
|
const module = defineNuxtModule({
|
|
4
5
|
meta: {
|
|
5
6
|
name: "harlemify",
|
|
6
7
|
configKey: "harlemify",
|
|
7
8
|
compatibility: {
|
|
8
|
-
nuxt: "
|
|
9
|
+
nuxt: "^3.14.0 || ^4.0.0"
|
|
9
10
|
}
|
|
10
11
|
},
|
|
11
12
|
defaults: {},
|
|
12
13
|
setup(options, nuxt) {
|
|
13
14
|
const { resolve } = createResolver(import.meta.url);
|
|
14
|
-
addTemplate({
|
|
15
|
+
const template = addTemplate({
|
|
15
16
|
write: true,
|
|
16
17
|
filename: "harlemify.config.mjs",
|
|
17
18
|
getContents() {
|
|
@@ -27,6 +28,7 @@ const module = defineNuxtModule({
|
|
|
27
28
|
}
|
|
28
29
|
]);
|
|
29
30
|
nuxt.options.build.transpile.push(/@harlem\//);
|
|
31
|
+
logger.success(`Module registered, config template: ${template.dst}`);
|
|
30
32
|
}
|
|
31
33
|
});
|
|
32
34
|
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { Ref } from "vue";
|
|
2
|
+
import type { ComposeCallback, ComposeDefinitions, StoreCompose } from "../core/types/compose.js";
|
|
3
|
+
export type UseStoreCompose<A extends any[] = any[]> = {
|
|
4
|
+
execute: (...args: A) => Promise<void>;
|
|
5
|
+
active: Readonly<Ref<boolean>>;
|
|
6
|
+
};
|
|
7
|
+
export declare function useStoreCompose<CD extends ComposeDefinitions, K extends keyof StoreCompose<CD> & string, A extends any[] = CD[K] extends ComposeCallback<infer P> ? P : any[]>(store: {
|
|
8
|
+
compose: StoreCompose<CD>;
|
|
9
|
+
}, key: K): UseStoreCompose<A>;
|
|
@@ -6,28 +6,10 @@ export interface UseStoreViewTrackOptions {
|
|
|
6
6
|
debounce?: number;
|
|
7
7
|
throttle?: number;
|
|
8
8
|
}
|
|
9
|
-
export
|
|
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> = {
|
|
9
|
+
export type UseStoreView<T> = {
|
|
23
10
|
data: ComputedRef<T>;
|
|
24
11
|
track: (handler: (value: T) => void, options?: UseStoreViewTrackOptions) => WatchStopHandle;
|
|
25
12
|
};
|
|
26
13
|
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
14
|
view: V;
|
|
28
|
-
}, key: K
|
|
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>;
|
|
15
|
+
}, key: K): UseStoreView<T>;
|
|
@@ -1,29 +1,11 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { debounce, throttle
|
|
3
|
-
function
|
|
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) {
|
|
1
|
+
import { watch } from "vue";
|
|
2
|
+
import { debounce, throttle } from "../core/utils/base.js";
|
|
3
|
+
export function useStoreView(store, key) {
|
|
22
4
|
if (!store.view[key]) {
|
|
23
5
|
throw new Error(`View "${key}" not found in store`);
|
|
24
6
|
}
|
|
25
|
-
const source =
|
|
26
|
-
const data =
|
|
7
|
+
const source = store.view[key];
|
|
8
|
+
const data = source;
|
|
27
9
|
function resolveCallback(callback, callbackOptions) {
|
|
28
10
|
if (callbackOptions?.debounce) {
|
|
29
11
|
return debounce(callback, callbackOptions.debounce);
|
|
@@ -1,26 +1,55 @@
|
|
|
1
1
|
import { wrapBaseDefinition } from "../utils/base.js";
|
|
2
|
+
import { resolveShapeIdentifier } from "../utils/shape.js";
|
|
2
3
|
import {
|
|
3
|
-
ModelType
|
|
4
|
+
ModelType,
|
|
5
|
+
ModelManyKind
|
|
4
6
|
} from "../types/model.js";
|
|
5
7
|
export function createModelFactory(config, logger) {
|
|
6
8
|
function one(shape, options) {
|
|
9
|
+
function defaultResolver() {
|
|
10
|
+
if (options?.default) {
|
|
11
|
+
return options.default();
|
|
12
|
+
}
|
|
13
|
+
if ("defaults" in shape && typeof shape.defaults === "function") {
|
|
14
|
+
return shape.defaults();
|
|
15
|
+
}
|
|
16
|
+
return {};
|
|
17
|
+
}
|
|
7
18
|
return wrapBaseDefinition({
|
|
8
19
|
shape,
|
|
9
20
|
type: ModelType.ONE,
|
|
21
|
+
default: defaultResolver,
|
|
10
22
|
options: {
|
|
11
|
-
|
|
12
|
-
|
|
23
|
+
pre: options?.pre,
|
|
24
|
+
post: options?.post
|
|
13
25
|
},
|
|
14
26
|
logger
|
|
15
27
|
});
|
|
16
28
|
}
|
|
17
29
|
function many(shape, options) {
|
|
30
|
+
const kind = options?.kind ?? ModelManyKind.LIST;
|
|
31
|
+
let identifier;
|
|
32
|
+
if (kind === ModelManyKind.LIST) {
|
|
33
|
+
identifier = resolveShapeIdentifier(shape, options?.identifier, config?.identifier);
|
|
34
|
+
}
|
|
35
|
+
function defaultResolver() {
|
|
36
|
+
if (options?.default) {
|
|
37
|
+
return options.default();
|
|
38
|
+
}
|
|
39
|
+
if (kind === ModelManyKind.LIST) {
|
|
40
|
+
return [];
|
|
41
|
+
}
|
|
42
|
+
return {};
|
|
43
|
+
}
|
|
18
44
|
return wrapBaseDefinition({
|
|
19
45
|
shape,
|
|
20
46
|
type: ModelType.MANY,
|
|
47
|
+
kind,
|
|
48
|
+
identifier,
|
|
49
|
+
default: defaultResolver,
|
|
21
50
|
options: {
|
|
22
|
-
|
|
23
|
-
|
|
51
|
+
pre: options?.pre,
|
|
52
|
+
post: options?.post
|
|
24
53
|
},
|
|
25
54
|
logger
|
|
26
55
|
});
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { ModelDefinitions } from "./types/model.js";
|
|
2
2
|
import type { ViewDefinitions } from "./types/view.js";
|
|
3
3
|
import type { ActionDefinitions } from "./types/action.js";
|
|
4
|
+
import type { ComposeDefinitions } from "./types/compose.js";
|
|
4
5
|
import type { Store, StoreConfig } from "./types/store.js";
|
|
5
|
-
export declare function createStore<MD extends ModelDefinitions, VD extends ViewDefinitions<MD>, AD extends ActionDefinitions<MD, VD
|
|
6
|
+
export declare function createStore<MD extends ModelDefinitions, VD extends ViewDefinitions<MD>, AD extends ActionDefinitions<MD, VD>, CD extends ComposeDefinitions = ComposeDefinitions>(config: StoreConfig<MD, VD, AD, CD>): Store<MD, VD, AD, CD>;
|
|
@@ -5,29 +5,46 @@ import { createModelFactory } from "./layers/model.js";
|
|
|
5
5
|
import { createViewFactory } from "./layers/view.js";
|
|
6
6
|
import { createActionFactory } from "./layers/action.js";
|
|
7
7
|
import { createStoreState, createStoreModel, createStoreView, createStoreAction } from "./utils/store.js";
|
|
8
|
+
import { createStoreCompose } from "./utils/compose.js";
|
|
8
9
|
export function createStore(config) {
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
10
|
+
function init() {
|
|
11
|
+
const logger = createConsola({
|
|
12
|
+
level: runtimeConfig.logger,
|
|
13
|
+
defaults: {
|
|
14
|
+
tag: `harlemify:${config.name}`
|
|
15
|
+
}
|
|
16
|
+
});
|
|
17
|
+
logger.info("Creating store");
|
|
18
|
+
const modelFactory = createModelFactory(runtimeConfig.model, logger);
|
|
19
|
+
const viewFactory = createViewFactory(runtimeConfig.view, logger);
|
|
20
|
+
const actionFactory = createActionFactory(runtimeConfig.action, logger);
|
|
21
|
+
const modelDefinitions = config.model(modelFactory);
|
|
22
|
+
const viewDefinitions = config.view(viewFactory);
|
|
23
|
+
const actionDefinitions = config.action(actionFactory);
|
|
24
|
+
const state = createStoreState(modelDefinitions);
|
|
25
|
+
const source = createStoreSource(config.name, state);
|
|
26
|
+
const model = createStoreModel(modelDefinitions, source);
|
|
27
|
+
const view = createStoreView(viewDefinitions, source);
|
|
28
|
+
const action = createStoreAction(actionDefinitions, model, view);
|
|
29
|
+
const compose = createStoreCompose(config.compose, { model, view, action }, logger);
|
|
30
|
+
logger.info("Store created");
|
|
31
|
+
return {
|
|
32
|
+
model,
|
|
33
|
+
view,
|
|
34
|
+
action,
|
|
35
|
+
compose
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
if (config.lazy) {
|
|
39
|
+
let instance;
|
|
40
|
+
return new Proxy({}, {
|
|
41
|
+
get(_, prop) {
|
|
42
|
+
if (!instance) {
|
|
43
|
+
instance = init();
|
|
44
|
+
}
|
|
45
|
+
return instance[prop];
|
|
46
|
+
}
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
return init();
|
|
33
50
|
}
|
|
@@ -64,7 +64,7 @@ export type ActionHandlerCallback<MD extends ModelDefinitions, VD extends ViewDe
|
|
|
64
64
|
model: StoreModel<MD>;
|
|
65
65
|
view: StoreView<MD, VD>;
|
|
66
66
|
payload: P;
|
|
67
|
-
}) => Promise<R
|
|
67
|
+
}) => Promise<R> | R;
|
|
68
68
|
export interface ActionHandlerDefinition<MD extends ModelDefinitions, VD extends ViewDefinitions<MD>, P = unknown, R = void> extends BaseDefinition {
|
|
69
69
|
callback: ActionHandlerCallback<MD, VD, P, R>;
|
|
70
70
|
options?: ActionHandlerOptions<P>;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { Ref } from "vue";
|
|
2
|
+
import type { ModelDefinitions, StoreModel } from "./model.js";
|
|
3
|
+
import type { ViewDefinitions, StoreView } from "./view.js";
|
|
4
|
+
import type { ActionDefinitions, StoreAction } from "./action.js";
|
|
5
|
+
export type ComposeCallback<A extends any[] = any[]> = (...args: A) => Promise<void> | void;
|
|
6
|
+
export type ComposeDefinitions = Record<string, ComposeCallback<any[]>>;
|
|
7
|
+
export interface ComposeContext<MD extends ModelDefinitions, VD extends ViewDefinitions<MD>, AD extends ActionDefinitions<MD, VD>> {
|
|
8
|
+
model: StoreModel<MD>;
|
|
9
|
+
view: StoreView<MD, VD>;
|
|
10
|
+
action: StoreAction<MD, VD, AD>;
|
|
11
|
+
}
|
|
12
|
+
export type ComposeCall<A extends any[] = any[]> = {
|
|
13
|
+
(...args: A): Promise<void>;
|
|
14
|
+
active: Readonly<Ref<boolean>>;
|
|
15
|
+
};
|
|
16
|
+
export type StoreCompose<CD extends ComposeDefinitions> = {
|
|
17
|
+
[K in keyof CD]: CD[K] extends ComposeCallback<infer A> ? ComposeCall<A> : never;
|
|
18
|
+
};
|
|
File without changes
|
|
@@ -23,33 +23,35 @@ export declare enum ModelManyMode {
|
|
|
23
23
|
REMOVE = "remove",
|
|
24
24
|
ADD = "add"
|
|
25
25
|
}
|
|
26
|
+
export declare enum ModelSilent {
|
|
27
|
+
PRE = "pre",
|
|
28
|
+
POST = "post"
|
|
29
|
+
}
|
|
26
30
|
export type ModelDefaultIdentifier<S extends Shape> = "id" extends keyof S ? "id" : keyof S;
|
|
27
31
|
export type AtLeastOne<S extends Shape> = {
|
|
28
32
|
[K in keyof S]: Pick<S, K>;
|
|
29
33
|
}[keyof S];
|
|
30
|
-
export interface
|
|
31
|
-
|
|
32
|
-
|
|
34
|
+
export interface ModelDefinitionOptions {
|
|
35
|
+
pre?: () => void;
|
|
36
|
+
post?: () => void;
|
|
33
37
|
}
|
|
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
|
-
} : {});
|
|
40
38
|
export interface ModelOneDefinition<S extends Shape> extends BaseDefinition {
|
|
41
39
|
shape: ShapeType<S>;
|
|
42
40
|
type: ModelType.ONE;
|
|
43
|
-
|
|
41
|
+
default: () => S;
|
|
42
|
+
options?: ModelDefinitionOptions;
|
|
44
43
|
}
|
|
45
44
|
export interface ModelManyDefinition<S extends Shape, I extends keyof S = ModelDefaultIdentifier<S>, T extends ModelManyKind = ModelManyKind.LIST> extends BaseDefinition {
|
|
46
45
|
shape: ShapeType<S>;
|
|
47
46
|
type: ModelType.MANY;
|
|
48
|
-
|
|
47
|
+
kind: T;
|
|
48
|
+
identifier: [T] extends [ModelManyKind.LIST] ? I : never;
|
|
49
|
+
default: () => [T] extends [ModelManyKind.LIST] ? S[] : Record<string, S[]>;
|
|
50
|
+
options?: ModelDefinitionOptions;
|
|
49
51
|
}
|
|
50
52
|
export type ModelDefinition<S extends Shape> = ModelOneDefinition<S> | ModelManyDefinition<S, any, any>;
|
|
51
53
|
export type ModelDefinitions = Record<string, ModelDefinition<any>>;
|
|
52
|
-
export type ModelDefinitionInfer<MD extends ModelDefinitions, K extends keyof MD> = MD[K] extends ModelOneDefinition<infer S> ? S
|
|
54
|
+
export type ModelDefinitionInfer<MD extends ModelDefinitions, K extends keyof MD> = MD[K] extends ModelOneDefinition<infer S> ? S : MD[K] extends ModelManyDefinition<infer S, any, infer T> ? [T] extends [ModelManyKind.LIST] ? S[] : Record<string, S[]> : never;
|
|
53
55
|
export type ModelDefinitionInferTuple<MD extends ModelDefinitions, K extends readonly (keyof MD)[]> = {
|
|
54
56
|
[I in keyof K]: K[I] extends keyof MD ? ModelDefinitionInfer<MD, K[I]> : never;
|
|
55
57
|
};
|
|
@@ -57,36 +59,47 @@ export type ModelDefinitionsInfer<MD extends ModelDefinitions> = {
|
|
|
57
59
|
[K in keyof MD]: ModelDefinitionInfer<MD, K>;
|
|
58
60
|
};
|
|
59
61
|
export interface ModelFactory {
|
|
60
|
-
one<S extends Shape>(shape: ShapeType<S>, options?:
|
|
61
|
-
|
|
62
|
+
one<S extends Shape>(shape: ShapeType<S>, options?: ModelDefinitionOptions & {
|
|
63
|
+
default?: () => S;
|
|
64
|
+
}): ModelOneDefinition<S>;
|
|
65
|
+
many<S extends Shape, I extends keyof S = ModelDefaultIdentifier<S>, T extends ModelManyKind = ModelManyKind.LIST>(shape: ShapeType<S>, options?: ModelDefinitionOptions & {
|
|
66
|
+
kind?: T;
|
|
67
|
+
identifier?: [T] extends [ModelManyKind.LIST] ? I : never;
|
|
68
|
+
default?: () => [T] extends [ModelManyKind.LIST] ? S[] : Record<string, S[]>;
|
|
69
|
+
}): ModelManyDefinition<S, I, T>;
|
|
62
70
|
}
|
|
63
71
|
export interface ModelOneCommitOptions {
|
|
64
72
|
deep?: boolean;
|
|
73
|
+
silent?: true | ModelSilent;
|
|
65
74
|
}
|
|
66
75
|
export interface ModelManyCommitOptions {
|
|
67
76
|
by?: string;
|
|
68
77
|
prepend?: boolean;
|
|
69
78
|
unique?: boolean;
|
|
70
79
|
deep?: boolean;
|
|
80
|
+
silent?: true | ModelSilent;
|
|
71
81
|
}
|
|
72
82
|
export interface ModelOneCommit<S extends Shape> {
|
|
73
|
-
set: (
|
|
74
|
-
reset: () => void;
|
|
75
|
-
patch: (
|
|
83
|
+
set: (payload: S, options?: Pick<ModelOneCommitOptions, "silent">) => void;
|
|
84
|
+
reset: (options?: Pick<ModelOneCommitOptions, "silent">) => void;
|
|
85
|
+
patch: (payload: Partial<S>, options?: Pick<ModelOneCommitOptions, "deep" | "silent">) => void;
|
|
76
86
|
}
|
|
77
87
|
export interface ModelManyListCommit<S extends Shape, I extends keyof S = ModelDefaultIdentifier<S>> {
|
|
78
|
-
set: (
|
|
79
|
-
reset: () => void;
|
|
80
|
-
patch: (
|
|
81
|
-
remove: (
|
|
82
|
-
add: (
|
|
88
|
+
set: (payload: S[], options?: Pick<ModelManyCommitOptions, "silent">) => void;
|
|
89
|
+
reset: (options?: Pick<ModelManyCommitOptions, "silent">) => void;
|
|
90
|
+
patch: (payload: Partial<S> | Partial<S>[], options?: Pick<ModelManyCommitOptions, "by" | "deep" | "silent">) => void;
|
|
91
|
+
remove: (payload: Pick<S, I> | Pick<S, I>[] | AtLeastOne<S> | AtLeastOne<S>[], options?: Pick<ModelManyCommitOptions, "silent">) => void;
|
|
92
|
+
add: (payload: S | S[], options?: Pick<ModelManyCommitOptions, "by" | "prepend" | "unique" | "silent">) => void;
|
|
83
93
|
}
|
|
84
94
|
export interface ModelManyRecordCommit<S extends Shape> {
|
|
85
|
-
set: (
|
|
86
|
-
reset: () => void;
|
|
87
|
-
patch: (
|
|
88
|
-
remove: (
|
|
89
|
-
add: (
|
|
95
|
+
set: (payload: Record<string, S[]>, options?: Pick<ModelOneCommitOptions, "silent">) => void;
|
|
96
|
+
reset: (options?: Pick<ModelOneCommitOptions, "silent">) => void;
|
|
97
|
+
patch: (payload: Record<string, S[]>, options?: Pick<ModelOneCommitOptions, "deep" | "silent">) => void;
|
|
98
|
+
remove: (payload: string, options?: Pick<ModelOneCommitOptions, "silent">) => void;
|
|
99
|
+
add: (payload: {
|
|
100
|
+
key: string;
|
|
101
|
+
value: S[];
|
|
102
|
+
}, options?: Pick<ModelOneCommitOptions, "silent">) => void;
|
|
90
103
|
}
|
|
91
104
|
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>;
|
|
92
105
|
export type ModelOneCall<S extends Shape> = ModelOneCommit<S> & {
|
|
@@ -22,3 +22,8 @@ export var ModelManyMode = /* @__PURE__ */ ((ModelManyMode2) => {
|
|
|
22
22
|
ModelManyMode2["ADD"] = "add";
|
|
23
23
|
return ModelManyMode2;
|
|
24
24
|
})(ModelManyMode || {});
|
|
25
|
+
export var ModelSilent = /* @__PURE__ */ ((ModelSilent2) => {
|
|
26
|
+
ModelSilent2["PRE"] = "pre";
|
|
27
|
+
ModelSilent2["POST"] = "post";
|
|
28
|
+
return ModelSilent2;
|
|
29
|
+
})(ModelSilent || {});
|
|
@@ -7,12 +7,6 @@ export type ShapeInfer<T extends z.ZodType<any>> = z.infer<T>;
|
|
|
7
7
|
export type ShapeCall<T extends ShapeRawDefinition> = z.ZodObject<T> & {
|
|
8
8
|
defaults: (overrides?: Partial<z.infer<z.ZodObject<T>>>) => z.infer<z.ZodObject<T>>;
|
|
9
9
|
};
|
|
10
|
-
export interface ShapeResolved<T extends ShapeDefinition = ShapeDefinition> {
|
|
11
|
-
identifier?: keyof T["shape"] & string;
|
|
12
|
-
defaults: Record<string, unknown>;
|
|
13
|
-
fields: (keyof T["shape"] & string)[];
|
|
14
|
-
aliases: Record<string, string>;
|
|
15
|
-
}
|
|
16
10
|
export interface ShapeFieldDefinition {
|
|
17
11
|
meta?: {
|
|
18
12
|
identifier?: boolean;
|
|
@@ -1,14 +1,18 @@
|
|
|
1
1
|
import type { ModelDefinitions, ModelFactory, StoreModel } from "./model.js";
|
|
2
2
|
import type { ViewDefinitions, ViewFactory, StoreView } from "./view.js";
|
|
3
3
|
import type { ActionDefinitions, ActionFactory, StoreAction } from "./action.js";
|
|
4
|
-
|
|
4
|
+
import type { ComposeDefinitions, ComposeContext, StoreCompose } from "./compose.js";
|
|
5
|
+
export interface StoreConfig<MD extends ModelDefinitions, VD extends ViewDefinitions<MD>, AD extends ActionDefinitions<MD, VD>, CD extends ComposeDefinitions = ComposeDefinitions> {
|
|
5
6
|
name: string;
|
|
6
7
|
model: (factory: ModelFactory) => MD;
|
|
7
8
|
view: (factory: ViewFactory<MD>) => VD;
|
|
8
9
|
action: (factory: ActionFactory<MD, VD>) => AD;
|
|
10
|
+
compose?: (context: ComposeContext<MD, VD, AD>) => CD;
|
|
11
|
+
lazy?: boolean;
|
|
9
12
|
}
|
|
10
|
-
export interface Store<MD extends ModelDefinitions, VD extends ViewDefinitions<MD>, AD extends ActionDefinitions<MD, VD
|
|
13
|
+
export interface Store<MD extends ModelDefinitions, VD extends ViewDefinitions<MD>, AD extends ActionDefinitions<MD, VD>, CD extends ComposeDefinitions = ComposeDefinitions> {
|
|
11
14
|
model: StoreModel<MD>;
|
|
12
15
|
view: StoreView<MD, VD>;
|
|
13
16
|
action: StoreAction<MD, VD, AD>;
|
|
17
|
+
compose: StoreCompose<CD>;
|
|
14
18
|
}
|
|
@@ -6,12 +6,5 @@ export declare function ensureArray<T>(value: T | T[]): T[];
|
|
|
6
6
|
export declare function isObject(value: unknown): value is object;
|
|
7
7
|
export declare function isPlainObject(value: unknown): value is Record<string, unknown>;
|
|
8
8
|
export declare function isEmptyRecord(record: Record<string, unknown> | undefined): record is undefined;
|
|
9
|
-
type ReferenceProxy<T> = {
|
|
10
|
-
value: T;
|
|
11
|
-
} & Record<string | symbol, unknown>;
|
|
12
|
-
export declare function toReactiveProxy<T>(reference: {
|
|
13
|
-
value: T;
|
|
14
|
-
}): ReferenceProxy<T>;
|
|
15
9
|
export declare function debounce<T extends (...args: any[]) => any>(callback: T, delay: number): T;
|
|
16
10
|
export declare function throttle<T extends (...args: any[]) => any>(callback: T, delay: number): T;
|
|
17
|
-
export {};
|
|
@@ -43,51 +43,6 @@ export function isEmptyRecord(record) {
|
|
|
43
43
|
}
|
|
44
44
|
return false;
|
|
45
45
|
}
|
|
46
|
-
export function toReactiveProxy(reference) {
|
|
47
|
-
function get(_target, prop) {
|
|
48
|
-
if (prop === "value") {
|
|
49
|
-
return reference.value;
|
|
50
|
-
}
|
|
51
|
-
if (!isObject(reference.value)) {
|
|
52
|
-
return void 0;
|
|
53
|
-
}
|
|
54
|
-
return reference.value[prop];
|
|
55
|
-
}
|
|
56
|
-
function has(_target, prop) {
|
|
57
|
-
if (prop === "value") {
|
|
58
|
-
return true;
|
|
59
|
-
}
|
|
60
|
-
if (!isObject(reference.value)) {
|
|
61
|
-
return false;
|
|
62
|
-
}
|
|
63
|
-
return prop in reference.value;
|
|
64
|
-
}
|
|
65
|
-
function ownKeys() {
|
|
66
|
-
if (!isObject(reference.value)) {
|
|
67
|
-
return [];
|
|
68
|
-
}
|
|
69
|
-
return Reflect.ownKeys(reference.value);
|
|
70
|
-
}
|
|
71
|
-
function getOwnPropertyDescriptor(_target, prop) {
|
|
72
|
-
if (!isObject(reference.value) || !(prop in reference.value)) {
|
|
73
|
-
return void 0;
|
|
74
|
-
}
|
|
75
|
-
return {
|
|
76
|
-
configurable: true,
|
|
77
|
-
enumerable: true,
|
|
78
|
-
value: reference.value[prop]
|
|
79
|
-
};
|
|
80
|
-
}
|
|
81
|
-
return new Proxy(
|
|
82
|
-
{},
|
|
83
|
-
{
|
|
84
|
-
get,
|
|
85
|
-
has,
|
|
86
|
-
ownKeys,
|
|
87
|
-
getOwnPropertyDescriptor
|
|
88
|
-
}
|
|
89
|
-
);
|
|
90
|
-
}
|
|
91
46
|
export function debounce(callback, delay) {
|
|
92
47
|
let timer = null;
|
|
93
48
|
return (...args) => {
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import type { ConsolaInstance } from "consola";
|
|
2
|
+
import type { ComposeDefinitions, StoreCompose } from "../types/compose.js";
|
|
3
|
+
export declare function createStoreCompose<CD extends ComposeDefinitions>(composeConfig: ((...args: any[]) => CD) | undefined, context: Record<string, unknown>, logger?: ConsolaInstance): StoreCompose<CD>;
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { ref, readonly } from "vue";
|
|
2
|
+
function createComposeAction(key, callback, logger) {
|
|
3
|
+
logger?.debug("Registering compose action", {
|
|
4
|
+
action: key
|
|
5
|
+
});
|
|
6
|
+
const active = ref(false);
|
|
7
|
+
async function execute(...args) {
|
|
8
|
+
active.value = true;
|
|
9
|
+
try {
|
|
10
|
+
logger?.debug("Compose action executing", {
|
|
11
|
+
action: key
|
|
12
|
+
});
|
|
13
|
+
await callback(...args);
|
|
14
|
+
logger?.debug("Compose action success", {
|
|
15
|
+
action: key
|
|
16
|
+
});
|
|
17
|
+
} finally {
|
|
18
|
+
active.value = false;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
return Object.assign(execute, {
|
|
22
|
+
get active() {
|
|
23
|
+
return readonly(active);
|
|
24
|
+
}
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
export function createStoreCompose(composeConfig, context, logger) {
|
|
28
|
+
const output = {};
|
|
29
|
+
if (!composeConfig) {
|
|
30
|
+
return output;
|
|
31
|
+
}
|
|
32
|
+
const composeDefinitions = composeConfig(context);
|
|
33
|
+
for (const [key, callback] of Object.entries(composeDefinitions)) {
|
|
34
|
+
output[key] = createComposeAction(key, callback, logger);
|
|
35
|
+
}
|
|
36
|
+
return output;
|
|
37
|
+
}
|