chore: patch next-safe-action with onExecute callback

This commit is contained in:
Nicolas Meienberger 2023-10-01 15:02:17 +02:00 committed by Nicolas Meienberger
parent 9bc96ffa9c
commit 7b533bb0bc
5 changed files with 333 additions and 10 deletions

View File

@ -14,6 +14,7 @@ WORKDIR /app
COPY ./pnpm-lock.yaml ./
COPY ./pnpm-workspace.yaml ./
COPY ./patches ./patches
RUN pnpm fetch --no-scripts
COPY ./package*.json ./

View File

@ -8,6 +8,7 @@ RUN npm install pnpm -g
WORKDIR /app
COPY ./pnpm-lock.yaml ./
COPY ./patches ./patches
RUN pnpm fetch --ignore-scripts
COPY ./package*.json ./

View File

@ -156,5 +156,10 @@
"bugs": {
"url": "https://github.com/meienberger/runtipi/issues"
},
"homepage": "https://github.com/meienberger/runtipi#readme"
"homepage": "https://github.com/meienberger/runtipi#readme",
"pnpm": {
"patchedDependencies": {
"next-safe-action@3.0.1": "patches/next-safe-action@3.0.1.patch"
}
}
}

View File

@ -0,0 +1,312 @@
diff --git a/dist/hook.d.ts b/dist/hook.d.ts
index 42220517df6bad298dd77f2e1961d6798ecfef0d..7b32f3634610ae20c0b108034a7da8048bc96205 100644
--- a/dist/hook.d.ts
+++ b/dist/hook.d.ts
@@ -1,5 +1,9 @@
-import { z } from 'zod';
-import { C as ClientCaller, H as HookCallbacks, a as HookRes } from './types-31a698ec.js';
+import { z } from "zod";
+import {
+ C as ClientCaller,
+ H as HookCallbacks,
+ a as HookRes,
+} from "./types-31a698ec.js";
/**
* Use the action from a Client Component via hook.
@@ -8,14 +12,17 @@ import { C as ClientCaller, H as HookCallbacks, a as HookRes } from './types-31a
*
* {@link https://github.com/TheEdoRan/next-safe-action/tree/main/packages/next-safe-action#2-the-hook-way See an example}
*/
-declare const useAction: <const IV extends z.ZodTypeAny, const Data>(clientCaller: ClientCaller<IV, Data>, cb?: HookCallbacks<IV, Data> | undefined) => {
- execute: (input: z.input<IV>) => void;
- isExecuting: boolean;
- res: HookRes<IV, Data>;
- reset: () => void;
- hasExecuted: boolean;
- hasSucceded: boolean;
- hasErrored: boolean;
+declare const useAction: <const IV extends z.ZodTypeAny, const Data>(
+ clientCaller: ClientCaller<IV, Data>,
+ cb?: HookCallbacks<IV, Data> | undefined
+) => {
+ execute: (input: z.input<IV>) => void;
+ isExecuting: boolean;
+ res: HookRes<IV, Data>;
+ reset: () => void;
+ hasExecuted: boolean;
+ hasSucceded: boolean;
+ hasErrored: boolean;
};
/**
* Use the action from a Client Component via hook, with optimistic data update.
@@ -27,15 +34,22 @@ declare const useAction: <const IV extends z.ZodTypeAny, const Data>(clientCalle
*
* {@link https://github.com/TheEdoRan/next-safe-action/tree/main/packages/next-safe-action#optimistic-update--experimental See an example}
*/
-declare const useOptimisticAction: <const IV extends z.ZodTypeAny, const Data>(clientCaller: ClientCaller<IV, Data>, initialOptData: Data, cb?: HookCallbacks<IV, Data> | undefined) => {
- execute: (input: z.input<IV>, newOptimisticData: Partial<Data>) => Promise<void>;
- isExecuting: boolean;
- res: HookRes<IV, Data>;
- optimisticData: Data;
- reset: () => void;
- hasExecuted: boolean;
- hasSucceded: boolean;
- hasErrored: boolean;
+declare const useOptimisticAction: <const IV extends z.ZodTypeAny, const Data>(
+ clientCaller: ClientCaller<IV, Data>,
+ initialOptData: Data,
+ cb?: HookCallbacks<IV, Data> | undefined
+) => {
+ execute: (
+ input: z.input<IV>,
+ newOptimisticData: Partial<Data>
+ ) => Promise<void>;
+ isExecuting: boolean;
+ res: HookRes<IV, Data>;
+ optimisticData: Data;
+ reset: () => void;
+ hasExecuted: boolean;
+ hasSucceded: boolean;
+ hasErrored: boolean;
};
export { HookCallbacks, HookRes, useAction, useOptimisticAction };
diff --git a/dist/hook.mjs b/dist/hook.mjs
index 89d77b1da720c87508e525f09e2c0005a1986819..5b0d50450441734813511cce9c6df203104c6f66 100644
--- a/dist/hook.mjs
+++ b/dist/hook.mjs
@@ -1,3 +1,5 @@
+"use client";
+
// src/hook.ts
import {
experimental_useOptimistic,
@@ -5,31 +7,34 @@ import {
useEffect,
useRef,
useState,
- useTransition
+ useTransition,
} from "react";
// src/utils.ts
-var isNextRedirectError = (e) => e instanceof Error && e.message === "NEXT_REDIRECT";
-var isNextNotFoundError = (e) => e instanceof Error && e.message === "NEXT_NOT_FOUND";
+var isError = (e) => e instanceof Error;
+var isNextRedirectError = (e) => isError(e) && e.message === "NEXT_REDIRECT";
+var isNextNotFoundError = (e) => isError(e) && e.message === "NEXT_NOT_FOUND";
// src/hook.ts
-"use client";
var getActionStatus = (res) => {
const hasSucceded = typeof res.data !== "undefined";
- const hasErrored = typeof res.validationError !== "undefined" || typeof res.serverError !== "undefined" || typeof res.fetchError !== "undefined";
+ const hasErrored =
+ typeof res.validationError !== "undefined" ||
+ typeof res.serverError !== "undefined" ||
+ typeof res.fetchError !== "undefined";
const hasExecuted = hasSucceded || hasErrored;
return { hasExecuted, hasSucceded, hasErrored };
};
-var useActionCallbacks = (res, hasSucceded, hasErrored, reset, cb) => {
+var useActionCallbacks = (input, res, hasSucceded, hasErrored, reset, cb) => {
const onSuccessRef = useRef(cb?.onSuccess);
const onErrorRef = useRef(cb?.onError);
useEffect(() => {
const onSuccess = onSuccessRef.current;
const onError = onErrorRef.current;
if (onSuccess && hasSucceded) {
- onSuccess(res.data, reset);
+ onSuccess(res.data, reset, input);
} else if (onError && hasErrored) {
- onError(res, reset);
+ onError(res, reset, input);
}
}, [hasErrored, hasSucceded, res, reset]);
};
@@ -37,21 +42,31 @@ var useAction = (clientCaller, cb) => {
const [isExecuting, startTransition] = useTransition();
const executor = useRef(clientCaller);
const [res, setRes] = useState({});
+ const [input, setInput] = useState();
+ const onExecuteRef = useRef(cb?.onExecute);
const { hasExecuted, hasSucceded, hasErrored } = getActionStatus(res);
- const execute = useCallback((input) => {
+ const execute = useCallback((input2) => {
+ setInput(input2);
+ const onExecute = onExecuteRef.current;
+ if (onExecute) {
+ onExecute(input2);
+ }
return startTransition(() => {
- return executor.current(input).then((res2) => setRes(res2)).catch((e) => {
- if (isNextRedirectError(e) || isNextNotFoundError(e)) {
- throw e;
- }
- setRes({ fetchError: e });
- });
+ return executor
+ .current(input2)
+ .then((res2) => setRes(res2))
+ .catch((e) => {
+ if (isNextRedirectError(e) || isNextNotFoundError(e)) {
+ throw e;
+ }
+ setRes({ fetchError: e });
+ });
});
}, []);
const reset = useCallback(() => {
setRes({});
}, []);
- useActionCallbacks(res, hasSucceded, hasErrored, reset, cb);
+ useActionCallbacks(input, res, hasSucceded, hasErrored, reset, cb);
return {
execute,
isExecuting,
@@ -59,34 +74,47 @@ var useAction = (clientCaller, cb) => {
reset,
hasExecuted,
hasSucceded,
- hasErrored
+ hasErrored,
};
};
var useOptimisticAction = (clientCaller, initialOptData, cb) => {
const [res, setRes] = useState({});
- const [optState, syncState] = experimental_useOptimistic({ ...initialOptData, ...res.data, __isExecuting__: false }, (state, newState) => ({
- ...state,
- ...newState,
- __isExecuting__: true
- }));
+ const [input, setInput] = useState();
+ const [optState, syncState] = experimental_useOptimistic(
+ { ...initialOptData, ...res.data, __isExecuting__: false },
+ (state, newState) => ({
+ ...state,
+ ...newState,
+ __isExecuting__: true,
+ })
+ );
const executor = useRef(clientCaller);
+ const onExecuteRef = useRef(cb?.onExecute);
const { hasExecuted, hasSucceded, hasErrored } = getActionStatus(res);
const execute = useCallback(
- (input, newOptimisticData) => {
+ (input2, newOptimisticData) => {
syncState(newOptimisticData);
- return executor.current(input).then((res2) => setRes(res2)).catch((e) => {
- if (isNextRedirectError(e) || isNextNotFoundError(e)) {
- throw e;
- }
- setRes({ fetchError: e });
- });
+ setInput(input2);
+ const onExecute = onExecuteRef.current;
+ if (onExecute) {
+ onExecute(input2);
+ }
+ return executor
+ .current(input2)
+ .then((res2) => setRes(res2))
+ .catch((e) => {
+ if (isNextRedirectError(e) || isNextNotFoundError(e)) {
+ throw e;
+ }
+ setRes({ fetchError: e });
+ });
},
[syncState]
);
const reset = useCallback(() => {
setRes({});
}, []);
- useActionCallbacks(res, hasSucceded, hasErrored, reset, cb);
+ useActionCallbacks(input, res, hasSucceded, hasErrored, reset, cb);
const { __isExecuting__, ...optimisticData } = optState;
return {
execute,
@@ -97,11 +125,8 @@ var useOptimisticAction = (clientCaller, initialOptData, cb) => {
reset,
hasExecuted,
hasSucceded,
- hasErrored
+ hasErrored,
};
};
-export {
- useAction,
- useOptimisticAction
-};
+export { useAction, useOptimisticAction };
//# sourceMappingURL=hook.mjs.map
diff --git a/dist/types-31a698ec.d.ts b/dist/types-31a698ec.d.ts
index c9339a0a530dd1825af0c6e1b4a6e9a58adc3c97..1eb8b8303d1534deee9f0084b6c62c9eabb147b2 100644
--- a/dist/types-31a698ec.d.ts
+++ b/dist/types-31a698ec.d.ts
@@ -1,30 +1,53 @@
-import { z } from 'zod';
+import { z } from "zod";
/**
* Type of the function called from Client Components with typesafe input data for the Server Action.
*/
-type ClientCaller<IV extends z.ZodTypeAny, Data> = (input: z.input<IV>) => Promise<{
- data?: Data;
- serverError?: true;
- validationError?: Partial<Record<keyof z.input<IV>, string[]>>;
+type ClientCaller<IV extends z.ZodTypeAny, Data> = (
+ input: z.input<IV>
+) => Promise<{
+ data?: Data;
+ serverError?: string;
+ validationError?: Partial<Record<keyof z.input<IV>, string[]>>;
}>;
/**
* Type of the function that executes server code when defining a new safe action.
*/
-type ActionServerFn<IV extends z.ZodTypeAny, Data, Context extends object> = (parsedInput: z.input<IV>, ctx: Context) => Promise<Data>;
+type ActionServerFn<IV extends z.ZodTypeAny, Data, Context extends object> = (
+ parsedInput: z.input<IV>,
+ ctx: Context
+) => Promise<Data>;
/**
* Type of `res` object returned by `useAction` and `useOptimisticAction` hooks.
*/
-type HookRes<IV extends z.ZodTypeAny, Data> = Awaited<ReturnType<ClientCaller<IV, Data>>> & {
- fetchError?: unknown;
+type HookRes<IV extends z.ZodTypeAny, Data> = Awaited<
+ ReturnType<ClientCaller<IV, Data>>
+> & {
+ fetchError?: unknown;
};
/**
* Type of hooks callbacks (`onSuccess` and `onError`).
* These are executed when the action succeeds or fails.
*/
type HookCallbacks<IV extends z.ZodTypeAny, Data> = {
- onSuccess?: (data: NonNullable<Pick<HookRes<IV, Data>, "data">["data"]>, reset: () => void) => void;
- onError?: (error: Omit<HookRes<IV, Data>, "data">, reset: () => void) => void;
+ onSuccess?: (
+ data: NonNullable<Pick<HookRes<IV, Data>, "data">["data"]>,
+ reset: () => void,
+ input: z.input<IV>
+ ) => void;
+ onError?: (
+ error: Omit<HookRes<IV, Data>, "data">,
+ reset: () => void,
+ input: z.input<IV>
+ ) => void;
+ onExecute?: (input: z.input<IV>) => unknown;
};
+type MaybePromise<T> = T | Promise<T>;
-export { ActionServerFn as A, ClientCaller as C, HookCallbacks as H, HookRes as a };
+export {
+ ActionServerFn as A,
+ ClientCaller as C,
+ HookCallbacks as H,
+ MaybePromise as M,
+ HookRes as a,
+};

View File

@ -1,5 +1,10 @@
lockfileVersion: '6.0'
patchedDependencies:
next-safe-action@3.0.1:
hash: i3wdronoj5npuplkzavpvyaj6e
path: patches/next-safe-action@3.0.1.patch
importers:
.:
@ -96,7 +101,7 @@ importers:
version: 2.20.0(next@13.5.3)(react@18.2.0)
next-safe-action:
specifier: ^3.0.1
version: 3.0.1(next@13.5.3)(react@18.2.0)(zod@3.21.4)
version: 3.0.1(patch_hash=i3wdronoj5npuplkzavpvyaj6e)(next@13.5.3)(react@18.2.0)(zod@3.21.4)
pg:
specifier: ^8.11.1
version: 8.11.1
@ -3713,7 +3718,7 @@ packages:
debug: 4.3.4
globby: 11.1.0
is-glob: 4.0.3
semver: 7.5.3
semver: 7.5.4
tsutils: 3.21.0(typescript@5.2.2)
typescript: 5.2.2
transitivePeerDependencies:
@ -7284,7 +7289,7 @@ packages:
'@babel/parser': 7.22.5
'@istanbuljs/schema': 0.1.3
istanbul-lib-coverage: 3.2.0
semver: 6.3.0
semver: 6.3.1
transitivePeerDependencies:
- supports-color
dev: true
@ -8164,7 +8169,7 @@ packages:
resolution: {integrity: sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==}
engines: {node: '>=8'}
dependencies:
semver: 6.3.0
semver: 6.3.1
dev: false
/make-dir@4.0.0:
@ -8913,7 +8918,7 @@ packages:
react: 18.2.0
dev: true
/next-safe-action@3.0.1(next@13.5.3)(react@18.2.0)(zod@3.21.4):
/next-safe-action@3.0.1(patch_hash=i3wdronoj5npuplkzavpvyaj6e)(next@13.5.3)(react@18.2.0)(zod@3.21.4):
resolution: {integrity: sha512-qQOHz4Z1vnW9fKAl3+nmSoONtX8kvqJBJJ4PkRlkSF8AfFJnYp7PZ5qvtdIBTzxNoQLtM/CyVqlAM/6dCHJ62w==}
engines: {node: '>=16'}
peerDependencies:
@ -8925,6 +8930,7 @@ packages:
react: 18.2.0
zod: 3.21.4
dev: false
patched: true
/next@13.5.3(@babel/core@7.22.5)(react-dom@18.2.0)(react@18.2.0)(sass@1.63.6):
resolution: {integrity: sha512-4Nt4HRLYDW/yRpJ/QR2t1v63UOMS55A38dnWv3UDOWGezuY0ZyFO1ABNbD7mulVzs9qVhgy2+ppjdsANpKP1mg==}
@ -8970,7 +8976,7 @@ packages:
resolution: {integrity: sha512-7GGVawqyHF4pfd0YFybhv/eM9JwTtPqx0mAanQ146O3FlSh3pA24zf9IRQTOsfTSqXTNzPSP5iagAJ94jjuVog==}
engines: {node: '>=10'}
dependencies:
semver: 7.5.3
semver: 7.5.4
/node-addon-api@5.1.0:
resolution: {integrity: sha512-eh0GgfEkpnoWDq+VY8OyvYhFEzBk6jIYbRKdIlyTiAXIVJ8PyBaKb0rp7oDtoddbdoHWhq8wwr+XZ81F1rpNdA==}
@ -9464,7 +9470,7 @@ packages:
https-proxy-agent: 5.0.1
node-fetch: 2.6.9
progress: 2.0.3
semver: 7.5.3
semver: 7.5.4
tar-fs: 2.1.1
yargs: 16.2.0
transitivePeerDependencies:
@ -10263,7 +10269,6 @@ packages:
/semver@6.3.1:
resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==}
hasBin: true
dev: true
/semver@7.0.0:
resolution: {integrity: sha512-+GB6zVA9LWh6zovYQLALHwv5rb2PHGlJi3lfiqIHxR0uuwCgefcOJc59v9fv1w8GbStwxuuqqAjI9NMAOOgq1A==}
@ -10283,7 +10288,6 @@ packages:
hasBin: true
dependencies:
lru-cache: 6.0.0
dev: true
/set-blocking@2.0.0:
resolution: {integrity: sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==}