@diphyx/harlemify 6.2.0 → 6.3.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/dist/module.json +1 -1
- package/dist/runtime/core/layers/action.d.ts +2 -2
- package/dist/runtime/core/layers/model.d.ts +2 -2
- package/dist/runtime/core/layers/view.d.ts +2 -2
- package/dist/runtime/core/store.js +2 -7
- package/dist/runtime/core/types/action.d.ts +2 -1
- package/dist/runtime/core/types/base.d.ts +7 -2
- package/dist/runtime/core/types/model.d.ts +11 -7
- package/dist/runtime/core/utils/action.js +5 -5
- package/dist/runtime/core/utils/base.d.ts +2 -0
- package/dist/runtime/core/utils/base.js +20 -8
- package/dist/runtime/core/utils/compose.d.ts +2 -2
- package/dist/runtime/core/utils/logger.d.ts +2 -0
- package/dist/runtime/core/utils/logger.js +22 -0
- package/dist/runtime/core/utils/model.js +64 -24
- package/dist/runtime/core/utils/shape.js +2 -3
- package/dist/runtime/core/utils/view.js +2 -1
- package/dist/runtime/index.d.ts +1 -1
- package/dist/runtime/index.js +8 -1
- package/package.json +7 -6
package/dist/module.json
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { Logger } from "../types/base.js";
|
|
2
2
|
import type { ModelDefinitions } from "../types/model.js";
|
|
3
3
|
import type { ViewDefinitions } from "../types/view.js";
|
|
4
4
|
import { type RuntimeActionConfig, type ActionFactory } from "../types/action.js";
|
|
5
|
-
export declare function createActionFactory<MD extends ModelDefinitions, VD extends ViewDefinitions<MD>>(config?: RuntimeActionConfig, logger?:
|
|
5
|
+
export declare function createActionFactory<MD extends ModelDefinitions, VD extends ViewDefinitions<MD>>(config?: RuntimeActionConfig, logger?: Logger): ActionFactory<MD, VD>;
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { Logger } from "../types/base.js";
|
|
2
2
|
import { type RuntimeModelConfig, type ModelFactory } from "../types/model.js";
|
|
3
|
-
export declare function createModelFactory(config?: RuntimeModelConfig, logger?:
|
|
3
|
+
export declare function createModelFactory(config?: RuntimeModelConfig, logger?: Logger): ModelFactory;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { Logger } from "../types/base.js";
|
|
2
2
|
import type { ModelDefinitions } from "../types/model.js";
|
|
3
3
|
import type { RuntimeViewConfig, ViewFactory } from "../types/view.js";
|
|
4
|
-
export declare function createViewFactory<MD extends ModelDefinitions>(config?: RuntimeViewConfig, logger?:
|
|
4
|
+
export declare function createViewFactory<MD extends ModelDefinitions>(config?: RuntimeViewConfig, logger?: Logger): ViewFactory<MD>;
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { effectScope } from "vue";
|
|
2
|
-
import { createConsola } from "consola";
|
|
3
2
|
import { createStore as createStoreSource } from "@harlem/core";
|
|
4
3
|
import { runtimeConfig } from "../config.js";
|
|
5
4
|
import { createModelFactory } from "./layers/model.js";
|
|
@@ -7,14 +6,10 @@ import { createViewFactory } from "./layers/view.js";
|
|
|
7
6
|
import { createActionFactory } from "./layers/action.js";
|
|
8
7
|
import { createStoreState, createStoreModel, createStoreView, createStoreAction } from "./utils/store.js";
|
|
9
8
|
import { createStoreCompose } from "./utils/compose.js";
|
|
9
|
+
import { createLogger } from "./utils/logger.js";
|
|
10
10
|
export function createStore(config) {
|
|
11
11
|
function init() {
|
|
12
|
-
const logger =
|
|
13
|
-
level: runtimeConfig.logger,
|
|
14
|
-
defaults: {
|
|
15
|
-
tag: `harlemify:${config.name}`
|
|
16
|
-
}
|
|
17
|
-
});
|
|
12
|
+
const logger = createLogger(`harlemify:${config.name}`, runtimeConfig.logger);
|
|
18
13
|
logger.info("Creating store");
|
|
19
14
|
const modelFactory = createModelFactory(runtimeConfig.model, logger);
|
|
20
15
|
const viewFactory = createViewFactory(runtimeConfig.view, logger);
|
|
@@ -54,6 +54,7 @@ export interface ActionApiCommitContext<MD extends ModelDefinitions, VD extends
|
|
|
54
54
|
query: Readonly<Record<string, unknown>>;
|
|
55
55
|
body: unknown;
|
|
56
56
|
}>;
|
|
57
|
+
params: Readonly<Record<string, string | number>>;
|
|
57
58
|
view: DeepReadonly<StoreView<MD, VD>>;
|
|
58
59
|
}
|
|
59
60
|
export interface ActionApiCommit<MD extends ModelDefinitions, VD extends ViewDefinitions<MD>, K extends keyof MD = keyof MD> {
|
|
@@ -136,7 +137,7 @@ export interface ActionCallCommitOptions {
|
|
|
136
137
|
mode?: ModelOneMode | ModelManyMode | Record<string, ModelOneMode | ModelManyMode>;
|
|
137
138
|
}
|
|
138
139
|
export interface ActionApiCallOptions extends ActionCallBaseOptions {
|
|
139
|
-
params?: Record<string, string>;
|
|
140
|
+
params?: Record<string, string | number>;
|
|
140
141
|
headers?: Record<string, string>;
|
|
141
142
|
query?: Record<string, unknown>;
|
|
142
143
|
body?: unknown;
|
|
@@ -1,5 +1,10 @@
|
|
|
1
|
-
|
|
1
|
+
export interface Logger {
|
|
2
|
+
info(message: string, ...args: unknown[]): void;
|
|
3
|
+
debug(message: string, ...args: unknown[]): void;
|
|
4
|
+
warn(message: string, ...args: unknown[]): void;
|
|
5
|
+
error(message: string, ...args: unknown[]): void;
|
|
6
|
+
}
|
|
2
7
|
export interface BaseDefinition {
|
|
3
8
|
key: string;
|
|
4
|
-
logger?:
|
|
9
|
+
logger?: Logger;
|
|
5
10
|
}
|
|
@@ -31,15 +31,19 @@ export type ModelDefaultIdentifier<S extends Shape> = "id" extends keyof S ? "id
|
|
|
31
31
|
export type AtLeastOne<S extends Shape> = {
|
|
32
32
|
[K in keyof S]: Pick<S, K>;
|
|
33
33
|
}[keyof S];
|
|
34
|
-
export
|
|
35
|
-
|
|
36
|
-
|
|
34
|
+
export type ModelHookContext<T> = {
|
|
35
|
+
mode: ModelOneMode | ModelManyMode;
|
|
36
|
+
state: T;
|
|
37
|
+
};
|
|
38
|
+
export interface ModelDefinitionOptions<T = unknown> {
|
|
39
|
+
pre?: (context: ModelHookContext<T>) => void;
|
|
40
|
+
post?: (context: ModelHookContext<T>) => void;
|
|
37
41
|
}
|
|
38
42
|
export interface ModelOneDefinition<S extends Shape> extends BaseDefinition {
|
|
39
43
|
shape: ShapeType<S>;
|
|
40
44
|
type: ModelType.ONE;
|
|
41
45
|
default: () => S;
|
|
42
|
-
options?: ModelDefinitionOptions
|
|
46
|
+
options?: ModelDefinitionOptions<S>;
|
|
43
47
|
}
|
|
44
48
|
export interface ModelManyDefinition<S extends Shape, I extends keyof S = ModelDefaultIdentifier<S>, T extends ModelManyKind = ModelManyKind.LIST> extends BaseDefinition {
|
|
45
49
|
shape: ShapeType<S>;
|
|
@@ -47,7 +51,7 @@ export interface ModelManyDefinition<S extends Shape, I extends keyof S = ModelD
|
|
|
47
51
|
kind: T;
|
|
48
52
|
identifier: [T] extends [ModelManyKind.LIST] ? I : never;
|
|
49
53
|
default: () => [T] extends [ModelManyKind.LIST] ? S[] : Record<string, S[]>;
|
|
50
|
-
options?: ModelDefinitionOptions
|
|
54
|
+
options?: ModelDefinitionOptions<[T] extends [ModelManyKind.LIST] ? S[] : Record<string, S[]>>;
|
|
51
55
|
}
|
|
52
56
|
export type ModelDefinition<S extends Shape> = ModelOneDefinition<S> | ModelManyDefinition<S, any, any>;
|
|
53
57
|
export type ModelDefinitions = Record<string, ModelDefinition<any>>;
|
|
@@ -59,10 +63,10 @@ export type ModelDefinitionsInfer<MD extends ModelDefinitions> = {
|
|
|
59
63
|
[K in keyof MD]: ModelDefinitionInfer<MD, K>;
|
|
60
64
|
};
|
|
61
65
|
export interface ModelFactory {
|
|
62
|
-
one<S extends Shape>(shape: ShapeType<S>, options?: ModelDefinitionOptions & {
|
|
66
|
+
one<S extends Shape>(shape: ShapeType<S>, options?: ModelDefinitionOptions<S> & {
|
|
63
67
|
default?: () => S;
|
|
64
68
|
}): ModelOneDefinition<S>;
|
|
65
|
-
many<S extends Shape, I extends keyof S = ModelDefaultIdentifier<S>, T extends ModelManyKind = ModelManyKind.LIST>(shape: ShapeType<S>, options?: ModelDefinitionOptions & {
|
|
69
|
+
many<S extends Shape, I extends keyof S = ModelDefaultIdentifier<S>, T extends ModelManyKind = ModelManyKind.LIST>(shape: ShapeType<S>, options?: ModelDefinitionOptions<[T] extends [ModelManyKind.LIST] ? S[] : Record<string, S[]>> & {
|
|
66
70
|
kind?: T;
|
|
67
71
|
identifier?: [T] extends [ModelManyKind.LIST] ? I : never;
|
|
68
72
|
default?: () => [T] extends [ModelManyKind.LIST] ? S[] : Record<string, S[]>;
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { defu } from "defu";
|
|
2
1
|
import { ref, computed, readonly, toValue, nextTick } from "vue";
|
|
3
2
|
import {
|
|
4
3
|
ActionApiMethod,
|
|
@@ -6,7 +5,7 @@ import {
|
|
|
6
5
|
ActionStatus,
|
|
7
6
|
ActionConcurrent
|
|
8
7
|
} from "../types/action.js";
|
|
9
|
-
import { trimStart, trimEnd, isEmptyRecord, isPlainObject } from "./base.js";
|
|
8
|
+
import { trimStart, trimEnd, isEmptyRecord, isPlainObject, merge } from "./base.js";
|
|
10
9
|
import {
|
|
11
10
|
ActionApiError,
|
|
12
11
|
ActionHandlerError,
|
|
@@ -38,12 +37,12 @@ function resolveApiUrl(definition, view, options) {
|
|
|
38
37
|
function resolveApiHeaders(definition, view, options) {
|
|
39
38
|
const initial = resolveValue(definition.request.headers, view, {});
|
|
40
39
|
const custom = options?.headers ?? {};
|
|
41
|
-
return
|
|
40
|
+
return merge(custom, initial);
|
|
42
41
|
}
|
|
43
42
|
function resolveApiQuery(definition, view, options) {
|
|
44
43
|
const initial = resolveValue(definition.request.query, view, {});
|
|
45
44
|
const custom = options?.query ?? {};
|
|
46
|
-
return
|
|
45
|
+
return merge(custom, initial);
|
|
47
46
|
}
|
|
48
47
|
function resolveApiBody(definition, view, target, options) {
|
|
49
48
|
if (definition.request.method === ActionApiMethod.GET || definition.request.method === ActionApiMethod.HEAD) {
|
|
@@ -51,7 +50,7 @@ function resolveApiBody(definition, view, target, options) {
|
|
|
51
50
|
}
|
|
52
51
|
const initial = resolveValue(definition.request.body, view, {});
|
|
53
52
|
const custom = options?.body ?? {};
|
|
54
|
-
const body =
|
|
53
|
+
const body = merge(custom, initial);
|
|
55
54
|
if (!isPlainObject(body)) {
|
|
56
55
|
return body;
|
|
57
56
|
}
|
|
@@ -298,6 +297,7 @@ export function createAction(definition, model, view) {
|
|
|
298
297
|
);
|
|
299
298
|
const context = {
|
|
300
299
|
request: { url, method, headers, query, body },
|
|
300
|
+
params: options?.params ?? {},
|
|
301
301
|
view
|
|
302
302
|
};
|
|
303
303
|
data = executeCommit(definition, model, response, context, options);
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { BaseDefinition } from "../types/base.js";
|
|
2
|
+
export declare function snapshot<T>(value: T): T;
|
|
2
3
|
export declare function wrapBaseDefinition<T extends Omit<BaseDefinition, "key">>(definition: T): T & BaseDefinition;
|
|
3
4
|
export declare function trimStart(value: string, char: string): string;
|
|
4
5
|
export declare function trimEnd(value: string, char: string): string;
|
|
@@ -6,5 +7,6 @@ export declare function ensureArray<T>(value: T | T[]): T[];
|
|
|
6
7
|
export declare function isObject(value: unknown): value is object;
|
|
7
8
|
export declare function isPlainObject(value: unknown): value is Record<string, unknown>;
|
|
8
9
|
export declare function isEmptyRecord(record: Record<string, unknown> | undefined): record is undefined;
|
|
10
|
+
export declare function merge<T>(priority: unknown, base: T): T;
|
|
9
11
|
export declare function debounce<T extends (...args: any[]) => any>(callback: T, delay: number): T;
|
|
10
12
|
export declare function throttle<T extends (...args: any[]) => any>(callback: T, delay: number): T;
|
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
import { objectClone, typeIsObject } from "@harlem/utilities";
|
|
2
|
+
export function snapshot(value) {
|
|
3
|
+
return objectClone(value);
|
|
4
|
+
}
|
|
1
5
|
export function wrapBaseDefinition(definition) {
|
|
2
6
|
let key = "";
|
|
3
7
|
return Object.defineProperties(definition, {
|
|
@@ -23,16 +27,10 @@ export function ensureArray(value) {
|
|
|
23
27
|
return Array.isArray(value) ? value : [value];
|
|
24
28
|
}
|
|
25
29
|
export function isObject(value) {
|
|
26
|
-
return value
|
|
30
|
+
return typeIsObject(value);
|
|
27
31
|
}
|
|
28
32
|
export function isPlainObject(value) {
|
|
29
|
-
|
|
30
|
-
return false;
|
|
31
|
-
}
|
|
32
|
-
if (Array.isArray(value)) {
|
|
33
|
-
return false;
|
|
34
|
-
}
|
|
35
|
-
return true;
|
|
33
|
+
return isObject(value);
|
|
36
34
|
}
|
|
37
35
|
export function isEmptyRecord(record) {
|
|
38
36
|
if (!record) {
|
|
@@ -43,6 +41,20 @@ export function isEmptyRecord(record) {
|
|
|
43
41
|
}
|
|
44
42
|
return false;
|
|
45
43
|
}
|
|
44
|
+
export function merge(priority, base) {
|
|
45
|
+
if (!isPlainObject(priority) || !isPlainObject(base)) {
|
|
46
|
+
return priority;
|
|
47
|
+
}
|
|
48
|
+
const output = { ...base };
|
|
49
|
+
for (const key of Object.keys(priority)) {
|
|
50
|
+
const value = priority[key];
|
|
51
|
+
if (value === null || value === void 0) {
|
|
52
|
+
continue;
|
|
53
|
+
}
|
|
54
|
+
output[key] = merge(value, output[key]);
|
|
55
|
+
}
|
|
56
|
+
return output;
|
|
57
|
+
}
|
|
46
58
|
export function debounce(callback, delay) {
|
|
47
59
|
let timer = null;
|
|
48
60
|
return (...args) => {
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { Logger } from "../types/base.js";
|
|
2
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?:
|
|
3
|
+
export declare function createStoreCompose<CD extends ComposeDefinitions>(composeConfig: ((...args: any[]) => CD) | undefined, context: Record<string, unknown>, logger?: Logger): StoreCompose<CD>;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
const LEVELS = {
|
|
2
|
+
error: 0,
|
|
3
|
+
warn: 1,
|
|
4
|
+
info: 3,
|
|
5
|
+
debug: 4
|
|
6
|
+
};
|
|
7
|
+
export function createLogger(tag, level = -999) {
|
|
8
|
+
function report(method, sink) {
|
|
9
|
+
return (message, ...args) => {
|
|
10
|
+
if (LEVELS[method] > level) {
|
|
11
|
+
return;
|
|
12
|
+
}
|
|
13
|
+
sink(`[${tag}]`, message, ...args);
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
return {
|
|
17
|
+
info: report("info", console.info),
|
|
18
|
+
debug: report("debug", console.debug),
|
|
19
|
+
warn: report("warn", console.warn),
|
|
20
|
+
error: report("error", console.error)
|
|
21
|
+
};
|
|
22
|
+
}
|
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { ensureArray } from "./base.js";
|
|
1
|
+
import { ensureArray, snapshot, merge } from "./base.js";
|
|
3
2
|
import { resolveShapeAliases } from "./shape.js";
|
|
4
3
|
import {
|
|
5
4
|
ModelType,
|
|
@@ -8,12 +7,17 @@ import {
|
|
|
8
7
|
ModelManyMode,
|
|
9
8
|
ModelSilent
|
|
10
9
|
} from "../types/model.js";
|
|
11
|
-
function callHook(definition, hook, silent) {
|
|
10
|
+
function callHook(definition, source, hook, mode, silent) {
|
|
12
11
|
if (silent === true || silent === hook) {
|
|
13
12
|
return;
|
|
14
13
|
}
|
|
14
|
+
const handler = definition.options?.[hook];
|
|
15
|
+
if (!handler) {
|
|
16
|
+
return;
|
|
17
|
+
}
|
|
15
18
|
try {
|
|
16
|
-
definition.
|
|
19
|
+
const state = snapshot(source.state[definition.key]);
|
|
20
|
+
handler({ mode, state });
|
|
17
21
|
} catch (error) {
|
|
18
22
|
definition.logger?.error(`Model ${hook} hook error`, {
|
|
19
23
|
model: definition.key,
|
|
@@ -21,14 +25,14 @@ function callHook(definition, hook, silent) {
|
|
|
21
25
|
});
|
|
22
26
|
}
|
|
23
27
|
}
|
|
24
|
-
function wrapOperation(definition,
|
|
28
|
+
function wrapOperation(definition, source, mode, operation, silent) {
|
|
25
29
|
definition.logger?.debug("Model mutation", {
|
|
26
30
|
model: definition.key,
|
|
27
|
-
mutation
|
|
31
|
+
mutation: mode
|
|
28
32
|
});
|
|
29
|
-
callHook(definition, ModelSilent.PRE, silent);
|
|
33
|
+
callHook(definition, source, ModelSilent.PRE, mode, silent);
|
|
30
34
|
operation();
|
|
31
|
-
callHook(definition, ModelSilent.POST, silent);
|
|
35
|
+
callHook(definition, source, ModelSilent.POST, mode, silent);
|
|
32
36
|
}
|
|
33
37
|
function createOneCommit(definition, source) {
|
|
34
38
|
const setOperation = source.mutation(`${definition.key}:set`, (state, { payload }) => {
|
|
@@ -39,7 +43,7 @@ function createOneCommit(definition, source) {
|
|
|
39
43
|
});
|
|
40
44
|
const patchOperation = source.mutation(`${definition.key}:patch`, (state, { payload, options }) => {
|
|
41
45
|
if (options?.deep) {
|
|
42
|
-
state[definition.key] =
|
|
46
|
+
state[definition.key] = merge(payload, state[definition.key]);
|
|
43
47
|
return;
|
|
44
48
|
}
|
|
45
49
|
state[definition.key] = {
|
|
@@ -49,13 +53,19 @@ function createOneCommit(definition, source) {
|
|
|
49
53
|
});
|
|
50
54
|
return {
|
|
51
55
|
set(payload, options) {
|
|
52
|
-
wrapOperation(definition,
|
|
56
|
+
wrapOperation(definition, source, ModelOneMode.SET, () => setOperation({ payload }), options?.silent);
|
|
53
57
|
},
|
|
54
58
|
reset(options) {
|
|
55
|
-
wrapOperation(definition,
|
|
59
|
+
wrapOperation(definition, source, ModelOneMode.RESET, () => resetOperation(), options?.silent);
|
|
56
60
|
},
|
|
57
61
|
patch(payload, options) {
|
|
58
|
-
wrapOperation(
|
|
62
|
+
wrapOperation(
|
|
63
|
+
definition,
|
|
64
|
+
source,
|
|
65
|
+
ModelOneMode.PATCH,
|
|
66
|
+
() => patchOperation({ payload, options }),
|
|
67
|
+
options?.silent
|
|
68
|
+
);
|
|
59
69
|
}
|
|
60
70
|
};
|
|
61
71
|
}
|
|
@@ -77,7 +87,7 @@ function createManyListCommit(definition, source) {
|
|
|
77
87
|
return item;
|
|
78
88
|
}
|
|
79
89
|
if (options?.deep) {
|
|
80
|
-
return
|
|
90
|
+
return merge(found, item);
|
|
81
91
|
}
|
|
82
92
|
return {
|
|
83
93
|
...item,
|
|
@@ -120,19 +130,37 @@ function createManyListCommit(definition, source) {
|
|
|
120
130
|
});
|
|
121
131
|
return {
|
|
122
132
|
set(payload, options) {
|
|
123
|
-
wrapOperation(definition,
|
|
133
|
+
wrapOperation(definition, source, ModelManyMode.SET, () => setOperation({ payload }), options?.silent);
|
|
124
134
|
},
|
|
125
135
|
reset(options) {
|
|
126
|
-
wrapOperation(definition,
|
|
136
|
+
wrapOperation(definition, source, ModelManyMode.RESET, () => resetOperation(), options?.silent);
|
|
127
137
|
},
|
|
128
138
|
patch(payload, options) {
|
|
129
|
-
wrapOperation(
|
|
139
|
+
wrapOperation(
|
|
140
|
+
definition,
|
|
141
|
+
source,
|
|
142
|
+
ModelManyMode.PATCH,
|
|
143
|
+
() => patchOperation({ payload, options }),
|
|
144
|
+
options?.silent
|
|
145
|
+
);
|
|
130
146
|
},
|
|
131
147
|
remove(payload, options) {
|
|
132
|
-
wrapOperation(
|
|
148
|
+
wrapOperation(
|
|
149
|
+
definition,
|
|
150
|
+
source,
|
|
151
|
+
ModelManyMode.REMOVE,
|
|
152
|
+
() => removeOperation({ payload }),
|
|
153
|
+
options?.silent
|
|
154
|
+
);
|
|
133
155
|
},
|
|
134
156
|
add(payload, options) {
|
|
135
|
-
wrapOperation(
|
|
157
|
+
wrapOperation(
|
|
158
|
+
definition,
|
|
159
|
+
source,
|
|
160
|
+
ModelManyMode.ADD,
|
|
161
|
+
() => addOperation({ payload, options }),
|
|
162
|
+
options?.silent
|
|
163
|
+
);
|
|
136
164
|
}
|
|
137
165
|
};
|
|
138
166
|
}
|
|
@@ -145,7 +173,7 @@ function createManyRecordCommit(definition, source) {
|
|
|
145
173
|
});
|
|
146
174
|
const patchOperation = source.mutation(`${definition.key}:patch`, (state, { payload, options }) => {
|
|
147
175
|
if (options?.deep) {
|
|
148
|
-
state[definition.key] =
|
|
176
|
+
state[definition.key] = merge(payload, state[definition.key]);
|
|
149
177
|
return;
|
|
150
178
|
}
|
|
151
179
|
state[definition.key] = {
|
|
@@ -170,19 +198,31 @@ function createManyRecordCommit(definition, source) {
|
|
|
170
198
|
});
|
|
171
199
|
return {
|
|
172
200
|
set(payload, options) {
|
|
173
|
-
wrapOperation(definition,
|
|
201
|
+
wrapOperation(definition, source, ModelManyMode.SET, () => setOperation({ payload }), options?.silent);
|
|
174
202
|
},
|
|
175
203
|
reset(options) {
|
|
176
|
-
wrapOperation(definition,
|
|
204
|
+
wrapOperation(definition, source, ModelManyMode.RESET, () => resetOperation(), options?.silent);
|
|
177
205
|
},
|
|
178
206
|
patch(payload, options) {
|
|
179
|
-
wrapOperation(
|
|
207
|
+
wrapOperation(
|
|
208
|
+
definition,
|
|
209
|
+
source,
|
|
210
|
+
ModelManyMode.PATCH,
|
|
211
|
+
() => patchOperation({ payload, options }),
|
|
212
|
+
options?.silent
|
|
213
|
+
);
|
|
180
214
|
},
|
|
181
215
|
remove(payload, options) {
|
|
182
|
-
wrapOperation(
|
|
216
|
+
wrapOperation(
|
|
217
|
+
definition,
|
|
218
|
+
source,
|
|
219
|
+
ModelManyMode.REMOVE,
|
|
220
|
+
() => removeOperation({ payload }),
|
|
221
|
+
options?.silent
|
|
222
|
+
);
|
|
183
223
|
},
|
|
184
224
|
add(payload, options) {
|
|
185
|
-
wrapOperation(definition,
|
|
225
|
+
wrapOperation(definition, source, ModelManyMode.ADD, () => addOperation({ payload }), options?.silent);
|
|
186
226
|
}
|
|
187
227
|
};
|
|
188
228
|
}
|
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
import { defu } from "defu";
|
|
2
1
|
import { z } from "zod";
|
|
3
|
-
import { isPlainObject, isEmptyRecord } from "./base.js";
|
|
2
|
+
import { isPlainObject, isEmptyRecord, merge } from "./base.js";
|
|
4
3
|
function resolveShapeFields(shape) {
|
|
5
4
|
if (!("shape" in shape) || typeof shape.shape !== "object" || !shape.shape) {
|
|
6
5
|
return void 0;
|
|
@@ -183,7 +182,7 @@ export function decorateShape(object) {
|
|
|
183
182
|
defaults(overrides) {
|
|
184
183
|
const zero = resolveZeroValues(object);
|
|
185
184
|
if (overrides) {
|
|
186
|
-
return
|
|
185
|
+
return merge(overrides, zero);
|
|
187
186
|
}
|
|
188
187
|
return zero;
|
|
189
188
|
}
|
|
@@ -1,10 +1,11 @@
|
|
|
1
|
+
import { snapshot } from "./base.js";
|
|
1
2
|
import { ViewClone } from "../types/view.js";
|
|
2
3
|
function resolveClonedValue(definition, value) {
|
|
3
4
|
if (!definition.options?.clone) {
|
|
4
5
|
return value;
|
|
5
6
|
}
|
|
6
7
|
if (definition.options.clone === ViewClone.DEEP) {
|
|
7
|
-
return
|
|
8
|
+
return snapshot(value);
|
|
8
9
|
}
|
|
9
10
|
if (Array.isArray(value)) {
|
|
10
11
|
return [...value];
|
package/dist/runtime/index.d.ts
CHANGED
|
@@ -8,7 +8,7 @@ export { ViewClone } from "./core/types/view.js";
|
|
|
8
8
|
export type { ViewDefinitionOptions } from "./core/types/view.js";
|
|
9
9
|
export { ActionStatus, ActionConcurrent, ActionType, ActionApiMethod } from "./core/types/action.js";
|
|
10
10
|
export type { ActionCall, ActionApiCall, ActionApiCommitContext, ActionHandlerCall, ActionCallOptions, ActionCallBaseOptions, ActionApiCallOptions, ActionHandlerCallOptions, ActionCallTransformerOptions, ActionCallBindOptions, ActionCallCommitOptions, ActionHandlerOptions, ActionResolvedApi, } from "./core/types/action.js";
|
|
11
|
-
export { ActionApiError, ActionHandlerError, ActionCommitError, ActionConcurrentError, isError, toError } from "./core/utils/error.js";
|
|
11
|
+
export { ActionApiError, ActionHandlerError, ActionCommitError, ActionConcurrentError, isError, toError, } from "./core/utils/error.js";
|
|
12
12
|
export type { ComposeCallback, ComposeCall, ComposeDefinitions, ComposeContext, StoreCompose, } from "./core/types/compose.js";
|
|
13
13
|
export { useStoreCompose } from "./composables/compose.js";
|
|
14
14
|
export type { UseStoreCompose } from "./composables/compose.js";
|
package/dist/runtime/index.js
CHANGED
|
@@ -3,7 +3,14 @@ export { shape } from "./core/layers/shape.js";
|
|
|
3
3
|
export { ModelType, ModelManyKind, ModelOneMode, ModelManyMode, ModelSilent } from "./core/types/model.js";
|
|
4
4
|
export { ViewClone } from "./core/types/view.js";
|
|
5
5
|
export { ActionStatus, ActionConcurrent, ActionType, ActionApiMethod } from "./core/types/action.js";
|
|
6
|
-
export {
|
|
6
|
+
export {
|
|
7
|
+
ActionApiError,
|
|
8
|
+
ActionHandlerError,
|
|
9
|
+
ActionCommitError,
|
|
10
|
+
ActionConcurrentError,
|
|
11
|
+
isError,
|
|
12
|
+
toError
|
|
13
|
+
} from "./core/utils/error.js";
|
|
7
14
|
export { useStoreCompose } from "./composables/compose.js";
|
|
8
15
|
export { useIsolatedActionStatus, useIsolatedActionError, useStoreAction } from "./composables/action.js";
|
|
9
16
|
export { useStoreModel } from "./composables/model.js";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@diphyx/harlemify",
|
|
3
|
-
"version": "6.
|
|
3
|
+
"version": "6.3.1",
|
|
4
4
|
"description": "API state management for Nuxt powered by Harlem",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"nuxt",
|
|
@@ -45,7 +45,8 @@
|
|
|
45
45
|
"prepare": "pnpm nuxt prepare && pnpm nuxt prepare playground",
|
|
46
46
|
"dev": "pnpm nuxt dev playground",
|
|
47
47
|
"build": "nuxt-module-build build",
|
|
48
|
-
"lint": "eslint
|
|
48
|
+
"lint": "eslint ./ --fix",
|
|
49
|
+
"format": "prettier ./ --write",
|
|
49
50
|
"test": "vitest run",
|
|
50
51
|
"test:e2e": "playwright test"
|
|
51
52
|
},
|
|
@@ -54,9 +55,8 @@
|
|
|
54
55
|
},
|
|
55
56
|
"dependencies": {
|
|
56
57
|
"@harlem/core": "^3.1.8",
|
|
57
|
-
"@
|
|
58
|
-
"
|
|
59
|
-
"defu": "^6.1.7"
|
|
58
|
+
"@harlem/utilities": "^3.1.8",
|
|
59
|
+
"@nuxt/kit": "^4.4.6"
|
|
60
60
|
},
|
|
61
61
|
"devDependencies": {
|
|
62
62
|
"@nuxt/eslint-config": "^0.6.2",
|
|
@@ -68,9 +68,10 @@
|
|
|
68
68
|
"@vitest/coverage-v8": "^2.1.9",
|
|
69
69
|
"eslint": "^9.39.4",
|
|
70
70
|
"nuxt": "^4.4.6",
|
|
71
|
+
"prettier": "^3.8.3",
|
|
71
72
|
"typescript": "^5.9.3",
|
|
72
73
|
"vitest": "^2.1.9",
|
|
73
|
-
"vue": "^3.5.
|
|
74
|
+
"vue": "^3.5.35",
|
|
74
75
|
"zod": "^4.4.3"
|
|
75
76
|
}
|
|
76
77
|
}
|