@diphyx/harlemify 6.1.0 → 6.2.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 CHANGED
@@ -23,9 +23,11 @@ If you are an AI coding agent working on a project that uses `@diphyx/harlemify`
23
23
  ## Install
24
24
 
25
25
  ```bash
26
- npm install @diphyx/harlemify
26
+ npm install @diphyx/harlemify zod
27
27
  ```
28
28
 
29
+ > `zod` is a peer dependency — install it in your project.
30
+
29
31
  ```typescript
30
32
  // nuxt.config.ts
31
33
  export default defineNuxtConfig({
package/dist/module.json CHANGED
@@ -4,7 +4,7 @@
4
4
  "compatibility": {
5
5
  "nuxt": "^3.14.0 || ^4.0.0"
6
6
  },
7
- "version": "6.1.0",
7
+ "version": "6.2.0",
8
8
  "builder": {
9
9
  "@nuxt/module-builder": "0.8.4",
10
10
  "unbuild": "unknown"
@@ -1,3 +1,4 @@
1
+ import { effectScope } from "vue";
1
2
  import { createConsola } from "consola";
2
3
  import { createStore as createStoreSource } from "@harlem/core";
3
4
  import { runtimeConfig } from "../config.js";
@@ -37,10 +38,13 @@ export function createStore(config) {
37
38
  }
38
39
  if (config.lazy) {
39
40
  let instance;
41
+ const scope = effectScope(true);
40
42
  return new Proxy({}, {
41
43
  get(_, prop) {
42
44
  if (!instance) {
43
- instance = init();
45
+ scope.run(() => {
46
+ instance = init();
47
+ });
44
48
  }
45
49
  return instance[prop];
46
50
  }
@@ -46,16 +46,26 @@ export interface ActionApiRequest<MD extends ModelDefinitions, VD extends ViewDe
46
46
  concurrent?: ActionConcurrent;
47
47
  }
48
48
  export type ActionApiRequestShortcut<MD extends ModelDefinitions, VD extends ViewDefinitions<MD>> = Omit<ActionApiRequest<MD, VD>, "method">;
49
- export interface ActionApiCommit<MD extends ModelDefinitions, K extends keyof MD = keyof MD> {
49
+ export interface ActionApiCommitContext<MD extends ModelDefinitions, VD extends ViewDefinitions<MD>> {
50
+ request: Readonly<{
51
+ url: string;
52
+ method: ActionApiMethod;
53
+ headers: Readonly<Record<string, string>>;
54
+ query: Readonly<Record<string, unknown>>;
55
+ body: unknown;
56
+ }>;
57
+ view: DeepReadonly<StoreView<MD, VD>>;
58
+ }
59
+ export interface ActionApiCommit<MD extends ModelDefinitions, VD extends ViewDefinitions<MD>, K extends keyof MD = keyof MD> {
50
60
  model: K;
51
61
  mode: ModelOneMode | ModelManyMode;
52
- value?: (data: unknown) => unknown;
62
+ transform?: (data: unknown, context: ActionApiCommitContext<MD, VD>) => unknown;
53
63
  options?: ModelOneCommitOptions | ModelManyCommitOptions;
54
64
  }
55
- export type ActionApiCommitReturn<MD extends ModelDefinitions, C extends readonly ActionApiCommit<MD>[]> = C extends readonly [] ? unknown : {
65
+ export type ActionApiCommitReturn<MD extends ModelDefinitions, VD extends ViewDefinitions<MD>, C extends readonly ActionApiCommit<MD, VD>[]> = C extends readonly [] ? unknown : {
56
66
  [E in C[number] as E["model"] & string]: E["model"] extends keyof MD ? ModelDefinitionInfer<MD, E["model"]> : never;
57
67
  };
58
- export interface ActionApiDefinition<MD extends ModelDefinitions, VD extends ViewDefinitions<MD>, C extends readonly ActionApiCommit<MD>[] = readonly ActionApiCommit<MD>[]> extends BaseDefinition {
68
+ export interface ActionApiDefinition<MD extends ModelDefinitions, VD extends ViewDefinitions<MD>, C extends readonly ActionApiCommit<MD, VD>[] = readonly ActionApiCommit<MD, VD>[]> extends BaseDefinition {
59
69
  request: ActionApiRequest<MD, VD>;
60
70
  commits: C;
61
71
  }
@@ -74,25 +84,25 @@ export interface ActionHandlerDefinition<MD extends ModelDefinitions, VD extends
74
84
  }
75
85
  export type ActionDefinition<MD extends ModelDefinitions, VD extends ViewDefinitions<MD>> = ActionApiDefinition<MD, VD, any> | ActionHandlerDefinition<MD, VD, any, any>;
76
86
  export type ActionDefinitions<MD extends ModelDefinitions, VD extends ViewDefinitions<MD>> = Record<string, ActionDefinition<MD, VD>>;
77
- type ActionApiCommitTuple<MD extends ModelDefinitions> = readonly [
78
- ActionApiCommit<MD, keyof MD>,
79
- ...ActionApiCommit<MD, keyof MD>[]
87
+ type ActionApiCommitTuple<MD extends ModelDefinitions, VD extends ViewDefinitions<MD>> = readonly [
88
+ ActionApiCommit<MD, VD, keyof MD>,
89
+ ...ActionApiCommit<MD, VD, keyof MD>[]
80
90
  ];
81
91
  export interface ActionApiFactory<MD extends ModelDefinitions, VD extends ViewDefinitions<MD>> {
82
92
  (request: ActionApiRequest<MD, VD>): ActionApiDefinition<MD, VD, []>;
83
- <const C extends ActionApiCommitTuple<MD>>(request: ActionApiRequest<MD, VD>, ...commits: C): ActionApiDefinition<MD, VD, C>;
93
+ <const C extends ActionApiCommitTuple<MD, VD>>(request: ActionApiRequest<MD, VD>, ...commits: C): ActionApiDefinition<MD, VD, C>;
84
94
  get(request: ActionApiRequestShortcut<MD, VD>): ActionApiDefinition<MD, VD, []>;
85
- get<const C extends ActionApiCommitTuple<MD>>(request: ActionApiRequestShortcut<MD, VD>, ...commits: C): ActionApiDefinition<MD, VD, C>;
95
+ get<const C extends ActionApiCommitTuple<MD, VD>>(request: ActionApiRequestShortcut<MD, VD>, ...commits: C): ActionApiDefinition<MD, VD, C>;
86
96
  head(request: ActionApiRequestShortcut<MD, VD>): ActionApiDefinition<MD, VD, []>;
87
- head<const C extends ActionApiCommitTuple<MD>>(request: ActionApiRequestShortcut<MD, VD>, ...commits: C): ActionApiDefinition<MD, VD, C>;
97
+ head<const C extends ActionApiCommitTuple<MD, VD>>(request: ActionApiRequestShortcut<MD, VD>, ...commits: C): ActionApiDefinition<MD, VD, C>;
88
98
  post(request: ActionApiRequestShortcut<MD, VD>): ActionApiDefinition<MD, VD, []>;
89
- post<const C extends ActionApiCommitTuple<MD>>(request: ActionApiRequestShortcut<MD, VD>, ...commits: C): ActionApiDefinition<MD, VD, C>;
99
+ post<const C extends ActionApiCommitTuple<MD, VD>>(request: ActionApiRequestShortcut<MD, VD>, ...commits: C): ActionApiDefinition<MD, VD, C>;
90
100
  put(request: ActionApiRequestShortcut<MD, VD>): ActionApiDefinition<MD, VD, []>;
91
- put<const C extends ActionApiCommitTuple<MD>>(request: ActionApiRequestShortcut<MD, VD>, ...commits: C): ActionApiDefinition<MD, VD, C>;
101
+ put<const C extends ActionApiCommitTuple<MD, VD>>(request: ActionApiRequestShortcut<MD, VD>, ...commits: C): ActionApiDefinition<MD, VD, C>;
92
102
  patch(request: ActionApiRequestShortcut<MD, VD>): ActionApiDefinition<MD, VD, []>;
93
- patch<const C extends ActionApiCommitTuple<MD>>(request: ActionApiRequestShortcut<MD, VD>, ...commits: C): ActionApiDefinition<MD, VD, C>;
103
+ patch<const C extends ActionApiCommitTuple<MD, VD>>(request: ActionApiRequestShortcut<MD, VD>, ...commits: C): ActionApiDefinition<MD, VD, C>;
94
104
  delete(request: ActionApiRequestShortcut<MD, VD>): ActionApiDefinition<MD, VD, []>;
95
- delete<const C extends ActionApiCommitTuple<MD>>(request: ActionApiRequestShortcut<MD, VD>, ...commits: C): ActionApiDefinition<MD, VD, C>;
105
+ delete<const C extends ActionApiCommitTuple<MD, VD>>(request: ActionApiRequestShortcut<MD, VD>, ...commits: C): ActionApiDefinition<MD, VD, C>;
96
106
  }
97
107
  export interface ActionHandlerFactory<MD extends ModelDefinitions, VD extends ViewDefinitions<MD>> {
98
108
  <P = unknown, R = void>(callback: ActionHandlerCallback<MD, VD, P, R>, options?: ActionHandlerOptions<P>): ActionHandlerDefinition<MD, VD, P, R>;
@@ -160,6 +170,6 @@ export interface ActionHandlerCall<P = unknown, T = void> extends ActionCallBase
160
170
  }
161
171
  export type ActionCall<T = void> = ActionApiCall<T> | ActionHandlerCall<any, T>;
162
172
  export type StoreAction<MD extends ModelDefinitions, VD extends ViewDefinitions<MD>, AD extends ActionDefinitions<MD, VD>> = {
163
- [K in keyof AD]: AD[K] extends ActionApiDefinition<MD, VD, infer C> ? C extends readonly ActionApiCommit<MD>[] ? ActionApiCall<ActionApiCommitReturn<MD, C>> : ActionApiCall : AD[K] extends ActionHandlerDefinition<MD, VD, infer P, infer R> ? ActionHandlerCall<P, R> : never;
173
+ [K in keyof AD]: AD[K] extends ActionApiDefinition<MD, VD, infer C> ? C extends readonly ActionApiCommit<MD, VD>[] ? ActionApiCall<ActionApiCommitReturn<MD, VD, C>> : ActionApiCall : AD[K] extends ActionHandlerDefinition<MD, VD, infer P, infer R> ? ActionHandlerCall<P, R> : never;
164
174
  };
165
175
  export {};
@@ -97,9 +97,9 @@ function resolveCommitMode(commit, options) {
97
97
  }
98
98
  return commit.mode;
99
99
  }
100
- function resolveCommitValue(commit, data) {
101
- if (typeof commit.value === "function") {
102
- return commit.value(data);
100
+ function resolveCommitTransform(commit, data, context) {
101
+ if (typeof commit.transform === "function") {
102
+ return commit.transform(data, context);
103
103
  }
104
104
  return data;
105
105
  }
@@ -177,7 +177,7 @@ async function executeHandler(definition, handler) {
177
177
  throw handlerError;
178
178
  }
179
179
  }
180
- function executeCommit(definition, model, data, options) {
180
+ function executeCommit(definition, model, data, context, options) {
181
181
  const commits = definition.commits;
182
182
  if (!commits || commits.length === 0) {
183
183
  return data;
@@ -192,7 +192,7 @@ function executeCommit(definition, model, data, options) {
192
192
  });
193
193
  }
194
194
  const mode = resolveCommitMode(commit, options);
195
- let value = resolveCommitValue(commit, data);
195
+ let value = resolveCommitTransform(commit, data, context);
196
196
  if (!isEmptyRecord(target.aliases())) {
197
197
  value = resolveAliasInbound(value, target.aliases());
198
198
  }
@@ -296,7 +296,11 @@ export function createAction(definition, model, view) {
296
296
  },
297
297
  options
298
298
  );
299
- data = executeCommit(definition, model, response, options);
299
+ const context = {
300
+ request: { url, method, headers, query, body },
301
+ view
302
+ };
303
+ data = executeCommit(definition, model, response, context, options);
300
304
  } else if (isHandlerDefinition(definition)) {
301
305
  const payload = resolveHandlerPayload(definition, options);
302
306
  data = await executeHandler(definition, {
@@ -7,7 +7,7 @@ export type { ModelOneCommitOptions, ModelManyCommitOptions } from "./core/types
7
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
- export type { ActionCall, ActionApiCall, ActionHandlerCall, ActionCallOptions, ActionCallBaseOptions, ActionApiCallOptions, ActionHandlerCallOptions, ActionCallTransformerOptions, ActionCallBindOptions, ActionCallCommitOptions, ActionHandlerOptions, ActionResolvedApi, } from "./core/types/action.js";
10
+ export type { ActionCall, ActionApiCall, ActionApiCommitContext, ActionHandlerCall, ActionCallOptions, ActionCallBaseOptions, ActionApiCallOptions, ActionHandlerCallOptions, ActionCallTransformerOptions, ActionCallBindOptions, ActionCallCommitOptions, ActionHandlerOptions, ActionResolvedApi, } from "./core/types/action.js";
11
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";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@diphyx/harlemify",
3
- "version": "6.1.0",
3
+ "version": "6.2.0",
4
4
  "description": "API state management for Nuxt powered by Harlem",
5
5
  "keywords": [
6
6
  "nuxt",
@@ -49,25 +49,28 @@
49
49
  "test": "vitest run",
50
50
  "test:e2e": "playwright test"
51
51
  },
52
+ "peerDependencies": {
53
+ "zod": "^4.4.3"
54
+ },
52
55
  "dependencies": {
53
56
  "@harlem/core": "^3.1.8",
54
- "@nuxt/kit": "^3.14.0 || ^4.0.0",
57
+ "@nuxt/kit": "^4.4.6",
55
58
  "consola": "^3.4.2",
56
- "defu": "^6.1.4",
57
- "zod": "^4.3.6"
59
+ "defu": "^6.1.7"
58
60
  },
59
61
  "devDependencies": {
60
62
  "@nuxt/eslint-config": "^0.6.2",
61
63
  "@nuxt/module-builder": "^0.8.4",
62
- "@nuxt/schema": "^4.3.1",
64
+ "@nuxt/schema": "^4.4.6",
63
65
  "@nuxt/test-utils": "^3.23.0",
64
- "@playwright/test": "^1.58.2",
65
- "@types/node": "^22.19.11",
66
+ "@playwright/test": "^1.60.0",
67
+ "@types/node": "^22.19.19",
66
68
  "@vitest/coverage-v8": "^2.1.9",
67
- "eslint": "^9.39.2",
68
- "nuxt": "^4.3.1",
69
+ "eslint": "^9.39.4",
70
+ "nuxt": "^4.4.6",
69
71
  "typescript": "^5.9.3",
70
72
  "vitest": "^2.1.9",
71
- "vue": "^3.5.28"
73
+ "vue": "^3.5.34",
74
+ "zod": "^4.4.3"
72
75
  }
73
76
  }