appflare 0.2.25 → 0.2.27
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/Documentation.md +758 -758
- package/cli/commands/index.ts +238 -238
- package/cli/generate.ts +178 -178
- package/cli/index.ts +120 -120
- package/cli/load-config.ts +184 -184
- package/cli/schema-compiler.ts +1183 -1183
- package/cli/templates/auth/README.md +156 -156
- package/cli/templates/auth/config.ts +61 -61
- package/cli/templates/auth/route-config.ts +1 -1
- package/cli/templates/auth/route-handler.ts +1 -1
- package/cli/templates/auth/route-request-utils.ts +5 -5
- package/cli/templates/auth/route.config.ts +18 -18
- package/cli/templates/auth/route.handler.ts +18 -18
- package/cli/templates/auth/route.request-utils.ts +55 -55
- package/cli/templates/auth/route.ts +14 -14
- package/cli/templates/core/README.md +266 -266
- package/cli/templates/core/app-creation.ts +19 -19
- package/cli/templates/core/client/appflare.ts +112 -112
- package/cli/templates/core/client/handlers/index.ts +748 -748
- package/cli/templates/core/client/handlers.ts +1 -1
- package/cli/templates/core/client/index.ts +7 -7
- package/cli/templates/core/client/storage.ts +205 -180
- package/cli/templates/core/client/types.ts +186 -184
- package/cli/templates/core/client-modules/appflare.ts +1 -1
- package/cli/templates/core/client-modules/handlers.ts +1 -1
- package/cli/templates/core/client-modules/index.ts +1 -1
- package/cli/templates/core/client-modules/storage.ts +1 -1
- package/cli/templates/core/client-modules/types.ts +1 -1
- package/cli/templates/core/client.artifacts.ts +39 -39
- package/cli/templates/core/client.ts +4 -4
- package/cli/templates/core/drizzle.ts +15 -15
- package/cli/templates/core/export.ts +14 -14
- package/cli/templates/core/handlers.route.ts +24 -24
- package/cli/templates/core/handlers.ts +1 -1
- package/cli/templates/core/imports.ts +9 -9
- package/cli/templates/core/server.ts +38 -38
- package/cli/templates/core/types.ts +6 -6
- package/cli/templates/core/wrangler.ts +109 -109
- package/cli/templates/dashboard/builders/functions/index.ts +17 -17
- package/cli/templates/dashboard/builders/functions/render-page/header.ts +20 -20
- package/cli/templates/dashboard/builders/functions/render-page/index.ts +33 -33
- package/cli/templates/dashboard/builders/functions/render-page/request-panel.ts +171 -171
- package/cli/templates/dashboard/builders/functions/render-page/result-panel.ts +85 -85
- package/cli/templates/dashboard/builders/functions/render-page/scripts.ts +554 -554
- package/cli/templates/dashboard/builders/navigation.ts +122 -122
- package/cli/templates/dashboard/builders/storage/index.ts +13 -13
- package/cli/templates/dashboard/builders/storage/routes/create-directory-route.ts +29 -29
- package/cli/templates/dashboard/builders/storage/routes/delete-route.ts +18 -18
- package/cli/templates/dashboard/builders/storage/routes/download-route.ts +23 -23
- package/cli/templates/dashboard/builders/storage/routes/index.ts +22 -22
- package/cli/templates/dashboard/builders/storage/routes/list-route.ts +25 -25
- package/cli/templates/dashboard/builders/storage/routes/preview-route.ts +21 -21
- package/cli/templates/dashboard/builders/storage/routes/upload-route.ts +21 -21
- package/cli/templates/dashboard/builders/storage/runtime/helpers.ts +72 -72
- package/cli/templates/dashboard/builders/storage/runtime/storage-page.ts +130 -130
- package/cli/templates/dashboard/builders/table-routes/common/drawer-panel.ts +27 -27
- package/cli/templates/dashboard/builders/table-routes/common/pagination.ts +30 -30
- package/cli/templates/dashboard/builders/table-routes/common/search-bar.ts +23 -23
- package/cli/templates/dashboard/builders/table-routes/fragments.ts +217 -217
- package/cli/templates/dashboard/builders/table-routes/helpers.ts +45 -45
- package/cli/templates/dashboard/builders/table-routes/index.ts +8 -8
- package/cli/templates/dashboard/builders/table-routes/table/actions-cell.ts +71 -71
- package/cli/templates/dashboard/builders/table-routes/table/get-route.ts +291 -291
- package/cli/templates/dashboard/builders/table-routes/table/index.ts +80 -80
- package/cli/templates/dashboard/builders/table-routes/table/post-routes.ts +163 -163
- package/cli/templates/dashboard/builders/table-routes/table-route.ts +7 -7
- package/cli/templates/dashboard/builders/table-routes/users/get-route.ts +69 -69
- package/cli/templates/dashboard/builders/table-routes/users/html/modals.ts +57 -57
- package/cli/templates/dashboard/builders/table-routes/users/html/page.ts +27 -27
- package/cli/templates/dashboard/builders/table-routes/users/html/table.ts +128 -128
- package/cli/templates/dashboard/builders/table-routes/users/index.ts +32 -32
- package/cli/templates/dashboard/builders/table-routes/users/post-routes.ts +150 -150
- package/cli/templates/dashboard/builders/table-routes/users/redirect.ts +14 -14
- package/cli/templates/dashboard/builders/table-routes/users-route.ts +10 -10
- package/cli/templates/dashboard/components/dashboard-home.ts +23 -23
- package/cli/templates/dashboard/components/layout.ts +388 -388
- package/cli/templates/dashboard/components/login-page.ts +65 -65
- package/cli/templates/dashboard/index.ts +61 -61
- package/cli/templates/dashboard/types.ts +9 -9
- package/cli/templates/handlers/README.md +353 -353
- package/cli/templates/handlers/auth.ts +37 -37
- package/cli/templates/handlers/execution.ts +42 -42
- package/cli/templates/handlers/generators/context/context-creation.ts +101 -101
- package/cli/templates/handlers/generators/context/error-helpers.ts +11 -11
- package/cli/templates/handlers/generators/context/scheduler.ts +24 -24
- package/cli/templates/handlers/generators/context/storage-api.ts +82 -112
- package/cli/templates/handlers/generators/context/storage-helpers.ts +59 -59
- package/cli/templates/handlers/generators/context/types.ts +18 -18
- package/cli/templates/handlers/generators/context.ts +43 -43
- package/cli/templates/handlers/generators/execution.ts +15 -15
- package/cli/templates/handlers/generators/handlers.ts +13 -13
- package/cli/templates/handlers/generators/registration/modules/cron.ts +26 -26
- package/cli/templates/handlers/generators/registration/modules/realtime/auth.ts +75 -75
- package/cli/templates/handlers/generators/registration/modules/realtime/durable-object.ts +144 -144
- package/cli/templates/handlers/generators/registration/modules/realtime/index.ts +14 -14
- package/cli/templates/handlers/generators/registration/modules/realtime/publisher.ts +102 -102
- package/cli/templates/handlers/generators/registration/modules/realtime/routes.ts +164 -164
- package/cli/templates/handlers/generators/registration/modules/realtime/types.ts +30 -30
- package/cli/templates/handlers/generators/registration/modules/realtime/utils.ts +516 -516
- package/cli/templates/handlers/generators/registration/modules/scheduler.ts +56 -56
- package/cli/templates/handlers/generators/registration/modules/storage.ts +192 -194
- package/cli/templates/handlers/generators/registration/sections.ts +210 -210
- package/cli/templates/handlers/generators/types/context.ts +67 -66
- package/cli/templates/handlers/generators/types/core.ts +106 -106
- package/cli/templates/handlers/generators/types/operations.ts +135 -135
- package/cli/templates/handlers/generators/types/query-definitions/filter-and-where-types.ts +259 -259
- package/cli/templates/handlers/generators/types/query-definitions/query-api-types.ts +135 -135
- package/cli/templates/handlers/generators/types/query-definitions/query-helper-functions.ts +1031 -1031
- package/cli/templates/handlers/generators/types/query-definitions/schema-and-table-types.ts +246 -246
- package/cli/templates/handlers/generators/types/query-definitions.ts +13 -13
- package/cli/templates/handlers/generators/types/query-runtime/handled-error.ts +13 -13
- package/cli/templates/handlers/generators/types/query-runtime/runtime-aggregate-and-footer.ts +174 -174
- package/cli/templates/handlers/generators/types/query-runtime/runtime-read.ts +121 -121
- package/cli/templates/handlers/generators/types/query-runtime/runtime-setup.ts +45 -45
- package/cli/templates/handlers/generators/types/query-runtime/runtime-write.ts +676 -676
- package/cli/templates/handlers/generators/types/query-runtime.ts +15 -15
- package/cli/templates/handlers/index.ts +43 -43
- package/cli/templates/handlers/operations.ts +116 -116
- package/cli/templates/handlers/registration.ts +91 -91
- package/cli/templates/handlers/types.ts +15 -15
- package/cli/templates/handlers/utils.ts +48 -48
- package/cli/types.ts +110 -110
- package/cli/utils/handler-discovery.ts +466 -466
- package/cli/utils/json-utils.ts +24 -24
- package/cli/utils/path-utils.ts +19 -19
- package/cli/utils/schema-discovery.ts +399 -399
- package/dist/cli/index.js +95 -99
- package/dist/cli/index.mjs +95 -99
- package/index.ts +18 -18
- package/package.json +58 -58
- package/react/index.ts +5 -5
- package/react/use-infinite-query.ts +252 -252
- package/react/use-mutation.ts +89 -89
- package/react/use-query.ts +207 -207
- package/schema.ts +415 -415
- package/test-better-auth-hash.ts +2 -2
- package/tsconfig.json +6 -6
- package/tsup.config.ts +82 -82
- package/dist/cli/index.d.mts +0 -2
- package/dist/cli/index.d.ts +0 -2
package/package.json
CHANGED
|
@@ -1,58 +1,58 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "appflare",
|
|
3
|
-
"version": "0.2.
|
|
4
|
-
"main": "./dist/index.js",
|
|
5
|
-
"module": "./dist/index.mjs",
|
|
6
|
-
"types": "./dist/index.d.ts",
|
|
7
|
-
"bin": {
|
|
8
|
-
"appflare": "./dist/cli/index.js"
|
|
9
|
-
},
|
|
10
|
-
"exports": {
|
|
11
|
-
".": {
|
|
12
|
-
"types": "./dist/index.d.ts",
|
|
13
|
-
"import": "./dist/index.mjs",
|
|
14
|
-
"require": "./dist/index.js"
|
|
15
|
-
},
|
|
16
|
-
"./react": {
|
|
17
|
-
"types": "./dist/react/index.d.ts",
|
|
18
|
-
"import": "./dist/react/index.mjs",
|
|
19
|
-
"require": "./dist/react/index.js"
|
|
20
|
-
},
|
|
21
|
-
"./*": "./dist/*.js"
|
|
22
|
-
},
|
|
23
|
-
"scripts": {
|
|
24
|
-
"build": "tsup",
|
|
25
|
-
"dev": "tsup --watch",
|
|
26
|
-
"lint": "tsc --noEmit",
|
|
27
|
-
"prepublishOnly": "bun run build"
|
|
28
|
-
},
|
|
29
|
-
"peerDependencies": {
|
|
30
|
-
"@tanstack/react-query": "^5.90.21",
|
|
31
|
-
"react": ">=18"
|
|
32
|
-
},
|
|
33
|
-
"devDependencies": {
|
|
34
|
-
"@cloudflare/workers-types": "^4.20260219.0",
|
|
35
|
-
"@types/react": "^19.2.0",
|
|
36
|
-
"@tanstack/react-query": "^5.90.21",
|
|
37
|
-
"@types/bun": "^1.3.9",
|
|
38
|
-
"@types/node": "^25.3.0",
|
|
39
|
-
"npm-check-updates": "^19.4.0",
|
|
40
|
-
"tsup": "^8.3.6"
|
|
41
|
-
},
|
|
42
|
-
"dependencies": {
|
|
43
|
-
"@better-auth/cli": "^1.4.21",
|
|
44
|
-
"better-auth": "^1.5.5",
|
|
45
|
-
"@hono/standard-validator": "0.2.2",
|
|
46
|
-
"better-auth-cloudflare": "0.2.9",
|
|
47
|
-
"better-fetch": "1.1.2",
|
|
48
|
-
"bun": "1.3.9",
|
|
49
|
-
"chokidar": "5.0.0",
|
|
50
|
-
"commander": "14.0.3",
|
|
51
|
-
"drizzle-kit": "0.31.9",
|
|
52
|
-
"drizzle-orm": "0.45.1",
|
|
53
|
-
"hono": "4.12.0",
|
|
54
|
-
"typescript": "^5.9.3",
|
|
55
|
-
"wrangler": "4.67.0",
|
|
56
|
-
"zod": "4.3.6"
|
|
57
|
-
}
|
|
58
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"name": "appflare",
|
|
3
|
+
"version": "0.2.27",
|
|
4
|
+
"main": "./dist/index.js",
|
|
5
|
+
"module": "./dist/index.mjs",
|
|
6
|
+
"types": "./dist/index.d.ts",
|
|
7
|
+
"bin": {
|
|
8
|
+
"appflare": "./dist/cli/index.js"
|
|
9
|
+
},
|
|
10
|
+
"exports": {
|
|
11
|
+
".": {
|
|
12
|
+
"types": "./dist/index.d.ts",
|
|
13
|
+
"import": "./dist/index.mjs",
|
|
14
|
+
"require": "./dist/index.js"
|
|
15
|
+
},
|
|
16
|
+
"./react": {
|
|
17
|
+
"types": "./dist/react/index.d.ts",
|
|
18
|
+
"import": "./dist/react/index.mjs",
|
|
19
|
+
"require": "./dist/react/index.js"
|
|
20
|
+
},
|
|
21
|
+
"./*": "./dist/*.js"
|
|
22
|
+
},
|
|
23
|
+
"scripts": {
|
|
24
|
+
"build": "tsup",
|
|
25
|
+
"dev": "tsup --watch",
|
|
26
|
+
"lint": "tsc --noEmit",
|
|
27
|
+
"prepublishOnly": "bun run build"
|
|
28
|
+
},
|
|
29
|
+
"peerDependencies": {
|
|
30
|
+
"@tanstack/react-query": "^5.90.21",
|
|
31
|
+
"react": ">=18"
|
|
32
|
+
},
|
|
33
|
+
"devDependencies": {
|
|
34
|
+
"@cloudflare/workers-types": "^4.20260219.0",
|
|
35
|
+
"@types/react": "^19.2.0",
|
|
36
|
+
"@tanstack/react-query": "^5.90.21",
|
|
37
|
+
"@types/bun": "^1.3.9",
|
|
38
|
+
"@types/node": "^25.3.0",
|
|
39
|
+
"npm-check-updates": "^19.4.0",
|
|
40
|
+
"tsup": "^8.3.6"
|
|
41
|
+
},
|
|
42
|
+
"dependencies": {
|
|
43
|
+
"@better-auth/cli": "^1.4.21",
|
|
44
|
+
"better-auth": "^1.5.5",
|
|
45
|
+
"@hono/standard-validator": "0.2.2",
|
|
46
|
+
"better-auth-cloudflare": "0.2.9",
|
|
47
|
+
"better-fetch": "1.1.2",
|
|
48
|
+
"bun": "1.3.9",
|
|
49
|
+
"chokidar": "5.0.0",
|
|
50
|
+
"commander": "14.0.3",
|
|
51
|
+
"drizzle-kit": "0.31.9",
|
|
52
|
+
"drizzle-orm": "0.45.1",
|
|
53
|
+
"hono": "4.12.0",
|
|
54
|
+
"typescript": "^5.9.3",
|
|
55
|
+
"wrangler": "4.67.0",
|
|
56
|
+
"zod": "4.3.6"
|
|
57
|
+
}
|
|
58
|
+
}
|
package/react/index.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
export { useQuery } from "./use-query";
|
|
2
|
-
export type { UseAppflareQueryOptions } from "./use-query";
|
|
3
|
-
export { useInfiniteQuery } from "./use-infinite-query";
|
|
4
|
-
export type { UseAppflareInfiniteQueryOptions } from "./use-infinite-query";
|
|
5
|
-
export { useMutation } from "./use-mutation";
|
|
1
|
+
export { useQuery } from "./use-query";
|
|
2
|
+
export type { UseAppflareQueryOptions } from "./use-query";
|
|
3
|
+
export { useInfiniteQuery } from "./use-infinite-query";
|
|
4
|
+
export type { UseAppflareInfiniteQueryOptions } from "./use-infinite-query";
|
|
5
|
+
export { useMutation } from "./use-mutation";
|
|
@@ -1,252 +1,252 @@
|
|
|
1
|
-
import {
|
|
2
|
-
hashKey,
|
|
3
|
-
type InfiniteData,
|
|
4
|
-
type QueryKey,
|
|
5
|
-
type UseInfiniteQueryOptions,
|
|
6
|
-
type UseInfiniteQueryResult,
|
|
7
|
-
useInfiniteQuery as useTanstackInfiniteQuery,
|
|
8
|
-
useQueryClient,
|
|
9
|
-
} from "@tanstack/react-query";
|
|
10
|
-
import { useEffect, useMemo, useRef } from "react";
|
|
11
|
-
|
|
12
|
-
type AppflareRequestErrorLike = {
|
|
13
|
-
message: string;
|
|
14
|
-
status?: number;
|
|
15
|
-
};
|
|
16
|
-
|
|
17
|
-
type AppflareRequestResultLike<TData> = {
|
|
18
|
-
data: TData | null;
|
|
19
|
-
error: AppflareRequestErrorLike | null;
|
|
20
|
-
};
|
|
21
|
-
|
|
22
|
-
type AppflareRealtimeSubscriptionLike = {
|
|
23
|
-
remove: () => void;
|
|
24
|
-
};
|
|
25
|
-
|
|
26
|
-
type AppflareRealtimeQueryUpdateLike<TData> = {
|
|
27
|
-
event: "query:update";
|
|
28
|
-
payload: {
|
|
29
|
-
queryName: string;
|
|
30
|
-
signature: string;
|
|
31
|
-
data: TData;
|
|
32
|
-
};
|
|
33
|
-
};
|
|
34
|
-
|
|
35
|
-
type AppflareRequiredInputKeys<TInput extends Record<string, unknown>> = {
|
|
36
|
-
[K in keyof TInput]-?: undefined extends TInput[K] ? never : K;
|
|
37
|
-
}[keyof TInput];
|
|
38
|
-
|
|
39
|
-
type AppflareHasRequiredInputKeys<TInput extends Record<string, unknown>> = [
|
|
40
|
-
AppflareRequiredInputKeys<TInput>,
|
|
41
|
-
] extends [never]
|
|
42
|
-
? false
|
|
43
|
-
: true;
|
|
44
|
-
|
|
45
|
-
type AppflareRouteRunArgs<TInput extends Record<string, unknown>> =
|
|
46
|
-
AppflareHasRequiredInputKeys<TInput> extends true
|
|
47
|
-
? [args: TInput, options?: any]
|
|
48
|
-
: [args?: TInput, options?: any];
|
|
49
|
-
|
|
50
|
-
type AppflareQueryLike<TArgs extends Record<string, unknown>, TData> = {
|
|
51
|
-
run: (
|
|
52
|
-
...params: AppflareRouteRunArgs<TArgs>
|
|
53
|
-
) => Promise<AppflareRequestResultLike<TData>>;
|
|
54
|
-
subscribe?: (options: {
|
|
55
|
-
args?: TArgs;
|
|
56
|
-
authToken?: string;
|
|
57
|
-
requestOptions?: any;
|
|
58
|
-
signal?: AbortSignal;
|
|
59
|
-
onChange: (
|
|
60
|
-
data: TData,
|
|
61
|
-
update: AppflareRealtimeQueryUpdateLike<TData>,
|
|
62
|
-
) => void;
|
|
63
|
-
onError?: (error: unknown) => void;
|
|
64
|
-
}) => AppflareRealtimeSubscriptionLike;
|
|
65
|
-
};
|
|
66
|
-
|
|
67
|
-
export type UseAppflareInfiniteQueryOptions<
|
|
68
|
-
TArgs extends Record<string, unknown>,
|
|
69
|
-
TData,
|
|
70
|
-
TPageParam,
|
|
71
|
-
TSelected = InfiniteData<TData, TPageParam>,
|
|
72
|
-
TKey extends QueryKey = QueryKey,
|
|
73
|
-
> = {
|
|
74
|
-
realtime?: {
|
|
75
|
-
enabled?: boolean;
|
|
76
|
-
authToken?: string;
|
|
77
|
-
requestOptions?: any;
|
|
78
|
-
onChange?: (
|
|
79
|
-
data: TData,
|
|
80
|
-
update: AppflareRealtimeQueryUpdateLike<TData>,
|
|
81
|
-
) => void;
|
|
82
|
-
onError?: (error: unknown) => void;
|
|
83
|
-
};
|
|
84
|
-
requestOptions?: any;
|
|
85
|
-
pageParamToArgs?: (baseArgs: TArgs, pageParam: TPageParam) => TArgs;
|
|
86
|
-
queryOptions?: Omit<
|
|
87
|
-
UseInfiniteQueryOptions<TData, Error, TSelected, TKey, TPageParam>,
|
|
88
|
-
"queryFn" | "queryKey"
|
|
89
|
-
> & {
|
|
90
|
-
queryKey?: TKey;
|
|
91
|
-
};
|
|
92
|
-
};
|
|
93
|
-
|
|
94
|
-
type UseInfiniteQueryCallParams<
|
|
95
|
-
TArgs extends Record<string, unknown>,
|
|
96
|
-
TData,
|
|
97
|
-
TPageParam,
|
|
98
|
-
TSelected,
|
|
99
|
-
TKey extends QueryKey,
|
|
100
|
-
> =
|
|
101
|
-
AppflareHasRequiredInputKeys<TArgs> extends true
|
|
102
|
-
? [
|
|
103
|
-
args: TArgs,
|
|
104
|
-
options?: UseAppflareInfiniteQueryOptions<
|
|
105
|
-
TArgs,
|
|
106
|
-
TData,
|
|
107
|
-
TPageParam,
|
|
108
|
-
TSelected,
|
|
109
|
-
TKey
|
|
110
|
-
>,
|
|
111
|
-
]
|
|
112
|
-
: [
|
|
113
|
-
args?: TArgs,
|
|
114
|
-
options?: UseAppflareInfiniteQueryOptions<
|
|
115
|
-
TArgs,
|
|
116
|
-
TData,
|
|
117
|
-
TPageParam,
|
|
118
|
-
TSelected,
|
|
119
|
-
TKey
|
|
120
|
-
>,
|
|
121
|
-
];
|
|
122
|
-
|
|
123
|
-
function toError(error: AppflareRequestErrorLike): Error {
|
|
124
|
-
const next = new Error(error.message);
|
|
125
|
-
if (error.status !== undefined) {
|
|
126
|
-
(next as Error & { status?: number }).status = error.status;
|
|
127
|
-
}
|
|
128
|
-
return next;
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
export function useInfiniteQuery<
|
|
132
|
-
TArgs extends Record<string, unknown>,
|
|
133
|
-
TData,
|
|
134
|
-
TPageParam = unknown,
|
|
135
|
-
TSelected = InfiniteData<TData, TPageParam>,
|
|
136
|
-
TKey extends QueryKey = QueryKey,
|
|
137
|
-
>(
|
|
138
|
-
query: AppflareQueryLike<TArgs, TData>,
|
|
139
|
-
...params: UseInfiniteQueryCallParams<
|
|
140
|
-
TArgs,
|
|
141
|
-
TData,
|
|
142
|
-
TPageParam,
|
|
143
|
-
TSelected,
|
|
144
|
-
TKey
|
|
145
|
-
>
|
|
146
|
-
): UseInfiniteQueryResult<TSelected, Error> {
|
|
147
|
-
const args = (params[0] ?? {}) as TArgs;
|
|
148
|
-
const options = params[1];
|
|
149
|
-
const queryClient = useQueryClient();
|
|
150
|
-
const realtimeOnChangeRef = useRef(options?.realtime?.onChange);
|
|
151
|
-
const realtimeOnErrorRef = useRef(options?.realtime?.onError);
|
|
152
|
-
|
|
153
|
-
useEffect(() => {
|
|
154
|
-
realtimeOnChangeRef.current = options?.realtime?.onChange;
|
|
155
|
-
realtimeOnErrorRef.current = options?.realtime?.onError;
|
|
156
|
-
}, [options?.realtime?.onChange, options?.realtime?.onError]);
|
|
157
|
-
|
|
158
|
-
const resolvedQueryKey = useMemo(() => {
|
|
159
|
-
return (
|
|
160
|
-
options?.queryOptions?.queryKey ??
|
|
161
|
-
(["appflare", "infinite-query", query, args] as unknown as TKey)
|
|
162
|
-
);
|
|
163
|
-
}, [args, options?.queryOptions?.queryKey, query]);
|
|
164
|
-
|
|
165
|
-
const resolvedQueryKeyHash = useMemo(
|
|
166
|
-
() => hashKey(resolvedQueryKey as QueryKey),
|
|
167
|
-
[resolvedQueryKey],
|
|
168
|
-
);
|
|
169
|
-
|
|
170
|
-
const realtimeArgsHash = useMemo(() => hashKey([args] as QueryKey), [args]);
|
|
171
|
-
|
|
172
|
-
const realtimeRequestOptionsHash = useMemo(
|
|
173
|
-
() => hashKey([options?.realtime?.requestOptions] as QueryKey),
|
|
174
|
-
[options?.realtime?.requestOptions],
|
|
175
|
-
);
|
|
176
|
-
|
|
177
|
-
const result = useTanstackInfiniteQuery<
|
|
178
|
-
TData,
|
|
179
|
-
Error,
|
|
180
|
-
TSelected,
|
|
181
|
-
TKey,
|
|
182
|
-
TPageParam
|
|
183
|
-
>({
|
|
184
|
-
...(options?.queryOptions as Omit<
|
|
185
|
-
UseInfiniteQueryOptions<TData, Error, TSelected, TKey, TPageParam>,
|
|
186
|
-
"queryFn" | "queryKey"
|
|
187
|
-
>),
|
|
188
|
-
queryKey: resolvedQueryKey,
|
|
189
|
-
queryFn: async ({ pageParam }) => {
|
|
190
|
-
const nextArgs =
|
|
191
|
-
pageParam === undefined || !options?.pageParamToArgs
|
|
192
|
-
? args
|
|
193
|
-
: options.pageParamToArgs(args, pageParam as TPageParam);
|
|
194
|
-
const response = await query.run(nextArgs, options?.requestOptions);
|
|
195
|
-
if (response.error) {
|
|
196
|
-
throw toError(response.error);
|
|
197
|
-
}
|
|
198
|
-
return response.data as TData;
|
|
199
|
-
},
|
|
200
|
-
});
|
|
201
|
-
|
|
202
|
-
useEffect(() => {
|
|
203
|
-
if (options?.realtime?.enabled === false || !query.subscribe) {
|
|
204
|
-
return;
|
|
205
|
-
}
|
|
206
|
-
|
|
207
|
-
const controller = new AbortController();
|
|
208
|
-
const subscription = query.subscribe({
|
|
209
|
-
args,
|
|
210
|
-
authToken: options.realtime?.authToken,
|
|
211
|
-
requestOptions: options.realtime?.requestOptions,
|
|
212
|
-
signal: controller.signal,
|
|
213
|
-
onChange: (data, update) => {
|
|
214
|
-
queryClient.setQueryData<InfiniteData<TData, TPageParam>>(
|
|
215
|
-
resolvedQueryKey,
|
|
216
|
-
(previous) => {
|
|
217
|
-
if (!previous || previous.pages.length === 0) {
|
|
218
|
-
return previous;
|
|
219
|
-
}
|
|
220
|
-
|
|
221
|
-
return {
|
|
222
|
-
...previous,
|
|
223
|
-
pages: [data as TData, ...previous.pages.slice(1)],
|
|
224
|
-
};
|
|
225
|
-
},
|
|
226
|
-
);
|
|
227
|
-
realtimeOnChangeRef.current?.(
|
|
228
|
-
data as TData,
|
|
229
|
-
update as AppflareRealtimeQueryUpdateLike<TData>,
|
|
230
|
-
);
|
|
231
|
-
},
|
|
232
|
-
onError: (error) => {
|
|
233
|
-
realtimeOnErrorRef.current?.(error);
|
|
234
|
-
},
|
|
235
|
-
});
|
|
236
|
-
|
|
237
|
-
return () => {
|
|
238
|
-
controller.abort();
|
|
239
|
-
subscription.remove();
|
|
240
|
-
};
|
|
241
|
-
}, [
|
|
242
|
-
realtimeArgsHash,
|
|
243
|
-
options?.realtime?.authToken,
|
|
244
|
-
options?.realtime?.enabled,
|
|
245
|
-
realtimeRequestOptionsHash,
|
|
246
|
-
query.subscribe,
|
|
247
|
-
queryClient,
|
|
248
|
-
resolvedQueryKeyHash,
|
|
249
|
-
]);
|
|
250
|
-
|
|
251
|
-
return result;
|
|
252
|
-
}
|
|
1
|
+
import {
|
|
2
|
+
hashKey,
|
|
3
|
+
type InfiniteData,
|
|
4
|
+
type QueryKey,
|
|
5
|
+
type UseInfiniteQueryOptions,
|
|
6
|
+
type UseInfiniteQueryResult,
|
|
7
|
+
useInfiniteQuery as useTanstackInfiniteQuery,
|
|
8
|
+
useQueryClient,
|
|
9
|
+
} from "@tanstack/react-query";
|
|
10
|
+
import { useEffect, useMemo, useRef } from "react";
|
|
11
|
+
|
|
12
|
+
type AppflareRequestErrorLike = {
|
|
13
|
+
message: string;
|
|
14
|
+
status?: number;
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
type AppflareRequestResultLike<TData> = {
|
|
18
|
+
data: TData | null;
|
|
19
|
+
error: AppflareRequestErrorLike | null;
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
type AppflareRealtimeSubscriptionLike = {
|
|
23
|
+
remove: () => void;
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
type AppflareRealtimeQueryUpdateLike<TData> = {
|
|
27
|
+
event: "query:update";
|
|
28
|
+
payload: {
|
|
29
|
+
queryName: string;
|
|
30
|
+
signature: string;
|
|
31
|
+
data: TData;
|
|
32
|
+
};
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
type AppflareRequiredInputKeys<TInput extends Record<string, unknown>> = {
|
|
36
|
+
[K in keyof TInput]-?: undefined extends TInput[K] ? never : K;
|
|
37
|
+
}[keyof TInput];
|
|
38
|
+
|
|
39
|
+
type AppflareHasRequiredInputKeys<TInput extends Record<string, unknown>> = [
|
|
40
|
+
AppflareRequiredInputKeys<TInput>,
|
|
41
|
+
] extends [never]
|
|
42
|
+
? false
|
|
43
|
+
: true;
|
|
44
|
+
|
|
45
|
+
type AppflareRouteRunArgs<TInput extends Record<string, unknown>> =
|
|
46
|
+
AppflareHasRequiredInputKeys<TInput> extends true
|
|
47
|
+
? [args: TInput, options?: any]
|
|
48
|
+
: [args?: TInput, options?: any];
|
|
49
|
+
|
|
50
|
+
type AppflareQueryLike<TArgs extends Record<string, unknown>, TData> = {
|
|
51
|
+
run: (
|
|
52
|
+
...params: AppflareRouteRunArgs<TArgs>
|
|
53
|
+
) => Promise<AppflareRequestResultLike<TData>>;
|
|
54
|
+
subscribe?: (options: {
|
|
55
|
+
args?: TArgs;
|
|
56
|
+
authToken?: string;
|
|
57
|
+
requestOptions?: any;
|
|
58
|
+
signal?: AbortSignal;
|
|
59
|
+
onChange: (
|
|
60
|
+
data: TData,
|
|
61
|
+
update: AppflareRealtimeQueryUpdateLike<TData>,
|
|
62
|
+
) => void;
|
|
63
|
+
onError?: (error: unknown) => void;
|
|
64
|
+
}) => AppflareRealtimeSubscriptionLike;
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
export type UseAppflareInfiniteQueryOptions<
|
|
68
|
+
TArgs extends Record<string, unknown>,
|
|
69
|
+
TData,
|
|
70
|
+
TPageParam,
|
|
71
|
+
TSelected = InfiniteData<TData, TPageParam>,
|
|
72
|
+
TKey extends QueryKey = QueryKey,
|
|
73
|
+
> = {
|
|
74
|
+
realtime?: {
|
|
75
|
+
enabled?: boolean;
|
|
76
|
+
authToken?: string;
|
|
77
|
+
requestOptions?: any;
|
|
78
|
+
onChange?: (
|
|
79
|
+
data: TData,
|
|
80
|
+
update: AppflareRealtimeQueryUpdateLike<TData>,
|
|
81
|
+
) => void;
|
|
82
|
+
onError?: (error: unknown) => void;
|
|
83
|
+
};
|
|
84
|
+
requestOptions?: any;
|
|
85
|
+
pageParamToArgs?: (baseArgs: TArgs, pageParam: TPageParam) => TArgs;
|
|
86
|
+
queryOptions?: Omit<
|
|
87
|
+
UseInfiniteQueryOptions<TData, Error, TSelected, TKey, TPageParam>,
|
|
88
|
+
"queryFn" | "queryKey"
|
|
89
|
+
> & {
|
|
90
|
+
queryKey?: TKey;
|
|
91
|
+
};
|
|
92
|
+
};
|
|
93
|
+
|
|
94
|
+
type UseInfiniteQueryCallParams<
|
|
95
|
+
TArgs extends Record<string, unknown>,
|
|
96
|
+
TData,
|
|
97
|
+
TPageParam,
|
|
98
|
+
TSelected,
|
|
99
|
+
TKey extends QueryKey,
|
|
100
|
+
> =
|
|
101
|
+
AppflareHasRequiredInputKeys<TArgs> extends true
|
|
102
|
+
? [
|
|
103
|
+
args: TArgs,
|
|
104
|
+
options?: UseAppflareInfiniteQueryOptions<
|
|
105
|
+
TArgs,
|
|
106
|
+
TData,
|
|
107
|
+
TPageParam,
|
|
108
|
+
TSelected,
|
|
109
|
+
TKey
|
|
110
|
+
>,
|
|
111
|
+
]
|
|
112
|
+
: [
|
|
113
|
+
args?: TArgs,
|
|
114
|
+
options?: UseAppflareInfiniteQueryOptions<
|
|
115
|
+
TArgs,
|
|
116
|
+
TData,
|
|
117
|
+
TPageParam,
|
|
118
|
+
TSelected,
|
|
119
|
+
TKey
|
|
120
|
+
>,
|
|
121
|
+
];
|
|
122
|
+
|
|
123
|
+
function toError(error: AppflareRequestErrorLike): Error {
|
|
124
|
+
const next = new Error(error.message);
|
|
125
|
+
if (error.status !== undefined) {
|
|
126
|
+
(next as Error & { status?: number }).status = error.status;
|
|
127
|
+
}
|
|
128
|
+
return next;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
export function useInfiniteQuery<
|
|
132
|
+
TArgs extends Record<string, unknown>,
|
|
133
|
+
TData,
|
|
134
|
+
TPageParam = unknown,
|
|
135
|
+
TSelected = InfiniteData<TData, TPageParam>,
|
|
136
|
+
TKey extends QueryKey = QueryKey,
|
|
137
|
+
>(
|
|
138
|
+
query: AppflareQueryLike<TArgs, TData>,
|
|
139
|
+
...params: UseInfiniteQueryCallParams<
|
|
140
|
+
TArgs,
|
|
141
|
+
TData,
|
|
142
|
+
TPageParam,
|
|
143
|
+
TSelected,
|
|
144
|
+
TKey
|
|
145
|
+
>
|
|
146
|
+
): UseInfiniteQueryResult<TSelected, Error> {
|
|
147
|
+
const args = (params[0] ?? {}) as TArgs;
|
|
148
|
+
const options = params[1];
|
|
149
|
+
const queryClient = useQueryClient();
|
|
150
|
+
const realtimeOnChangeRef = useRef(options?.realtime?.onChange);
|
|
151
|
+
const realtimeOnErrorRef = useRef(options?.realtime?.onError);
|
|
152
|
+
|
|
153
|
+
useEffect(() => {
|
|
154
|
+
realtimeOnChangeRef.current = options?.realtime?.onChange;
|
|
155
|
+
realtimeOnErrorRef.current = options?.realtime?.onError;
|
|
156
|
+
}, [options?.realtime?.onChange, options?.realtime?.onError]);
|
|
157
|
+
|
|
158
|
+
const resolvedQueryKey = useMemo(() => {
|
|
159
|
+
return (
|
|
160
|
+
options?.queryOptions?.queryKey ??
|
|
161
|
+
(["appflare", "infinite-query", query, args] as unknown as TKey)
|
|
162
|
+
);
|
|
163
|
+
}, [args, options?.queryOptions?.queryKey, query]);
|
|
164
|
+
|
|
165
|
+
const resolvedQueryKeyHash = useMemo(
|
|
166
|
+
() => hashKey(resolvedQueryKey as QueryKey),
|
|
167
|
+
[resolvedQueryKey],
|
|
168
|
+
);
|
|
169
|
+
|
|
170
|
+
const realtimeArgsHash = useMemo(() => hashKey([args] as QueryKey), [args]);
|
|
171
|
+
|
|
172
|
+
const realtimeRequestOptionsHash = useMemo(
|
|
173
|
+
() => hashKey([options?.realtime?.requestOptions] as QueryKey),
|
|
174
|
+
[options?.realtime?.requestOptions],
|
|
175
|
+
);
|
|
176
|
+
|
|
177
|
+
const result = useTanstackInfiniteQuery<
|
|
178
|
+
TData,
|
|
179
|
+
Error,
|
|
180
|
+
TSelected,
|
|
181
|
+
TKey,
|
|
182
|
+
TPageParam
|
|
183
|
+
>({
|
|
184
|
+
...(options?.queryOptions as Omit<
|
|
185
|
+
UseInfiniteQueryOptions<TData, Error, TSelected, TKey, TPageParam>,
|
|
186
|
+
"queryFn" | "queryKey"
|
|
187
|
+
>),
|
|
188
|
+
queryKey: resolvedQueryKey,
|
|
189
|
+
queryFn: async ({ pageParam }) => {
|
|
190
|
+
const nextArgs =
|
|
191
|
+
pageParam === undefined || !options?.pageParamToArgs
|
|
192
|
+
? args
|
|
193
|
+
: options.pageParamToArgs(args, pageParam as TPageParam);
|
|
194
|
+
const response = await query.run(nextArgs, options?.requestOptions);
|
|
195
|
+
if (response.error) {
|
|
196
|
+
throw toError(response.error);
|
|
197
|
+
}
|
|
198
|
+
return response.data as TData;
|
|
199
|
+
},
|
|
200
|
+
});
|
|
201
|
+
|
|
202
|
+
useEffect(() => {
|
|
203
|
+
if (options?.realtime?.enabled === false || !query.subscribe) {
|
|
204
|
+
return;
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
const controller = new AbortController();
|
|
208
|
+
const subscription = query.subscribe({
|
|
209
|
+
args,
|
|
210
|
+
authToken: options.realtime?.authToken,
|
|
211
|
+
requestOptions: options.realtime?.requestOptions,
|
|
212
|
+
signal: controller.signal,
|
|
213
|
+
onChange: (data, update) => {
|
|
214
|
+
queryClient.setQueryData<InfiniteData<TData, TPageParam>>(
|
|
215
|
+
resolvedQueryKey,
|
|
216
|
+
(previous) => {
|
|
217
|
+
if (!previous || previous.pages.length === 0) {
|
|
218
|
+
return previous;
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
return {
|
|
222
|
+
...previous,
|
|
223
|
+
pages: [data as TData, ...previous.pages.slice(1)],
|
|
224
|
+
};
|
|
225
|
+
},
|
|
226
|
+
);
|
|
227
|
+
realtimeOnChangeRef.current?.(
|
|
228
|
+
data as TData,
|
|
229
|
+
update as AppflareRealtimeQueryUpdateLike<TData>,
|
|
230
|
+
);
|
|
231
|
+
},
|
|
232
|
+
onError: (error) => {
|
|
233
|
+
realtimeOnErrorRef.current?.(error);
|
|
234
|
+
},
|
|
235
|
+
});
|
|
236
|
+
|
|
237
|
+
return () => {
|
|
238
|
+
controller.abort();
|
|
239
|
+
subscription.remove();
|
|
240
|
+
};
|
|
241
|
+
}, [
|
|
242
|
+
realtimeArgsHash,
|
|
243
|
+
options?.realtime?.authToken,
|
|
244
|
+
options?.realtime?.enabled,
|
|
245
|
+
realtimeRequestOptionsHash,
|
|
246
|
+
query.subscribe,
|
|
247
|
+
queryClient,
|
|
248
|
+
resolvedQueryKeyHash,
|
|
249
|
+
]);
|
|
250
|
+
|
|
251
|
+
return result;
|
|
252
|
+
}
|