@orpc/react 0.0.0-next.ec7d801 → 0.0.0-next.ed05c40

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
@@ -30,7 +30,7 @@
30
30
  - **🔗 End-to-End Type Safety**: Ensure type-safe inputs, outputs, and errors from client to server.
31
31
  - **📘 First-Class OpenAPI**: Built-in support that fully adheres to the OpenAPI standard.
32
32
  - **📝 Contract-First Development**: Optionally define your API contract before implementation.
33
- - **⚙️ Framework Integrations**: Seamlessly integrate with TanStack Query (React, Vue, Solid, Svelte), Pinia Colada, and more.
33
+ - **⚙️ Framework Integrations**: Seamlessly integrate with TanStack Query (React, Vue, Solid, Svelte, Angular), Pinia Colada, and more.
34
34
  - **🚀 Server Actions**: Fully compatible with React Server Actions on Next.js, TanStack Start, and other platforms.
35
35
  - **🔠 Standard Schema Support**: Works out of the box with Zod, Valibot, ArkType, and other schema validators.
36
36
  - **🗃️ Native Types**: Supports native types like Date, File, Blob, BigInt, URL, and more.
@@ -58,12 +58,22 @@ interface UseServerActionErrorResult<TInput, TOutput, TError> extends UseServerA
58
58
  status: 'error';
59
59
  executedAt: Date;
60
60
  }
61
+ type UseServerActionResult<TInput, TOutput, TError> = UseServerActionIdleResult<TInput, TOutput, TError> | UseServerActionSuccessResult<TInput, TOutput, TError> | UseServerActionErrorResult<TInput, TOutput, TError> | UseServerActionPendingResult<TInput, TOutput, TError>;
61
62
  /**
62
63
  * Use a Server Action Hook
63
64
  *
64
65
  * @see {@link https://orpc.unnoq.com/docs/server-action#useserveraction-hook Server Action Hook Docs}
65
66
  */
66
- declare function useServerAction<TInput, TOutput, TError extends ORPCErrorJSON<any, any>>(action: ActionableClient<TInput, TOutput, TError>, options?: NoInfer<UseServerActionOptions<TInput, TOutput, UnactionableError<TError>>>): UseServerActionIdleResult<TInput, TOutput, UnactionableError<TError>> | UseServerActionSuccessResult<TInput, TOutput, UnactionableError<TError>> | UseServerActionErrorResult<TInput, TOutput, UnactionableError<TError>> | UseServerActionPendingResult<TInput, TOutput, UnactionableError<TError>>;
67
+ declare function useServerAction<TInput, TOutput, TError extends ORPCErrorJSON<any, any>>(action: ActionableClient<TInput, TOutput, TError>, options?: UseServerActionOptions<TInput, TOutput, UnactionableError<TError>>): UseServerActionResult<TInput, TOutput, UnactionableError<TError>>;
67
68
 
68
- export { useServerAction };
69
- export type { UseServerActionErrorResult, UseServerActionExecuteOptions, UseServerActionExecuteRest, UseServerActionIdleResult, UseServerActionOptions, UseServerActionPendingResult, UseServerActionResultBase, UseServerActionSuccessResult };
69
+ interface UseOptimisticServerActionOptions<TInput, TOutput, TError, TOptimisticState> extends UseServerActionOptions<TInput, TOutput, TError> {
70
+ optimisticPassthrough: TOptimisticState;
71
+ optimisticReducer: (state: TOptimisticState, input: TInput) => TOptimisticState;
72
+ }
73
+ type UseOptimisticServerActionResult<TInput, TOutput, TError, TOptimisticState> = UseServerActionResult<TInput, TOutput, TError> & {
74
+ optimisticState: TOptimisticState;
75
+ };
76
+ declare function useOptimisticServerAction<TInput, TOutput, TError extends ORPCErrorJSON<any, any>, TOptimisticState>(action: ActionableClient<TInput, TOutput, TError>, options: UseOptimisticServerActionOptions<TInput, TOutput, UnactionableError<TError>, TOptimisticState>): UseOptimisticServerActionResult<TInput, TOutput, UnactionableError<TError>, TOptimisticState>;
77
+
78
+ export { useOptimisticServerAction, useServerAction };
79
+ export type { UseOptimisticServerActionOptions, UseOptimisticServerActionResult, UseServerActionErrorResult, UseServerActionExecuteOptions, UseServerActionExecuteRest, UseServerActionIdleResult, UseServerActionOptions, UseServerActionPendingResult, UseServerActionResult, UseServerActionResultBase, UseServerActionSuccessResult };
@@ -58,12 +58,22 @@ interface UseServerActionErrorResult<TInput, TOutput, TError> extends UseServerA
58
58
  status: 'error';
59
59
  executedAt: Date;
60
60
  }
61
+ type UseServerActionResult<TInput, TOutput, TError> = UseServerActionIdleResult<TInput, TOutput, TError> | UseServerActionSuccessResult<TInput, TOutput, TError> | UseServerActionErrorResult<TInput, TOutput, TError> | UseServerActionPendingResult<TInput, TOutput, TError>;
61
62
  /**
62
63
  * Use a Server Action Hook
63
64
  *
64
65
  * @see {@link https://orpc.unnoq.com/docs/server-action#useserveraction-hook Server Action Hook Docs}
65
66
  */
66
- declare function useServerAction<TInput, TOutput, TError extends ORPCErrorJSON<any, any>>(action: ActionableClient<TInput, TOutput, TError>, options?: NoInfer<UseServerActionOptions<TInput, TOutput, UnactionableError<TError>>>): UseServerActionIdleResult<TInput, TOutput, UnactionableError<TError>> | UseServerActionSuccessResult<TInput, TOutput, UnactionableError<TError>> | UseServerActionErrorResult<TInput, TOutput, UnactionableError<TError>> | UseServerActionPendingResult<TInput, TOutput, UnactionableError<TError>>;
67
+ declare function useServerAction<TInput, TOutput, TError extends ORPCErrorJSON<any, any>>(action: ActionableClient<TInput, TOutput, TError>, options?: UseServerActionOptions<TInput, TOutput, UnactionableError<TError>>): UseServerActionResult<TInput, TOutput, UnactionableError<TError>>;
67
68
 
68
- export { useServerAction };
69
- export type { UseServerActionErrorResult, UseServerActionExecuteOptions, UseServerActionExecuteRest, UseServerActionIdleResult, UseServerActionOptions, UseServerActionPendingResult, UseServerActionResultBase, UseServerActionSuccessResult };
69
+ interface UseOptimisticServerActionOptions<TInput, TOutput, TError, TOptimisticState> extends UseServerActionOptions<TInput, TOutput, TError> {
70
+ optimisticPassthrough: TOptimisticState;
71
+ optimisticReducer: (state: TOptimisticState, input: TInput) => TOptimisticState;
72
+ }
73
+ type UseOptimisticServerActionResult<TInput, TOutput, TError, TOptimisticState> = UseServerActionResult<TInput, TOutput, TError> & {
74
+ optimisticState: TOptimisticState;
75
+ };
76
+ declare function useOptimisticServerAction<TInput, TOutput, TError extends ORPCErrorJSON<any, any>, TOptimisticState>(action: ActionableClient<TInput, TOutput, TError>, options: UseOptimisticServerActionOptions<TInput, TOutput, UnactionableError<TError>, TOptimisticState>): UseOptimisticServerActionResult<TInput, TOutput, UnactionableError<TError>, TOptimisticState>;
77
+
78
+ export { useOptimisticServerAction, useServerAction };
79
+ export type { UseOptimisticServerActionOptions, UseOptimisticServerActionResult, UseServerActionErrorResult, UseServerActionExecuteOptions, UseServerActionExecuteRest, UseServerActionIdleResult, UseServerActionOptions, UseServerActionPendingResult, UseServerActionResult, UseServerActionResultBase, UseServerActionSuccessResult };
@@ -1,6 +1,6 @@
1
+ import { intercept, toArray, onStart } from '@orpc/shared';
2
+ import { useState, useRef, useTransition, useCallback, useMemo, useOptimistic } from 'react';
1
3
  import { safe, createORPCErrorFromJson } from '@orpc/client';
2
- import { intercept, toArray } from '@orpc/shared';
3
- import { useState, useRef, useTransition, useCallback, useMemo } from 'react';
4
4
 
5
5
  const INITIAL_STATE = {
6
6
  data: void 0,
@@ -74,4 +74,18 @@ function useServerAction(action, options = {}) {
74
74
  return result;
75
75
  }
76
76
 
77
- export { useServerAction };
77
+ function useOptimisticServerAction(action, options) {
78
+ const [optimisticState, addOptimistic] = useOptimistic(options.optimisticPassthrough, options.optimisticReducer);
79
+ const state = useServerAction(action, {
80
+ ...options,
81
+ interceptors: [
82
+ useCallback(onStart(({ input }) => {
83
+ addOptimistic(input);
84
+ }), [addOptimistic]),
85
+ ...toArray(options.interceptors)
86
+ ]
87
+ });
88
+ return useMemo(() => ({ ...state, optimisticState }), [state, optimisticState]);
89
+ }
90
+
91
+ export { useOptimisticServerAction, useServerAction };
package/dist/index.d.mts CHANGED
@@ -1,6 +1,6 @@
1
1
  import { AnySchema } from '@orpc/contract';
2
2
  import { Context, ErrorMap, Meta, Lazyable, Procedure, CreateProcedureClientOptions } from '@orpc/server';
3
- import { Interceptor, MaybeOptionalOptions } from '@orpc/shared';
3
+ import { Interceptor, MaybeOptionalOptions, onStart, onSuccess, onError, onFinish } from '@orpc/shared';
4
4
  export { getIssueMessage, parseFormData } from '@orpc/openapi-client/standard';
5
5
 
6
6
  interface FormAction {
@@ -15,5 +15,22 @@ declare const orpcErrorToNextHttpFallbackInterceptor: Interceptor<any, Promise<a
15
15
  */
16
16
  declare function createFormAction<TInitialContext extends Context, TInputSchema extends AnySchema, TOutputSchema extends AnySchema, TErrorMap extends ErrorMap, TMeta extends Meta>(lazyableProcedure: Lazyable<Procedure<TInitialContext, any, TInputSchema, TOutputSchema, TErrorMap, TMeta>>, ...rest: MaybeOptionalOptions<CreateProcedureClientOptions<TInitialContext, TOutputSchema, TErrorMap, TMeta, Record<never, never>>>): FormAction;
17
17
 
18
- export { createFormAction, orpcErrorToNextHttpFallbackInterceptor };
18
+ /**
19
+ * Like `onStart`, but defers execution, useful for updating states.
20
+ */
21
+ declare const onStartDeferred: typeof onStart;
22
+ /**
23
+ * Like `onSuccess`, but defers execution, useful for updating states.
24
+ */
25
+ declare const onSuccessDeferred: typeof onSuccess;
26
+ /**
27
+ * Like `onError`, but defers execution, useful for updating states.
28
+ */
29
+ declare const onErrorDeferred: typeof onError;
30
+ /**
31
+ * Like `onFinish`, but defers execution, useful for updating states.
32
+ */
33
+ declare const onFinishDeferred: typeof onFinish;
34
+
35
+ export { createFormAction, onErrorDeferred, onFinishDeferred, onStartDeferred, onSuccessDeferred, orpcErrorToNextHttpFallbackInterceptor };
19
36
  export type { FormAction };
package/dist/index.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import { AnySchema } from '@orpc/contract';
2
2
  import { Context, ErrorMap, Meta, Lazyable, Procedure, CreateProcedureClientOptions } from '@orpc/server';
3
- import { Interceptor, MaybeOptionalOptions } from '@orpc/shared';
3
+ import { Interceptor, MaybeOptionalOptions, onStart, onSuccess, onError, onFinish } from '@orpc/shared';
4
4
  export { getIssueMessage, parseFormData } from '@orpc/openapi-client/standard';
5
5
 
6
6
  interface FormAction {
@@ -15,5 +15,22 @@ declare const orpcErrorToNextHttpFallbackInterceptor: Interceptor<any, Promise<a
15
15
  */
16
16
  declare function createFormAction<TInitialContext extends Context, TInputSchema extends AnySchema, TOutputSchema extends AnySchema, TErrorMap extends ErrorMap, TMeta extends Meta>(lazyableProcedure: Lazyable<Procedure<TInitialContext, any, TInputSchema, TOutputSchema, TErrorMap, TMeta>>, ...rest: MaybeOptionalOptions<CreateProcedureClientOptions<TInitialContext, TOutputSchema, TErrorMap, TMeta, Record<never, never>>>): FormAction;
17
17
 
18
- export { createFormAction, orpcErrorToNextHttpFallbackInterceptor };
18
+ /**
19
+ * Like `onStart`, but defers execution, useful for updating states.
20
+ */
21
+ declare const onStartDeferred: typeof onStart;
22
+ /**
23
+ * Like `onSuccess`, but defers execution, useful for updating states.
24
+ */
25
+ declare const onSuccessDeferred: typeof onSuccess;
26
+ /**
27
+ * Like `onError`, but defers execution, useful for updating states.
28
+ */
29
+ declare const onErrorDeferred: typeof onError;
30
+ /**
31
+ * Like `onFinish`, but defers execution, useful for updating states.
32
+ */
33
+ declare const onFinishDeferred: typeof onFinish;
34
+
35
+ export { createFormAction, onErrorDeferred, onFinishDeferred, onStartDeferred, onSuccessDeferred, orpcErrorToNextHttpFallbackInterceptor };
19
36
  export type { FormAction };
package/dist/index.mjs CHANGED
@@ -2,7 +2,7 @@ import { ORPCError, createORPCErrorFromJson } from '@orpc/client';
2
2
  import { StandardBracketNotationSerializer } from '@orpc/openapi-client/standard';
3
3
  export { getIssueMessage, parseFormData } from '@orpc/openapi-client/standard';
4
4
  import { createProcedureClient } from '@orpc/server';
5
- import { onError, resolveMaybeOptionalOptions, toArray } from '@orpc/shared';
5
+ import { onError, resolveMaybeOptionalOptions, toArray, onStart, onSuccess, onFinish } from '@orpc/shared';
6
6
 
7
7
  const orpcErrorToNextHttpFallbackInterceptor = onError((error) => {
8
8
  if (error instanceof ORPCError && [401, 403, 404].includes(error.status)) {
@@ -25,4 +25,33 @@ function createFormAction(lazyableProcedure, ...rest) {
25
25
  };
26
26
  }
27
27
 
28
- export { createFormAction, orpcErrorToNextHttpFallbackInterceptor };
28
+ const onStartDeferred = (callback, ...rest) => {
29
+ return onStart((...args) => {
30
+ setTimeout(() => {
31
+ callback(...args);
32
+ }, 6);
33
+ }, ...rest);
34
+ };
35
+ const onSuccessDeferred = (callback, ...rest) => {
36
+ return onSuccess((...args) => {
37
+ setTimeout(() => {
38
+ callback(...args);
39
+ }, 6);
40
+ }, ...rest);
41
+ };
42
+ const onErrorDeferred = (callback, ...rest) => {
43
+ return onError((...args) => {
44
+ setTimeout(() => {
45
+ callback(...args);
46
+ }, 6);
47
+ }, ...rest);
48
+ };
49
+ const onFinishDeferred = (callback, ...rest) => {
50
+ return onFinish((...args) => {
51
+ setTimeout(() => {
52
+ callback(...args);
53
+ }, 6);
54
+ }, ...rest);
55
+ };
56
+
57
+ export { createFormAction, onErrorDeferred, onFinishDeferred, onStartDeferred, onSuccessDeferred, orpcErrorToNextHttpFallbackInterceptor };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@orpc/react",
3
3
  "type": "module",
4
- "version": "0.0.0-next.ec7d801",
4
+ "version": "0.0.0-next.ed05c40",
5
5
  "license": "MIT",
6
6
  "homepage": "https://orpc.unnoq.com",
7
7
  "repository": {
@@ -34,15 +34,15 @@
34
34
  "react": ">=18.0.0"
35
35
  },
36
36
  "dependencies": {
37
- "@orpc/client": "0.0.0-next.ec7d801",
38
- "@orpc/openapi-client": "0.0.0-next.ec7d801",
39
- "@orpc/contract": "0.0.0-next.ec7d801",
40
- "@orpc/server": "0.0.0-next.ec7d801",
41
- "@orpc/shared": "0.0.0-next.ec7d801"
37
+ "@orpc/client": "0.0.0-next.ed05c40",
38
+ "@orpc/contract": "0.0.0-next.ed05c40",
39
+ "@orpc/openapi-client": "0.0.0-next.ed05c40",
40
+ "@orpc/server": "0.0.0-next.ed05c40",
41
+ "@orpc/shared": "0.0.0-next.ed05c40"
42
42
  },
43
43
  "devDependencies": {
44
44
  "react": "^19.1.0",
45
- "zod": "^3.25.57"
45
+ "zod": "^4.0.5"
46
46
  },
47
47
  "scripts": {
48
48
  "build": "unbuild",