@pixotope/query 0.6.0 → 0.7.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/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../../utils/dist/comparison/index.js","../src/factories.ts","../src/useMutation.ts","../src/useQuery.ts","../src/useSubscriptionCore.ts","../src/useSubscription.ts","../src/proxyBinders.ts"],"sourcesContent":["\"use strict\";\nvar __defProp = Object.defineProperty;\nvar __getOwnPropDesc = Object.getOwnPropertyDescriptor;\nvar __getOwnPropNames = Object.getOwnPropertyNames;\nvar __hasOwnProp = Object.prototype.hasOwnProperty;\nvar __export = (target, all) => {\n for (var name in all)\n __defProp(target, name, { get: all[name], enumerable: true });\n};\nvar __copyProps = (to, from, except, desc) => {\n if (from && typeof from === \"object\" || typeof from === \"function\") {\n for (let key of __getOwnPropNames(from))\n if (!__hasOwnProp.call(to, key) && key !== except)\n __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });\n }\n return to;\n};\nvar __toCommonJS = (mod) => __copyProps(__defProp({}, \"__esModule\", { value: true }), mod);\n\n// src/comparison/index.ts\nvar comparison_exports = {};\n__export(comparison_exports, {\n shallowEqual: () => shallowEqual\n});\nmodule.exports = __toCommonJS(comparison_exports);\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// Annotate the CommonJS export names for ESM import in node:\n0 && (module.exports = {\n shallowEqual\n});\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> = (\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) => Promise<TResponse>;\n\nconst useCallMutationBase = <\n TFnToParams extends FnToParamsBase,\n TData = unknown,\n TError = unknown,\n TParams = unknown,\n>(\n promiseFunc: TPromiseFunction<TData, TParams>,\n functionName: keyof TFnToParams,\n service: string,\n options?: Omit<MutationOptions<TData, TError, TParams>, \"mutationFn\">\n) => {\n const timeout = options?.timeout;\n const { ...rest } = useMemo(() => options ?? {}, [options]);\n const mutationFn = useCallback(\n async (parameters: TParams) => {\n try {\n return await promiseFunc({\n service,\n functionName: functionName.toString(),\n parameters,\n options: {\n avoidTimeout: !timeout,\n customTimeout: timeout,\n },\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>({\n mutationFn,\n ...rest,\n });\n};\n\nexport function buildMutationHook<TFnToParams extends FnToParamsBase>(\n promiseFunc: TPromiseFunction<unknown, unknown>,\n genTargetService: (machine: string | undefined) => 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 >\n >[3] & { machine?: string }\n ) {\n const targetService = genTargetService(options?.machine);\n\n return useCallMutationBase<\n TFnToParams,\n TFnToParams[TFn][\"data\"],\n TFnToParams[TFn][\"error\"],\n TFnToParams[TFn][\"params\"]\n >(promiseFunc, func, targetService, options);\n };\n}\n\nconst useCallQueryBase = <\n TFnToParams extends FnToParamsBase,\n TData = unknown,\n TError = unknown,\n TParams = unknown,\n TSelect = TData,\n>(\n promiseFunction: TPromiseFunction<TData, TParams>,\n functionName: keyof TFnToParams,\n params: TParams,\n service: string,\n options?: Omit<QueryOptions<TData, TError, TParams, TSelect>, \"queryFn\">\n) => {\n const timeout = options?.timeout;\n const { ...rest } = useMemo(() => options ?? {}, [options]);\n const queryFn = useCallback(\n async (refetchParams: TParams | void, overrideTargetMachine?: string) => {\n try {\n return await promiseFunction({\n service: overrideTargetMachine ?? service,\n functionName: functionName.toString(),\n parameters: refetchParams ?? params,\n options: {\n avoidTimeout: !timeout,\n customTimeout: timeout,\n },\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>({\n queryFn,\n ...rest,\n });\n};\n\nexport function buildQueryHook<TFnToParams extends FnToParamsBase>(\n promiseFunction: TPromiseFunction<unknown, unknown>,\n getTargetService: (machine: string | undefined) => string\n) {\n return function useCallQueryBuilder<\n TFn extends keyof TFnToParams,\n TSelect = TFnToParams[TFn][\"data\"],\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 >\n >[4] & { machine?: string }\n ) {\n const targetService = getTargetService(options?.machine);\n\n return useCallQueryBase<\n TFnToParams,\n TFnToParams[TFn][\"data\"],\n TFnToParams[TFn][\"error\"],\n TFnToParams[TFn][\"params\"],\n TSelect\n >(promiseFunction, func, params, targetService, options);\n };\n}\n","import { useCallback, useRef, useState } from \"react\";\n\nexport type MutationFunction<TData = unknown, TParams = unknown> = (\n params: TParams,\n overrideTargetMachine?: string\n) => Promise<TData>;\n\nexport interface MutationOptions<\n TData = unknown,\n TError = unknown,\n TParams = void,\n> {\n mutationFn: MutationFunction<TData, TParams>;\n params?: TParams;\n onSuccess?: (data: TData, variables: TParams) => Promise<unknown> | unknown;\n onError?: (\n error: TMutationError<TError>,\n variables: TParams\n ) => Promise<unknown> | unknown;\n onSettled?: (\n data: TData | undefined,\n error: TMutationError<TError> | null,\n variables: TParams\n ) => Promise<unknown> | unknown;\n compareOrThrow?: (result: TData | TError) => boolean;\n timeout?: number;\n prepareParams?: (variables: TParams, defaults?: TParams) => TParams;\n}\n\ntype TMutationError<TError> = TError | Error | null;\n\nexport interface MutateOptions<\n TData = unknown,\n TError = unknown,\n TParams = void,\n> {\n onSuccess?: (data: TData, variables: TParams) => void;\n onError?: (error: TMutationError<TError>, variables: TParams) => void;\n onSettled?: (\n data: TData | undefined,\n error: TMutationError<TError> | null,\n variables: TParams\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\n/**\n * `useMutation` is a hook that allows you to perform a mutation/push updates to the services while\n * providing extensive API to tap into the status and results of the mutation.\n * @param mutationFn The mutation function to be called when the `mutate` function is called.\n * `useMutation` does not care about what the function does, all it needs it a function that returns\n * a promise.\n * @param options Options to configure the mutation.\n * @returns An object with the following properties:\n * - `mutateAsync`: A function that takes in the variables and returns a promise that resolves to the\n * result of the mutation. This function can be awaited to get the result of the mutation. Callbacks can\n * be passed to this function to be called when the mutation is successful or when it fails. It's good idea\n * to wrap this function in a try/catch block.\n * - `mutate`: A function that takes in the variables and returns nothing. This function does not\n * return a promise. Callbacks can be passed to this function to be called when the mutation is\n * successful or when it fails.\n * - `status`: The status of the mutation. Can be one of `idle`, `loading`, `success` or `error`.\n * - `result`: The result of the mutation. This is undefined until the mutation is successful.\n * - `reset`: A function that resets the mutation to the initial state.\n * - `error`: The error object if the mutation has failed.\n * @example\n * ```typescript\n * const mutationRes = useMutation({\n * mutationFn: (variables) => {\n * return ZMQHelper.callSomethingAsync(variables)\n * },\n * onSuccess: (data) => {\n * // do something with the result\n * },\n * onError: (error) => {\n * // do something with the error\n * },\n * onSettled: (data, error) => {\n * // do something when the mutation is done\n * }});\n *\n * // call the mutation\n * const res = await mutationRes.mutateAsync({ foo: \"bar\" });\n * // OR\n * mutationRes.mutate({ foo: \"bar\" }, {\n * onSuccess: (data) => {\n * // do something with the result\n * // for example show a toast message\n * // stop local loading state\n * });\n * ```\n */\nexport const useMutation = <\n TData = unknown,\n TError = TMutationError<unknown>,\n TParams = void,\n>(\n options: MutationOptions<TData, TError, TParams>\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(\n async (params: TParams, overrideTargetMachine?: string) => {\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 )\n : params,\n overrideTargetMachine\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);\n internalCallbackRef.current.onSettled?.(res, null, params);\n\n return res;\n } catch (error: any) {\n setError(error);\n setStatus(\"error\");\n\n internalCallbackRef.current.onError?.(error, params);\n internalCallbackRef.current.onSettled?.(undefined, error, params);\n\n throw error;\n }\n },\n []\n );\n\n const mutate = useCallback(\n (\n variables: TParams,\n options?: MutateOptions<TData, TError, TParams> & {\n overrideTargetMachine?: string;\n }\n ) => {\n mutateAsync(variables, options?.overrideTargetMachine).then(\n (data) => {\n options?.onSuccess?.(data, variables);\n options?.onSettled?.(data, null, variables);\n },\n (error) => {\n options?.onError?.(error, variables);\n options?.onSettled?.(undefined, error, variables);\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) => 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),\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 () => {\n if (shouldRefetch()) {\n refetch();\n }\n },\n Math.max(refetchInterval, 1000)\n );\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","/**\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\";\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 to compare the message with the\n * previous message. If the function returns true, the message will be ignored.\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 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> = Omit<\n SubscriptionCoreOptions<TData, TMessage, Stateless>,\n \"subscriberFn\"\n> & {\n service: string;\n topic: string;\n maxDownwardDepth?: number;\n};\n\nexport type TSubscriptionHandlerFunction<TMessage> = (opts: {\n service: string;\n name: string;\n callback: (message: TMessage) => void;\n maxDownwardDepth?: number;\n}) => () => void;\n\nexport function useSubscription<\n TData = unknown,\n TMessage = TData,\n Stateless extends true | undefined = undefined,\n>(\n subscriptionHandler: TSubscriptionHandlerFunction<TMessage>,\n options: SubscriptionOptions<TData, TMessage, Stateless>\n) {\n const { topic, service, maxDownwardDepth = 1000 } = options;\n\n return useSubscriptionCore<TData, TMessage, Stateless>({\n ...options,\n subscriberFn: (handler) => {\n const unsubscribe = subscriptionHandler({\n service,\n name: topic,\n callback: (message: TMessage) => {\n handler(message);\n },\n maxDownwardDepth,\n });\n\n return unsubscribe;\n },\n });\n}\n\nexport function buildServiceSubscriptionHook(\n subscriptionHandler: TSubscriptionHandlerFunction<unknown>,\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>,\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 function bindClientSocketProxy(socketClientProxy: ZMQProxyWSClient) {\n return (\n ...args: Parameters<Parameters<typeof buildServiceSubscriptionHook>[0]>\n ) => {\n const { callback: cbHook, ...rest } = args[0];\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 (...args: Parameters<TPromiseFunction<unknown, unknown>>) => {\n const res = await clientSocketProxy.callAsync(...args);\n return res.message.Result;\n };\n}\n"],"mappings":"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","names":["__defProp","__getOwnPropDesc","__getOwnPropNames","__hasOwnProp","__copyProps","shallowEqual","useCallback","params","error","options","useCallback","useRef","useState","useRef","useState","useCallback","data","_a","_b","error","useCallback","useCallback","useEffect","useMemo","useRef","useState","useState","useRef","useCallback","useMemo","useEffect"]}
1
+ {"version":3,"sources":["../../utils/dist/comparison/index.js","../src/factories.ts","../src/useMutation.ts","../src/useQuery.ts","../src/useSubscriptionCore.ts","../src/useSubscription.ts","../src/proxyBinders.ts"],"sourcesContent":["\"use strict\";\nvar __defProp = Object.defineProperty;\nvar __getOwnPropDesc = Object.getOwnPropertyDescriptor;\nvar __getOwnPropNames = Object.getOwnPropertyNames;\nvar __hasOwnProp = Object.prototype.hasOwnProperty;\nvar __export = (target, all) => {\n for (var name in all)\n __defProp(target, name, { get: all[name], enumerable: true });\n};\nvar __copyProps = (to, from, except, desc) => {\n if (from && typeof from === \"object\" || typeof from === \"function\") {\n for (let key of __getOwnPropNames(from))\n if (!__hasOwnProp.call(to, key) && key !== except)\n __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });\n }\n return to;\n};\nvar __toCommonJS = (mod) => __copyProps(__defProp({}, \"__esModule\", { value: true }), mod);\n\n// src/comparison/index.ts\nvar comparison_exports = {};\n__export(comparison_exports, {\n shallowEqual: () => shallowEqual\n});\nmodule.exports = __toCommonJS(comparison_exports);\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// Annotate the CommonJS export names for ESM import in node:\n0 && (module.exports = {\n shallowEqual\n});\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>(\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>, \"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>({\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 >(\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 >\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 >(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) => 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),\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","/**\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\";\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 to compare the message with the\n * previous message. If the function returns true, the message will be ignored.\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 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> = Omit<\n SubscriptionCoreOptions<TData, TMessage, Stateless>,\n \"subscriberFn\"\n> & {\n service: string;\n topic: string;\n maxDownwardDepth?: number;\n};\n\nexport type TSubscriptionHandlerFunction<TMessage> = (opts: {\n service: string;\n name: string;\n callback: (message: TMessage) => void;\n maxDownwardDepth?: number;\n}) => () => void;\n\nexport function useSubscription<\n TData = unknown,\n TMessage = TData,\n Stateless extends true | undefined = undefined,\n>(\n subscriptionHandler: TSubscriptionHandlerFunction<TMessage>,\n options: SubscriptionOptions<TData, TMessage, Stateless>\n) {\n const { topic, service, maxDownwardDepth = 1000 } = options;\n\n return useSubscriptionCore<TData, TMessage, Stateless>({\n ...options,\n subscriberFn: (handler) => {\n const unsubscribe = subscriptionHandler({\n service,\n name: topic,\n callback: (message: TMessage) => {\n handler(message);\n },\n maxDownwardDepth,\n });\n\n return unsubscribe;\n },\n });\n}\n\nexport function buildServiceSubscriptionHook(\n subscriptionHandler: TSubscriptionHandlerFunction<unknown>,\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>,\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 function bindClientSocketProxy(socketClientProxy: ZMQProxyWSClient) {\n return (\n ...args: Parameters<Parameters<typeof buildServiceSubscriptionHook>[0]>\n ) => {\n const { callback: cbHook, ...rest } = args[0];\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":["__defProp","__getOwnPropDesc","__getOwnPropNames","__hasOwnProp","__copyProps","shallowEqual","useCallback","params","error","options","useCallback","useRef","useState","useRef","useState","useCallback","data","_a","_b","error","useCallback","useCallback","useEffect","useMemo","useRef","useState","useState","useRef","useCallback","useMemo","useEffect"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pixotope/query",
3
- "version": "0.6.0",
3
+ "version": "0.7.0",
4
4
  "description": "",
5
5
  "private": false,
6
6
  "main": "dist/index.js",
@@ -20,8 +20,8 @@
20
20
  "tsup": "^8.5.0",
21
21
  "typescript": "^5.7.2",
22
22
  "vitest": "^3.2.4",
23
- "@pixotope/utils": "0.1.0",
24
- "@pixotope/zmq-client": "0.9.0"
23
+ "@pixotope/utils": "0.2.0",
24
+ "@pixotope/zmq-client": "0.9.1"
25
25
  },
26
26
  "peerDependencies": {
27
27
  "react": ">=17.0.0"
@@ -0,0 +1,65 @@
1
+ import { describe, expect, it, vi } from "vitest";
2
+ import { act, renderHook, waitFor } from "@testing-library/react";
3
+ import { buildMutationHook, buildQueryHook, MutationInfo } from "./factories";
4
+
5
+ describe("factories", () => {
6
+ it("should build mutation hook", () => {
7
+ const mutationHook = buildMutationHook(vi.fn(), vi.fn());
8
+ expect(mutationHook).toBeDefined();
9
+ });
10
+
11
+ it("should build query hook", () => {
12
+ const queryHook = buildQueryHook(vi.fn(), vi.fn());
13
+ expect(queryHook).toBeDefined();
14
+ });
15
+
16
+ it("mutation hook should call promise function", async () => {
17
+ const promiseFunction = vi.fn();
18
+ const getServiceName = vi.fn();
19
+ const useCustomMutationHook = buildMutationHook(
20
+ promiseFunction,
21
+ getServiceName
22
+ );
23
+ const { result } = renderHook(() => useCustomMutationHook("testFunction"));
24
+ act(() => result.current.mutate({}, { meta: { foo: "bar" } }));
25
+ await waitFor(() => expect(promiseFunction).toBeCalledTimes(1));
26
+ expect(promiseFunction).toBeCalledWith({
27
+ service: getServiceName(),
28
+ functionName: "testFunction",
29
+ parameters: {},
30
+ options: {
31
+ avoidTimeout: true,
32
+ customTimeout: undefined,
33
+ },
34
+ meta: { foo: "bar" },
35
+ });
36
+ expect(getServiceName).toBeCalledWith({ foo: "bar" });
37
+ });
38
+
39
+ it("query hook should call promise function", async () => {
40
+ const promiseFunction = vi.fn();
41
+ const getServiceName = vi.fn();
42
+ const useCustomQueryHook = buildQueryHook<{
43
+ testFunction: MutationInfo<unknown, unknown, { foo: string }>;
44
+ }>(promiseFunction, getServiceName);
45
+ renderHook(() =>
46
+ useCustomQueryHook(
47
+ "testFunction",
48
+ { foo: "bar" },
49
+ { meta: { machine: "machine" } }
50
+ )
51
+ );
52
+ await waitFor(() => expect(promiseFunction).toBeCalledTimes(1));
53
+ expect(getServiceName).toBeCalledWith({ machine: "machine" });
54
+ expect(promiseFunction).toBeCalledWith({
55
+ service: getServiceName({ machine: "machine" }),
56
+ functionName: "testFunction",
57
+ parameters: { foo: "bar" },
58
+ options: {
59
+ avoidTimeout: true,
60
+ customTimeout: undefined,
61
+ },
62
+ meta: { machine: "machine" },
63
+ });
64
+ });
65
+ });
package/src/factories.ts CHANGED
@@ -11,7 +11,7 @@ export type MutationInfo<TData, TError, TParams> = {
11
11
 
12
12
  type FnToParamsBase = Record<string, MutationInfo<unknown, unknown, unknown>>;
13
13
 
14
- export type TPromiseFunction<TResponse, TParams> = (
14
+ export type TPromiseFunction<TResponse, TParams, TExtraParams> = (
15
15
  args: Omit<
16
16
  ZMQClient.Call<
17
17
  TResponse,
@@ -22,7 +22,9 @@ export type TPromiseFunction<TResponse, TParams> = (
22
22
  }
23
23
  >,
24
24
  "id"
25
- >
25
+ > & {
26
+ meta?: TExtraParams;
27
+ }
26
28
  ) => Promise<TResponse>;
27
29
 
28
30
  const useCallMutationBase = <
@@ -30,25 +32,30 @@ const useCallMutationBase = <
30
32
  TData = unknown,
31
33
  TError = unknown,
32
34
  TParams = unknown,
35
+ TMetadata = unknown,
33
36
  >(
34
- promiseFunc: TPromiseFunction<TData, TParams>,
37
+ promiseFunc: TPromiseFunction<TData, TParams, TMetadata>,
35
38
  functionName: keyof TFnToParams,
36
- service: string,
37
- options?: Omit<MutationOptions<TData, TError, TParams>, "mutationFn">
39
+ service: (meta?: TMetadata) => string,
40
+ options?: Omit<
41
+ MutationOptions<TData, TError, TParams, TMetadata>,
42
+ "mutationFn"
43
+ >
38
44
  ) => {
39
45
  const timeout = options?.timeout;
40
46
  const { ...rest } = useMemo(() => options ?? {}, [options]);
41
47
  const mutationFn = useCallback(
42
- async (parameters: TParams) => {
48
+ async (parameters: TParams, meta?: TMetadata) => {
43
49
  try {
44
50
  return await promiseFunc({
45
- service,
51
+ service: service(meta),
46
52
  functionName: functionName.toString(),
47
53
  parameters,
48
54
  options: {
49
55
  avoidTimeout: !timeout,
50
56
  customTimeout: timeout,
51
57
  },
58
+ meta,
52
59
  });
53
60
  } catch (e) {
54
61
  if (e instanceof Error) {
@@ -60,15 +67,18 @@ const useCallMutationBase = <
60
67
  [functionName, service, timeout]
61
68
  );
62
69
 
63
- return useMutation<TData, TError, TParams>({
70
+ return useMutation<TData, TError, TParams, TMetadata>({
64
71
  mutationFn,
65
72
  ...rest,
66
73
  });
67
74
  };
68
75
 
69
- export function buildMutationHook<TFnToParams extends FnToParamsBase>(
70
- promiseFunc: TPromiseFunction<unknown, unknown>,
71
- genTargetService: (machine: string | undefined) => string
76
+ export function buildMutationHook<
77
+ TFnToParams extends FnToParamsBase,
78
+ TMetadata = unknown,
79
+ >(
80
+ promiseFunc: TPromiseFunction<unknown, unknown, unknown>,
81
+ genTargetService: (meta?: TMetadata) => string
72
82
  ) {
73
83
  return function useCallMutationBuilder<TFn extends keyof TFnToParams>(
74
84
  func: TFn,
@@ -77,18 +87,18 @@ export function buildMutationHook<TFnToParams extends FnToParamsBase>(
77
87
  TFnToParams,
78
88
  TFnToParams[TFn]["data"],
79
89
  TFnToParams[TFn]["error"],
80
- TFnToParams[TFn]["params"]
90
+ TFnToParams[TFn]["params"],
91
+ TMetadata
81
92
  >
82
- >[3] & { machine?: string }
93
+ >[3]
83
94
  ) {
84
- const targetService = genTargetService(options?.machine);
85
-
86
95
  return useCallMutationBase<
87
96
  TFnToParams,
88
97
  TFnToParams[TFn]["data"],
89
98
  TFnToParams[TFn]["error"],
90
- TFnToParams[TFn]["params"]
91
- >(promiseFunc, func, targetService, options);
99
+ TFnToParams[TFn]["params"],
100
+ TMetadata
101
+ >(promiseFunc, func, genTargetService, options);
92
102
  };
93
103
  }
94
104
 
@@ -98,26 +108,30 @@ const useCallQueryBase = <
98
108
  TError = unknown,
99
109
  TParams = unknown,
100
110
  TSelect = TData,
111
+ TMetadata = unknown,
101
112
  >(
102
- promiseFunction: TPromiseFunction<TData, TParams>,
113
+ promiseFunction: TPromiseFunction<TData, TParams, TMetadata>,
103
114
  functionName: keyof TFnToParams,
104
115
  params: TParams,
105
- service: string,
106
- options?: Omit<QueryOptions<TData, TError, TParams, TSelect>, "queryFn">
116
+ service: (meta?: TMetadata) => string,
117
+ options?: Omit<QueryOptions<TData, TError, TParams, TSelect>, "queryFn"> & {
118
+ meta?: TMetadata;
119
+ }
107
120
  ) => {
108
121
  const timeout = options?.timeout;
109
122
  const { ...rest } = useMemo(() => options ?? {}, [options]);
110
123
  const queryFn = useCallback(
111
- async (refetchParams: TParams | void, overrideTargetMachine?: string) => {
124
+ async (refetchParams: TParams | void) => {
112
125
  try {
113
126
  return await promiseFunction({
114
- service: overrideTargetMachine ?? service,
127
+ service: service(options?.meta),
115
128
  functionName: functionName.toString(),
116
129
  parameters: refetchParams ?? params,
117
130
  options: {
118
131
  avoidTimeout: !timeout,
119
132
  customTimeout: timeout,
120
133
  },
134
+ meta: options?.meta,
121
135
  });
122
136
  } catch (e) {
123
137
  if (e instanceof Error) {
@@ -135,9 +149,12 @@ const useCallQueryBase = <
135
149
  });
136
150
  };
137
151
 
138
- export function buildQueryHook<TFnToParams extends FnToParamsBase>(
139
- promiseFunction: TPromiseFunction<unknown, unknown>,
140
- getTargetService: (machine: string | undefined) => string
152
+ export function buildQueryHook<
153
+ TFnToParams extends FnToParamsBase,
154
+ TMetadata = unknown,
155
+ >(
156
+ promiseFunction: TPromiseFunction<unknown, unknown, unknown>,
157
+ getTargetService: (meta?: TMetadata) => string
141
158
  ) {
142
159
  return function useCallQueryBuilder<
143
160
  TFn extends keyof TFnToParams,
@@ -151,18 +168,18 @@ export function buildQueryHook<TFnToParams extends FnToParamsBase>(
151
168
  TFnToParams[TFn]["data"],
152
169
  TFnToParams[TFn]["error"],
153
170
  TFnToParams[TFn]["params"],
154
- TSelect
171
+ TSelect,
172
+ TMetadata
155
173
  >
156
- >[4] & { machine?: string }
174
+ >[4] & { meta?: TMetadata }
157
175
  ) {
158
- const targetService = getTargetService(options?.machine);
159
-
160
176
  return useCallQueryBase<
161
177
  TFnToParams,
162
178
  TFnToParams[TFn]["data"],
163
179
  TFnToParams[TFn]["error"],
164
180
  TFnToParams[TFn]["params"],
165
- TSelect
166
- >(promiseFunction, func, params, targetService, options);
181
+ TSelect,
182
+ TMetadata
183
+ >(promiseFunction, func, params, getTargetService, options);
167
184
  };
168
185
  }
@@ -17,7 +17,9 @@ export function bindClientSocketProxy(socketClientProxy: ZMQProxyWSClient) {
17
17
  }
18
18
 
19
19
  export function bindPromiseFunction(clientSocketProxy: ZMQProxyWSClient) {
20
- return async (...args: Parameters<TPromiseFunction<unknown, unknown>>) => {
20
+ return async (
21
+ ...args: Parameters<TPromiseFunction<unknown, unknown, unknown>>
22
+ ) => {
21
23
  const res = await clientSocketProxy.callAsync(...args);
22
24
  return res.message.Result;
23
25
  };
@@ -0,0 +1,106 @@
1
+ import { describe, expect, it, vi } from "vitest";
2
+ import { useMutation } from "./useMutation";
3
+ import { act, renderHook, waitFor } from "@testing-library/react";
4
+
5
+ describe("useMutation", () => {
6
+ it("should be in idle state on mount", () => {
7
+ const { result } = renderHook(() => useMutation({ mutationFn: vi.fn() }));
8
+ expect(result.current.status).toBe("idle");
9
+ });
10
+
11
+ it("should be in loading state after mutationFn is called", async () => {
12
+ const { result } = renderHook(() => useMutation({ mutationFn: vi.fn() }));
13
+ act(() => result.current.mutate({}));
14
+ await waitFor(() => expect(result.current.status).toBe("loading"));
15
+ });
16
+
17
+ it("should be in success state after mutationFn resolves", async () => {
18
+ const { result } = renderHook(() =>
19
+ useMutation({ mutationFn: vi.fn().mockResolvedValue("test") })
20
+ );
21
+ act(() => result.current.mutate({}));
22
+ await waitFor(() => expect(result.current.status).toBe("success"));
23
+ });
24
+
25
+ it("should be in error state after mutationFn rejects", async () => {
26
+ const { result } = renderHook(() =>
27
+ useMutation({ mutationFn: vi.fn().mockRejectedValue("test") })
28
+ );
29
+ act(() => result.current.mutate({}));
30
+ await waitFor(() => expect(result.current.status).toBe("error"));
31
+ });
32
+
33
+ it("should call onSuccess callback after mutationFn resolves", async () => {
34
+ const onSuccess = vi.fn();
35
+ const { result } = renderHook(() =>
36
+ useMutation({ mutationFn: vi.fn().mockResolvedValue("test"), onSuccess })
37
+ );
38
+ act(() => result.current.mutate({}, { onSuccess }));
39
+ await waitFor(() => expect(onSuccess).toBeCalledTimes(2));
40
+ expect(onSuccess).toBeCalledWith("test", {}, undefined);
41
+ });
42
+
43
+ it("should call onError callback after mutationFn rejects", async () => {
44
+ const onError = vi.fn();
45
+ const { result } = renderHook(() =>
46
+ useMutation({ mutationFn: vi.fn().mockRejectedValue("test"), onError })
47
+ );
48
+ act(() => result.current.mutate({}, { onError }));
49
+ await waitFor(() => expect(onError).toBeCalledTimes(2));
50
+ expect(onError).toBeCalledWith("test", {}, undefined);
51
+ });
52
+
53
+ it("should call onSettled callback after mutationFn resolves", async () => {
54
+ const onSettled = vi.fn();
55
+ const { result } = renderHook(() =>
56
+ useMutation({
57
+ mutationFn: vi.fn().mockResolvedValue("test"),
58
+ onSettled,
59
+ })
60
+ );
61
+ act(() => result.current.mutate({}, { onSettled }));
62
+ await waitFor(() => expect(onSettled).toBeCalledTimes(2));
63
+ expect(onSettled).toBeCalledWith("test", null, {}, undefined);
64
+ });
65
+
66
+ it("should call onSettled callback after mutationFn rejects", async () => {
67
+ const onSettled = vi.fn();
68
+ const { result } = renderHook(() =>
69
+ useMutation({ mutationFn: vi.fn().mockRejectedValue("test"), onSettled })
70
+ );
71
+ act(() => result.current.mutate({}, { onSettled }));
72
+ await waitFor(() => expect(onSettled).toBeCalledTimes(2));
73
+ expect(onSettled).toBeCalledWith(undefined, "test", {}, undefined);
74
+ });
75
+
76
+ it("should pass correct params mutationFn and callbacks to mutationFn", async () => {
77
+ const mutationFn = vi.fn();
78
+ const params = { foo: "bar" };
79
+ const { result } = renderHook(() => useMutation({ mutationFn }));
80
+ act(() => result.current.mutate(params));
81
+ await waitFor(() => expect(mutationFn).toBeCalledTimes(1));
82
+ expect(mutationFn).toBeCalledWith(params, undefined);
83
+ });
84
+
85
+ it("should pass meta to mutationFn", async () => {
86
+ const mutationFn = vi.fn();
87
+ const { result } = renderHook(() => useMutation({ mutationFn }));
88
+ act(() => result.current.mutate({}, { meta: { foo: "bar" } }));
89
+ await waitFor(() => expect(mutationFn).toBeCalledTimes(1));
90
+ expect(mutationFn).toBeCalledWith({}, { foo: "bar" });
91
+ });
92
+
93
+ it("should call prepareParams", async () => {
94
+ const prepareParams = vi.fn();
95
+ const { result } = renderHook(() =>
96
+ useMutation({
97
+ mutationFn: vi.fn(),
98
+ prepareParams,
99
+ params: { baz: "baz" },
100
+ })
101
+ );
102
+ act(() => result.current.mutate({}, { meta: { foo: "bar" } }));
103
+ await waitFor(() => expect(prepareParams).toBeCalledTimes(1));
104
+ expect(prepareParams).toBeCalledWith({}, { baz: "baz" }, { foo: "bar" });
105
+ });
106
+ });