@pixotope/query 0.7.0 → 0.9.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 +11 -9
- package/CHANGELOG.md +13 -0
- package/dist/index.cjs +52 -91
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +19 -15
- package/dist/index.d.ts +19 -15
- package/dist/index.js +52 -101
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
- package/src/proxyBinders.test.ts +42 -0
- package/src/proxyBinders.ts +5 -4
- package/src/useQuery.test.ts +13 -0
- package/src/useQuery.ts +2 -2
- package/src/useSubscription.test.ts +79 -0
- package/src/useSubscription.ts +23 -13
- package/src/useSubscriptionCore.ts +6 -3
package/src/useQuery.ts
CHANGED
|
@@ -7,7 +7,7 @@ export interface QueryOptions<
|
|
|
7
7
|
TSelectData = TData,
|
|
8
8
|
Stateless extends true | undefined = undefined,
|
|
9
9
|
> {
|
|
10
|
-
queryFn: (params: TParams | undefined | void) => Promise<TData>;
|
|
10
|
+
queryFn: (params: TParams | undefined | void, queryInfo: {key: TQueryKey | undefined, lastFetchedAt: number | undefined}) => Promise<TData>;
|
|
11
11
|
onSuccess?: (data: TData) => Promise<void> | void;
|
|
12
12
|
onError?: (error: TQueryError<TError>) => Promise<void> | void;
|
|
13
13
|
onSettled?: (
|
|
@@ -189,7 +189,7 @@ export const useQuery = <
|
|
|
189
189
|
|
|
190
190
|
try {
|
|
191
191
|
const promises: RacePromises<TData>[] = [
|
|
192
|
-
queryFnRef.current(params),
|
|
192
|
+
queryFnRef.current(params, { key: queryKeyPassed, lastFetchedAt: lastFetchedAt.current ?? undefined }),
|
|
193
193
|
...(internalOptionsRef.current.timeout
|
|
194
194
|
? [
|
|
195
195
|
new Promise<RaceErrorReason>((resolve) =>
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import { renderHook } from "@testing-library/react";
|
|
2
|
+
import { vi, describe, expect, it } from "vitest";
|
|
3
|
+
|
|
4
|
+
import {
|
|
5
|
+
buildServiceSubscriptionHook,
|
|
6
|
+
useSubscription,
|
|
7
|
+
} from "./useSubscription";
|
|
8
|
+
|
|
9
|
+
describe("useSubscription", () => {
|
|
10
|
+
it("should call subscription handler", () => {
|
|
11
|
+
const subscriptionHandler = vi.fn();
|
|
12
|
+
renderHook(() =>
|
|
13
|
+
useSubscription(subscriptionHandler, {
|
|
14
|
+
topic: "test",
|
|
15
|
+
service: "test",
|
|
16
|
+
})
|
|
17
|
+
);
|
|
18
|
+
expect(subscriptionHandler).toBeCalledTimes(1);
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
it("should correctly pass options to subscription handler", () => {
|
|
22
|
+
const subscriptionHandler = vi.fn();
|
|
23
|
+
renderHook(() =>
|
|
24
|
+
useSubscription(subscriptionHandler, {
|
|
25
|
+
topic: "test",
|
|
26
|
+
service: "test",
|
|
27
|
+
meta: { foo: "bar" },
|
|
28
|
+
maxDownwardDepth: 100,
|
|
29
|
+
})
|
|
30
|
+
);
|
|
31
|
+
expect(subscriptionHandler).toBeCalledTimes(1);
|
|
32
|
+
expect(subscriptionHandler).toHaveBeenCalledWith({
|
|
33
|
+
service: "test",
|
|
34
|
+
name: "test",
|
|
35
|
+
callback: expect.any(Function),
|
|
36
|
+
maxDownwardDepth: 100,
|
|
37
|
+
meta: { foo: "bar" },
|
|
38
|
+
});
|
|
39
|
+
});
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
describe("buildServiceSubscriptionHook", () => {
|
|
43
|
+
it("should correctly pass options to subscription handler", () => {
|
|
44
|
+
const subscriptionHandler = vi.fn();
|
|
45
|
+
const useHook = buildServiceSubscriptionHook(
|
|
46
|
+
subscriptionHandler,
|
|
47
|
+
() => "test"
|
|
48
|
+
);
|
|
49
|
+
renderHook(() => useHook({ topic: "test", meta: { foo: "bar" } }));
|
|
50
|
+
expect(subscriptionHandler).toHaveBeenCalledTimes(1);
|
|
51
|
+
expect(subscriptionHandler).toHaveBeenCalledWith(
|
|
52
|
+
expect.objectContaining({
|
|
53
|
+
service: "test",
|
|
54
|
+
name: "test",
|
|
55
|
+
meta: { foo: "bar" },
|
|
56
|
+
})
|
|
57
|
+
);
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
it("should correctly handle overridden machine", () => {
|
|
61
|
+
const subscriptionHandler = vi.fn();
|
|
62
|
+
const useHook = buildServiceSubscriptionHook(
|
|
63
|
+
subscriptionHandler,
|
|
64
|
+
(machine) => machine || "test"
|
|
65
|
+
);
|
|
66
|
+
renderHook(() =>
|
|
67
|
+
useHook({
|
|
68
|
+
topic: "test",
|
|
69
|
+
machine: "myCustomMachineName",
|
|
70
|
+
})
|
|
71
|
+
);
|
|
72
|
+
expect(subscriptionHandler).toHaveBeenCalledWith(
|
|
73
|
+
expect.objectContaining({
|
|
74
|
+
service: "myCustomMachineName",
|
|
75
|
+
name: "test",
|
|
76
|
+
})
|
|
77
|
+
);
|
|
78
|
+
});
|
|
79
|
+
});
|
package/src/useSubscription.ts
CHANGED
|
@@ -7,6 +7,7 @@ export type SubscriptionOptions<
|
|
|
7
7
|
TData,
|
|
8
8
|
TMessage = unknown,
|
|
9
9
|
Stateless extends true | undefined = undefined,
|
|
10
|
+
TMetadata extends {} = {},
|
|
10
11
|
> = Omit<
|
|
11
12
|
SubscriptionCoreOptions<TData, TMessage, Stateless>,
|
|
12
13
|
"subscriberFn"
|
|
@@ -14,27 +15,35 @@ export type SubscriptionOptions<
|
|
|
14
15
|
service: string;
|
|
15
16
|
topic: string;
|
|
16
17
|
maxDownwardDepth?: number;
|
|
18
|
+
} & {
|
|
19
|
+
meta?: TMetadata;
|
|
17
20
|
};
|
|
18
21
|
|
|
19
|
-
export type TSubscriptionHandlerFunction<
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
22
|
+
export type TSubscriptionHandlerFunction<
|
|
23
|
+
TMessage,
|
|
24
|
+
TMetadata extends {} = {},
|
|
25
|
+
> = (
|
|
26
|
+
opts: {
|
|
27
|
+
service: string;
|
|
28
|
+
name: string;
|
|
29
|
+
callback: (message: TMessage) => void;
|
|
30
|
+
maxDownwardDepth?: number;
|
|
31
|
+
} & { meta?: TMetadata }
|
|
32
|
+
) => () => void;
|
|
25
33
|
|
|
26
34
|
export function useSubscription<
|
|
27
35
|
TData = unknown,
|
|
28
36
|
TMessage = TData,
|
|
29
37
|
Stateless extends true | undefined = undefined,
|
|
38
|
+
TMetadata extends {} = {},
|
|
30
39
|
>(
|
|
31
|
-
subscriptionHandler: TSubscriptionHandlerFunction<TMessage>,
|
|
32
|
-
options: SubscriptionOptions<TData, TMessage, Stateless>
|
|
40
|
+
subscriptionHandler: TSubscriptionHandlerFunction<TMessage, TMetadata>,
|
|
41
|
+
options: SubscriptionOptions<TData, TMessage, Stateless, TMetadata>
|
|
33
42
|
) {
|
|
34
|
-
const { topic, service, maxDownwardDepth = 1000 } = options;
|
|
43
|
+
const { topic, service, maxDownwardDepth = 1000, meta, ...rest } = options;
|
|
35
44
|
|
|
36
45
|
return useSubscriptionCore<TData, TMessage, Stateless>({
|
|
37
|
-
...
|
|
46
|
+
...rest,
|
|
38
47
|
subscriberFn: (handler) => {
|
|
39
48
|
const unsubscribe = subscriptionHandler({
|
|
40
49
|
service,
|
|
@@ -43,6 +52,7 @@ export function useSubscription<
|
|
|
43
52
|
handler(message);
|
|
44
53
|
},
|
|
45
54
|
maxDownwardDepth,
|
|
55
|
+
meta,
|
|
46
56
|
});
|
|
47
57
|
|
|
48
58
|
return unsubscribe;
|
|
@@ -50,8 +60,8 @@ export function useSubscription<
|
|
|
50
60
|
});
|
|
51
61
|
}
|
|
52
62
|
|
|
53
|
-
export function buildServiceSubscriptionHook(
|
|
54
|
-
subscriptionHandler: TSubscriptionHandlerFunction<unknown>,
|
|
63
|
+
export function buildServiceSubscriptionHook<TMetadata extends {} = {}>(
|
|
64
|
+
subscriptionHandler: TSubscriptionHandlerFunction<unknown, TMetadata>,
|
|
55
65
|
targetMachine: (machine: string | undefined) => string
|
|
56
66
|
) {
|
|
57
67
|
return function useSubscriptionBuilder<
|
|
@@ -60,7 +70,7 @@ export function buildServiceSubscriptionHook(
|
|
|
60
70
|
Stateless extends true | undefined = undefined,
|
|
61
71
|
>(
|
|
62
72
|
options: Omit<
|
|
63
|
-
SubscriptionOptions<TData, TMessage, Stateless>,
|
|
73
|
+
SubscriptionOptions<TData, TMessage, Stateless, TMetadata>,
|
|
64
74
|
"service"
|
|
65
75
|
> & {
|
|
66
76
|
machine?: string;
|
|
@@ -8,7 +8,8 @@
|
|
|
8
8
|
import { shallowEqual } from "@pixotope/utils/comparison";
|
|
9
9
|
import { useCallback, useEffect, useMemo, useRef, useState } from "react";
|
|
10
10
|
|
|
11
|
-
type SubscriptionState = "idle" | "subscribed" | "subscribing";
|
|
11
|
+
type SubscriptionState = "idle" | "subscribed" | "subscribing" | "error";
|
|
12
|
+
|
|
12
13
|
export type MessageHandler<TMessage> = (message: TMessage) => void;
|
|
13
14
|
export type Connection = {
|
|
14
15
|
acknowledge: () => void;
|
|
@@ -36,8 +37,9 @@ export type SubscriptionCoreOptions<
|
|
|
36
37
|
*/
|
|
37
38
|
enabled?: boolean;
|
|
38
39
|
/**
|
|
39
|
-
* @description Function that will be called
|
|
40
|
-
*
|
|
40
|
+
* @description Function that will be called before the message is processed.
|
|
41
|
+
* Returning `true` will cause the message to not be set to state and call {@link onError} if provided.
|
|
42
|
+
* Status will be set to `error`.
|
|
41
43
|
*/
|
|
42
44
|
compareOrThrow?: (data: TMessage) => boolean;
|
|
43
45
|
/**
|
|
@@ -165,6 +167,7 @@ export function useSubscriptionCore<
|
|
|
165
167
|
const handler = useCallback(
|
|
166
168
|
async (message: TMessage) => {
|
|
167
169
|
if (internalCallbacksRef.current.compareOrThrow?.(message)) {
|
|
170
|
+
updateStatus("error");
|
|
168
171
|
internalCallbacksRef.current.onError?.(message);
|
|
169
172
|
|
|
170
173
|
return;
|