Преглед изворни кода

chore: patch next-safe-action with onExecute callback

Nicolas Meienberger пре 1 година
родитељ
комит
a7d6c183ab
5 измењених фајлова са 333 додато и 10 уклоњено
  1. 1 0
      Dockerfile
  2. 1 0
      Dockerfile.dev
  3. 6 1
      package.json
  4. 312 0
      patches/next-safe-action@3.0.1.patch
  5. 13 9
      pnpm-lock.yaml

+ 1 - 0
Dockerfile

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

+ 1 - 0
Dockerfile.dev

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

+ 6 - 1
package.json

@@ -156,5 +156,10 @@
   "bugs": {
   "bugs": {
     "url": "https://github.com/meienberger/runtipi/issues"
     "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"
+    }
+  }
 }
 }

+ 312 - 0
patches/next-safe-action@3.0.1.patch

@@ -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,
++};

+ 13 - 9
pnpm-lock.yaml

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