@pixotope/query 0.10.0 → 0.11.0
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/.turbo/turbo-build.log +10 -10
- package/.turbo/turbo-check-types.log +1 -1
- package/.turbo/turbo-test.log +9 -9
- package/CHANGELOG.md +6 -0
- package/README.md +96 -0
- package/dist/index.cjs +5 -0
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +436 -39
- package/dist/index.d.ts +436 -39
- package/dist/index.js +5 -0
- package/dist/index.js.map +1 -1
- package/package.json +4 -4
- package/src/factories.ts +83 -1
- package/src/proxyBinders.ts +36 -0
- package/src/useMutation.ts +99 -2
- package/src/useQuery.ts +116 -8
- package/src/useSubscription.ts +63 -0
- package/src/useSubscriptionCore.ts +47 -34
- package/typedoc.json +3 -0
package/.turbo/turbo-build.log
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
|
|
2
|
-
> @pixotope/query@0.
|
|
2
|
+
> @pixotope/query@0.11.0 build /home/circleci/project/packages/query
|
|
3
3
|
> tsup src/index.ts --format cjs,esm --dts --sourcemap
|
|
4
4
|
|
|
5
5
|
[34mCLI[39m Building entry: src/index.ts
|
|
@@ -8,13 +8,13 @@
|
|
|
8
8
|
[34mCLI[39m Target: es6
|
|
9
9
|
[34mCJS[39m Build start
|
|
10
10
|
[34mESM[39m Build start
|
|
11
|
-
[32mCJS[39m [1mdist/index.cjs [22m[32m20.
|
|
12
|
-
[32mCJS[39m [1mdist/index.cjs.map [22m[
|
|
13
|
-
[32mCJS[39m ⚡️ Build success in
|
|
14
|
-
[32mESM[39m [1mdist/index.js [22m[
|
|
15
|
-
[32mESM[39m [1mdist/index.js.map [22m[
|
|
16
|
-
[32mESM[39m ⚡️ Build success in
|
|
11
|
+
[32mCJS[39m [1mdist/index.cjs [22m[32m20.84 KB[39m
|
|
12
|
+
[32mCJS[39m [1mdist/index.cjs.map [22m[32m61.16 KB[39m
|
|
13
|
+
[32mCJS[39m ⚡️ Build success in 82ms
|
|
14
|
+
[32mESM[39m [1mdist/index.js [22m[32m19.04 KB[39m
|
|
15
|
+
[32mESM[39m [1mdist/index.js.map [22m[32m61.10 KB[39m
|
|
16
|
+
[32mESM[39m ⚡️ Build success in 83ms
|
|
17
17
|
[34mDTS[39m Build start
|
|
18
|
-
[32mDTS[39m ⚡️ Build success in
|
|
19
|
-
[32mDTS[39m [1mdist/index.d.cts [22m[
|
|
20
|
-
[32mDTS[39m [1mdist/index.d.ts [22m[
|
|
18
|
+
[32mDTS[39m ⚡️ Build success in 2429ms
|
|
19
|
+
[32mDTS[39m [1mdist/index.d.cts [22m[32m33.56 KB[39m
|
|
20
|
+
[32mDTS[39m [1mdist/index.d.ts [22m[32m33.56 KB[39m
|
package/.turbo/turbo-test.log
CHANGED
|
@@ -1,19 +1,19 @@
|
|
|
1
1
|
|
|
2
|
-
> @pixotope/query@0.
|
|
2
|
+
> @pixotope/query@0.11.0 test /home/circleci/project/packages/query
|
|
3
3
|
> vitest
|
|
4
4
|
|
|
5
5
|
|
|
6
6
|
[1m[46m RUN [49m[22m [36mv3.2.4 [39m[90m/home/circleci/project/packages/query[39m
|
|
7
7
|
|
|
8
|
-
[32m✓[39m src/proxyBinders.test.ts [2m([22m[2m2 tests[22m[2m)[22m[32m
|
|
9
|
-
[32m✓[39m src/useSubscription.test.ts [2m([22m[2m4 tests[22m[2m)[22m[32m
|
|
10
|
-
[32m✓[39m src/useSubscriptionCore.test.ts [2m([22m[2m21 tests[22m[2m)[22m[32m
|
|
11
|
-
[32m✓[39m src/factories.test.ts [2m([22m[2m4 tests[22m[2m)[22m[32m
|
|
12
|
-
[32m✓[39m src/useMutation.test.ts [2m([22m[2m11 tests[22m[2m)[22m[33m
|
|
13
|
-
[32m✓[39m src/useQuery.test.ts [2m([22m[2m18 tests[22m[2m)[22m[33m
|
|
8
|
+
[32m✓[39m src/proxyBinders.test.ts [2m([22m[2m2 tests[22m[2m)[22m[32m 82[2mms[22m[39m
|
|
9
|
+
[32m✓[39m src/useSubscription.test.ts [2m([22m[2m4 tests[22m[2m)[22m[32m 181[2mms[22m[39m
|
|
10
|
+
[32m✓[39m src/useSubscriptionCore.test.ts [2m([22m[2m21 tests[22m[2m)[22m[32m 292[2mms[22m[39m
|
|
11
|
+
[32m✓[39m src/factories.test.ts [2m([22m[2m4 tests[22m[2m)[22m[32m 115[2mms[22m[39m
|
|
12
|
+
[32m✓[39m src/useMutation.test.ts [2m([22m[2m11 tests[22m[2m)[22m[33m 705[2mms[22m[39m
|
|
13
|
+
[32m✓[39m src/useQuery.test.ts [2m([22m[2m18 tests[22m[2m)[22m[33m 1291[2mms[22m[39m
|
|
14
14
|
|
|
15
15
|
[2m Test Files [22m [1m[32m6 passed[39m[22m[90m (6)[39m
|
|
16
16
|
[2m Tests [22m [1m[32m60 passed[39m[22m[90m (60)[39m
|
|
17
|
-
[2m Start at [22m
|
|
18
|
-
[2m Duration [22m
|
|
17
|
+
[2m Start at [22m 13:44:03
|
|
18
|
+
[2m Duration [22m 8.41s[2m (transform 2.25s, setup 1.89s, collect 4.89s, tests 2.67s, environment 12.71s, prepare 9.12s)[22m
|
|
19
19
|
|
package/CHANGELOG.md
CHANGED
package/README.md
ADDED
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
# @pixotope/query
|
|
2
|
+
|
|
3
|
+
React hooks for fetching, mutating and subscribing to data over Pixotope's ZMQ transport layer, react-query-style.
|
|
4
|
+
|
|
5
|
+
## Install
|
|
6
|
+
|
|
7
|
+
```sh
|
|
8
|
+
pnpm add @pixotope/query
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
`@pixotope/query` has a peer dependency on `react` (`>=17.0.0`), which must be installed in the consuming app. It also relies on `@pixotope/utils` and `@pixotope/zmq-client` internally — these are resolved automatically as part of the workspace and you don't need to install them yourself, but you do need a `ZMQClient` (or a `ZMQProxyWSClient` wrapping one) to actually talk to a service, since that's the transport the hooks in this package send calls and subscriptions over.
|
|
12
|
+
|
|
13
|
+
## Quick start
|
|
14
|
+
|
|
15
|
+
### `useQuery`
|
|
16
|
+
|
|
17
|
+
Fetches data on mount, and refetches when its `key` changes or `refetch` is called explicitly.
|
|
18
|
+
|
|
19
|
+
```tsx
|
|
20
|
+
import { useQuery } from "@pixotope/query";
|
|
21
|
+
|
|
22
|
+
function UserProfile({ userId }: { userId: string }) {
|
|
23
|
+
const { data, status, error, refetch } = useQuery({
|
|
24
|
+
key: ["user", userId],
|
|
25
|
+
queryFn: () => fetchUser(userId),
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
if (status === "loading") return <p>Loading...</p>;
|
|
29
|
+
if (status === "error") return <p>Failed to load: {String(error)}</p>;
|
|
30
|
+
|
|
31
|
+
return (
|
|
32
|
+
<div>
|
|
33
|
+
<p>{data?.name}</p>
|
|
34
|
+
<button onClick={() => refetch()}>Refresh</button>
|
|
35
|
+
</div>
|
|
36
|
+
);
|
|
37
|
+
}
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
### `useMutation`
|
|
41
|
+
|
|
42
|
+
Triggers an async side effect on demand and tracks its status/result/error.
|
|
43
|
+
|
|
44
|
+
```tsx
|
|
45
|
+
import { useMutation } from "@pixotope/query";
|
|
46
|
+
|
|
47
|
+
function CreateUserForm() {
|
|
48
|
+
const { mutate, status } = useMutation({
|
|
49
|
+
mutationFn: (vars: { name: string }) => createUser(vars),
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
return (
|
|
53
|
+
<button
|
|
54
|
+
disabled={status === "loading"}
|
|
55
|
+
onClick={() =>
|
|
56
|
+
mutate(
|
|
57
|
+
{ name: "Ada" },
|
|
58
|
+
{ onSuccess: (user) => console.log("created", user.id) }
|
|
59
|
+
)
|
|
60
|
+
}
|
|
61
|
+
>
|
|
62
|
+
Create user
|
|
63
|
+
</button>
|
|
64
|
+
);
|
|
65
|
+
}
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
### `useSubscription`
|
|
69
|
+
|
|
70
|
+
Subscribes to a `service`/`topic` pair for as long as the component is mounted, exposing the latest message as `data`.
|
|
71
|
+
|
|
72
|
+
```tsx
|
|
73
|
+
import { useSubscription } from "@pixotope/query";
|
|
74
|
+
import { bindClientSocketProxy } from "@pixotope/query";
|
|
75
|
+
|
|
76
|
+
function LiveStatus({ proxyClient }) {
|
|
77
|
+
const { data, status } = useSubscription(bindClientSocketProxy(proxyClient), {
|
|
78
|
+
service: "MyService",
|
|
79
|
+
topic: "MyTopic",
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
return <p>[{status}] {JSON.stringify(data)}</p>;
|
|
83
|
+
}
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
## API overview
|
|
87
|
+
|
|
88
|
+
- **`useQuery`** — fetch data on mount/key-change/interval/window-focus, with `select`, `initialData`, `timeout` and refetch support.
|
|
89
|
+
- **`useMutation`** — trigger an async side effect on demand and track its `status`/`result`/`error`, via `mutate` (fire-and-forget) or `mutateAsync` (awaitable).
|
|
90
|
+
- **`useSubscription`** — subscribe to a `service`/`topic` pair through a pluggable transport handler, managing subscribe/unsubscribe across the component lifecycle.
|
|
91
|
+
- **`useSubscriptionCore`** — the lower-level hook behind `useSubscription`; useful when building a subscription hook around a custom transport rather than a service/topic pair.
|
|
92
|
+
- **`buildServiceSubscriptionHook`** — builds a `useSubscription`-like hook pre-bound to a transport and machine/service resolver, for exposing a typed per-domain subscription hook.
|
|
93
|
+
- **`buildMutationHook`** / **`buildQueryHook`** — build typed `useMutation`/`useQuery`-like hooks for calling remote ZMQ functions by name, with `data`/`error`/`params` inferred per function from a `TFnToParams` map.
|
|
94
|
+
- **`bindClientSocketProxy`** / **`bindPromiseFunction`** — adapt a `ZMQProxyWSClient` (from `@pixotope/zmq-client`) into the transport functions expected by the subscription and factory hooks above.
|
|
95
|
+
|
|
96
|
+
See the generated API reference (`pnpm typedoc`) for full type signatures.
|
package/dist/index.cjs
CHANGED
|
@@ -89,8 +89,13 @@ var import_react3 = require("react");
|
|
|
89
89
|
// src/useMutation.ts
|
|
90
90
|
var import_react = require("react");
|
|
91
91
|
var ComparisonFailError = class _ComparisonFailError extends Error {
|
|
92
|
+
/**
|
|
93
|
+
* @param message - The error message.
|
|
94
|
+
* @param payload - The result that `compareOrThrow` rejected, preserved on the error.
|
|
95
|
+
*/
|
|
92
96
|
constructor(message, payload) {
|
|
93
97
|
super(message);
|
|
98
|
+
/** The result that `compareOrThrow` rejected. */
|
|
94
99
|
__publicField(this, "payload");
|
|
95
100
|
this.name = this.constructor.name;
|
|
96
101
|
this.payload = payload;
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/factories.ts","../src/useMutation.ts","../src/useQuery.ts","../../utils/dist/chunk-5QIHMQPV.js","../src/useSubscriptionCore.ts","../src/useSubscription.ts","../src/proxyBinders.ts"],"sourcesContent":["export * from \"./factories\";\nexport * from \"./useSubscription\";\nexport * from \"./useQuery\";\nexport * from \"./useMutation\";\nexport * from \"./useSubscriptionCore\";\nexport * from \"./proxyBinders\";\n","import type { TSocketServerCallOptions, ZMQClient } from \"@pixotope/zmq-client\";\nimport { useCallback, useMemo } from \"react\";\nimport { MutationOptions, useMutation } from \"./useMutation\";\nimport { QueryOptions, useQuery } from \"./useQuery\";\n\nexport type MutationInfo<TData, TError, TParams> = {\n data: TData;\n error: TError;\n params: TParams;\n};\n\ntype FnToParamsBase = Record<string, MutationInfo<unknown, unknown, unknown>>;\n\nexport type TPromiseFunction<TResponse, TParams, TExtraParams> = (\n args: Omit<\n ZMQClient.Call<\n TResponse,\n {\n functionName: string;\n parameters: TParams;\n options?: Omit<TSocketServerCallOptions, \"toCallIfNoResponse\">;\n }\n >,\n \"id\"\n > & {\n meta?: TExtraParams;\n }\n) => Promise<TResponse>;\n\nconst useCallMutationBase = <\n TFnToParams extends FnToParamsBase,\n TData = unknown,\n TError = unknown,\n TParams = unknown,\n TMetadata = unknown,\n>(\n promiseFunc: TPromiseFunction<TData, TParams, TMetadata>,\n functionName: keyof TFnToParams,\n service: (meta?: TMetadata) => string,\n options?: Omit<\n MutationOptions<TData, TError, TParams, TMetadata>,\n \"mutationFn\"\n >\n) => {\n const timeout = options?.timeout;\n const { ...rest } = useMemo(() => options ?? {}, [options]);\n const mutationFn = useCallback(\n async (parameters: TParams, meta?: TMetadata) => {\n try {\n return await promiseFunc({\n service: service(meta),\n functionName: functionName.toString(),\n parameters,\n options: {\n avoidTimeout: !timeout,\n customTimeout: timeout,\n },\n meta,\n });\n } catch (e) {\n if (e instanceof Error) {\n throw e;\n }\n throw new Error(e as string);\n }\n },\n [functionName, service, timeout]\n );\n\n return useMutation<TData, TError, TParams, TMetadata>({\n mutationFn,\n ...rest,\n });\n};\n\nexport function buildMutationHook<\n TFnToParams extends FnToParamsBase,\n TMetadata = unknown,\n>(\n promiseFunc: TPromiseFunction<unknown, unknown, unknown>,\n genTargetService: (meta?: TMetadata) => string\n) {\n return function useCallMutationBuilder<TFn extends keyof TFnToParams>(\n func: TFn,\n options?: Parameters<\n typeof useCallMutationBase<\n TFnToParams,\n TFnToParams[TFn][\"data\"],\n TFnToParams[TFn][\"error\"],\n TFnToParams[TFn][\"params\"],\n TMetadata\n >\n >[3]\n ) {\n return useCallMutationBase<\n TFnToParams,\n TFnToParams[TFn][\"data\"],\n TFnToParams[TFn][\"error\"],\n TFnToParams[TFn][\"params\"],\n TMetadata\n >(promiseFunc, func, genTargetService, options);\n };\n}\n\nconst useCallQueryBase = <\n TFnToParams extends FnToParamsBase,\n TData = unknown,\n TError = unknown,\n TParams = unknown,\n TSelect = TData,\n TMetadata = unknown,\n TStateless extends true | undefined = undefined,\n>(\n promiseFunction: TPromiseFunction<TData, TParams, TMetadata>,\n functionName: keyof TFnToParams,\n params: TParams,\n service: (meta?: TMetadata) => string,\n options?: Omit<QueryOptions<TData, TError, TParams, TSelect, TStateless>, \"queryFn\"> & {\n meta?: TMetadata;\n }\n) => {\n const timeout = options?.timeout;\n const { ...rest } = useMemo(() => options ?? {}, [options]);\n const queryFn = useCallback(\n async (refetchParams: TParams | void) => {\n try {\n return await promiseFunction({\n service: service(options?.meta),\n functionName: functionName.toString(),\n parameters: refetchParams ?? params,\n options: {\n avoidTimeout: !timeout,\n customTimeout: timeout,\n },\n meta: options?.meta,\n });\n } catch (e) {\n if (e instanceof Error) {\n throw e;\n }\n throw new Error(e as string);\n }\n },\n [functionName, service, params, timeout]\n );\n\n return useQuery<TData, TError, TParams, TSelect, TStateless>({\n queryFn,\n ...rest,\n });\n};\n\nexport function buildQueryHook<\n TFnToParams extends FnToParamsBase,\n TMetadata = unknown,\n>(\n promiseFunction: TPromiseFunction<unknown, unknown, unknown>,\n getTargetService: (meta?: TMetadata) => string\n) {\n return function useCallQueryBuilder<\n TFn extends keyof TFnToParams,\n TSelect = TFnToParams[TFn][\"data\"],\n TStateless extends true | undefined = undefined,\n >(\n func: TFn,\n params: TFnToParams[TFn][\"params\"],\n options?: Parameters<\n typeof useCallQueryBase<\n TFnToParams,\n TFnToParams[TFn][\"data\"],\n TFnToParams[TFn][\"error\"],\n TFnToParams[TFn][\"params\"],\n TSelect,\n TMetadata,\n TStateless\n >\n >[4] & { meta?: TMetadata }\n ) {\n return useCallQueryBase<\n TFnToParams,\n TFnToParams[TFn][\"data\"],\n TFnToParams[TFn][\"error\"],\n TFnToParams[TFn][\"params\"],\n TSelect,\n TMetadata,\n TStateless\n >(promiseFunction, func, params, getTargetService, options);\n };\n}\n","import { useCallback, useRef, useState } from \"react\";\n\nexport type MutationFunction<\n TData = unknown,\n TParams = unknown,\n TMetadata = unknown,\n> = (params: TParams, meta?: TMetadata) => Promise<TData>;\n\nexport interface MutationOptions<\n TData = unknown,\n TError = unknown,\n TParams = void,\n TMetadata = unknown,\n> {\n mutationFn: MutationFunction<TData, TParams, TMetadata>;\n params?: TParams;\n onSuccess?: (\n data: TData,\n variables: TParams,\n meta?: TMetadata\n ) => Promise<unknown> | unknown;\n onError?: (\n error: TMutationError<TError>,\n variables: TParams,\n meta?: TMetadata\n ) => Promise<unknown> | unknown;\n onSettled?: (\n data: TData | undefined,\n error: TMutationError<TError> | null,\n variables: TParams,\n meta?: TMetadata\n ) => Promise<unknown> | unknown;\n compareOrThrow?: (result: TData | TError) => boolean;\n timeout?: number;\n prepareParams?: (\n variables: TParams,\n defaults?: TParams,\n meta?: TMetadata\n ) => TParams;\n}\n\ntype TMutationError<TError> = TError | Error | null;\n\nexport interface MutateOptions<\n TData = unknown,\n TError = unknown,\n TParams = void,\n TMetadata = unknown,\n> {\n onSuccess?: (data: TData, variables: TParams, meta?: TMetadata) => void;\n onError?: (\n error: TMutationError<TError>,\n variables: TParams,\n meta?: TMetadata\n ) => void;\n onSettled?: (\n data: TData | undefined,\n error: TMutationError<TError> | null,\n variables: TParams,\n meta?: TMetadata\n ) => void;\n}\n\ntype MutationStatus = \"idle\" | \"loading\" | \"success\" | \"error\";\ntype RaceErrorReason = \"timeout\";\ntype RacePromises<T> = Promise<T | RaceErrorReason>;\n\nexport class ComparisonFailError<TPayload = unknown> extends Error {\n public readonly payload: TPayload;\n\n constructor(message: string, payload: TPayload) {\n super(message);\n this.name = this.constructor.name;\n this.payload = payload;\n\n if (Error.captureStackTrace) {\n Error.captureStackTrace(this, ComparisonFailError);\n }\n }\n}\n\nexport const useMutation = <\n TData = unknown,\n TError = TMutationError<unknown>,\n TParams = void,\n TMetadata = unknown,\n>(\n options: MutationOptions<TData, TError, TParams, TMetadata>\n) => {\n const {\n mutationFn,\n compareOrThrow,\n onError,\n onSettled,\n onSuccess,\n prepareParams,\n params,\n timeout,\n } = options;\n const [status, setStatus] = useState<MutationStatus>(\"idle\");\n const [error, setError] = useState<TMutationError<TError>>(null);\n const [result, setResult] = useState<TData | undefined>(undefined);\n const mutationFnRef = useRef(mutationFn);\n const internalOptionsRef = useRef({\n params,\n timeout,\n });\n const internalCallbackRefistry = <const>{\n onSuccess,\n onError,\n onSettled,\n compareOrThrow,\n prepareParams,\n };\n const internalCallbackRef = useRef(internalCallbackRefistry);\n internalCallbackRef.current = internalCallbackRefistry;\n\n const mutateAsync = useCallback(async (params: TParams, meta?: TMetadata) => {\n setStatus(\"loading\");\n setError(null);\n\n try {\n const promises: RacePromises<TData>[] = [\n mutationFnRef.current(\n internalCallbackRef.current.prepareParams\n ? internalCallbackRef.current.prepareParams(\n params,\n internalOptionsRef.current.params,\n meta\n )\n : params,\n meta\n ),\n ...(internalOptionsRef.current.timeout\n ? [\n new Promise<RaceErrorReason>((resolve) =>\n setTimeout(\n () => resolve(\"timeout\"),\n internalOptionsRef.current.timeout\n )\n ),\n ]\n : []),\n ];\n\n const res = await Promise.race(promises);\n\n if (res === \"timeout\") {\n throw new Error(\"timeout\");\n }\n\n if (internalCallbackRef.current.compareOrThrow?.(res)) {\n throw new ComparisonFailError(JSON.stringify(res), res);\n }\n\n setResult(res);\n setStatus(\"success\");\n\n internalCallbackRef.current.onSuccess?.(res, params, meta);\n internalCallbackRef.current.onSettled?.(res, null, params, meta);\n\n return res;\n } catch (error: any) {\n setError(error);\n setStatus(\"error\");\n\n internalCallbackRef.current.onError?.(error, params, meta);\n internalCallbackRef.current.onSettled?.(undefined, error, params, meta);\n\n throw error;\n }\n }, []);\n\n const mutate = useCallback(\n (\n variables: TParams,\n options?: MutateOptions<TData, TError, TParams, TMetadata> & {\n meta?: TMetadata;\n }\n ) => {\n mutateAsync(variables, options?.meta).then(\n (data) => {\n options?.onSuccess?.(data, variables, options?.meta);\n options?.onSettled?.(data, null, variables, options?.meta);\n },\n (error) => {\n options?.onError?.(error, variables, options?.meta);\n options?.onSettled?.(undefined, error, variables, options?.meta);\n }\n );\n },\n [mutateAsync]\n );\n\n return {\n mutateAsync,\n status,\n result,\n mutate,\n reset: () => {\n setStatus(\"idle\");\n setError(null);\n setResult(undefined);\n },\n error,\n };\n};\n","import { useCallback, useEffect, useRef, useState } from \"react\";\n\nexport interface QueryOptions<\n TData = unknown,\n TError = unknown,\n TParams = void,\n TSelectData = TData,\n Stateless extends true | undefined = undefined,\n> {\n queryFn: (params: TParams | undefined | void, queryInfo: {key: TQueryKey | undefined, lastFetchedAt: number | undefined}) => Promise<TData>;\n onSuccess?: (data: TData) => Promise<void> | void;\n onError?: (error: TQueryError<TError>) => Promise<void> | void;\n onSettled?: (\n data: TData | undefined,\n error: TQueryError<TError> | undefined\n ) => Promise<void> | void;\n timeout?: number;\n enabled?: boolean;\n initialData?: TData | Functionize<TData>;\n select?: (data: TData) => TSelectData;\n refetchOnWindowFocus?: boolean;\n refetchInterval?: number;\n compareOrThrow?: (data: TData) => boolean;\n stateless?: Stateless;\n key?: TQueryKey;\n}\n\ntype Functionize<T> = () => T;\ntype QueryStatus = \"idle\" | \"loading\" | \"success\" | \"error\" | \"timeout\";\ntype RaceErrorReason = \"timeout\";\ntype RacePromises<T> = Promise<T | RaceErrorReason>;\ntype WithData<TData> = { data: TData | undefined };\ntype TQueryKey = readonly any[];\n\ntype TQueryError<TError> = TError | Error | null;\n\nexport type UseQueryResult<\n TData = unknown,\n TError = unknown,\n TParams = void,\n TSelectData = TData,\n Stateless extends true | undefined = undefined,\n> = {\n error: TQueryError<TError>;\n status: QueryStatus;\n refetch: (params: TParams | void | undefined) => Promise<void>;\n reset: () => void;\n // eslint-disable-next-line @typescript-eslint/no-empty-object-type\n} & (Stateless extends true ? {} : WithData<TSelectData>);\n\nfunction normalizeQueryKey(queryKey: TQueryKey): string {\n return JSON.stringify(queryKey);\n}\n\ntype TInternalCallbackRef<TData, TError, TSelectData> = {\n onError?: (error: TQueryError<TError>) => Promise<void> | void;\n onSuccess?: (data: TData) => Promise<void> | void;\n onSettled?: (\n data: TData | undefined,\n error: TQueryError<TError> | undefined\n ) => Promise<void> | void;\n compareOrThrow?: (data: TData) => boolean;\n select?: (data: TData) => TSelectData;\n};\n\ntype TInternalOptionsRef<TData> = {\n timeout?: number;\n enabled: boolean;\n refetchOnWindowFocus: boolean;\n refetchInterval: number;\n compareOrThrow?: (data: TData) => boolean;\n stateless?: boolean;\n};\n\nconst getRandomUUID = () => Math.random().toString(36).substring(2, 15);\n\nexport const useQuery = <\n TData = unknown,\n TError = TQueryError<unknown>,\n TParams = void,\n TSelected = TData,\n Stateless extends true | undefined = undefined,\n>({\n queryFn,\n ...options\n}: QueryOptions<TData, TError, TParams, TSelected, Stateless>): UseQueryResult<\n TSelected,\n TError,\n TParams,\n TSelected,\n Stateless\n> => {\n const {\n enabled = true,\n refetchOnWindowFocus = false,\n refetchInterval = 0,\n initialData,\n select,\n onError,\n onSuccess,\n onSettled,\n timeout,\n compareOrThrow,\n stateless,\n key: queryKeyPassed,\n } = options;\n const queryKey = normalizeQueryKey(queryKeyPassed ?? []);\n const lastFetchedAt = useRef<number | null>(null);\n const lastQueryKey = useRef<string | undefined>(undefined);\n const queryFnRef = useRef(queryFn);\n queryFnRef.current = queryFn;\n const internalCallbackRef = useRef<\n TInternalCallbackRef<TData, TError, TSelected>\n >({});\n internalCallbackRef.current = {\n onError,\n onSuccess,\n onSettled,\n compareOrThrow,\n select,\n };\n const internalOptionsRef = useRef<TInternalOptionsRef<TData>>({\n enabled,\n refetchOnWindowFocus,\n refetchInterval,\n compareOrThrow,\n stateless,\n timeout,\n });\n internalOptionsRef.current = {\n enabled,\n refetchOnWindowFocus,\n refetchInterval,\n compareOrThrow,\n stateless,\n timeout,\n };\n const requestIdRef = useRef(getRandomUUID());\n\n const [status, setStatus] = useState<QueryStatus>(() => {\n return \"idle\";\n });\n const [error, setError] = useState<TQueryError<TError>>(null);\n const [data, setData] = useState<TData | undefined>(() => {\n if (initialData !== undefined) {\n if (typeof initialData === \"function\") {\n return (initialData as Functionize<TData>)();\n }\n\n return initialData as TData;\n }\n\n return undefined;\n });\n\n const handleSetData = useCallback((data: TData) => {\n if (internalOptionsRef.current.stateless) {\n return;\n }\n\n setData(data);\n }, []);\n\n const shouldRefetch = useCallback(() => {\n if (!internalOptionsRef.current.enabled) {\n return false;\n }\n\n if (lastFetchedAt.current === null) {\n return true;\n }\n\n return (\n new Date().getTime() - lastFetchedAt.current >\n internalOptionsRef.current?.refetchInterval\n );\n }, []);\n\n const refetch = useCallback(\n async (params: TParams | void | undefined = undefined) => {\n const requestId = getRandomUUID();\n requestIdRef.current = requestId;\n if (!internalOptionsRef.current.enabled) {\n return;\n }\n\n setStatus(\"loading\");\n setError(null);\n\n try {\n const promises: RacePromises<TData>[] = [\n queryFnRef.current(params, { key: queryKeyPassed, lastFetchedAt: lastFetchedAt.current ?? undefined }),\n ...(internalOptionsRef.current.timeout\n ? [\n new Promise<RaceErrorReason>((resolve) =>\n setTimeout(\n () => resolve(\"timeout\"),\n internalOptionsRef.current.timeout\n )\n ),\n ]\n : []),\n ];\n\n const res = await Promise.race(promises);\n if (requestIdRef.current !== requestId) {\n return;\n }\n\n if (res === \"timeout\") {\n throw new Error(\"timeout\");\n }\n\n handleSetData(res);\n\n if (\n internalCallbackRef.current.compareOrThrow &&\n internalCallbackRef.current.compareOrThrow(res) === true\n ) {\n throw new Error(\"failedComparison\");\n }\n\n setStatus(\"success\");\n lastFetchedAt.current = new Date().getTime();\n internalCallbackRef.current.onSuccess?.(res);\n internalCallbackRef.current.onSettled?.(res, undefined);\n } catch (error: any) {\n setError(error);\n setStatus(\"error\");\n internalCallbackRef.current.onError?.(error);\n internalCallbackRef.current.onSettled?.(undefined, error);\n }\n },\n [handleSetData]\n );\n\n const reset = useCallback(() => {\n setData(undefined);\n setStatus(\"idle\");\n setError(null);\n refetch();\n }, [refetch]);\n\n useEffect(() => {\n const cleanups: (() => void)[] = [];\n\n // If the query should be refetched on window focus, add a listener\n if (refetchOnWindowFocus) {\n const queryHandleFocus = () => {\n refetch();\n };\n\n window.addEventListener(\"focus\", queryHandleFocus);\n\n cleanups.push(() => {\n window.removeEventListener(\"focus\", queryHandleFocus);\n });\n }\n\n // If the query should be refetched on an interval, add an interval\n if (refetchInterval > 0) {\n const interval = setInterval(() => {\n if (shouldRefetch()) {\n refetch();\n }\n }, refetchInterval);\n\n cleanups.push(() => {\n clearInterval(interval);\n });\n }\n\n // If the query key has changed, refetch\n if (\n lastQueryKey.current === undefined ||\n queryKey !== lastQueryKey.current\n ) {\n lastQueryKey.current = queryKey;\n refetch();\n }\n\n return () => {\n cleanups.forEach((cleanup) => cleanup());\n };\n }, [\n queryKey,\n enabled,\n refetchOnWindowFocus,\n refetchInterval,\n shouldRefetch,\n refetch,\n ]);\n\n return {\n data:\n select && data !== undefined\n ? select(data as TData)\n : (data as unknown as TSelected),\n error,\n status,\n refetch,\n reset,\n };\n};\n","// src/comparison/shallowEqual.ts\nfunction shallowEqual(objA, objB) {\n if (Object.is(objA, objB)) {\n return true;\n }\n if (typeof objA !== \"object\" || objA === null || typeof objB !== \"object\" || objB === null) {\n return false;\n }\n if (objA instanceof Map && objB instanceof Map) {\n if (objA.size !== objB.size) return false;\n for (const [key, value] of objA) {\n if (!Object.is(value, objB.get(key))) {\n return false;\n }\n }\n return true;\n }\n if (objA instanceof Set && objB instanceof Set) {\n if (objA.size !== objB.size) return false;\n for (const value of objA) {\n if (!objB.has(value)) {\n return false;\n }\n }\n return true;\n }\n const keysA = Object.keys(objA);\n if (keysA.length !== Object.keys(objB).length) {\n return false;\n }\n for (let i = 0; i < keysA.length; i++) {\n if (!Object.prototype.hasOwnProperty.call(objB, keysA[i]) || !Object.is(objA[keysA[i]], objB[keysA[i]])) {\n return false;\n }\n }\n return true;\n}\n\nexport {\n shallowEqual\n};\n","/**\n * @fileoverview useSubscriptionCore\n * @name useSubscriptionCore.ts\n * @description useSubscriptionCore | This hook handle core subscription logic\n * and provides a way to subscribe and unsubscribe to a topic via any callback\n */\n\nimport { shallowEqual } from \"@pixotope/utils/comparison\";\nimport { useCallback, useEffect, useMemo, useRef, useState } from \"react\";\n\ntype SubscriptionState = \"idle\" | \"subscribed\" | \"subscribing\" | \"error\";\n\nexport type MessageHandler<TMessage> = (message: TMessage) => void;\nexport type Connection = {\n acknowledge: () => void;\n};\nexport type SubscriptionCoreOptions<\n TData,\n TMessage = TData,\n Stateless extends true | undefined = undefined,\n> = {\n /**\n * @description Function that will be called when the message is received.\n */\n onMessage?: (message: TMessage) => void;\n /**\n * @description Function that will be called when the subscription is created.\n */\n onSubscribed?: (message: TMessage) => void;\n /**\n * @description Function that will be called when the subscription is created.\n */\n onError?: (error: TMessage) => void;\n /**\n * @description Whether the subscription is enabled.\n * @default true\n */\n enabled?: boolean;\n /**\n * @description Function that will be called before the message is processed.\n * Returning `true` will cause the message to not be set to state and call {@link onError} if provided.\n * Status will be set to `error`.\n */\n compareOrThrow?: (data: TMessage) => boolean;\n /**\n * @description Function that will be called to select the data from the message.\n */\n select?: (data: TMessage) => TData;\n /**\n * @description Initial state of the subscription.\n * @default undefined\n */\n initialState?: TData;\n /**\n * @description Function that will be called when the subscription is created.\n */\n subscriberFn: (\n handler: MessageHandler<TMessage>,\n connection: Connection\n ) => () => void /** unsubscribe Fn */;\n /**\n * @description Whether the subscription is stateless. Data will not be\n * stored by the hook internally.\n * @default false\n */\n stateless?: Stateless;\n /**\n * @description Custom equality function for comparing data.\n * @default shallowEqual\n */\n isEqual?: <T = TData>(a: T, b: T) => boolean;\n};\n\ntype WithStatus = {\n status: SubscriptionState;\n};\n\ntype WithData<TData> = {\n data: TData;\n};\n\nexport type SubscriptionCoreReturnType<\n TData,\n Stateless extends true | undefined,\n> = {\n reSubscribe: () => void;\n // eslint-disable-next-line @typescript-eslint/no-empty-object-type\n} & (Stateless extends true ? {} : WithStatus & WithData<TData>);\n\n/**\n * @description `useSubscriptionCore` | This hook handle core subscription logic\n * and provides a way to subscribe and unsubscribe to a topic via any callback.\n * The hook expose a handler function. All the consumer code need to do is to\n * call this handler function with the message received from the topic or pass\n * it directly to the callback function that is passed to the subscriberFn.\n * - `status` - current status of the subscription\n * - `data` - the data after the select function is applied to the message\n * - `reSubscribe` - function that can be called to re-subscribe to the topic\n *\n * An example how this hook works can be found in {@link ./useSubscription.ts}\n */\nexport function useSubscriptionCore<\n TData = unknown,\n TMessage = TData,\n Stateless extends true | undefined = undefined,\n>(\n options: SubscriptionCoreOptions<TData, TMessage, Stateless>\n): SubscriptionCoreReturnType<TData, Stateless> {\n const {\n enabled = true,\n initialState = undefined,\n onSubscribed,\n stateless,\n compareOrThrow,\n subscriberFn,\n onMessage,\n onError,\n select,\n isEqual = shallowEqual,\n } = options;\n const [status, setStatus] = useState<SubscriptionState>(\"idle\");\n const [data, setData] = useState<TData | undefined>(initialState);\n const unsubcribeRef = useRef<() => void | undefined>(undefined);\n const initialStateRef = useRef(initialState);\n const subscriberFnRef = useRef(subscriberFn);\n const callbackRefRegistry = <const>{\n onMessage,\n onError,\n select,\n compareOrThrow,\n onSubscribed,\n isEqual,\n };\n const internalCallbacksRef = useRef(callbackRefRegistry);\n internalCallbacksRef.current = callbackRefRegistry;\n\n const updateStatus = useCallback(\n (newStatus: SubscriptionState, message?: TMessage) => {\n if (stateless) {\n return;\n }\n\n setStatus((prev) => {\n if (prev === newStatus) {\n return prev;\n }\n\n if (newStatus === \"subscribed\" && message) {\n internalCallbacksRef.current.onSubscribed?.(message);\n }\n\n return newStatus;\n });\n },\n [stateless]\n );\n\n const connection: Connection = useMemo(\n () => ({\n acknowledge: () => {\n updateStatus(\"subscribed\");\n },\n }),\n [updateStatus]\n );\n\n const handler = useCallback(\n async (message: TMessage) => {\n if (internalCallbacksRef.current.compareOrThrow?.(message)) {\n updateStatus(\"error\");\n internalCallbacksRef.current.onError?.(message);\n\n return;\n }\n\n const selectedMessage = <TData>(\n (internalCallbacksRef.current.select?.(message) ?? message)\n );\n\n if (!stateless) {\n setData((prev) => {\n if (isEqual(prev, selectedMessage)) {\n return prev;\n }\n\n return selectedMessage;\n });\n }\n\n updateStatus(\"subscribed\", message);\n internalCallbacksRef.current.onMessage?.(message);\n },\n [stateless, updateStatus]\n );\n\n const unsubscribe = useCallback(() => {\n updateStatus(\"idle\");\n unsubcribeRef.current?.();\n unsubcribeRef.current = undefined;\n }, [updateStatus]);\n\n const subscribe = useCallback(() => {\n unsubcribeRef.current?.();\n updateStatus(\"subscribing\");\n setData(initialStateRef.current);\n unsubcribeRef.current = subscriberFnRef.current(handler, connection);\n }, [connection, handler, updateStatus]);\n\n useEffect(() => {\n if (enabled) {\n subscribe();\n } else {\n unsubscribe();\n }\n\n return () => {\n unsubscribe();\n };\n }, [enabled, subscribe, unsubscribe]);\n\n return {\n status,\n data,\n reSubscribe: subscribe,\n } as unknown as any;\n}\n","import {\n SubscriptionCoreOptions,\n useSubscriptionCore,\n} from \"./useSubscriptionCore\";\n\nexport type SubscriptionOptions<\n TData,\n TMessage = unknown,\n Stateless extends true | undefined = undefined,\n TMetadata extends {} = {},\n> = Omit<\n SubscriptionCoreOptions<TData, TMessage, Stateless>,\n \"subscriberFn\"\n> & {\n service: string;\n topic: string;\n maxDownwardDepth?: number;\n} & {\n meta?: TMetadata;\n};\n\nexport type TSubscriptionHandlerFunction<\n TMessage,\n TMetadata extends {} = {},\n> = (\n opts: {\n service: string;\n name: string;\n callback: (message: TMessage) => void;\n maxDownwardDepth?: number;\n } & { meta?: TMetadata }\n) => () => void;\n\nexport function useSubscription<\n TData = unknown,\n TMessage = TData,\n Stateless extends true | undefined = undefined,\n TMetadata extends {} = {},\n>(\n subscriptionHandler: TSubscriptionHandlerFunction<TMessage, TMetadata>,\n options: SubscriptionOptions<TData, TMessage, Stateless, TMetadata>\n) {\n const { topic, service, maxDownwardDepth = 1000, meta, ...rest } = options;\n\n return useSubscriptionCore<TData, TMessage, Stateless>({\n ...rest,\n subscriberFn: (handler) => {\n const unsubscribe = subscriptionHandler({\n service,\n name: topic,\n callback: (message: TMessage) => {\n handler(message);\n },\n maxDownwardDepth,\n meta,\n });\n\n return unsubscribe;\n },\n });\n}\n\nexport function buildServiceSubscriptionHook<TMetadata extends {} = {}>(\n subscriptionHandler: TSubscriptionHandlerFunction<unknown, TMetadata>,\n targetMachine: (machine: string | undefined) => string\n) {\n return function useSubscriptionBuilder<\n TData,\n TMessage = TData,\n Stateless extends true | undefined = undefined,\n >(\n options: Omit<\n SubscriptionOptions<TData, TMessage, Stateless, TMetadata>,\n \"service\"\n > & {\n machine?: string;\n }\n ) {\n const targetService = targetMachine(options.machine);\n return useSubscription<TData, TMessage, Stateless>(\n <TSubscriptionHandlerFunction<TMessage>>subscriptionHandler,\n {\n service: targetService,\n ...options,\n }\n );\n };\n}\n","import type { ZMQProxyWSClient } from \"@pixotope/zmq-client\";\nimport type { TPromiseFunction } from \"./factories\";\nimport type { buildServiceSubscriptionHook } from \"./useSubscription\";\n\nexport type TProxySubscriptionHandlerParams<TMetadata extends {} = {}> =\n Parameters<Parameters<typeof buildServiceSubscriptionHook<TMetadata>>[0]>[0];\n\nexport function bindClientSocketProxy(socketClientProxy: ZMQProxyWSClient) {\n return (args: TProxySubscriptionHandlerParams) => {\n const { callback: cbHook, ...rest } = args;\n return socketClientProxy.mirror({\n ...rest,\n callback: (message) => {\n cbHook(message.message);\n },\n })[0];\n };\n}\n\nexport function bindPromiseFunction(clientSocketProxy: ZMQProxyWSClient) {\n return async (\n ...args: Parameters<TPromiseFunction<unknown, unknown, unknown>>\n ) => {\n const res = await clientSocketProxy.callAsync(...args);\n return res.message.Result;\n };\n}\n"],"mappings":"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","names":["import_react","params","error","options","import_react","data","_a","_b","error","import_react"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/factories.ts","../src/useMutation.ts","../src/useQuery.ts","../../utils/dist/chunk-5QIHMQPV.js","../src/useSubscriptionCore.ts","../src/useSubscription.ts","../src/proxyBinders.ts"],"sourcesContent":["export * from \"./factories\";\nexport * from \"./useSubscription\";\nexport * from \"./useQuery\";\nexport * from \"./useMutation\";\nexport * from \"./useSubscriptionCore\";\nexport * from \"./proxyBinders\";\n","import type { TSocketServerCallOptions, ZMQClient } from \"@pixotope/zmq-client\";\nimport { useCallback, useMemo } from \"react\";\nimport { MutationOptions, useMutation } from \"./useMutation\";\nimport { QueryOptions, useQuery } from \"./useQuery\";\n\n/**\n * Describes the data/error/params types for a single remote function, keyed by function name in\n * a `TFnToParams` map. Used with {@link buildMutationHook} and {@link buildQueryHook} to give the\n * hooks they build full type inference for `func`, its params and its result, based on the\n * function name passed in.\n *\n * @example\n * ```ts\n * type MyFunctions = {\n * createUser: MutationInfo<User, ApiError, { name: string }>;\n * };\n * ```\n */\nexport type MutationInfo<TData, TError, TParams> = {\n data: TData;\n error: TError;\n params: TParams;\n};\n\n/** The constraint a `TFnToParams` map must satisfy for {@link buildMutationHook}/{@link buildQueryHook}: a record of function name to its {@link MutationInfo}. */\nexport type FnToParamsBase = Record<string, MutationInfo<unknown, unknown, unknown>>;\n\n/**\n * The shape of a ZMQ remote-call function, as bound by {@link bindPromiseFunction}. Given a\n * service/function/parameters triple, it performs the call and resolves with the response.\n *\n * @typeParam TResponse - The type of data the call resolves with.\n * @typeParam TParams - The type of the `parameters` sent with the call.\n * @typeParam TExtraParams - The type of the optional `meta` passed alongside the call.\n * @param args - The service and function to call, its parameters, and call options/metadata.\n * @returns A promise that resolves with the call's result.\n */\nexport type TPromiseFunction<TResponse, TParams, TExtraParams> = (\n args: Omit<\n ZMQClient.Call<\n TResponse,\n {\n functionName: string;\n parameters: TParams;\n options?: Omit<TSocketServerCallOptions, \"toCallIfNoResponse\">;\n }\n >,\n \"id\"\n > & {\n meta?: TExtraParams;\n }\n) => Promise<TResponse>;\n\n/**\n * Internal helper backing the hook returned by {@link buildMutationHook}. Wraps a ZMQ\n * `promiseFunc` call for a single remote function name into a {@link useMutation} instance.\n */\nconst useCallMutationBase = <\n TFnToParams extends FnToParamsBase,\n TData = unknown,\n TError = unknown,\n TParams = unknown,\n TMetadata = unknown,\n>(\n promiseFunc: TPromiseFunction<TData, TParams, TMetadata>,\n functionName: keyof TFnToParams,\n service: (meta?: TMetadata) => string,\n options?: Omit<\n MutationOptions<TData, TError, TParams, TMetadata>,\n \"mutationFn\"\n >\n) => {\n const timeout = options?.timeout;\n const { ...rest } = useMemo(() => options ?? {}, [options]);\n const mutationFn = useCallback(\n async (parameters: TParams, meta?: TMetadata) => {\n try {\n return await promiseFunc({\n service: service(meta),\n functionName: functionName.toString(),\n parameters,\n options: {\n avoidTimeout: !timeout,\n customTimeout: timeout,\n },\n meta,\n });\n } catch (e) {\n if (e instanceof Error) {\n throw e;\n }\n throw new Error(e as string);\n }\n },\n [functionName, service, timeout]\n );\n\n return useMutation<TData, TError, TParams, TMetadata>({\n mutationFn,\n ...rest,\n });\n};\n\n/**\n * Builds a `useMutation`-like hook for calling remote ZMQ functions by name, with full type\n * inference of `data`/`error`/`params` from the `TFnToParams` map.\n *\n * This is the recommended way to expose a typed mutation hook for a service: call this once\n * with a bound {@link TPromiseFunction} (see {@link bindPromiseFunction}) and a function that\n * resolves the target service name, then export the resulting hook for consumers.\n *\n * @typeParam TFnToParams - A map from remote function name to its {@link MutationInfo}\n * (data/error/params types).\n * @typeParam TMetadata - The type of the optional metadata forwarded to `genTargetService` and `promiseFunc`.\n * @param promiseFunc - The transport function that performs the actual remote call.\n * @param genTargetService - Resolves the target service name for a call, given its metadata.\n * @returns A `useCallMutationBuilder` hook: call it with a function name (a key of\n * `TFnToParams`) and the same options as {@link useMutation} (minus `mutationFn`) to get a\n * mutation scoped to that remote function.\n * @example\n * ```ts\n * const useCreateUser = buildMutationHook<MyFunctions>(\n * bindPromiseFunction(proxyClient),\n * () => \"UserService\"\n * );\n * ```\n */\nexport function buildMutationHook<\n TFnToParams extends FnToParamsBase,\n TMetadata = unknown,\n>(\n promiseFunc: TPromiseFunction<unknown, unknown, unknown>,\n genTargetService: (meta?: TMetadata) => string\n) {\n return function useCallMutationBuilder<TFn extends keyof TFnToParams>(\n func: TFn,\n options?: Parameters<\n typeof useCallMutationBase<\n TFnToParams,\n TFnToParams[TFn][\"data\"],\n TFnToParams[TFn][\"error\"],\n TFnToParams[TFn][\"params\"],\n TMetadata\n >\n >[3]\n ) {\n return useCallMutationBase<\n TFnToParams,\n TFnToParams[TFn][\"data\"],\n TFnToParams[TFn][\"error\"],\n TFnToParams[TFn][\"params\"],\n TMetadata\n >(promiseFunc, func, genTargetService, options);\n };\n}\n\n/**\n * Internal helper backing the hook returned by {@link buildQueryHook}. Wraps a ZMQ\n * `promiseFunction` call for a single remote function name into a {@link useQuery} instance.\n */\nconst useCallQueryBase = <\n TFnToParams extends FnToParamsBase,\n TData = unknown,\n TError = unknown,\n TParams = unknown,\n TSelect = TData,\n TMetadata = unknown,\n TStateless extends true | undefined = undefined,\n>(\n promiseFunction: TPromiseFunction<TData, TParams, TMetadata>,\n functionName: keyof TFnToParams,\n params: TParams,\n service: (meta?: TMetadata) => string,\n options?: Omit<QueryOptions<TData, TError, TParams, TSelect, TStateless>, \"queryFn\"> & {\n meta?: TMetadata;\n }\n) => {\n const timeout = options?.timeout;\n const { ...rest } = useMemo(() => options ?? {}, [options]);\n const queryFn = useCallback(\n async (refetchParams: TParams | void) => {\n try {\n return await promiseFunction({\n service: service(options?.meta),\n functionName: functionName.toString(),\n parameters: refetchParams ?? params,\n options: {\n avoidTimeout: !timeout,\n customTimeout: timeout,\n },\n meta: options?.meta,\n });\n } catch (e) {\n if (e instanceof Error) {\n throw e;\n }\n throw new Error(e as string);\n }\n },\n [functionName, service, params, timeout]\n );\n\n return useQuery<TData, TError, TParams, TSelect, TStateless>({\n queryFn,\n ...rest,\n });\n};\n\n/**\n * Builds a `useQuery`-like hook for calling remote ZMQ functions by name, with full type\n * inference of `data`/`error`/`params` from the `TFnToParams` map.\n *\n * This is the recommended way to expose a typed query hook for a service: call this once with a\n * bound {@link TPromiseFunction} (see {@link bindPromiseFunction}) and a function that resolves\n * the target service name, then export the resulting hook for consumers.\n *\n * @typeParam TFnToParams - A map from remote function name to its {@link MutationInfo}\n * (data/error/params types).\n * @typeParam TMetadata - The type of the optional metadata forwarded to `getTargetService` and `promiseFunction`.\n * @param promiseFunction - The transport function that performs the actual remote call.\n * @param getTargetService - Resolves the target service name for a call, given its metadata.\n * @returns A `useCallQueryBuilder` hook: call it with a function name (a key of `TFnToParams`),\n * the params for that call, and the same options as {@link useQuery} (minus `queryFn`) to get a\n * query scoped to that remote function.\n * @example\n * ```ts\n * const useGetUser = buildQueryHook<MyFunctions>(\n * bindPromiseFunction(proxyClient),\n * () => \"UserService\"\n * );\n *\n * const { data } = useGetUser(\"getUser\", { id: userId });\n * ```\n */\nexport function buildQueryHook<\n TFnToParams extends FnToParamsBase,\n TMetadata = unknown,\n>(\n promiseFunction: TPromiseFunction<unknown, unknown, unknown>,\n getTargetService: (meta?: TMetadata) => string\n) {\n return function useCallQueryBuilder<\n TFn extends keyof TFnToParams,\n TSelect = TFnToParams[TFn][\"data\"],\n TStateless extends true | undefined = undefined,\n >(\n func: TFn,\n params: TFnToParams[TFn][\"params\"],\n options?: Parameters<\n typeof useCallQueryBase<\n TFnToParams,\n TFnToParams[TFn][\"data\"],\n TFnToParams[TFn][\"error\"],\n TFnToParams[TFn][\"params\"],\n TSelect,\n TMetadata,\n TStateless\n >\n >[4] & { meta?: TMetadata }\n ) {\n return useCallQueryBase<\n TFnToParams,\n TFnToParams[TFn][\"data\"],\n TFnToParams[TFn][\"error\"],\n TFnToParams[TFn][\"params\"],\n TSelect,\n TMetadata,\n TStateless\n >(promiseFunction, func, params, getTargetService, options);\n };\n}\n","import { useCallback, useRef, useState } from \"react\";\n\n/**\n * The async function a mutation invokes to perform its side effect.\n * @typeParam TData - The type of data the mutation resolves with.\n * @typeParam TParams - The type of the variables passed in to trigger the mutation.\n * @typeParam TMetadata - The type of the optional, per-call metadata.\n * @param params - The variables for this mutation call.\n * @param meta - Optional per-call metadata, passed through unchanged from `mutate`/`mutateAsync`.\n * @returns A promise that resolves with the mutation's result.\n */\nexport type MutationFunction<\n TData = unknown,\n TParams = unknown,\n TMetadata = unknown,\n> = (params: TParams, meta?: TMetadata) => Promise<TData>;\n\n/**\n * Configuration options for {@link useMutation}.\n *\n * @typeParam TData - The type of data `mutationFn` resolves with.\n * @typeParam TError - The error type reported to `onError`/`onSettled` and exposed via `error`.\n * @typeParam TParams - The type of the variables passed in to trigger the mutation.\n * @typeParam TMetadata - The type of the optional, per-call metadata.\n */\nexport interface MutationOptions<\n TData = unknown,\n TError = unknown,\n TParams = void,\n TMetadata = unknown,\n> {\n /** The async function invoked by `mutate`/`mutateAsync` to perform the mutation. */\n mutationFn: MutationFunction<TData, TParams, TMetadata>;\n /** Default variables passed to `prepareParams` (as its `defaults` argument) for every call. */\n params?: TParams;\n /** Called after `mutationFn` resolves successfully. */\n onSuccess?: (\n data: TData,\n variables: TParams,\n meta?: TMetadata\n ) => Promise<unknown> | unknown;\n /** Called after `mutationFn` rejects, or after `compareOrThrow` reports a failed comparison. */\n onError?: (\n error: TMutationError<TError>,\n variables: TParams,\n meta?: TMetadata\n ) => Promise<unknown> | unknown;\n /**\n * Called after every mutation attempt settles, whether it succeeded or failed. Exactly one of\n * `data`/`error` will be defined.\n */\n onSettled?: (\n data: TData | undefined,\n error: TMutationError<TError> | null,\n variables: TParams,\n meta?: TMetadata\n ) => Promise<unknown> | unknown;\n /**\n * Function that will be called with the result of `mutationFn` before it is stored. Returning\n * `true` causes the call to fail with a {@link ComparisonFailError} instead of succeeding.\n */\n compareOrThrow?: (result: TData | TError) => boolean;\n /**\n * Maximum time, in milliseconds, to wait for `mutationFn` to resolve before the call is\n * considered failed with a `timeout` error. When omitted, the call never times out.\n */\n timeout?: number;\n /**\n * Transforms the variables passed to `mutate`/`mutateAsync` before they reach `mutationFn`.\n * @param variables - The variables passed to this call.\n * @param defaults - The `params` configured on the hook, if any.\n * @param meta - The per-call metadata, if any.\n * @returns The variables to actually pass to `mutationFn`.\n */\n prepareParams?: (\n variables: TParams,\n defaults?: TParams,\n meta?: TMetadata\n ) => TParams;\n}\n\n/** The error type exposed via `error`/`onError`/`onSettled` on {@link MutationOptions}, {@link MutateOptions}, and {@link useMutation}'s return value. */\nexport type TMutationError<TError> = TError | Error | null;\n\n/**\n * Per-call callback overrides accepted as the second argument to `mutate` (see\n * {@link useMutation}'s return value). Called in addition to the callbacks configured via\n * {@link MutationOptions}.\n *\n * @typeParam TData - The type of data the mutation resolves with.\n * @typeParam TError - The error type reported to `onError`/`onSettled`.\n * @typeParam TParams - The type of the variables passed in to trigger the mutation.\n * @typeParam TMetadata - The type of the optional, per-call metadata.\n */\nexport interface MutateOptions<\n TData = unknown,\n TError = unknown,\n TParams = void,\n TMetadata = unknown,\n> {\n /** Called after `mutationFn` resolves successfully. */\n onSuccess?: (data: TData, variables: TParams, meta?: TMetadata) => void;\n /** Called after `mutationFn` rejects, or after `compareOrThrow` reports a failed comparison. */\n onError?: (\n error: TMutationError<TError>,\n variables: TParams,\n meta?: TMetadata\n ) => void;\n /**\n * Called after every mutation attempt settles, whether it succeeded or failed. Exactly one of\n * `data`/`error` will be defined.\n */\n onSettled?: (\n data: TData | undefined,\n error: TMutationError<TError> | null,\n variables: TParams,\n meta?: TMetadata\n ) => void;\n}\n\n/** The status of a {@link useMutation} call, as exposed via its return value's `status`. */\nexport type MutationStatus = \"idle\" | \"loading\" | \"success\" | \"error\";\ntype RaceErrorReason = \"timeout\";\ntype RacePromises<T> = Promise<T | RaceErrorReason>;\n\n/**\n * Error thrown (and stored as the mutation's `error`) when a mutation's `compareOrThrow` option\n * returns `true` for a successfully resolved result, i.e. the call is treated as a failure\n * despite `mutationFn` not rejecting.\n *\n * @typeParam TPayload - The type of the offending result, available via `payload`.\n */\nexport class ComparisonFailError<TPayload = unknown> extends Error {\n /** The result that `compareOrThrow` rejected. */\n public readonly payload: TPayload;\n\n /**\n * @param message - The error message.\n * @param payload - The result that `compareOrThrow` rejected, preserved on the error.\n */\n constructor(message: string, payload: TPayload) {\n super(message);\n this.name = this.constructor.name;\n this.payload = payload;\n\n if (Error.captureStackTrace) {\n Error.captureStackTrace(this, ComparisonFailError);\n }\n }\n}\n\n/**\n * React hook for triggering an async side effect (a \"mutation\") and tracking its status, result\n * and error, without fetching automatically the way {@link useQuery} does.\n *\n * @typeParam TData - The type of data `mutationFn` resolves with.\n * @typeParam TError - The error type surfaced via `error` and `onError`.\n * @typeParam TParams - The type of the variables passed in to trigger the mutation.\n * @typeParam TMetadata - The type of the optional, per-call metadata.\n * @param options - See {@link MutationOptions}.\n * @returns An object with:\n * - `status` - the current status: `\"idle\"`, `\"loading\"`, `\"success\"`, or `\"error\"`.\n * - `result` - the data from the most recently successful call, if any.\n * - `error` - the error from the most recently failed call, if any.\n * - `mutate` - fire-and-forget trigger; accepts per-call `variables` and, optionally,\n * {@link MutateOptions} plus `meta`.\n * - `mutateAsync` - same as `mutate`, but returns the promise from `mutationFn` (rejects on\n * failure) so callers can `await` it.\n * - `reset` - resets `status`, `result` and `error` back to their initial values.\n * @example\n * ```tsx\n * const { mutate, status } = useMutation({\n * mutationFn: (vars: { name: string }) => createUser(vars),\n * });\n *\n * mutate({ name: \"Ada\" }, { onSuccess: (user) => console.log(user.id) });\n * ```\n */\nexport const useMutation = <\n TData = unknown,\n TError = TMutationError<unknown>,\n TParams = void,\n TMetadata = unknown,\n>(\n options: MutationOptions<TData, TError, TParams, TMetadata>\n) => {\n const {\n mutationFn,\n compareOrThrow,\n onError,\n onSettled,\n onSuccess,\n prepareParams,\n params,\n timeout,\n } = options;\n const [status, setStatus] = useState<MutationStatus>(\"idle\");\n const [error, setError] = useState<TMutationError<TError>>(null);\n const [result, setResult] = useState<TData | undefined>(undefined);\n const mutationFnRef = useRef(mutationFn);\n const internalOptionsRef = useRef({\n params,\n timeout,\n });\n const internalCallbackRefistry = <const>{\n onSuccess,\n onError,\n onSettled,\n compareOrThrow,\n prepareParams,\n };\n const internalCallbackRef = useRef(internalCallbackRefistry);\n internalCallbackRef.current = internalCallbackRefistry;\n\n const mutateAsync = useCallback(async (params: TParams, meta?: TMetadata) => {\n setStatus(\"loading\");\n setError(null);\n\n try {\n const promises: RacePromises<TData>[] = [\n mutationFnRef.current(\n internalCallbackRef.current.prepareParams\n ? internalCallbackRef.current.prepareParams(\n params,\n internalOptionsRef.current.params,\n meta\n )\n : params,\n meta\n ),\n ...(internalOptionsRef.current.timeout\n ? [\n new Promise<RaceErrorReason>((resolve) =>\n setTimeout(\n () => resolve(\"timeout\"),\n internalOptionsRef.current.timeout\n )\n ),\n ]\n : []),\n ];\n\n const res = await Promise.race(promises);\n\n if (res === \"timeout\") {\n throw new Error(\"timeout\");\n }\n\n if (internalCallbackRef.current.compareOrThrow?.(res)) {\n throw new ComparisonFailError(JSON.stringify(res), res);\n }\n\n setResult(res);\n setStatus(\"success\");\n\n internalCallbackRef.current.onSuccess?.(res, params, meta);\n internalCallbackRef.current.onSettled?.(res, null, params, meta);\n\n return res;\n } catch (error: any) {\n setError(error);\n setStatus(\"error\");\n\n internalCallbackRef.current.onError?.(error, params, meta);\n internalCallbackRef.current.onSettled?.(undefined, error, params, meta);\n\n throw error;\n }\n }, []);\n\n const mutate = useCallback(\n (\n variables: TParams,\n options?: MutateOptions<TData, TError, TParams, TMetadata> & {\n meta?: TMetadata;\n }\n ) => {\n mutateAsync(variables, options?.meta).then(\n (data) => {\n options?.onSuccess?.(data, variables, options?.meta);\n options?.onSettled?.(data, null, variables, options?.meta);\n },\n (error) => {\n options?.onError?.(error, variables, options?.meta);\n options?.onSettled?.(undefined, error, variables, options?.meta);\n }\n );\n },\n [mutateAsync]\n );\n\n return {\n mutateAsync,\n status,\n result,\n mutate,\n reset: () => {\n setStatus(\"idle\");\n setError(null);\n setResult(undefined);\n },\n error,\n };\n};\n","import { useCallback, useEffect, useRef, useState } from \"react\";\n\n/**\n * Configuration options for {@link useQuery}.\n *\n * @typeParam TData - The raw data type returned by `queryFn`.\n * @typeParam TError - The error type reported to `onError`/`onSettled` and exposed via `error`.\n * @typeParam TParams - The type of the parameters passed to `refetch`/`queryFn`.\n * @typeParam TSelectData - The type of the data after `select` has been applied. Defaults to `TData`.\n * @typeParam Stateless - When `true`, the hook does not keep fetched data in state (see {@link QueryOptions.stateless}).\n */\nexport interface QueryOptions<\n TData = unknown,\n TError = unknown,\n TParams = void,\n TSelectData = TData,\n Stateless extends true | undefined = undefined,\n> {\n /**\n * Function that fetches the data for this query. Called automatically on mount, whenever\n * `key` changes, and whenever `refetch` is invoked.\n * @param params - The params passed to `refetch`, or `undefined`/`void` for an automatic fetch.\n * @param queryInfo - Contextual info about the current query: `key` is the normalized query\n * key currently in use, and `lastFetchedAt` is the timestamp (ms) of the last successful fetch,\n * or `undefined` if the query has never succeeded.\n * @returns A promise that resolves with the fetched data.\n */\n queryFn: (params: TParams | undefined | void, queryInfo: {key: TQueryKey | undefined, lastFetchedAt: number | undefined}) => Promise<TData>;\n /** Called after `queryFn` resolves successfully, with the raw (pre-`select`) data. */\n onSuccess?: (data: TData) => Promise<void> | void;\n /** Called after `queryFn` rejects, or after `compareOrThrow` reports a failed comparison. */\n onError?: (error: TQueryError<TError>) => Promise<void> | void;\n /**\n * Called after every fetch attempt settles, whether it succeeded or failed. Exactly one of\n * `data`/`error` will be defined.\n */\n onSettled?: (\n data: TData | undefined,\n error: TQueryError<TError> | undefined\n ) => Promise<void> | void;\n /**\n * Maximum time, in milliseconds, to wait for `queryFn` to resolve before the query is\n * considered failed with a `timeout` error. When omitted, the query never times out.\n */\n timeout?: number;\n /**\n * Whether the query is allowed to fetch. When `false`, `queryFn` is not called on mount,\n * on `key` changes, or on an interval/focus refetch.\n * @default true\n */\n enabled?: boolean;\n /**\n * Data (or a function returning data) to seed `data` with before the first fetch resolves.\n */\n initialData?: TData | Functionize<TData>;\n /**\n * Transforms the raw fetched data into the shape consumers should receive via `data`. Applied\n * on every render, not just on fetch, so it should be cheap and side-effect free.\n */\n select?: (data: TData) => TSelectData;\n /**\n * Whether to automatically refetch when the browser window regains focus.\n * @default false\n */\n refetchOnWindowFocus?: boolean;\n /**\n * When greater than `0`, automatically refetches on this interval (in milliseconds), as long\n * as at least this much time has passed since the last successful fetch.\n * @default 0\n */\n refetchInterval?: number;\n /**\n * Function that will be called with the freshly fetched data before it is stored. Returning\n * `true` causes the fetch to be treated as a failure (status becomes `\"error\"`, `onError`/\n * `onSettled` are called) instead of a success.\n */\n compareOrThrow?: (data: TData) => boolean;\n /**\n * Whether the query is stateless. When `true`, fetched data is not stored by the hook and the\n * returned object will not include a `data` field.\n * @default false\n */\n stateless?: Stateless;\n /**\n * The query key. Whenever this array's serialized value changes, the query automatically\n * refetches. Pass a stable/memoized array to avoid unintended refetches.\n */\n key?: TQueryKey;\n}\n\n/** A value, or a function returning it. Used to type {@link QueryOptions.initialData}. */\nexport type Functionize<T> = () => T;\n/** The status of a {@link useQuery} call, as exposed via {@link UseQueryResult}'s `status`. */\nexport type QueryStatus = \"idle\" | \"loading\" | \"success\" | \"error\" | \"timeout\";\ntype RaceErrorReason = \"timeout\";\ntype RacePromises<T> = Promise<T | RaceErrorReason>;\n/** Adds the `data` field to {@link UseQueryResult} when the query is not {@link QueryOptions.stateless}. */\nexport type WithQueryData<TData> = { data: TData | undefined };\n/** The type of {@link QueryOptions.key}: an array whose serialized value determines when the query refetches. */\nexport type TQueryKey = readonly any[];\n\n/** The error type exposed via {@link UseQueryResult}'s `error` and passed to `onError`/`onSettled`. */\nexport type TQueryError<TError> = TError | Error | null;\n\n/**\n * The value returned by {@link useQuery}.\n *\n * @typeParam TData - The (post-`select`) data type exposed via `data`.\n * @typeParam TError - The error type exposed via `error`.\n * @typeParam TParams - The type of the parameters accepted by `refetch`.\n * @typeParam TSelectData - The type of the data after `select` has been applied.\n * @typeParam Stateless - When `true`, the `data` field is omitted from the result.\n */\nexport type UseQueryResult<\n TData = unknown,\n TError = unknown,\n TParams = void,\n TSelectData = TData,\n Stateless extends true | undefined = undefined,\n> = {\n /** The error from the most recent failed fetch, or `null` if the last fetch succeeded (or none has happened yet). */\n error: TQueryError<TError>;\n /** The current status of the query: `\"idle\"`, `\"loading\"`, `\"success\"`, `\"error\"`, or `\"timeout\"`. */\n status: QueryStatus;\n /**\n * Manually triggers a fetch, bypassing `enabled`'s effect on automatic fetches (it still\n * respects the current `enabled` value at call time).\n * @param params - Params to pass to `queryFn` for this fetch.\n * @returns A promise that resolves once the fetch has settled.\n */\n refetch: (params: TParams | void | undefined) => Promise<void>;\n /** Clears `data`, `error` and `status` back to their initial values, then triggers a refetch. */\n reset: () => void;\n // eslint-disable-next-line @typescript-eslint/no-empty-object-type\n} & (Stateless extends true ? {} : WithQueryData<TSelectData>);\n\nfunction normalizeQueryKey(queryKey: TQueryKey): string {\n return JSON.stringify(queryKey);\n}\n\ntype TInternalCallbackRef<TData, TError, TSelectData> = {\n onError?: (error: TQueryError<TError>) => Promise<void> | void;\n onSuccess?: (data: TData) => Promise<void> | void;\n onSettled?: (\n data: TData | undefined,\n error: TQueryError<TError> | undefined\n ) => Promise<void> | void;\n compareOrThrow?: (data: TData) => boolean;\n select?: (data: TData) => TSelectData;\n};\n\ntype TInternalOptionsRef<TData> = {\n timeout?: number;\n enabled: boolean;\n refetchOnWindowFocus: boolean;\n refetchInterval: number;\n compareOrThrow?: (data: TData) => boolean;\n stateless?: boolean;\n};\n\nconst getRandomUUID = () => Math.random().toString(36).substring(2, 15);\n\n/**\n * React hook for fetching, caching (per-render, in component state) and refetching async data.\n *\n * `queryFn` runs automatically on mount, whenever `key` changes, and whenever `refetch` is\n * called. It races against `timeout` (when provided), and its result is exposed via `data`\n * (after `select`, if provided), `status`, and `error`.\n *\n * @typeParam TData - The raw data type returned by `queryFn`.\n * @typeParam TError - The error type surfaced via `error` and `onError`.\n * @typeParam TParams - The type of the parameters accepted by `refetch`.\n * @typeParam TSelected - The type of the data after `select` has been applied. Defaults to `TData`.\n * @typeParam Stateless - When `true`, the hook does not keep fetched data in state.\n * @param options - See {@link QueryOptions}.\n * @returns See {@link UseQueryResult}.\n * @example\n * ```tsx\n * const { data, status, error, refetch } = useQuery({\n * key: [\"user\", userId],\n * queryFn: () => fetchUser(userId),\n * });\n * ```\n */\nexport const useQuery = <\n TData = unknown,\n TError = TQueryError<unknown>,\n TParams = void,\n TSelected = TData,\n Stateless extends true | undefined = undefined,\n>({\n queryFn,\n ...options\n}: QueryOptions<TData, TError, TParams, TSelected, Stateless>): UseQueryResult<\n TSelected,\n TError,\n TParams,\n TSelected,\n Stateless\n> => {\n const {\n enabled = true,\n refetchOnWindowFocus = false,\n refetchInterval = 0,\n initialData,\n select,\n onError,\n onSuccess,\n onSettled,\n timeout,\n compareOrThrow,\n stateless,\n key: queryKeyPassed,\n } = options;\n const queryKey = normalizeQueryKey(queryKeyPassed ?? []);\n const lastFetchedAt = useRef<number | null>(null);\n const lastQueryKey = useRef<string | undefined>(undefined);\n const queryFnRef = useRef(queryFn);\n queryFnRef.current = queryFn;\n const internalCallbackRef = useRef<\n TInternalCallbackRef<TData, TError, TSelected>\n >({});\n internalCallbackRef.current = {\n onError,\n onSuccess,\n onSettled,\n compareOrThrow,\n select,\n };\n const internalOptionsRef = useRef<TInternalOptionsRef<TData>>({\n enabled,\n refetchOnWindowFocus,\n refetchInterval,\n compareOrThrow,\n stateless,\n timeout,\n });\n internalOptionsRef.current = {\n enabled,\n refetchOnWindowFocus,\n refetchInterval,\n compareOrThrow,\n stateless,\n timeout,\n };\n const requestIdRef = useRef(getRandomUUID());\n\n const [status, setStatus] = useState<QueryStatus>(() => {\n return \"idle\";\n });\n const [error, setError] = useState<TQueryError<TError>>(null);\n const [data, setData] = useState<TData | undefined>(() => {\n if (initialData !== undefined) {\n if (typeof initialData === \"function\") {\n return (initialData as Functionize<TData>)();\n }\n\n return initialData as TData;\n }\n\n return undefined;\n });\n\n const handleSetData = useCallback((data: TData) => {\n if (internalOptionsRef.current.stateless) {\n return;\n }\n\n setData(data);\n }, []);\n\n const shouldRefetch = useCallback(() => {\n if (!internalOptionsRef.current.enabled) {\n return false;\n }\n\n if (lastFetchedAt.current === null) {\n return true;\n }\n\n return (\n new Date().getTime() - lastFetchedAt.current >\n internalOptionsRef.current?.refetchInterval\n );\n }, []);\n\n const refetch = useCallback(\n async (params: TParams | void | undefined = undefined) => {\n const requestId = getRandomUUID();\n requestIdRef.current = requestId;\n if (!internalOptionsRef.current.enabled) {\n return;\n }\n\n setStatus(\"loading\");\n setError(null);\n\n try {\n const promises: RacePromises<TData>[] = [\n queryFnRef.current(params, { key: queryKeyPassed, lastFetchedAt: lastFetchedAt.current ?? undefined }),\n ...(internalOptionsRef.current.timeout\n ? [\n new Promise<RaceErrorReason>((resolve) =>\n setTimeout(\n () => resolve(\"timeout\"),\n internalOptionsRef.current.timeout\n )\n ),\n ]\n : []),\n ];\n\n const res = await Promise.race(promises);\n if (requestIdRef.current !== requestId) {\n return;\n }\n\n if (res === \"timeout\") {\n throw new Error(\"timeout\");\n }\n\n handleSetData(res);\n\n if (\n internalCallbackRef.current.compareOrThrow &&\n internalCallbackRef.current.compareOrThrow(res) === true\n ) {\n throw new Error(\"failedComparison\");\n }\n\n setStatus(\"success\");\n lastFetchedAt.current = new Date().getTime();\n internalCallbackRef.current.onSuccess?.(res);\n internalCallbackRef.current.onSettled?.(res, undefined);\n } catch (error: any) {\n setError(error);\n setStatus(\"error\");\n internalCallbackRef.current.onError?.(error);\n internalCallbackRef.current.onSettled?.(undefined, error);\n }\n },\n [handleSetData]\n );\n\n const reset = useCallback(() => {\n setData(undefined);\n setStatus(\"idle\");\n setError(null);\n refetch();\n }, [refetch]);\n\n useEffect(() => {\n const cleanups: (() => void)[] = [];\n\n // If the query should be refetched on window focus, add a listener\n if (refetchOnWindowFocus) {\n const queryHandleFocus = () => {\n refetch();\n };\n\n window.addEventListener(\"focus\", queryHandleFocus);\n\n cleanups.push(() => {\n window.removeEventListener(\"focus\", queryHandleFocus);\n });\n }\n\n // If the query should be refetched on an interval, add an interval\n if (refetchInterval > 0) {\n const interval = setInterval(() => {\n if (shouldRefetch()) {\n refetch();\n }\n }, refetchInterval);\n\n cleanups.push(() => {\n clearInterval(interval);\n });\n }\n\n // If the query key has changed, refetch\n if (\n lastQueryKey.current === undefined ||\n queryKey !== lastQueryKey.current\n ) {\n lastQueryKey.current = queryKey;\n refetch();\n }\n\n return () => {\n cleanups.forEach((cleanup) => cleanup());\n };\n }, [\n queryKey,\n enabled,\n refetchOnWindowFocus,\n refetchInterval,\n shouldRefetch,\n refetch,\n ]);\n\n return {\n data:\n select && data !== undefined\n ? select(data as TData)\n : (data as unknown as TSelected),\n error,\n status,\n refetch,\n reset,\n };\n};\n","// src/comparison/shallowEqual.ts\nfunction shallowEqual(objA, objB) {\n if (Object.is(objA, objB)) {\n return true;\n }\n if (typeof objA !== \"object\" || objA === null || typeof objB !== \"object\" || objB === null) {\n return false;\n }\n if (objA instanceof Map && objB instanceof Map) {\n if (objA.size !== objB.size) return false;\n for (const [key, value] of objA) {\n if (!Object.is(value, objB.get(key))) {\n return false;\n }\n }\n return true;\n }\n if (objA instanceof Set && objB instanceof Set) {\n if (objA.size !== objB.size) return false;\n for (const value of objA) {\n if (!objB.has(value)) {\n return false;\n }\n }\n return true;\n }\n const keysA = Object.keys(objA);\n if (keysA.length !== Object.keys(objB).length) {\n return false;\n }\n for (let i = 0; i < keysA.length; i++) {\n if (!Object.prototype.hasOwnProperty.call(objB, keysA[i]) || !Object.is(objA[keysA[i]], objB[keysA[i]])) {\n return false;\n }\n }\n return true;\n}\n\nexport {\n shallowEqual\n};\n","/**\n * Core subscription logic: subscribe and unsubscribe to a topic via any\n * callback-based transport. See {@link useSubscriptionCore}.\n */\n\nimport { shallowEqual } from \"@pixotope/utils/comparison\";\nimport { useCallback, useEffect, useMemo, useRef, useState } from \"react\";\n\n/** The status of a {@link useSubscriptionCore} subscription, as exposed via {@link WithStatus.status}. */\nexport type SubscriptionState = \"idle\" | \"subscribed\" | \"subscribing\" | \"error\";\n\n/** A function invoked with each message received on the subscription. */\nexport type MessageHandler<TMessage> = (message: TMessage) => void;\n\n/**\n * Handle passed to a {@link SubscriptionCoreOptions.subscriberFn} implementation so it can report\n * subscription lifecycle events back into the hook.\n */\nexport type Connection = {\n /** Marks the subscription as `\"subscribed\"`. Call this once the subscription is confirmed active. */\n acknowledge: () => void;\n};\n\n/**\n * Configuration options for {@link useSubscriptionCore}.\n *\n * @typeParam TData - The data type exposed via `data`, after `select` (if provided).\n * @typeParam TMessage - The raw message type passed to `subscriberFn`'s handler.\n * @typeParam Stateless - When `true`, the hook does not keep the latest message in state.\n */\nexport type SubscriptionCoreOptions<\n TData,\n TMessage = TData,\n Stateless extends true | undefined = undefined,\n> = {\n /** Function that will be called when the message is received. */\n onMessage?: (message: TMessage) => void;\n /** Function that will be called when the subscription is created. */\n onSubscribed?: (message: TMessage) => void;\n /** Function that will be called when the subscription errors. */\n onError?: (error: TMessage) => void;\n /**\n * Whether the subscription is enabled.\n * @default true\n */\n enabled?: boolean;\n /**\n * Function that will be called before the message is processed.\n * Returning `true` will cause the message to not be set to state and call {@link onError} if provided.\n * Status will be set to `error`.\n */\n compareOrThrow?: (data: TMessage) => boolean;\n /** Function that will be called to select the data from the message. */\n select?: (data: TMessage) => TData;\n /**\n * Initial state of the subscription.\n * @default undefined\n */\n initialState?: TData;\n /** Function that will be called when the subscription is created. */\n subscriberFn: (\n handler: MessageHandler<TMessage>,\n connection: Connection\n ) => () => void /** unsubscribe Fn */;\n /**\n * Whether the subscription is stateless. Data will not be\n * stored by the hook internally.\n * @default false\n */\n stateless?: Stateless;\n /**\n * Custom equality function for comparing data.\n * @default shallowEqual\n */\n isEqual?: <T = TData>(a: T, b: T) => boolean;\n};\n\n/** Adds the `status` field to {@link SubscriptionCoreReturnType}. */\nexport type WithStatus = {\n status: SubscriptionState;\n};\n\n/** Adds the `data` field to {@link SubscriptionCoreReturnType}. */\nexport type WithSubscriptionData<TData> = {\n data: TData;\n};\n\n/**\n * The value returned by {@link useSubscriptionCore}.\n *\n * @typeParam TData - The data type exposed via `data`.\n * @typeParam Stateless - When `true`, `status` and `data` are omitted from the result.\n */\nexport type SubscriptionCoreReturnType<\n TData,\n Stateless extends true | undefined,\n> = {\n /** Unsubscribes (if currently subscribed) and immediately subscribes again. */\n reSubscribe: () => void;\n // eslint-disable-next-line @typescript-eslint/no-empty-object-type\n} & (Stateless extends true ? {} : WithStatus & WithSubscriptionData<TData>);\n\n/**\n * `useSubscriptionCore` handles core subscription logic and provides a way to\n * subscribe and unsubscribe to a topic via any callback. The hook exposes a\n * handler function - all the consumer code needs to do is call this handler\n * function with the message received from the topic, or pass it directly to\n * the callback function that is passed to `subscriberFn`.\n * - `status` - current status of the subscription\n * - `data` - the data after the select function is applied to the message\n * - `reSubscribe` - function that can be called to re-subscribe to the topic\n *\n * See {@link useSubscription} for an example of how this hook is used.\n */\nexport function useSubscriptionCore<\n TData = unknown,\n TMessage = TData,\n Stateless extends true | undefined = undefined,\n>(\n options: SubscriptionCoreOptions<TData, TMessage, Stateless>\n): SubscriptionCoreReturnType<TData, Stateless> {\n const {\n enabled = true,\n initialState = undefined,\n onSubscribed,\n stateless,\n compareOrThrow,\n subscriberFn,\n onMessage,\n onError,\n select,\n isEqual = shallowEqual,\n } = options;\n const [status, setStatus] = useState<SubscriptionState>(\"idle\");\n const [data, setData] = useState<TData | undefined>(initialState);\n const unsubcribeRef = useRef<() => void | undefined>(undefined);\n const initialStateRef = useRef(initialState);\n const subscriberFnRef = useRef(subscriberFn);\n const callbackRefRegistry = <const>{\n onMessage,\n onError,\n select,\n compareOrThrow,\n onSubscribed,\n isEqual,\n };\n const internalCallbacksRef = useRef(callbackRefRegistry);\n internalCallbacksRef.current = callbackRefRegistry;\n\n const updateStatus = useCallback(\n (newStatus: SubscriptionState, message?: TMessage) => {\n if (stateless) {\n return;\n }\n\n setStatus((prev) => {\n if (prev === newStatus) {\n return prev;\n }\n\n if (newStatus === \"subscribed\" && message) {\n internalCallbacksRef.current.onSubscribed?.(message);\n }\n\n return newStatus;\n });\n },\n [stateless]\n );\n\n const connection: Connection = useMemo(\n () => ({\n acknowledge: () => {\n updateStatus(\"subscribed\");\n },\n }),\n [updateStatus]\n );\n\n const handler = useCallback(\n async (message: TMessage) => {\n if (internalCallbacksRef.current.compareOrThrow?.(message)) {\n updateStatus(\"error\");\n internalCallbacksRef.current.onError?.(message);\n\n return;\n }\n\n const selectedMessage = <TData>(\n (internalCallbacksRef.current.select?.(message) ?? message)\n );\n\n if (!stateless) {\n setData((prev) => {\n if (isEqual(prev, selectedMessage)) {\n return prev;\n }\n\n return selectedMessage;\n });\n }\n\n updateStatus(\"subscribed\", message);\n internalCallbacksRef.current.onMessage?.(message);\n },\n [stateless, updateStatus]\n );\n\n const unsubscribe = useCallback(() => {\n updateStatus(\"idle\");\n unsubcribeRef.current?.();\n unsubcribeRef.current = undefined;\n }, [updateStatus]);\n\n const subscribe = useCallback(() => {\n unsubcribeRef.current?.();\n updateStatus(\"subscribing\");\n setData(initialStateRef.current);\n unsubcribeRef.current = subscriberFnRef.current(handler, connection);\n }, [connection, handler, updateStatus]);\n\n useEffect(() => {\n if (enabled) {\n subscribe();\n } else {\n unsubscribe();\n }\n\n return () => {\n unsubscribe();\n };\n }, [enabled, subscribe, unsubscribe]);\n\n return {\n status,\n data,\n reSubscribe: subscribe,\n } as unknown as any;\n}\n","import {\n SubscriptionCoreOptions,\n useSubscriptionCore,\n} from \"./useSubscriptionCore\";\n\n/**\n * Configuration options for {@link useSubscription}. Extends {@link SubscriptionCoreOptions}\n * (minus `subscriberFn`, which `useSubscription` builds internally) with the service/topic pair\n * that identifies what to subscribe to.\n *\n * @typeParam TData - The data type exposed via `data`, after `select` (if provided).\n * @typeParam TMessage - The raw message type received from the topic.\n * @typeParam Stateless - When `true`, the hook does not keep the latest message in state.\n * @typeParam TMetadata - The type of the optional metadata forwarded to `subscriptionHandler`.\n */\nexport type SubscriptionOptions<\n TData,\n TMessage = unknown,\n Stateless extends true | undefined = undefined,\n TMetadata extends {} = {},\n> = Omit<\n SubscriptionCoreOptions<TData, TMessage, Stateless>,\n \"subscriberFn\"\n> & {\n /** The name of the service/machine that owns the topic being subscribed to. */\n service: string;\n /** The name of the topic to subscribe to. */\n topic: string;\n /** How many levels deep to mirror nested updates. Forwarded as-is to `subscriptionHandler`. */\n maxDownwardDepth?: number;\n} & {\n /** Optional metadata forwarded to `subscriptionHandler` alongside the subscription request. */\n meta?: TMetadata;\n};\n\n/**\n * The shape of a low-level subscription transport function, e.g. one bound to a ZMQ proxy client\n * via {@link bindClientSocketProxy}. Given subscription details, it starts the subscription and\n * returns an unsubscribe function.\n *\n * @typeParam TMessage - The raw message type delivered to `callback`.\n * @typeParam TMetadata - The type of the optional metadata passed through `opts.meta`.\n * @param opts - The service/topic to subscribe to, the callback to invoke per message, and any\n * transport-specific options.\n * @returns A function that unsubscribes from the topic.\n */\nexport type TSubscriptionHandlerFunction<\n TMessage,\n TMetadata extends {} = {},\n> = (\n opts: {\n service: string;\n name: string;\n callback: (message: TMessage) => void;\n maxDownwardDepth?: number;\n } & { meta?: TMetadata }\n) => () => void;\n\n/**\n * React hook that subscribes to a `service`/`topic` pair via a transport-specific\n * `subscriptionHandler` (see {@link TSubscriptionHandlerFunction}), managing subscribe/unsubscribe\n * across the component's lifecycle. Built on top of {@link useSubscriptionCore} — see that hook\n * for the mechanics of status tracking, `select`, `compareOrThrow`, etc.\n *\n * @typeParam TData - The data type exposed via `data`, after `select` (if provided).\n * @typeParam TMessage - The raw message type received from the topic.\n * @typeParam Stateless - When `true`, the hook does not keep the latest message in state.\n * @typeParam TMetadata - The type of the optional metadata forwarded to `subscriptionHandler`.\n * @param subscriptionHandler - The transport function that performs the actual subscribe/unsubscribe.\n * @param options - See {@link SubscriptionOptions}.\n * @returns See {@link SubscriptionCoreReturnType}: `status`, `data` and `reSubscribe`\n * (`data`/`status` are omitted when `Stateless` is `true`).\n * @example\n * ```tsx\n * const { data, status } = useSubscription(bindClientSocketProxy(proxyClient), {\n * service: \"MyService\",\n * topic: \"MyTopic\",\n * });\n * ```\n */\nexport function useSubscription<\n TData = unknown,\n TMessage = TData,\n Stateless extends true | undefined = undefined,\n TMetadata extends {} = {},\n>(\n subscriptionHandler: TSubscriptionHandlerFunction<TMessage, TMetadata>,\n options: SubscriptionOptions<TData, TMessage, Stateless, TMetadata>\n) {\n const { topic, service, maxDownwardDepth = 1000, meta, ...rest } = options;\n\n return useSubscriptionCore<TData, TMessage, Stateless>({\n ...rest,\n subscriberFn: (handler) => {\n const unsubscribe = subscriptionHandler({\n service,\n name: topic,\n callback: (message: TMessage) => {\n handler(message);\n },\n maxDownwardDepth,\n meta,\n });\n\n return unsubscribe;\n },\n });\n}\n\n/**\n * Builds a `useSubscription`-like hook that is pre-bound to a specific transport\n * (`subscriptionHandler`) and a way of resolving the target service/machine name, so calling code\n * only needs to supply the `topic` (and, optionally, override the `machine`).\n *\n * This is the building block behind per-domain subscription hooks: a package can call this once\n * with its own transport binder and machine-resolution logic, and export the resulting hook for\n * consumers to use without having to know about services/transports at all.\n *\n * @typeParam TMetadata - The type of the optional metadata forwarded to `subscriptionHandler`.\n * @param subscriptionHandler - The transport function that performs the actual subscribe/unsubscribe.\n * @param targetMachine - Resolves the service name to subscribe on, given an optional `machine`\n * override supplied by the caller of the built hook.\n * @returns A `useSubscriptionBuilder` hook with the same options as {@link useSubscription} minus\n * `service`, plus an optional `machine` override.\n */\nexport function buildServiceSubscriptionHook<TMetadata extends {} = {}>(\n subscriptionHandler: TSubscriptionHandlerFunction<unknown, TMetadata>,\n targetMachine: (machine: string | undefined) => string\n) {\n return function useSubscriptionBuilder<\n TData,\n TMessage = TData,\n Stateless extends true | undefined = undefined,\n >(\n options: Omit<\n SubscriptionOptions<TData, TMessage, Stateless, TMetadata>,\n \"service\"\n > & {\n machine?: string;\n }\n ) {\n const targetService = targetMachine(options.machine);\n return useSubscription<TData, TMessage, Stateless>(\n <TSubscriptionHandlerFunction<TMessage>>subscriptionHandler,\n {\n service: targetService,\n ...options,\n }\n );\n };\n}\n","import type { ZMQProxyWSClient } from \"@pixotope/zmq-client\";\nimport type { TPromiseFunction } from \"./factories\";\nimport type { buildServiceSubscriptionHook } from \"./useSubscription\";\n\n/**\n * The parameters a {@link TSubscriptionHandlerFunction} receives, as consumed by\n * {@link bindClientSocketProxy}.\n * @typeParam TMetadata - The type of the optional metadata carried on `opts.meta`.\n */\nexport type TProxySubscriptionHandlerParams<TMetadata extends {} = {}> =\n Parameters<Parameters<typeof buildServiceSubscriptionHook<TMetadata>>[0]>[0];\n\n/**\n * Adapts a {@link @pixotope/zmq-client!ZMQProxyWSClient}'s `mirror` method into a\n * {@link TSubscriptionHandlerFunction}, so it can be passed to {@link useSubscription} or\n * {@link buildServiceSubscriptionHook}.\n *\n * @param socketClientProxy - The ZMQ proxy WebSocket client to subscribe through.\n * @returns A subscription handler function that mirrors the requested service/topic and\n * unwraps each message's `.message` payload before invoking the caller's callback.\n * @example\n * ```ts\n * const useMySubscription = buildServiceSubscriptionHook(\n * bindClientSocketProxy(proxyClient),\n * (machine) => machine ?? \"DefaultMachine\"\n * );\n * ```\n */\nexport function bindClientSocketProxy(socketClientProxy: ZMQProxyWSClient) {\n return (args: TProxySubscriptionHandlerParams) => {\n const { callback: cbHook, ...rest } = args;\n return socketClientProxy.mirror({\n ...rest,\n callback: (message) => {\n cbHook(message.message);\n },\n })[0];\n };\n}\n\n/**\n * Adapts a {@link @pixotope/zmq-client!ZMQProxyWSClient}'s `callAsync` method into a {@link TPromiseFunction}, so it\n * can be passed to {@link buildMutationHook} or {@link buildQueryHook}.\n *\n * @param clientSocketProxy - The ZMQ proxy WebSocket client to call through.\n * @returns A promise function that performs the remote call and resolves with the unwrapped\n * `.message.Result` payload (rejecting if the call times out or fails).\n * @example\n * ```ts\n * const useCreateUser = buildMutationHook<MyFunctions>(\n * bindPromiseFunction(proxyClient),\n * () => \"UserService\"\n * );\n * ```\n */\nexport function bindPromiseFunction(clientSocketProxy: ZMQProxyWSClient) {\n return async (\n ...args: Parameters<TPromiseFunction<unknown, unknown, unknown>>\n ) => {\n const res = await clientSocketProxy.callAsync(...args);\n return res.message.Result;\n };\n}\n"],"mappings":"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","names":["import_react","params","error","options","import_react","data","_a","_b","error","import_react"]}
|