@diphyx/harlemify 5.2.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.json CHANGED
@@ -4,7 +4,7 @@
4
4
  "compatibility": {
5
5
  "nuxt": ">=3.0.0 || >=4.0.0"
6
6
  },
7
- "version": "5.2.0",
7
+ "version": "5.3.0",
8
8
  "builder": {
9
9
  "@nuxt/module-builder": "0.8.4",
10
10
  "unbuild": "unknown"
@@ -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?: ActionCallOptions) => Promise<T>;
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>;
@@ -14,4 +14,4 @@ export declare function useIsolatedActionError(): Ref<Error | null>;
14
14
  export declare function useIsolatedActionStatus(): Ref<ActionStatus>;
15
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 ModelManyCommit<any>> = {
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,12 +1,12 @@
1
1
  import { wrapBaseDefinition } from "../utils/base.js";
2
2
  import {
3
- ModelKind
3
+ ModelType
4
4
  } from "../types/model.js";
5
5
  export function createModelFactory(config, logger) {
6
6
  function one(shape, options) {
7
7
  return wrapBaseDefinition({
8
8
  shape,
9
- kind: ModelKind.OBJECT,
9
+ type: ModelType.ONE,
10
10
  options: {
11
11
  identifier: config?.identifier,
12
12
  ...options
@@ -17,7 +17,7 @@ export function createModelFactory(config, logger) {
17
17
  function many(shape, options) {
18
18
  return wrapBaseDefinition({
19
19
  shape,
20
- kind: ModelKind.ARRAY,
20
+ type: ModelType.MANY,
21
21
  options: {
22
22
  identifier: config?.identifier,
23
23
  ...options
@@ -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,42 +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: keyof MD;
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>> extends BaseDefinition {
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>;
54
58
  }
55
- export interface ActionHandlerOptions {
56
- payload?: unknown;
59
+ export interface ActionHandlerOptions<P = unknown> {
60
+ payload?: P;
57
61
  concurrent?: ActionConcurrent;
58
62
  }
59
- 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: {
60
64
  model: StoreModel<MD>;
61
65
  view: StoreView<MD, VD>;
62
- payload: unknown;
66
+ payload: P;
63
67
  }) => Promise<R>;
64
- export interface ActionHandlerDefinition<MD extends ModelDefinitions, VD extends ViewDefinitions<MD>, R = void> extends BaseDefinition {
65
- callback: ActionHandlerCallback<MD, VD, R>;
66
- options?: ActionHandlerOptions;
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>;
67
71
  }
68
- export type ActionDefinition<MD extends ModelDefinitions, VD extends ViewDefinitions<MD>> = ActionApiDefinition<MD, VD> | ActionHandlerDefinition<MD, VD, unknown>;
72
+ export type ActionDefinition<MD extends ModelDefinitions, VD extends ViewDefinitions<MD>> = ActionApiDefinition<MD, VD> | ActionHandlerDefinition<MD, VD, any, any>;
69
73
  export type ActionDefinitions<MD extends ModelDefinitions, VD extends ViewDefinitions<MD>> = Record<string, ActionDefinition<MD, VD>>;
70
74
  export interface ActionApiFactory<MD extends ModelDefinitions, VD extends ViewDefinitions<MD>> {
71
- (request: ActionApiRequest<MD, VD>, commit?: ActionApiCommit<MD>): ActionApiDefinition<MD, VD>;
72
- get(request: ActionApiRequestShortcut<MD, VD>, commit?: ActionApiCommit<MD>): ActionApiDefinition<MD, VD>;
73
- head(request: ActionApiRequestShortcut<MD, VD>, commit?: ActionApiCommit<MD>): ActionApiDefinition<MD, VD>;
74
- post(request: ActionApiRequestShortcut<MD, VD>, commit?: ActionApiCommit<MD>): ActionApiDefinition<MD, VD>;
75
- put(request: ActionApiRequestShortcut<MD, VD>, commit?: ActionApiCommit<MD>): ActionApiDefinition<MD, VD>;
76
- patch(request: ActionApiRequestShortcut<MD, VD>, commit?: ActionApiCommit<MD>): ActionApiDefinition<MD, VD>;
77
- delete(request: ActionApiRequestShortcut<MD, VD>, commit?: ActionApiCommit<MD>): ActionApiDefinition<MD, VD>;
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>;
78
89
  }
79
90
  export interface ActionHandlerFactory<MD extends ModelDefinitions, VD extends ViewDefinitions<MD>> {
80
- <R>(callback: ActionHandlerCallback<MD, VD, R>, options?: ActionHandlerOptions): ActionHandlerDefinition<MD, VD, R>;
91
+ <P = unknown, R = void>(callback: ActionHandlerCallback<MD, VD, P, R>, options?: ActionHandlerOptions<P>): ActionHandlerDefinition<MD, VD, P, R>;
81
92
  }
82
93
  export interface ActionFactory<MD extends ModelDefinitions, VD extends ViewDefinitions<MD>> {
83
94
  api: ActionApiFactory<MD, VD>;
@@ -117,13 +128,13 @@ export interface ActionApiCallOptions extends ActionCallBaseOptions {
117
128
  transformer?: ActionCallTransformerOptions;
118
129
  commit?: ActionCallCommitOptions;
119
130
  }
120
- export interface ActionResolvedHandler<MD extends ModelDefinitions, VD extends ViewDefinitions<MD>> {
131
+ export interface ActionResolvedHandler<MD extends ModelDefinitions, VD extends ViewDefinitions<MD>, P = unknown> {
121
132
  model: StoreModel<MD>;
122
133
  view: StoreView<MD, VD>;
123
- payload: unknown;
134
+ payload: P;
124
135
  }
125
- export interface ActionHandlerCallOptions extends ActionCallBaseOptions {
126
- payload?: unknown;
136
+ export interface ActionHandlerCallOptions<P = unknown> extends ActionCallBaseOptions {
137
+ payload?: P;
127
138
  }
128
139
  export type ActionCallOptions = ActionApiCallOptions | ActionHandlerCallOptions;
129
140
  export interface ActionCallBase {
@@ -133,12 +144,14 @@ export interface ActionCallBase {
133
144
  reset: () => void;
134
145
  }
135
146
  export interface ActionApiCall<T = void> extends ActionCallBase {
147
+ readonly actionType: ActionType.API;
136
148
  (options?: ActionApiCallOptions): Promise<T>;
137
149
  }
138
- export interface ActionHandlerCall<T = void> extends ActionCallBase {
139
- (options?: ActionHandlerCallOptions): Promise<T>;
150
+ export interface ActionHandlerCall<P = unknown, T = void> extends ActionCallBase {
151
+ readonly actionType: ActionType.HANDLER;
152
+ (options?: ActionHandlerCallOptions<P>): Promise<T>;
140
153
  }
141
- export type ActionCall<T = void> = ActionApiCall<T> | ActionHandlerCall<T>;
154
+ export type ActionCall<T = void> = ActionApiCall<T> | ActionHandlerCall<any, T>;
142
155
  export type StoreAction<MD extends ModelDefinitions, VD extends ViewDefinitions<MD>, AD extends ActionDefinitions<MD, VD>> = {
143
- [K in keyof AD]: AD[K] extends ActionApiDefinition<MD, VD> ? ActionApiCall : AD[K] extends ActionHandlerDefinition<MD, VD, infer R> ? ActionHandlerCall<R> : never;
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;
144
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";
@@ -1,6 +1,5 @@
1
1
  import type { ConsolaInstance } from "consola";
2
2
  export interface BaseDefinition {
3
- readonly key: string;
3
+ key: string;
4
4
  logger?: ConsolaInstance;
5
- setKey(key: string): void;
6
5
  }
@@ -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 ModelKind {
7
- OBJECT = "object",
8
- ARRAY = "array"
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 interface ModelManyDefinitionOptions<S extends Shape> {
27
- identifier?: keyof S;
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
- kind: ModelKind.OBJECT;
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
- kind: ModelKind.ARRAY;
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 ModelManyCommit<S extends Shape> {
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[], options?: ModelManyCommitOptions) => void;
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 ModelKind = /* @__PURE__ */ ((ModelKind2) => {
2
- ModelKind2["OBJECT"] = "object";
3
- ModelKind2["ARRAY"] = "array";
4
- return ModelKind2;
5
- })(ModelKind || {});
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";
@@ -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";
@@ -211,9 +212,10 @@ function executeCommit(definition, target, mode, data) {
211
212
  }
212
213
  }
213
214
  export function createAction(definition, model, view) {
215
+ const actionType = isApiDefinition(definition) ? ActionType.API : ActionType.HANDLER;
214
216
  definition.logger?.debug("Registering action", {
215
217
  action: definition.key,
216
- type: isApiDefinition(definition) ? "api" : "handler"
218
+ type: actionType
217
219
  });
218
220
  let currentController = null;
219
221
  let abortController = null;
@@ -304,6 +306,7 @@ export function createAction(definition, model, view) {
304
306
  return currentController;
305
307
  }
306
308
  const action = Object.assign(execute, {
309
+ actionType,
307
310
  get error() {
308
311
  return readonly(globalError);
309
312
  },
@@ -1,7 +1,8 @@
1
1
  import type { BaseDefinition } from "../types/base.js";
2
- export declare function wrapBaseDefinition<T extends Omit<BaseDefinition, "key" | "setKey">>(definition: T): T & BaseDefinition;
2
+ export declare function wrapBaseDefinition<T extends Omit<BaseDefinition, "key">>(definition: T): T & BaseDefinition;
3
3
  export declare function trimStart(value: string, char: string): string;
4
4
  export declare function trimEnd(value: string, char: string): string;
5
+ export declare function ensureArray<T>(value: T | T[]): T[];
5
6
  export declare function isObject(value: unknown): value is object;
6
7
  export declare function isPlainObject(value: unknown): value is Record<string, unknown>;
7
8
  export declare function isEmptyRecord(record: Record<string, unknown> | undefined): record is undefined;
@@ -5,11 +5,7 @@ export function wrapBaseDefinition(definition) {
5
5
  get() {
6
6
  return key;
7
7
  },
8
- enumerable: true,
9
- configurable: true
10
- },
11
- setKey: {
12
- value(value) {
8
+ set(value) {
13
9
  key = value;
14
10
  },
15
11
  enumerable: true,
@@ -23,6 +19,9 @@ export function trimStart(value, char) {
23
19
  export function trimEnd(value, char) {
24
20
  return value.replace(new RegExp(`${char}+$`), "");
25
21
  }
22
+ export function ensureArray(value) {
23
+ return Array.isArray(value) ? value : [value];
24
+ }
26
25
  export function isObject(value) {
27
26
  return value != null && typeof value === "object";
28
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
- ModelKind,
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 createManyCommit(definition, shape, source) {
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 = Array.isArray(payload.value) ? payload.value : [payload.value];
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((p) => {
82
- return p[by] === item[by];
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, payload) => {
100
- const items = Array.isArray(payload.value) ? payload.value : [payload.value];
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 !ids.has(item[by]);
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 = Array.isArray(payload.value) ? payload.value : [payload.value];
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, options) {
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.kind === ModelKind.OBJECT;
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 createManyCommit(definition, shape, source);
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
- kind: definition.kind
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 { ModelKind } from "../types/model.js";
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, kind }] of Object.entries(modelDefinitions)) {
8
- output[key] = options?.default ?? (kind === ModelKind.OBJECT ? null : []);
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.setKey(key);
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.setKey(key);
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.setKey(key);
39
+ definition.key = key;
32
40
  output[key] = createAction(definition, model, view);
33
41
  }
34
42
  return output;
@@ -2,11 +2,11 @@ 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 { ModelKind, ModelOneMode, ModelManyMode } from "./core/types/model.js";
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";
9
+ export { ActionStatus, ActionConcurrent, ActionType, ActionApiMethod } from "./core/types/action.js";
10
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";
@@ -1,8 +1,8 @@
1
1
  export { createStore } from "./core/store.js";
2
2
  export { shape } from "./core/layers/shape.js";
3
- export { ModelKind, ModelOneMode, ModelManyMode } from "./core/types/model.js";
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";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@diphyx/harlemify",
3
- "version": "5.2.0",
3
+ "version": "5.3.0",
4
4
  "description": "API state management for Nuxt powered by Harlem",
5
5
  "keywords": [
6
6
  "nuxt",