From bf3acc0155414d82efb824ba944aa22e2a714fef Mon Sep 17 00:00:00 2001 From: Amir Reza Dalir Date: Mon, 9 Feb 2026 17:59:52 +0330 Subject: [PATCH 1/2] refactor!: remove action.data from core BREAKING CHANGE: removed data property from ActionCall interface. Users should capture data from the execute return value instead. - Remove globalData and data getter from action utils - Remove data from ActionCall type interface - Remove action.data references from playground pages - Remove action.data assertions from tests - Update action documentation to reflect removal --- docs/core-concepts/action.md | 3 +-- playground/pages/posts.vue | 7 +------ playground/pages/users.vue | 6 ------ src/runtime/core/types/action.ts | 5 ++--- src/runtime/core/utils/action.ts | 13 +++---------- test/action.test.ts | 4 +--- test/store.test.ts | 2 +- 7 files changed, 9 insertions(+), 31 deletions(-) diff --git a/docs/core-concepts/action.md b/docs/core-concepts/action.md index 15ca871..0bea56b 100644 --- a/docs/core-concepts/action.md +++ b/docs/core-concepts/action.md @@ -156,11 +156,10 @@ Every action has built-in reactive metadata: store.action.fetch.loading; // ComputedRef store.action.fetch.status; // Readonly> store.action.fetch.error; // Readonly> -store.action.fetch.data; // DeepReadonly | null store.action.fetch.reset(); // Reset to idle ``` -> **Note:** `data`, `status`, and `error` persist after execution. Call `reset()` to clear them back to their initial values (`null`, `IDLE`, `null`). +> **Note:** `status` and `error` persist after execution. Call `reset()` to clear them back to their initial values (`IDLE`, `null`). ### Template Usage diff --git a/playground/pages/posts.vue b/playground/pages/posts.vue index e9abb40..4854f45 100644 --- a/playground/pages/posts.vue +++ b/playground/pages/posts.vue @@ -131,11 +131,6 @@ function resetSortAction() {
{{ JSON.stringify(postStore.view.editor.value, null, 2) }}
-
-

action.sort.data (last sort result)

-

{{ (postStore.action.sort.data as any)?.length }} items sorted

-
-

Action Status

@@ -185,7 +180,7 @@ function resetSortAction() { action({ commit: { mode: ActionManyMode.ADD } }) - Call-time commit.mode override -
  • action.sort.data - Last successful result from action
  • +
  • action.sort.reset() - Reset action state
  • action({ body }) - Call-time payload with body data
  • shape.defaults() - Auto-generate zero-value form data from shape
  • diff --git a/playground/pages/users.vue b/playground/pages/users.vue index 7794b35..22a7746 100644 --- a/playground/pages/users.vue +++ b/playground/pages/users.vue @@ -143,11 +143,6 @@ function resetListAction() {
    {{ JSON.stringify(userStore.view.summary.value, null, 2) }}
    -
    -

    action.list.data (last successful result)

    -
    {{ JSON.stringify(userStore.action.list.data, null, 2)?.substring(0, 200) }}...
    -
    -

    Action Status

    @@ -218,7 +213,6 @@ function resetListAction() {
  • commit("list", ActionManyMode.RESET) - Standalone commit without api/handle
  • commit(..., { unique: true }) - Deduplicate on add
  • commit(..., { by: "email" }) - Custom identifier field for patch
  • -
  • action.list.data - Last successful result
  • action.list.reset() - Reset action state to idle
  • shape.defaults() - Auto-generate zero-value form data from shape
  • diff --git a/src/runtime/core/types/action.ts b/src/runtime/core/types/action.ts index ea61a1f..d0a58f6 100644 --- a/src/runtime/core/types/action.ts +++ b/src/runtime/core/types/action.ts @@ -181,9 +181,8 @@ export interface ActionCallOptions { export interface ActionCall { (options?: ActionCallOptions): Promise; - readonly loading: ComputedRef; - readonly status: Readonly>; readonly error: Readonly>; - readonly data: DeepReadonly | null; + readonly status: Readonly>; + readonly loading: ComputedRef; reset: () => void; } diff --git a/src/runtime/core/utils/action.ts b/src/runtime/core/utils/action.ts index 7468926..86c064d 100644 --- a/src/runtime/core/utils/action.ts +++ b/src/runtime/core/utils/action.ts @@ -1,5 +1,5 @@ import { defu } from "defu"; -import { type DeepReadonly, type Ref, ref, computed, readonly, toValue, nextTick } from "vue"; +import { type Ref, ref, computed, readonly, toValue, nextTick } from "vue"; import { type StoreModel, type ModelDefinitions, type ModelCall, ModelOneMode, ModelManyMode } from "../types/model"; import type { Shape } from "../types/shape"; @@ -341,8 +341,6 @@ export function createAction | null = null; let abortController: AbortController | null = null; - let globalData: R | null = null; - const globalError = ref(null); const globalStatus = ref(ActionStatus.IDLE); @@ -424,7 +422,6 @@ export function createAction, model, view); } - globalData = data; activeStatus.value = ActionStatus.SUCCESS; definition.logger?.debug("Action success", { @@ -447,22 +444,18 @@ export function createAction>; }, get status() { return readonly(globalStatus) as Readonly>; }, - get data() { - return globalData as DeepReadonly | null; + get loading() { + return loading; }, reset() { globalError.value = null; globalStatus.value = ActionStatus.IDLE; - globalData = null; }, }); diff --git a/test/action.test.ts b/test/action.test.ts index 1905c14..ddd6080 100644 --- a/test/action.test.ts +++ b/test/action.test.ts @@ -169,13 +169,12 @@ describe("createAction", () => { expect(action).toBeTypeOf("function"); }); - it("has loading, status, error, data, reset", () => { + it("has loading, status, error, reset", () => { const { action } = setup(); expect(action.loading).toBeDefined(); expect(action.status).toBeDefined(); expect(action.error).toBeDefined(); - expect(action.data).toBeNull(); expect(action.reset).toBeTypeOf("function"); }); @@ -237,7 +236,6 @@ describe("createAction", () => { expect(action.status.value).toBe(ActionStatus.IDLE); expect(action.error.value).toBeNull(); - expect(action.data).toBeNull(); }); }); diff --git a/test/store.test.ts b/test/store.test.ts index fceb19d..2a8c4cf 100644 --- a/test/store.test.ts +++ b/test/store.test.ts @@ -5,7 +5,7 @@ import { ModelOneMode, ModelManyMode } from "../src/runtime/core/types/model"; import { ActionStatus } from "../src/runtime/core/types/action"; import type { ShapeInfer } from "../src/runtime/core/types/shape"; -const mockFetch = globalThis.$fetch; +const mockFetch = (globalThis as any).$fetch; const UserShape = shape((factory) => { return { From 4e527168bf1064e1b2022643292225dacc190b7c Mon Sep 17 00:00:00 2001 From: Amir Reza Dalir Date: Mon, 9 Feb 2026 18:01:20 +0330 Subject: [PATCH 2/2] chore(test): remove global $fetch type declaration --- test/__mocks__/setup.ts | 4 ---- 1 file changed, 4 deletions(-) diff --git a/test/__mocks__/setup.ts b/test/__mocks__/setup.ts index 8ff66e9..43bf7b3 100644 --- a/test/__mocks__/setup.ts +++ b/test/__mocks__/setup.ts @@ -1,9 +1,5 @@ import { vi, beforeEach } from "vitest"; -declare global { - var $fetch: ReturnType; -} - vi.mock("#build/harlemify.config", () => { return { default: {