@kuckit/app-web 2.0.1
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.d.ts +1511 -0
- package/dist/index.js +210 -0
- package/package.json +58 -0
- package/src/index.ts +38 -0
package/dist/index.js
ADDED
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
import { createContext, createElement, useContext, useEffect, useMemo, useState } from "react";
|
|
2
|
+
import { QueryCache, QueryClient, QueryClientProvider } from "@tanstack/react-query";
|
|
3
|
+
import { RouterProvider, createRoute, createRouter } from "@tanstack/react-router";
|
|
4
|
+
import { KuckitNavProvider, KuckitRpcProvider, KuckitSlotProvider, loadKuckitClientModules } from "@kuckit/sdk-react";
|
|
5
|
+
import { createORPCClient } from "@orpc/client";
|
|
6
|
+
import { RPCLink } from "@orpc/client/fetch";
|
|
7
|
+
import { createTanstackQueryUtils } from "@orpc/tanstack-query";
|
|
8
|
+
import { createAuthClient } from "better-auth/react";
|
|
9
|
+
import { inferAdditionalFields } from "better-auth/client/plugins";
|
|
10
|
+
|
|
11
|
+
//#region src/services.ts
|
|
12
|
+
function createQueryClient(onError) {
|
|
13
|
+
return new QueryClient({ queryCache: new QueryCache({ onError: (error) => {
|
|
14
|
+
onError?.(error);
|
|
15
|
+
} }) });
|
|
16
|
+
}
|
|
17
|
+
function createRPCLink(serverUrl) {
|
|
18
|
+
return new RPCLink({
|
|
19
|
+
url: `${serverUrl}/rpc`,
|
|
20
|
+
fetch(url, options) {
|
|
21
|
+
return fetch(url, {
|
|
22
|
+
...options,
|
|
23
|
+
credentials: "include"
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
function createRPCClient(link) {
|
|
29
|
+
return createORPCClient(link);
|
|
30
|
+
}
|
|
31
|
+
function createORPCUtils(client) {
|
|
32
|
+
return createTanstackQueryUtils(client);
|
|
33
|
+
}
|
|
34
|
+
function createAuthClientService(serverUrl) {
|
|
35
|
+
return createAuthClient({
|
|
36
|
+
baseURL: serverUrl,
|
|
37
|
+
plugins: [inferAdditionalFields()]
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
function createKuckitWebServices(options = {}) {
|
|
41
|
+
const serverUrl = options.serverUrl || (typeof globalThis !== "undefined" && "location" in globalThis ? globalThis.location.origin : "");
|
|
42
|
+
const queryClient = createQueryClient(options.onQueryError);
|
|
43
|
+
const rpcClient = createRPCClient(createRPCLink(serverUrl));
|
|
44
|
+
return {
|
|
45
|
+
queryClient,
|
|
46
|
+
rpcClient,
|
|
47
|
+
orpc: createORPCUtils(rpcClient),
|
|
48
|
+
authClient: createAuthClientService(serverUrl)
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
//#endregion
|
|
53
|
+
//#region src/provider.tsx
|
|
54
|
+
const KuckitWebContext = createContext(null);
|
|
55
|
+
const ServicesContext = createContext(null);
|
|
56
|
+
function DefaultLoader() {
|
|
57
|
+
return createElement("div", {
|
|
58
|
+
style: {
|
|
59
|
+
display: "flex",
|
|
60
|
+
alignItems: "center",
|
|
61
|
+
justifyContent: "center",
|
|
62
|
+
height: "100vh"
|
|
63
|
+
},
|
|
64
|
+
children: "Loading..."
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
function DefaultError({ error }) {
|
|
68
|
+
return createElement("div", {
|
|
69
|
+
style: {
|
|
70
|
+
display: "flex",
|
|
71
|
+
alignItems: "center",
|
|
72
|
+
justifyContent: "center",
|
|
73
|
+
height: "100vh",
|
|
74
|
+
flexDirection: "column"
|
|
75
|
+
},
|
|
76
|
+
children: [createElement("h2", {
|
|
77
|
+
key: "title",
|
|
78
|
+
style: { color: "red" }
|
|
79
|
+
}, "Failed to load modules"), createElement("p", { key: "message" }, error.message)]
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
function useKuckitWeb() {
|
|
83
|
+
const ctx = useContext(KuckitWebContext);
|
|
84
|
+
if (!ctx) throw new Error("useKuckitWeb must be used within a KuckitWebProvider");
|
|
85
|
+
return ctx;
|
|
86
|
+
}
|
|
87
|
+
function useServices() {
|
|
88
|
+
const ctx = useContext(ServicesContext);
|
|
89
|
+
if (!ctx) throw new Error("useServices must be used within a KuckitWebProvider");
|
|
90
|
+
return ctx;
|
|
91
|
+
}
|
|
92
|
+
function useRpc() {
|
|
93
|
+
const { rpcClient } = useServices();
|
|
94
|
+
return rpcClient;
|
|
95
|
+
}
|
|
96
|
+
function useOrpc() {
|
|
97
|
+
const { orpc } = useServices();
|
|
98
|
+
return orpc;
|
|
99
|
+
}
|
|
100
|
+
function useAuth() {
|
|
101
|
+
const { authClient } = useServices();
|
|
102
|
+
return authClient;
|
|
103
|
+
}
|
|
104
|
+
function useQueryClient() {
|
|
105
|
+
const { queryClient } = useServices();
|
|
106
|
+
return queryClient;
|
|
107
|
+
}
|
|
108
|
+
function InternalKuckitWebProvider({ config, routeTree, rootRoute, children }) {
|
|
109
|
+
const { services, Loader, ErrorComponent } = useMemo(() => {
|
|
110
|
+
return {
|
|
111
|
+
services: createKuckitWebServices({ serverUrl: config.serverUrl }),
|
|
112
|
+
Loader: config.loaderComponent || DefaultLoader,
|
|
113
|
+
ErrorComponent: config.errorComponent || DefaultError
|
|
114
|
+
};
|
|
115
|
+
}, [
|
|
116
|
+
config.serverUrl,
|
|
117
|
+
config.loaderComponent,
|
|
118
|
+
config.errorComponent
|
|
119
|
+
]);
|
|
120
|
+
const [loadResult, setLoadResult] = useState(null);
|
|
121
|
+
const [error, setError] = useState(null);
|
|
122
|
+
useEffect(() => {
|
|
123
|
+
let cancelled = false;
|
|
124
|
+
const loadModules = async () => {
|
|
125
|
+
try {
|
|
126
|
+
const result = await loadKuckitClientModules({
|
|
127
|
+
orpc: services.orpc,
|
|
128
|
+
queryClient: services.queryClient,
|
|
129
|
+
env: config.env || "production",
|
|
130
|
+
modules: config.modules
|
|
131
|
+
});
|
|
132
|
+
if (!cancelled) setLoadResult(result);
|
|
133
|
+
} catch (err) {
|
|
134
|
+
if (!cancelled) setError(err instanceof Error ? err : new Error(String(err)));
|
|
135
|
+
}
|
|
136
|
+
};
|
|
137
|
+
loadModules();
|
|
138
|
+
return () => {
|
|
139
|
+
cancelled = true;
|
|
140
|
+
};
|
|
141
|
+
}, [
|
|
142
|
+
services,
|
|
143
|
+
config.modules,
|
|
144
|
+
config.env
|
|
145
|
+
]);
|
|
146
|
+
const router = useMemo(() => {
|
|
147
|
+
if (!loadResult) return null;
|
|
148
|
+
const moduleRouteDefs = loadResult.routeRegistry.getAll();
|
|
149
|
+
const moduleRoutes = moduleRouteDefs.map((routeDef) => createRoute({
|
|
150
|
+
getParentRoute: () => rootRoute,
|
|
151
|
+
path: routeDef.path,
|
|
152
|
+
component: routeDef.component
|
|
153
|
+
}));
|
|
154
|
+
if (moduleRoutes.length > 0) console.log(`[kuckit/app-web] Loaded ${moduleRoutes.length} module routes:`, moduleRouteDefs.map((r) => r.path));
|
|
155
|
+
return createRouter({
|
|
156
|
+
routeTree,
|
|
157
|
+
defaultPreload: "intent",
|
|
158
|
+
defaultPendingComponent: Loader,
|
|
159
|
+
context: {
|
|
160
|
+
orpc: services.orpc,
|
|
161
|
+
queryClient: services.queryClient
|
|
162
|
+
}
|
|
163
|
+
});
|
|
164
|
+
}, [
|
|
165
|
+
loadResult,
|
|
166
|
+
routeTree,
|
|
167
|
+
rootRoute,
|
|
168
|
+
services,
|
|
169
|
+
Loader
|
|
170
|
+
]);
|
|
171
|
+
if (error) return createElement(ErrorComponent, { error });
|
|
172
|
+
if (!loadResult || !router) return createElement(Loader);
|
|
173
|
+
const contextValue = {
|
|
174
|
+
routeRegistry: loadResult.routeRegistry,
|
|
175
|
+
navRegistry: loadResult.navRegistry,
|
|
176
|
+
slotRegistry: loadResult.slotRegistry,
|
|
177
|
+
services,
|
|
178
|
+
isLoaded: true
|
|
179
|
+
};
|
|
180
|
+
return createElement(ServicesContext.Provider, { value: services }, createElement(QueryClientProvider, { client: services.queryClient }, createElement(KuckitWebContext.Provider, { value: contextValue }, createElement(KuckitRpcProvider, {
|
|
181
|
+
client: services.rpcClient,
|
|
182
|
+
children: null
|
|
183
|
+
}, createElement(KuckitNavProvider, {
|
|
184
|
+
registry: loadResult.navRegistry,
|
|
185
|
+
children: null
|
|
186
|
+
}, createElement(KuckitSlotProvider, {
|
|
187
|
+
registry: loadResult.slotRegistry,
|
|
188
|
+
children: null
|
|
189
|
+
}, createElement(RouterProvider, { router }), children))))));
|
|
190
|
+
}
|
|
191
|
+
function createKuckitWebProvider(options) {
|
|
192
|
+
const { routeTree, rootRoute,...config } = options;
|
|
193
|
+
return function KuckitWebProvider({ children }) {
|
|
194
|
+
return createElement(InternalKuckitWebProvider, {
|
|
195
|
+
config,
|
|
196
|
+
routeTree,
|
|
197
|
+
rootRoute,
|
|
198
|
+
children
|
|
199
|
+
});
|
|
200
|
+
};
|
|
201
|
+
}
|
|
202
|
+
function withKuckitWeb(Component, options) {
|
|
203
|
+
const Provider = createKuckitWebProvider(options);
|
|
204
|
+
return function WrappedWithKuckit(props) {
|
|
205
|
+
return createElement(Provider, null, createElement(Component, props));
|
|
206
|
+
};
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
//#endregion
|
|
210
|
+
export { createAuthClientService, createKuckitWebProvider, createKuckitWebServices, createORPCUtils, createQueryClient, createRPCClient, createRPCLink, useAuth, useKuckitWeb, useOrpc, useQueryClient, useRpc, useServices, withKuckitWeb };
|
package/package.json
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@kuckit/app-web",
|
|
3
|
+
"version": "2.0.1",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"main": "src/index.ts",
|
|
6
|
+
"types": "src/index.ts",
|
|
7
|
+
"files": [
|
|
8
|
+
"dist"
|
|
9
|
+
],
|
|
10
|
+
"exports": {
|
|
11
|
+
".": {
|
|
12
|
+
"types": "./src/index.ts",
|
|
13
|
+
"default": "./src/index.ts"
|
|
14
|
+
},
|
|
15
|
+
"./*": {
|
|
16
|
+
"types": "./src/*.ts",
|
|
17
|
+
"default": "./src/*.ts"
|
|
18
|
+
}
|
|
19
|
+
},
|
|
20
|
+
"publishConfig": {
|
|
21
|
+
"main": "dist/index.js",
|
|
22
|
+
"types": "dist/index.d.ts",
|
|
23
|
+
"exports": {
|
|
24
|
+
".": {
|
|
25
|
+
"types": "./dist/index.d.ts",
|
|
26
|
+
"default": "./dist/index.js"
|
|
27
|
+
},
|
|
28
|
+
"./*": {
|
|
29
|
+
"types": "./dist/*.d.ts",
|
|
30
|
+
"default": "./dist/*.js"
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
},
|
|
34
|
+
"scripts": {
|
|
35
|
+
"build": "tsdown",
|
|
36
|
+
"check-types": "tsc -b"
|
|
37
|
+
},
|
|
38
|
+
"dependencies": {
|
|
39
|
+
"@kuckit/sdk-react": "workspace:*",
|
|
40
|
+
"@kuckit/api": "workspace:*",
|
|
41
|
+
"@kuckit/auth": "workspace:*",
|
|
42
|
+
"@tanstack/react-query": "^5.85.5",
|
|
43
|
+
"@tanstack/react-router": "^1.114.25",
|
|
44
|
+
"@orpc/client": "catalog:",
|
|
45
|
+
"@orpc/tanstack-query": "^1.10.0",
|
|
46
|
+
"better-auth": "catalog:",
|
|
47
|
+
"react": "19.1.0"
|
|
48
|
+
},
|
|
49
|
+
"devDependencies": {
|
|
50
|
+
"typescript": "catalog:",
|
|
51
|
+
"@types/react": "~19.1.10",
|
|
52
|
+
"tsdown": "catalog:"
|
|
53
|
+
},
|
|
54
|
+
"peerDependencies": {
|
|
55
|
+
"typescript": "^5",
|
|
56
|
+
"react": "^18 || ^19"
|
|
57
|
+
}
|
|
58
|
+
}
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
// Provider and HOC
|
|
2
|
+
export {
|
|
3
|
+
createKuckitWebProvider,
|
|
4
|
+
withKuckitWeb,
|
|
5
|
+
useKuckitWeb,
|
|
6
|
+
useServices,
|
|
7
|
+
useRpc,
|
|
8
|
+
useOrpc,
|
|
9
|
+
useAuth,
|
|
10
|
+
useQueryClient,
|
|
11
|
+
} from './provider'
|
|
12
|
+
|
|
13
|
+
// Service factories (for custom setup)
|
|
14
|
+
export {
|
|
15
|
+
createKuckitWebServices,
|
|
16
|
+
createQueryClient,
|
|
17
|
+
createRPCLink,
|
|
18
|
+
createRPCClient,
|
|
19
|
+
createORPCUtils,
|
|
20
|
+
createAuthClientService,
|
|
21
|
+
type CreateServicesOptions,
|
|
22
|
+
} from './services'
|
|
23
|
+
|
|
24
|
+
// Types
|
|
25
|
+
export type {
|
|
26
|
+
KuckitWebConfig,
|
|
27
|
+
KuckitWebContext,
|
|
28
|
+
KuckitWebServices,
|
|
29
|
+
KuckitWebProviderProps,
|
|
30
|
+
KuckitWebRouterProps,
|
|
31
|
+
CreateKuckitWebProviderOptions,
|
|
32
|
+
ORPCUtils,
|
|
33
|
+
AuthClient,
|
|
34
|
+
ModuleRoute,
|
|
35
|
+
} from './types'
|
|
36
|
+
|
|
37
|
+
// Re-export commonly used types from sdk-react for convenience
|
|
38
|
+
export type { ClientModuleSpec, RouteDefinition, NavItem } from '@kuckit/sdk-react'
|