@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.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'