@ic-reactor/react 3.7.0 → 3.8.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/README.md +93 -9
- package/dist/auth/authentication-manager.d.ts +37 -5
- package/dist/auth/authentication-manager.d.ts.map +1 -1
- package/dist/auth/authentication-manager.js +111 -37
- package/dist/auth/authentication-manager.js.map +1 -1
- package/dist/auth/createIdentityAttributeHooks.d.ts +2 -2
- package/dist/auth/createIdentityAttributeHooks.d.ts.map +1 -1
- package/dist/auth/identity-attributes-manager.d.ts +12 -5
- package/dist/auth/identity-attributes-manager.d.ts.map +1 -1
- package/dist/auth/identity-attributes-manager.js +42 -28
- package/dist/auth/identity-attributes-manager.js.map +1 -1
- package/dist/auth/identity-attributes.d.ts +1 -1
- package/dist/auth/identity-attributes.d.ts.map +1 -1
- package/dist/auth/identity-attributes.js +1 -1
- package/dist/auth/identity-attributes.js.map +1 -1
- package/dist/auth/index.d.ts +7 -7
- package/dist/auth/index.d.ts.map +1 -1
- package/dist/auth/index.js +7 -7
- package/dist/auth/index.js.map +1 -1
- package/dist/auth/types.d.ts +123 -16
- package/dist/auth/types.d.ts.map +1 -1
- package/dist/createActorHooks.d.ts +4 -4
- package/dist/createActorHooks.d.ts.map +1 -1
- package/dist/createActorHooks.js +6 -6
- package/dist/createActorHooks.js.map +1 -1
- package/dist/createInfiniteQuery.d.ts +1 -1
- package/dist/createInfiniteQuery.d.ts.map +1 -1
- package/dist/createInfiniteQuery.js +1 -1
- package/dist/createInfiniteQuery.js.map +1 -1
- package/dist/createMutation.d.ts +1 -1
- package/dist/createMutation.d.ts.map +1 -1
- package/dist/createQuery.d.ts +1 -1
- package/dist/createQuery.d.ts.map +1 -1
- package/dist/createQuery.js +1 -1
- package/dist/createQuery.js.map +1 -1
- package/dist/createSuspenseInfiniteQuery.d.ts +1 -1
- package/dist/createSuspenseInfiniteQuery.d.ts.map +1 -1
- package/dist/createSuspenseInfiniteQuery.js +1 -1
- package/dist/createSuspenseInfiniteQuery.js.map +1 -1
- package/dist/createSuspenseQuery.d.ts +1 -1
- package/dist/createSuspenseQuery.d.ts.map +1 -1
- package/dist/createSuspenseQuery.js +1 -1
- package/dist/createSuspenseQuery.js.map +1 -1
- package/dist/defineReactor.d.ts +54 -4
- package/dist/defineReactor.d.ts.map +1 -1
- package/dist/defineReactor.js +77 -7
- package/dist/defineReactor.js.map +1 -1
- package/dist/hooks/createAuthHooks.d.ts +2 -2
- package/dist/hooks/createAuthHooks.d.ts.map +1 -1
- package/dist/hooks/createAuthHooks.js +7 -2
- package/dist/hooks/createAuthHooks.js.map +1 -1
- package/dist/hooks/useActorInfiniteQuery.js +1 -1
- package/dist/hooks/useActorInfiniteQuery.js.map +1 -1
- package/dist/hooks/useActorSuspenseInfiniteQuery.js +1 -1
- package/dist/hooks/useActorSuspenseInfiniteQuery.js.map +1 -1
- package/dist/index.d.ts +11 -11
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +11 -11
- package/dist/index.js.map +1 -1
- package/llms.txt +1 -1
- package/package.json +14 -9
- package/src/auth/authentication-manager.ts +121 -49
- package/src/auth/createIdentityAttributeHooks.ts +2 -2
- package/src/auth/identity-attributes-manager.ts +53 -44
- package/src/auth/identity-attributes.ts +2 -2
- package/src/auth/index.ts +7 -7
- package/src/auth/types.ts +134 -18
- package/src/createActorHooks.ts +9 -9
- package/src/createInfiniteQuery.ts +2 -2
- package/src/createMutation.ts +1 -1
- package/src/createQuery.ts +2 -2
- package/src/createSuspenseInfiniteQuery.ts +2 -2
- package/src/createSuspenseQuery.ts +2 -2
- package/src/defineReactor.ts +136 -14
- package/src/hooks/createAuthHooks.ts +8 -3
- package/src/hooks/useActorInfiniteQuery.ts +1 -1
- package/src/hooks/useActorSuspenseInfiniteQuery.ts +1 -1
- package/src/index.ts +11 -11
- package/src/defineReactor.test.ts +0 -70
- package/src/hooks/useActorInfiniteQuery.test.tsx +0 -457
- package/src/hooks/useActorMethod.test.tsx +0 -798
- package/src/hooks/useActorMutation.test.tsx +0 -220
- package/src/hooks/useActorQuery.test.tsx +0 -287
- package/src/hooks/useActorSuspenseInfiniteQuery.test.tsx +0 -472
- package/src/hooks/useActorSuspenseQuery.test.tsx +0 -254
- package/src/utils.test.ts +0 -14
|
@@ -1,254 +0,0 @@
|
|
|
1
|
-
import { describe, it, expect, vi, beforeEach } from "vitest"
|
|
2
|
-
import { renderHook, waitFor } from "@testing-library/react"
|
|
3
|
-
import React, { Suspense } from "react"
|
|
4
|
-
import { QueryClient, QueryClientProvider } from "@tanstack/react-query"
|
|
5
|
-
import { useActorSuspenseQuery } from "./useActorSuspenseQuery"
|
|
6
|
-
import { ActorMethod } from "@icp-sdk/core/agent"
|
|
7
|
-
import { Reactor } from "@ic-reactor/core"
|
|
8
|
-
|
|
9
|
-
// Define a test actor type
|
|
10
|
-
type TestActor = {
|
|
11
|
-
greet: ActorMethod<[], string>
|
|
12
|
-
greetWithName: ActorMethod<[string], string>
|
|
13
|
-
getCount: ActorMethod<[], bigint>
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
// Mock Reactor
|
|
17
|
-
const createMockReactor = (queryClient: QueryClient): Reactor<TestActor> =>
|
|
18
|
-
({
|
|
19
|
-
queryClient,
|
|
20
|
-
getQueryOptions: vi.fn().mockImplementation(({ functionName, args }) => ({
|
|
21
|
-
queryKey: ["test-canister", functionName, ...(args || [])],
|
|
22
|
-
queryFn: vi.fn().mockImplementation(async () => {
|
|
23
|
-
if (functionName === "greet") return "Hello, World!"
|
|
24
|
-
if (functionName === "greetWithName")
|
|
25
|
-
return `Hello, ${args?.[0] || "Guest"}!`
|
|
26
|
-
if (functionName === "getCount") return BigInt(42)
|
|
27
|
-
return null
|
|
28
|
-
}),
|
|
29
|
-
})),
|
|
30
|
-
}) as unknown as Reactor<TestActor>
|
|
31
|
-
|
|
32
|
-
describe("useActorSuspenseQuery", () => {
|
|
33
|
-
let queryClient: QueryClient
|
|
34
|
-
let mockReactor: Reactor<TestActor>
|
|
35
|
-
|
|
36
|
-
beforeEach(() => {
|
|
37
|
-
queryClient = new QueryClient({
|
|
38
|
-
defaultOptions: {
|
|
39
|
-
queries: {
|
|
40
|
-
retry: false,
|
|
41
|
-
},
|
|
42
|
-
},
|
|
43
|
-
})
|
|
44
|
-
mockReactor = createMockReactor(queryClient)
|
|
45
|
-
})
|
|
46
|
-
|
|
47
|
-
const wrapper = ({ children }: { children: React.ReactNode }) => (
|
|
48
|
-
<QueryClientProvider client={queryClient}>
|
|
49
|
-
<Suspense fallback={<div>Loading...</div>}>{children}</Suspense>
|
|
50
|
-
</QueryClientProvider>
|
|
51
|
-
)
|
|
52
|
-
|
|
53
|
-
describe("basic functionality", () => {
|
|
54
|
-
it("should fetch data with suspense", async () => {
|
|
55
|
-
const { result } = renderHook(
|
|
56
|
-
() =>
|
|
57
|
-
useActorSuspenseQuery<TestActor, "greet">({
|
|
58
|
-
reactor: mockReactor,
|
|
59
|
-
functionName: "greet",
|
|
60
|
-
}),
|
|
61
|
-
{ wrapper }
|
|
62
|
-
)
|
|
63
|
-
|
|
64
|
-
await waitFor(() => {
|
|
65
|
-
expect(result.current.isSuccess).toBe(true)
|
|
66
|
-
})
|
|
67
|
-
|
|
68
|
-
expect(result.current.data).toBe("Hello, World!")
|
|
69
|
-
})
|
|
70
|
-
|
|
71
|
-
it("should pass args to the query", async () => {
|
|
72
|
-
const { result } = renderHook(
|
|
73
|
-
() =>
|
|
74
|
-
useActorSuspenseQuery<TestActor, "greetWithName">({
|
|
75
|
-
reactor: mockReactor,
|
|
76
|
-
functionName: "greetWithName",
|
|
77
|
-
args: ["Alice"],
|
|
78
|
-
}),
|
|
79
|
-
{ wrapper }
|
|
80
|
-
)
|
|
81
|
-
|
|
82
|
-
await waitFor(() => {
|
|
83
|
-
expect(result.current.isSuccess).toBe(true)
|
|
84
|
-
})
|
|
85
|
-
|
|
86
|
-
expect(result.current.data).toBe("Hello, Alice!")
|
|
87
|
-
expect(mockReactor.getQueryOptions).toHaveBeenCalledWith({
|
|
88
|
-
callConfig: undefined,
|
|
89
|
-
functionName: "greetWithName",
|
|
90
|
-
args: ["Alice"],
|
|
91
|
-
})
|
|
92
|
-
})
|
|
93
|
-
|
|
94
|
-
it("should handle bigint return types", async () => {
|
|
95
|
-
const { result } = renderHook(
|
|
96
|
-
() =>
|
|
97
|
-
useActorSuspenseQuery<TestActor, "getCount">({
|
|
98
|
-
reactor: mockReactor,
|
|
99
|
-
functionName: "getCount",
|
|
100
|
-
}),
|
|
101
|
-
{ wrapper }
|
|
102
|
-
)
|
|
103
|
-
|
|
104
|
-
await waitFor(() => {
|
|
105
|
-
expect(result.current.isSuccess).toBe(true)
|
|
106
|
-
})
|
|
107
|
-
|
|
108
|
-
expect(result.current.data).toBe(BigInt(42))
|
|
109
|
-
})
|
|
110
|
-
})
|
|
111
|
-
|
|
112
|
-
describe("select function", () => {
|
|
113
|
-
it("should transform data with select function", async () => {
|
|
114
|
-
const { result } = renderHook(
|
|
115
|
-
() =>
|
|
116
|
-
useActorSuspenseQuery<TestActor, "greet", "candid", number>({
|
|
117
|
-
reactor: mockReactor,
|
|
118
|
-
functionName: "greet",
|
|
119
|
-
select: (data: string) => data.length,
|
|
120
|
-
}),
|
|
121
|
-
{ wrapper }
|
|
122
|
-
)
|
|
123
|
-
|
|
124
|
-
await waitFor(() => {
|
|
125
|
-
expect(result.current.isSuccess).toBe(true)
|
|
126
|
-
})
|
|
127
|
-
|
|
128
|
-
// "Hello, World!" has 13 characters
|
|
129
|
-
expect(result.current.data).toBe(13)
|
|
130
|
-
})
|
|
131
|
-
|
|
132
|
-
it("should transform data to different type with select", async () => {
|
|
133
|
-
const { result } = renderHook(
|
|
134
|
-
() =>
|
|
135
|
-
useActorSuspenseQuery<
|
|
136
|
-
TestActor,
|
|
137
|
-
"greet",
|
|
138
|
-
"candid",
|
|
139
|
-
{ message: string }
|
|
140
|
-
>({
|
|
141
|
-
reactor: mockReactor,
|
|
142
|
-
functionName: "greet",
|
|
143
|
-
select: (data: string) => ({ message: data }),
|
|
144
|
-
}),
|
|
145
|
-
{ wrapper }
|
|
146
|
-
)
|
|
147
|
-
|
|
148
|
-
await waitFor(() => {
|
|
149
|
-
expect(result.current.isSuccess).toBe(true)
|
|
150
|
-
})
|
|
151
|
-
|
|
152
|
-
expect(result.current.data).toEqual({ message: "Hello, World!" })
|
|
153
|
-
})
|
|
154
|
-
|
|
155
|
-
it("should transform bigint to number with select", async () => {
|
|
156
|
-
const { result } = renderHook(
|
|
157
|
-
() =>
|
|
158
|
-
useActorSuspenseQuery<TestActor, "getCount", "candid", number>({
|
|
159
|
-
reactor: mockReactor,
|
|
160
|
-
functionName: "getCount",
|
|
161
|
-
select: (data: bigint) => Number(data),
|
|
162
|
-
}),
|
|
163
|
-
{ wrapper }
|
|
164
|
-
)
|
|
165
|
-
|
|
166
|
-
await waitFor(() => {
|
|
167
|
-
expect(result.current.isSuccess).toBe(true)
|
|
168
|
-
})
|
|
169
|
-
|
|
170
|
-
expect(result.current.data).toBe(42)
|
|
171
|
-
expect(typeof result.current.data).toBe("number")
|
|
172
|
-
})
|
|
173
|
-
})
|
|
174
|
-
|
|
175
|
-
describe("query options", () => {
|
|
176
|
-
it("should use custom staleTime", async () => {
|
|
177
|
-
const { result } = renderHook(
|
|
178
|
-
() =>
|
|
179
|
-
useActorSuspenseQuery<TestActor, "greet">({
|
|
180
|
-
reactor: mockReactor,
|
|
181
|
-
functionName: "greet",
|
|
182
|
-
staleTime: 1000 * 60 * 10, // 10 minutes
|
|
183
|
-
}),
|
|
184
|
-
{ wrapper }
|
|
185
|
-
)
|
|
186
|
-
|
|
187
|
-
await waitFor(() => {
|
|
188
|
-
expect(result.current.isSuccess).toBe(true)
|
|
189
|
-
})
|
|
190
|
-
|
|
191
|
-
expect(result.current.isStale).toBe(false)
|
|
192
|
-
})
|
|
193
|
-
})
|
|
194
|
-
|
|
195
|
-
describe("suspense behavior", () => {
|
|
196
|
-
it("should always return data (no undefined) when successful", async () => {
|
|
197
|
-
const { result } = renderHook(
|
|
198
|
-
() =>
|
|
199
|
-
useActorSuspenseQuery<TestActor, "greet">({
|
|
200
|
-
reactor: mockReactor,
|
|
201
|
-
functionName: "greet",
|
|
202
|
-
}),
|
|
203
|
-
{ wrapper }
|
|
204
|
-
)
|
|
205
|
-
|
|
206
|
-
await waitFor(() => {
|
|
207
|
-
expect(result.current.isSuccess).toBe(true)
|
|
208
|
-
})
|
|
209
|
-
|
|
210
|
-
// Suspense queries always have data when rendered
|
|
211
|
-
expect(result.current.data).toBeDefined()
|
|
212
|
-
expect(result.current.data).toBe("Hello, World!")
|
|
213
|
-
})
|
|
214
|
-
|
|
215
|
-
it("should have status 'success' when data is available", async () => {
|
|
216
|
-
const { result } = renderHook(
|
|
217
|
-
() =>
|
|
218
|
-
useActorSuspenseQuery<TestActor, "greet">({
|
|
219
|
-
reactor: mockReactor,
|
|
220
|
-
functionName: "greet",
|
|
221
|
-
}),
|
|
222
|
-
{ wrapper }
|
|
223
|
-
)
|
|
224
|
-
|
|
225
|
-
await waitFor(() => {
|
|
226
|
-
expect(result.current.status).toBe("success")
|
|
227
|
-
})
|
|
228
|
-
})
|
|
229
|
-
})
|
|
230
|
-
|
|
231
|
-
describe("refetching", () => {
|
|
232
|
-
it("should support manual refetch", async () => {
|
|
233
|
-
const { result } = renderHook(
|
|
234
|
-
() =>
|
|
235
|
-
useActorSuspenseQuery<TestActor, "greet">({
|
|
236
|
-
reactor: mockReactor,
|
|
237
|
-
functionName: "greet",
|
|
238
|
-
}),
|
|
239
|
-
{ wrapper }
|
|
240
|
-
)
|
|
241
|
-
|
|
242
|
-
await waitFor(() => {
|
|
243
|
-
expect(result.current.isSuccess).toBe(true)
|
|
244
|
-
})
|
|
245
|
-
|
|
246
|
-
// Refetch should be available
|
|
247
|
-
expect(typeof result.current.refetch).toBe("function")
|
|
248
|
-
|
|
249
|
-
await result.current.refetch()
|
|
250
|
-
|
|
251
|
-
expect(result.current.isSuccess).toBe(true)
|
|
252
|
-
})
|
|
253
|
-
})
|
|
254
|
-
})
|
package/src/utils.test.ts
DELETED
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
import { describe, expect, it } from "vitest"
|
|
2
|
-
import { normalizeQueryData } from "./utils"
|
|
3
|
-
|
|
4
|
-
describe("normalizeQueryData", () => {
|
|
5
|
-
it("uses null for a successful undefined query result", () => {
|
|
6
|
-
expect(normalizeQueryData(undefined)).toBeNull()
|
|
7
|
-
})
|
|
8
|
-
|
|
9
|
-
it("preserves defined query results, including nested undefined fields", () => {
|
|
10
|
-
const result = { value: undefined }
|
|
11
|
-
|
|
12
|
-
expect(normalizeQueryData(result)).toBe(result)
|
|
13
|
-
})
|
|
14
|
-
})
|