@defjs/react 0.0.1 → 0.0.3

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.
Files changed (4) hide show
  1. package/README.md +22 -41
  2. package/index.d.ts +12 -10
  3. package/index.js +7 -5
  4. package/package.json +2 -2
package/README.md CHANGED
@@ -1,12 +1,8 @@
1
1
  # @defjs/react
2
2
 
3
- Thin React plugin for `@defjs/core`. It provides an existing Defjs client through React Context.
3
+ Thin React plugin for `@defjs/core`: it provides an application-owned client through React Context. It adds no query layer, cache, Suspense integration, or state management, and never creates, replaces, or disposes a client.
4
4
 
5
- Keep reusable SDK definitions in their own package or module. A React application configures the client, provides it to components, and executes those definitions through `useClient()`. The SDK does not need a React dependency or a component-owned client.
6
-
7
- This plugin is optional: import a fixed application-owned client, pass a `Client` explicitly, use Context for tree-level defaults and overrides, or choose your own organization. SDK definitions do not require this plugin. Share an instance only when its captured configuration and state are safe to share; request-specific identity or credentials belong to the appropriate request boundary.
8
-
9
- Supports React 18+.
5
+ Keeping SDK definitions in their own package means the SDK needs no React dependency. Requires React 18 or later; the published entry is marked `'use client'`.
10
6
 
11
7
  ## Install
12
8
 
@@ -14,20 +10,12 @@ Supports React 18+.
14
10
  bun add @defjs/core @defjs/react react
15
11
  ```
16
12
 
17
- The package is ESM and requires `@defjs/core` as a peer in the `^0.4.0` range. Its tarball retains this `README.md` and the repository `LICENSE`; repository-wide guides and examples remain outside the package.
18
-
19
- ## What this package does
20
-
21
- `ClientProvider` exposes the exact `Client` instance supplied by the application. `useClient()` reads the nearest provided instance.
22
-
23
- Client creation and configuration stay in `@defjs/core`. The plugin does not create, cache, replace, dispose, abort, or close anything on behalf of the application, and it does not add a query layer, Suspense integration, GraphQL client, or application state management.
24
-
25
- ## Quick Start
13
+ The package is ESM and requires `@defjs/core` as a peer in the `^0.6.0` range.
26
14
 
27
- Define the SDK's requests in a shared module, or import them from your published SDK:
15
+ ## Quick start
28
16
 
29
17
  ```tsx
30
- // api.ts
18
+ // api.ts — reusable definition
31
19
  import { defineRequest, struct } from "@defjs/core";
32
20
 
33
21
  export const getUser = defineRequest({
@@ -39,8 +27,6 @@ export const getUser = defineRequest({
39
27
  });
40
28
  ```
41
29
 
42
- Create and own the client at the application boundary, then provide it:
43
-
44
30
  ```tsx
45
31
  // app.tsx
46
32
  import { createClient, withEndpoint } from "@defjs/core";
@@ -58,7 +44,7 @@ export function App() {
58
44
  }
59
45
  ```
60
46
 
61
- Read the client inside descendants and own request cleanup where the work starts. Best practice: name the command, pass that name to `execute`, and return before reading the user when `error` is set. Abort still belongs to the effect:
47
+ Read the client with `useClient()` and own request cleanup where the work starts:
62
48
 
63
49
  ```tsx
64
50
  import { useEffect, useState } from "react";
@@ -72,17 +58,16 @@ export function UserProfile({ id }: { id: number }) {
72
58
  useEffect(() => {
73
59
  const abort = new AbortController();
74
60
 
75
- const command = getUser({ id });
76
- void client
77
- .execute(command, { signal: abort.signal })
78
- .then(([error, user]) => {
61
+ void getUser(client({ signal: abort.signal }), { id }).then(
62
+ ([error, user]) => {
79
63
  if (abort.signal.aborted) return;
80
64
  if (error) {
81
65
  setName(error.message);
82
66
  return;
83
67
  }
84
68
  setName(user.name);
85
- });
69
+ },
70
+ );
86
71
 
87
72
  return () => abort.abort();
88
73
  }, [client, id]);
@@ -91,31 +76,27 @@ export function UserProfile({ id }: { id: number }) {
91
76
  }
92
77
  ```
93
78
 
94
- Nested providers follow normal React Context rules: descendants receive the nearest provider's exact client. Supplying a different `client` prop changes the provided value; the plugin does not invent a remount or caching policy.
95
-
96
79
  ## API
97
80
 
98
- ### `<ClientProvider client: Client>`
81
+ ### `<ClientProvider client={client}>`
99
82
 
100
- Provides the supplied client to descendant components. `children` is optional.
83
+ Provides the exact supplied `DerivableClient` to descendants. Nested providers follow normal React Context rules.
101
84
 
102
- ### `useClient(): Client`
85
+ ### `useClient(overrideClient?): DerivableClient`
103
86
 
104
- ```ts
105
- function useClient(overrideClient?: Client): Client;
106
- ```
87
+ Returns `overrideClient` when supplied, otherwise the nearest provided client. Throws only when neither source supplies one. Call it at the top level of a component or Hook — never as `explicitClient ?? useClient()`, which conditionally calls a Hook. The override does not write Context.
107
88
 
108
- Returns the exact `overrideClient` when supplied; omitted or `undefined` reads the nearest `ClientProvider`. Throws an `Error` only when neither source supplies a client. Zero-argument calls remain valid.
89
+ ## Notes
109
90
 
110
- Always call `useClient(explicitClient)` at the top level of a component or custom Hook, even with an explicit client; not in an ordinary function or event callback. Do not write `explicitClient ?? useClient()`, which conditionally calls a Hook. The override does not write Context or create a provider, and the Hook still subscribes to Context.
91
+ - `useClient()` returns the `DerivableClient` that was supplied, a function. Call it with request options where the operation runs to derive a `Client` value. Do not pass it to `useState` or a state setter: React calls a function argument as a lazy initializer or an updater and will invoke it. A derived `Client` value is not accepted by `ClientProvider` or `useClient`.
92
+ - Create request-specific clients (SSR data with credentials, cookies, or tenant state) at the application boundary.
93
+ - The owner that creates a client also owns its requests, SSE streams, and WebSocket sessions. Provider unmount does not clean them up.
94
+ - Import `createClient`, `withEndpoint`, `withInterceptors`, and other client options from `@defjs/core`.
111
95
 
112
- ## Notes
96
+ ## Documentation
113
97
 
114
- - The published entry is marked with `'use client'`, so React Server Component consumers treat this plugin as a client boundary.
115
- - Create request-specific clients at the application boundary for SSR data that contains credentials, cookies, or tenant state.
116
- - The owner that creates a client also owns all requests, SSE streams, and WebSocket sessions started through it. Provider unmount does not clean them up automatically.
117
- - Import `createClient`, `withEndpoint`, `withInterceptors`, and all other client options from `@defjs/core`.
98
+ - [React API](https://defjs.lyz.cloud/api/react) · [React guide](https://defjs.lyz.cloud/docs/integrations/react)
118
99
 
119
100
  ## License
120
101
 
121
- MIT License.
102
+ MIT.
package/index.d.ts CHANGED
@@ -1,31 +1,31 @@
1
1
 
2
2
  import { ReactNode } from "react";
3
- import { Client } from "@defjs/core";
3
+ import { DerivableClient } from "@defjs/core";
4
4
  /**
5
5
  * Props of {@link ClientProvider}: the required `client` and optional `children`.
6
6
  *
7
7
  * @group react
8
8
  */
9
9
  interface ClientProviderProps {
10
- /** Defjs client owned by the application. */
11
- client: Client;
10
+ /** Derivable client returned by `createClient`, owned by the application. */
11
+ client: DerivableClient;
12
12
  /** React tree that can call {@link useClient}. */
13
13
  children?: ReactNode;
14
14
  }
15
15
  /**
16
16
  * Provide a Defjs client to React descendants via context.
17
17
  *
18
- * Pass an existing client from `createClient` as `client`; descendants read it with `useClient`. The component does not create, cache, or dispose the client. A nested `ClientProvider` overrides the client for its own subtree, and a different `client` prop changes the context value for descendants.
18
+ * Pass the client returned by `createClient` as `client`; descendants read it with `useClient`. The component does not create, cache, or dispose the client. A nested `ClientProvider` overrides the client for its own subtree, and a different `client` prop changes the context value for descendants.
19
19
  *
20
20
  * @param props - `client` and optional `children`.
21
21
  * @returns A context provider element.
22
22
  *
23
23
  * @group react
24
- * @see {@link Client}
24
+ * @see {@link DerivableClient}
25
25
  * @see {@link ClientProviderProps}
26
26
  * @exampleFile examples/react/client-provider.tsx#example
27
27
  */
28
- export declare function ClientProvider({ client, children }: ClientProviderProps): React.FunctionComponentElement<React.ProviderProps<Client | null>>;
28
+ export declare function ClientProvider({ client, children }: ClientProviderProps): React.FunctionComponentElement<React.ProviderProps<DerivableClient | null>>;
29
29
  /**
30
30
  * React Hook that returns an explicit Defjs client or the nearest {@link ClientProvider}.
31
31
  *
@@ -33,8 +33,10 @@ export declare function ClientProvider({ client, children }: ClientProviderProps
33
33
  *
34
34
  * Always call `useClient(explicitClient)` at the top level of a component or custom Hook, even with an explicit client; not in an ordinary function or event callback. Do not write `explicitClient ?? useClient()`, which conditionally calls a Hook. The override does not write Context or create a provider, and the Hook still subscribes to Context.
35
35
  *
36
- * @param overrideClient - Client to use before context; `undefined` uses the provider.
37
- * @returns The selected `Client` instance.
36
+ * The returned value is the exact `DerivableClient` that was supplied. Call it with request options at the call site to derive a `Client` value for one call: `getUser(client({ signal }), input)`. It is a function, so do not pass it to `useState` or a state setter: React calls a function argument as a lazy initializer or an updater. The provider holds only a root client; a derived `Client` value is not accepted, so create it where the operation is called.
37
+ *
38
+ * @param overrideClient - Derivable client to use before context; `undefined` uses the provider.
39
+ * @returns The selected derivable client.
38
40
  * @throws If neither an explicit client nor a `ClientProvider` is available.
39
41
  *
40
42
  * @example
@@ -42,7 +44,7 @@ export declare function ClientProvider({ client, children }: ClientProviderProps
42
44
  * const client = useClient()
43
45
  * ```
44
46
  * @group react
45
- * @see {@link Client}
47
+ * @see {@link DerivableClient}
46
48
  */
47
- export declare function useClient(overrideClient?: Client): Client;
49
+ export declare function useClient(overrideClient?: DerivableClient): DerivableClient;
48
50
  export type { ClientProviderProps };
package/index.js CHANGED
@@ -5,13 +5,13 @@ const HttpClientContext = createContext(null);
5
5
  /**
6
6
  * Provide a Defjs client to React descendants via context.
7
7
  *
8
- * Pass an existing client from `createClient` as `client`; descendants read it with `useClient`. The component does not create, cache, or dispose the client. A nested `ClientProvider` overrides the client for its own subtree, and a different `client` prop changes the context value for descendants.
8
+ * Pass the client returned by `createClient` as `client`; descendants read it with `useClient`. The component does not create, cache, or dispose the client. A nested `ClientProvider` overrides the client for its own subtree, and a different `client` prop changes the context value for descendants.
9
9
  *
10
10
  * @param props - `client` and optional `children`.
11
11
  * @returns A context provider element.
12
12
  *
13
13
  * @group react
14
- * @see {@link Client}
14
+ * @see {@link DerivableClient}
15
15
  * @see {@link ClientProviderProps}
16
16
  * @exampleFile examples/react/client-provider.tsx#example
17
17
  */
@@ -25,8 +25,10 @@ function ClientProvider({ client, children }) {
25
25
  *
26
26
  * Always call `useClient(explicitClient)` at the top level of a component or custom Hook, even with an explicit client; not in an ordinary function or event callback. Do not write `explicitClient ?? useClient()`, which conditionally calls a Hook. The override does not write Context or create a provider, and the Hook still subscribes to Context.
27
27
  *
28
- * @param overrideClient - Client to use before context; `undefined` uses the provider.
29
- * @returns The selected `Client` instance.
28
+ * The returned value is the exact `DerivableClient` that was supplied. Call it with request options at the call site to derive a `Client` value for one call: `getUser(client({ signal }), input)`. It is a function, so do not pass it to `useState` or a state setter: React calls a function argument as a lazy initializer or an updater. The provider holds only a root client; a derived `Client` value is not accepted, so create it where the operation is called.
29
+ *
30
+ * @param overrideClient - Derivable client to use before context; `undefined` uses the provider.
31
+ * @returns The selected derivable client.
30
32
  * @throws If neither an explicit client nor a `ClientProvider` is available.
31
33
  *
32
34
  * @example
@@ -34,7 +36,7 @@ function ClientProvider({ client, children }) {
34
36
  * const client = useClient()
35
37
  * ```
36
38
  * @group react
37
- * @see {@link Client}
39
+ * @see {@link DerivableClient}
38
40
  */
39
41
  function useClient(overrideClient) {
40
42
  const providedClient = useContext(HttpClientContext);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@defjs/react",
3
- "version": "0.0.1",
3
+ "version": "0.0.3",
4
4
  "description": "Provide an existing Defjs client to a React tree.",
5
5
  "bugs": {
6
6
  "url": "https://github.com/defjs/defjs/issues"
@@ -14,7 +14,7 @@
14
14
  "main": "./index.js",
15
15
  "types": "./index.d.ts",
16
16
  "peerDependencies": {
17
- "@defjs/core": "^0.4.0",
17
+ "@defjs/core": "^0.6.0",
18
18
  "react": ">=18.0.0"
19
19
  },
20
20
  "module": "./index.js",