@kuckit/sdk-react 1.0.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/dist/index.d.ts +668 -0
- package/dist/index.js +700 -0
- package/package.json +41 -0
- package/src/index.ts +62 -0
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,668 @@
|
|
|
1
|
+
import { ComponentType, JSX, ReactNode } from "react";
|
|
2
|
+
import { QueryClient } from "@tanstack/react-query";
|
|
3
|
+
|
|
4
|
+
//#region src/types.d.ts
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Built-in capability types for common module features
|
|
8
|
+
*/
|
|
9
|
+
type BuiltInCapability = 'nav.item' | 'settings.page' | 'dashboard.widget' | 'api.webhook' | 'api.public' | 'slot.provider';
|
|
10
|
+
/**
|
|
11
|
+
* Module capability type - built-in or custom
|
|
12
|
+
* Custom capabilities must be prefixed with 'custom.'
|
|
13
|
+
*/
|
|
14
|
+
type ModuleCapability = BuiltInCapability | `custom.${string}`;
|
|
15
|
+
/**
|
|
16
|
+
* Module metadata for discovery and documentation
|
|
17
|
+
*/
|
|
18
|
+
interface KuckitClientModuleMeta {
|
|
19
|
+
/** Unique identifier, e.g., 'kuckit.users' or 'acme.billing' */
|
|
20
|
+
id: string;
|
|
21
|
+
/** Human-readable name */
|
|
22
|
+
displayName?: string;
|
|
23
|
+
/** Module description */
|
|
24
|
+
description?: string;
|
|
25
|
+
/** Module version */
|
|
26
|
+
version?: string;
|
|
27
|
+
/** Capabilities this module provides */
|
|
28
|
+
capabilities?: ModuleCapability[];
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Metadata for a route definition
|
|
32
|
+
*/
|
|
33
|
+
interface RouteMeta {
|
|
34
|
+
/** Page title for document head */
|
|
35
|
+
title?: string;
|
|
36
|
+
/** Icon identifier (e.g., 'credit-card', 'users') */
|
|
37
|
+
icon?: string;
|
|
38
|
+
/** Whether this route requires authentication */
|
|
39
|
+
requiresAuth?: boolean;
|
|
40
|
+
/** Custom metadata */
|
|
41
|
+
[key: string]: unknown;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Route definition for module-provided routes
|
|
45
|
+
*/
|
|
46
|
+
interface RouteDefinition {
|
|
47
|
+
/** Unique route identifier */
|
|
48
|
+
id: string;
|
|
49
|
+
/**
|
|
50
|
+
* URL path for the route.
|
|
51
|
+
*
|
|
52
|
+
* The path convention determines where the route is rendered:
|
|
53
|
+
* - `/some-path` → Root level route (outside dashboard, no layout wrapper)
|
|
54
|
+
* - `/dashboard/some-path` → Dashboard route (wrapped in dashboard layout)
|
|
55
|
+
*
|
|
56
|
+
* Root-level routes are public by default. Use `meta.requiresAuth: true`
|
|
57
|
+
* to require authentication for root routes.
|
|
58
|
+
*
|
|
59
|
+
* @example '/cli/activate' // Root level, no dashboard wrapper
|
|
60
|
+
* @example '/dashboard/settings/profile' // Dashboard route with layout
|
|
61
|
+
*/
|
|
62
|
+
path: string;
|
|
63
|
+
/** React component to render for this route */
|
|
64
|
+
component: ComponentType<unknown>;
|
|
65
|
+
/** Parent route ID (defaults to '__root__' if not specified) */
|
|
66
|
+
parentRouteId?: string;
|
|
67
|
+
/** Route metadata */
|
|
68
|
+
meta?: RouteMeta;
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Navigation item for sidebar/header menus
|
|
72
|
+
*/
|
|
73
|
+
interface NavItem {
|
|
74
|
+
/** Unique identifier */
|
|
75
|
+
id: string;
|
|
76
|
+
/** Display label */
|
|
77
|
+
label: string;
|
|
78
|
+
/** Navigation path */
|
|
79
|
+
path: string;
|
|
80
|
+
/** Icon identifier (lucide-react icon name, e.g., 'credit-card', 'users') */
|
|
81
|
+
icon?: string;
|
|
82
|
+
/** Sort order (lower = higher priority) */
|
|
83
|
+
order?: number;
|
|
84
|
+
/** Parent nav item ID for nested navigation */
|
|
85
|
+
parentId?: string;
|
|
86
|
+
/** If true, show in main nav instead of "Modules" section */
|
|
87
|
+
showInMainNav?: boolean;
|
|
88
|
+
/** Badge text (e.g., "New", "Beta") */
|
|
89
|
+
badge?: string;
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Options for slot registration
|
|
93
|
+
*/
|
|
94
|
+
interface SlotOptions {
|
|
95
|
+
/** Sort order (lower = higher priority, default: 100) */
|
|
96
|
+
order?: number;
|
|
97
|
+
/** Props to pass to the component */
|
|
98
|
+
props?: Record<string, unknown>;
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Internal representation of a registered slot component
|
|
102
|
+
*/
|
|
103
|
+
interface SlotRegistration {
|
|
104
|
+
/** The slot name this component is registered to */
|
|
105
|
+
slotName: string;
|
|
106
|
+
/** The component to render */
|
|
107
|
+
component: ComponentType<unknown>;
|
|
108
|
+
/** Module that registered this component */
|
|
109
|
+
moduleId: string;
|
|
110
|
+
/** Sort order (lower = higher priority) */
|
|
111
|
+
order: number;
|
|
112
|
+
/** Props to pass to the component */
|
|
113
|
+
props?: Record<string, unknown>;
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* Context passed to client module hooks
|
|
117
|
+
*/
|
|
118
|
+
interface KuckitClientModuleContext {
|
|
119
|
+
/** oRPC client instance */
|
|
120
|
+
orpc: unknown;
|
|
121
|
+
/** TanStack Query client */
|
|
122
|
+
queryClient: QueryClient;
|
|
123
|
+
/** Environment name (development, production, etc.) */
|
|
124
|
+
env: string;
|
|
125
|
+
/** Register a component for use in the application */
|
|
126
|
+
registerComponent: (name: string, component: ComponentType<unknown>) => void;
|
|
127
|
+
/** Register a route that will be injected into the router */
|
|
128
|
+
addRoute: (route: RouteDefinition) => void;
|
|
129
|
+
/** Register a navigation item for sidebar/header menus */
|
|
130
|
+
addNavItem: (item: NavItem) => void;
|
|
131
|
+
/** Register a component into a named slot */
|
|
132
|
+
registerSlot: (slotName: string, component: ComponentType<unknown>, options?: SlotOptions) => void;
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* Client module lifecycle hooks
|
|
136
|
+
*/
|
|
137
|
+
interface KuckitClientModuleHooks {
|
|
138
|
+
/**
|
|
139
|
+
* Called when the module is registered
|
|
140
|
+
* Use this to register components, initialize state, etc.
|
|
141
|
+
*/
|
|
142
|
+
register?(ctx: KuckitClientModuleContext): void | Promise<void>;
|
|
143
|
+
/**
|
|
144
|
+
* Called when the module is unloaded (optional)
|
|
145
|
+
* Use this for cleanup
|
|
146
|
+
*/
|
|
147
|
+
onUnload?(): void | Promise<void>;
|
|
148
|
+
}
|
|
149
|
+
/**
|
|
150
|
+
* Complete client module definition combining metadata and hooks
|
|
151
|
+
*/
|
|
152
|
+
interface KuckitClientModuleDefinition extends KuckitClientModuleMeta, KuckitClientModuleHooks {}
|
|
153
|
+
/**
|
|
154
|
+
* Client module specification in application config
|
|
155
|
+
*
|
|
156
|
+
* You can specify a module in two ways:
|
|
157
|
+
* 1. `module`: Direct reference to a module definition (preferred in monorepos)
|
|
158
|
+
* 2. `package`: NPM package path for dynamic import (for published packages)
|
|
159
|
+
*/
|
|
160
|
+
interface ClientModuleSpec {
|
|
161
|
+
/** Direct module definition (preferred in monorepos for better type safety) */
|
|
162
|
+
module?: KuckitClientModuleDefinition;
|
|
163
|
+
/** NPM package path for dynamic import, e.g., '@acme/billing-module/client' */
|
|
164
|
+
package?: string;
|
|
165
|
+
/** Whether to skip this module */
|
|
166
|
+
disabled?: boolean;
|
|
167
|
+
}
|
|
168
|
+
/**
|
|
169
|
+
* Internal type for loaded modules
|
|
170
|
+
*/
|
|
171
|
+
interface LoadedClientModule extends KuckitClientModuleDefinition {
|
|
172
|
+
_source: 'direct' | 'package';
|
|
173
|
+
}
|
|
174
|
+
//#endregion
|
|
175
|
+
//#region src/define-module.d.ts
|
|
176
|
+
/**
|
|
177
|
+
* Helper function to define a client module with type safety
|
|
178
|
+
*
|
|
179
|
+
* @example
|
|
180
|
+
* ```ts
|
|
181
|
+
* export const kuckitClientModule = defineKuckitClientModule({
|
|
182
|
+
* id: 'acme.billing',
|
|
183
|
+
* displayName: 'Billing',
|
|
184
|
+
* version: '1.0.0',
|
|
185
|
+
*
|
|
186
|
+
* register(ctx) {
|
|
187
|
+
* ctx.registerComponent('BillingDashboard', BillingDashboard)
|
|
188
|
+
* ctx.registerComponent('InvoiceList', InvoiceList)
|
|
189
|
+
* },
|
|
190
|
+
* })
|
|
191
|
+
* ```
|
|
192
|
+
*/
|
|
193
|
+
declare function defineKuckitClientModule<T extends KuckitClientModuleDefinition>(mod: T): T;
|
|
194
|
+
//#endregion
|
|
195
|
+
//#region src/registry.d.ts
|
|
196
|
+
/**
|
|
197
|
+
* Registry for module-provided routes
|
|
198
|
+
*
|
|
199
|
+
* Collects route definitions during module loading and provides
|
|
200
|
+
* methods to build a TanStack Router route tree.
|
|
201
|
+
*/
|
|
202
|
+
declare class RouteRegistry {
|
|
203
|
+
private routes;
|
|
204
|
+
private frozen;
|
|
205
|
+
/**
|
|
206
|
+
* Register a route definition
|
|
207
|
+
* @throws Error if registry is frozen or route ID already exists
|
|
208
|
+
*/
|
|
209
|
+
add(route: RouteDefinition): void;
|
|
210
|
+
/**
|
|
211
|
+
* Get all registered routes
|
|
212
|
+
*/
|
|
213
|
+
getAll(): RouteDefinition[];
|
|
214
|
+
/**
|
|
215
|
+
* Get a route by ID
|
|
216
|
+
*/
|
|
217
|
+
get(id: string): RouteDefinition | undefined;
|
|
218
|
+
/**
|
|
219
|
+
* Check if a route is registered
|
|
220
|
+
*/
|
|
221
|
+
has(id: string): boolean;
|
|
222
|
+
/**
|
|
223
|
+
* Get routes grouped by parent ID
|
|
224
|
+
*/
|
|
225
|
+
getByParent(parentId?: string): RouteDefinition[];
|
|
226
|
+
/**
|
|
227
|
+
* Freeze the registry to prevent further modifications
|
|
228
|
+
*/
|
|
229
|
+
freeze(): void;
|
|
230
|
+
/**
|
|
231
|
+
* Check if registry is frozen
|
|
232
|
+
*/
|
|
233
|
+
isFrozen(): boolean;
|
|
234
|
+
/**
|
|
235
|
+
* Get the number of registered routes
|
|
236
|
+
*/
|
|
237
|
+
get size(): number;
|
|
238
|
+
/**
|
|
239
|
+
* Clear all routes (only works if not frozen)
|
|
240
|
+
*/
|
|
241
|
+
clear(): void;
|
|
242
|
+
}
|
|
243
|
+
/**
|
|
244
|
+
* Registry for module-provided navigation items
|
|
245
|
+
*
|
|
246
|
+
* Collects nav items during module loading and provides
|
|
247
|
+
* methods to build navigation menus.
|
|
248
|
+
*/
|
|
249
|
+
declare class NavRegistry {
|
|
250
|
+
private items;
|
|
251
|
+
private frozen;
|
|
252
|
+
/**
|
|
253
|
+
* Register a navigation item
|
|
254
|
+
* @throws Error if registry is frozen or item ID already exists
|
|
255
|
+
*/
|
|
256
|
+
add(item: NavItem): void;
|
|
257
|
+
/**
|
|
258
|
+
* Get all registered navigation items, sorted by order
|
|
259
|
+
*/
|
|
260
|
+
getAll(): NavItem[];
|
|
261
|
+
/**
|
|
262
|
+
* Get a navigation item by ID
|
|
263
|
+
*/
|
|
264
|
+
get(id: string): NavItem | undefined;
|
|
265
|
+
/**
|
|
266
|
+
* Check if a nav item is registered
|
|
267
|
+
*/
|
|
268
|
+
has(id: string): boolean;
|
|
269
|
+
/**
|
|
270
|
+
* Get top-level navigation items (no parent)
|
|
271
|
+
*/
|
|
272
|
+
getTopLevel(): NavItem[];
|
|
273
|
+
/**
|
|
274
|
+
* Get nav items that should appear in main navigation
|
|
275
|
+
* (items with showInMainNav === true)
|
|
276
|
+
*/
|
|
277
|
+
getMainNavItems(): NavItem[];
|
|
278
|
+
/**
|
|
279
|
+
* Get module nav items (not in main nav)
|
|
280
|
+
* (items without showInMainNav or showInMainNav === false)
|
|
281
|
+
*/
|
|
282
|
+
getModuleNavItems(): NavItem[];
|
|
283
|
+
/**
|
|
284
|
+
* Get child navigation items for a parent
|
|
285
|
+
*/
|
|
286
|
+
getChildren(parentId: string): NavItem[];
|
|
287
|
+
/**
|
|
288
|
+
* Build a hierarchical navigation tree
|
|
289
|
+
*/
|
|
290
|
+
buildTree(): NavTreeItem[];
|
|
291
|
+
private buildTreeItem;
|
|
292
|
+
/**
|
|
293
|
+
* Freeze the registry to prevent further modifications
|
|
294
|
+
*/
|
|
295
|
+
freeze(): void;
|
|
296
|
+
/**
|
|
297
|
+
* Check if registry is frozen
|
|
298
|
+
*/
|
|
299
|
+
isFrozen(): boolean;
|
|
300
|
+
/**
|
|
301
|
+
* Get the number of registered items
|
|
302
|
+
*/
|
|
303
|
+
get size(): number;
|
|
304
|
+
/**
|
|
305
|
+
* Clear all items (only works if not frozen)
|
|
306
|
+
*/
|
|
307
|
+
clear(): void;
|
|
308
|
+
}
|
|
309
|
+
/**
|
|
310
|
+
* Registry for module-provided slot components
|
|
311
|
+
*
|
|
312
|
+
* Collects components registered to named slots during module loading
|
|
313
|
+
* and provides methods to retrieve them for rendering.
|
|
314
|
+
*/
|
|
315
|
+
declare class SlotRegistry {
|
|
316
|
+
private slots;
|
|
317
|
+
private frozen;
|
|
318
|
+
/**
|
|
319
|
+
* Register a component into a named slot
|
|
320
|
+
* @throws Error if registry is frozen
|
|
321
|
+
*/
|
|
322
|
+
add(slotName: string, component: ComponentType<unknown>, moduleId: string, options?: SlotOptions): void;
|
|
323
|
+
/**
|
|
324
|
+
* Get all components registered to a slot, sorted by order
|
|
325
|
+
*/
|
|
326
|
+
getSlot(name: string): SlotRegistration[];
|
|
327
|
+
/**
|
|
328
|
+
* Check if a slot has any components registered
|
|
329
|
+
*/
|
|
330
|
+
hasSlot(name: string): boolean;
|
|
331
|
+
/**
|
|
332
|
+
* Get all slot names that have components registered
|
|
333
|
+
*/
|
|
334
|
+
getSlotNames(): string[];
|
|
335
|
+
/**
|
|
336
|
+
* Get total number of registered components across all slots
|
|
337
|
+
*/
|
|
338
|
+
get size(): number;
|
|
339
|
+
/**
|
|
340
|
+
* Freeze the registry to prevent further modifications
|
|
341
|
+
*/
|
|
342
|
+
freeze(): void;
|
|
343
|
+
/**
|
|
344
|
+
* Check if registry is frozen
|
|
345
|
+
*/
|
|
346
|
+
isFrozen(): boolean;
|
|
347
|
+
/**
|
|
348
|
+
* Clear all slots (only works if not frozen)
|
|
349
|
+
*/
|
|
350
|
+
clear(): void;
|
|
351
|
+
}
|
|
352
|
+
/**
|
|
353
|
+
* Hierarchical navigation tree item
|
|
354
|
+
*/
|
|
355
|
+
interface NavTreeItem extends NavItem {
|
|
356
|
+
children?: NavTreeItem[];
|
|
357
|
+
}
|
|
358
|
+
/**
|
|
359
|
+
* Provider component for Kuckit navigation
|
|
360
|
+
*/
|
|
361
|
+
interface KuckitNavProviderProps {
|
|
362
|
+
registry: NavRegistry;
|
|
363
|
+
children: ReactNode;
|
|
364
|
+
}
|
|
365
|
+
declare function KuckitNavProvider({
|
|
366
|
+
registry,
|
|
367
|
+
children
|
|
368
|
+
}: KuckitNavProviderProps): ReactNode;
|
|
369
|
+
/**
|
|
370
|
+
* Hook to access navigation items
|
|
371
|
+
*/
|
|
372
|
+
declare function useKuckitNav(): NavRegistry;
|
|
373
|
+
/**
|
|
374
|
+
* Hook to get sorted navigation items
|
|
375
|
+
*/
|
|
376
|
+
declare function useNavItems(): NavItem[];
|
|
377
|
+
/**
|
|
378
|
+
* Hook to get hierarchical navigation tree
|
|
379
|
+
*/
|
|
380
|
+
declare function useNavTree(): NavTreeItem[];
|
|
381
|
+
/**
|
|
382
|
+
* Create a component registry for storing named components
|
|
383
|
+
*/
|
|
384
|
+
declare function createComponentRegistry(): ComponentRegistry;
|
|
385
|
+
interface ComponentRegistry {
|
|
386
|
+
register: (name: string, component: ComponentType<unknown>) => void;
|
|
387
|
+
get: (name: string) => ComponentType<unknown> | undefined;
|
|
388
|
+
has: (name: string) => boolean;
|
|
389
|
+
getAll: () => Map<string, ComponentType<unknown>>;
|
|
390
|
+
}
|
|
391
|
+
/**
|
|
392
|
+
* Information about a loaded client module
|
|
393
|
+
*/
|
|
394
|
+
interface LoadedClientModuleInfo {
|
|
395
|
+
/** Module unique identifier */
|
|
396
|
+
id: string;
|
|
397
|
+
/** Human-readable name */
|
|
398
|
+
displayName?: string;
|
|
399
|
+
/** Module description */
|
|
400
|
+
description?: string;
|
|
401
|
+
/** Module version */
|
|
402
|
+
version?: string;
|
|
403
|
+
/** Capabilities this module provides */
|
|
404
|
+
capabilities: ModuleCapability[];
|
|
405
|
+
}
|
|
406
|
+
/**
|
|
407
|
+
* Registry for loaded Kuckit client modules
|
|
408
|
+
*
|
|
409
|
+
* Tracks all loaded modules and their capabilities for querying.
|
|
410
|
+
*/
|
|
411
|
+
declare class ClientModuleRegistry {
|
|
412
|
+
private modules;
|
|
413
|
+
private frozen;
|
|
414
|
+
/**
|
|
415
|
+
* Register a loaded module
|
|
416
|
+
* @throws Error if registry is frozen or module ID already exists
|
|
417
|
+
*/
|
|
418
|
+
register(module: KuckitClientModuleDefinition): void;
|
|
419
|
+
/**
|
|
420
|
+
* Get all registered modules
|
|
421
|
+
*/
|
|
422
|
+
getAll(): LoadedClientModuleInfo[];
|
|
423
|
+
/**
|
|
424
|
+
* Get a module by ID
|
|
425
|
+
*/
|
|
426
|
+
getById(id: string): LoadedClientModuleInfo | undefined;
|
|
427
|
+
/**
|
|
428
|
+
* Check if a module is registered
|
|
429
|
+
*/
|
|
430
|
+
has(id: string): boolean;
|
|
431
|
+
/**
|
|
432
|
+
* Get all modules that have a specific capability
|
|
433
|
+
*/
|
|
434
|
+
getWithCapability(capability: ModuleCapability): LoadedClientModuleInfo[];
|
|
435
|
+
/**
|
|
436
|
+
* Check if a specific module has a capability
|
|
437
|
+
*/
|
|
438
|
+
hasCapability(moduleId: string, capability: ModuleCapability): boolean;
|
|
439
|
+
/**
|
|
440
|
+
* Get all unique capabilities across all modules
|
|
441
|
+
*/
|
|
442
|
+
getAllCapabilities(): ModuleCapability[];
|
|
443
|
+
/**
|
|
444
|
+
* Freeze the registry to prevent further modifications
|
|
445
|
+
*/
|
|
446
|
+
freeze(): void;
|
|
447
|
+
/**
|
|
448
|
+
* Check if registry is frozen
|
|
449
|
+
*/
|
|
450
|
+
isFrozen(): boolean;
|
|
451
|
+
/**
|
|
452
|
+
* Get the number of registered modules
|
|
453
|
+
*/
|
|
454
|
+
get size(): number;
|
|
455
|
+
/**
|
|
456
|
+
* Clear all modules (only works if not frozen)
|
|
457
|
+
*/
|
|
458
|
+
clear(): void;
|
|
459
|
+
}
|
|
460
|
+
/**
|
|
461
|
+
* Get the global client module registry
|
|
462
|
+
* Creates one if it doesn't exist
|
|
463
|
+
*/
|
|
464
|
+
declare function getClientModuleRegistry(): ClientModuleRegistry;
|
|
465
|
+
/**
|
|
466
|
+
* Get all client modules that have a specific capability
|
|
467
|
+
* Convenience function that uses the global registry
|
|
468
|
+
*/
|
|
469
|
+
declare function getClientModulesWithCapability(capability: ModuleCapability): LoadedClientModuleInfo[];
|
|
470
|
+
/**
|
|
471
|
+
* Reset the global client registry (mainly for testing)
|
|
472
|
+
*/
|
|
473
|
+
declare function resetClientModuleRegistry(): void;
|
|
474
|
+
/**
|
|
475
|
+
* Factory function to create fresh registries
|
|
476
|
+
*/
|
|
477
|
+
declare function createRegistries(): {
|
|
478
|
+
routeRegistry: RouteRegistry;
|
|
479
|
+
navRegistry: NavRegistry;
|
|
480
|
+
componentRegistry: ComponentRegistry;
|
|
481
|
+
slotRegistry: SlotRegistry;
|
|
482
|
+
moduleRegistry: ClientModuleRegistry;
|
|
483
|
+
};
|
|
484
|
+
//#endregion
|
|
485
|
+
//#region src/loader.d.ts
|
|
486
|
+
interface LoadClientModulesOptions {
|
|
487
|
+
/** oRPC client instance */
|
|
488
|
+
orpc: unknown;
|
|
489
|
+
/** TanStack Query client */
|
|
490
|
+
queryClient: QueryClient;
|
|
491
|
+
/** Environment name (development, production, etc.) */
|
|
492
|
+
env: string;
|
|
493
|
+
/** List of client modules to load */
|
|
494
|
+
modules: ClientModuleSpec[];
|
|
495
|
+
/** Callback when a component is registered (deprecated, use result.componentRegistry) */
|
|
496
|
+
onRegisterComponent?: (name: string, component: ComponentType<unknown>) => void;
|
|
497
|
+
/** Callback when a route is registered (deprecated, use result.routeRegistry) */
|
|
498
|
+
onRegisterRoute?: (route: RouteDefinition) => void;
|
|
499
|
+
/** Callback when a nav item is registered (deprecated, use result.navRegistry) */
|
|
500
|
+
onRegisterNavItem?: (item: NavItem) => void;
|
|
501
|
+
/** Callback when a slot component is registered (deprecated, use result.slotRegistry) */
|
|
502
|
+
onRegisterSlot?: (slotName: string, component: ComponentType<unknown>, moduleId: string, options?: SlotOptions) => void;
|
|
503
|
+
/** Hook called when all modules are loaded */
|
|
504
|
+
onComplete?: (result: LoadClientModulesResult) => void | Promise<void>;
|
|
505
|
+
}
|
|
506
|
+
/**
|
|
507
|
+
* Result of loading client modules
|
|
508
|
+
*/
|
|
509
|
+
interface LoadClientModulesResult {
|
|
510
|
+
/** All successfully loaded modules */
|
|
511
|
+
modules: LoadedClientModule[];
|
|
512
|
+
/** Registry containing all registered routes */
|
|
513
|
+
routeRegistry: RouteRegistry;
|
|
514
|
+
/** Registry containing all navigation items */
|
|
515
|
+
navRegistry: NavRegistry;
|
|
516
|
+
/** Registry containing all registered components */
|
|
517
|
+
componentRegistry: ComponentRegistry;
|
|
518
|
+
/** Registry containing all slot registrations */
|
|
519
|
+
slotRegistry: SlotRegistry;
|
|
520
|
+
/** Registry containing module info and capabilities */
|
|
521
|
+
moduleRegistry: ClientModuleRegistry;
|
|
522
|
+
}
|
|
523
|
+
/**
|
|
524
|
+
* Load and initialize Kuckit client modules
|
|
525
|
+
*
|
|
526
|
+
* This function orchestrates the client module loading lifecycle:
|
|
527
|
+
*
|
|
528
|
+
* 1. **Import Phase**: Dynamic import each module package (or use direct reference)
|
|
529
|
+
* 2. **Register Phase**: Run register() hooks with context (routes, nav, components, slots)
|
|
530
|
+
* 3. **Finalize Phase**: Freeze registries and call onComplete
|
|
531
|
+
*
|
|
532
|
+
* @example
|
|
533
|
+
* ```tsx
|
|
534
|
+
* const { modules, routeRegistry, navRegistry, slotRegistry, moduleRegistry } = await loadKuckitClientModules({
|
|
535
|
+
* orpc,
|
|
536
|
+
* queryClient,
|
|
537
|
+
* env: 'production',
|
|
538
|
+
* modules: [
|
|
539
|
+
* { package: '@acme/billing-module/client' },
|
|
540
|
+
* { module: myLocalModule },
|
|
541
|
+
* ],
|
|
542
|
+
* })
|
|
543
|
+
*
|
|
544
|
+
* // Use routeRegistry to build TanStack Router routes
|
|
545
|
+
* const moduleRoutes = routeRegistry.getAll()
|
|
546
|
+
*
|
|
547
|
+
* // Use navRegistry for sidebar navigation
|
|
548
|
+
* const navItems = navRegistry.getAll()
|
|
549
|
+
*
|
|
550
|
+
* // Use slotRegistry with KuckitSlot component
|
|
551
|
+
* <KuckitSlot name="dashboard.widgets" />
|
|
552
|
+
*
|
|
553
|
+
* // Query modules by capability
|
|
554
|
+
* const navModules = moduleRegistry.getWithCapability('nav.item')
|
|
555
|
+
* ```
|
|
556
|
+
*/
|
|
557
|
+
declare const loadKuckitClientModules: (opts: LoadClientModulesOptions) => Promise<LoadClientModulesResult>;
|
|
558
|
+
/**
|
|
559
|
+
* Create an unload handler for loaded client modules
|
|
560
|
+
*
|
|
561
|
+
* Returns a function that calls onUnload() on all modules in reverse order.
|
|
562
|
+
*
|
|
563
|
+
* @example
|
|
564
|
+
* ```ts
|
|
565
|
+
* const unload = createClientModuleUnloadHandler(loadedModules)
|
|
566
|
+
*
|
|
567
|
+
* // When cleaning up (e.g., HMR, route unmount)
|
|
568
|
+
* await unload()
|
|
569
|
+
* ```
|
|
570
|
+
*/
|
|
571
|
+
declare const createClientModuleUnloadHandler: (modules: LoadedClientModule[]) => (() => Promise<void>);
|
|
572
|
+
//#endregion
|
|
573
|
+
//#region src/slots.d.ts
|
|
574
|
+
/**
|
|
575
|
+
* Provider component for Kuckit slots
|
|
576
|
+
*/
|
|
577
|
+
interface KuckitSlotProviderProps {
|
|
578
|
+
registry: SlotRegistry;
|
|
579
|
+
children: ReactNode;
|
|
580
|
+
}
|
|
581
|
+
declare function KuckitSlotProvider({
|
|
582
|
+
registry,
|
|
583
|
+
children
|
|
584
|
+
}: KuckitSlotProviderProps): ReactNode;
|
|
585
|
+
/**
|
|
586
|
+
* Hook to access the slot registry
|
|
587
|
+
*/
|
|
588
|
+
declare function useSlotRegistry(): SlotRegistry;
|
|
589
|
+
/**
|
|
590
|
+
* Hook to get components registered to a specific slot
|
|
591
|
+
*/
|
|
592
|
+
declare function useSlot(name: string): SlotRegistration[];
|
|
593
|
+
/**
|
|
594
|
+
* Hook to check if a slot has any components
|
|
595
|
+
*/
|
|
596
|
+
declare function useHasSlot(name: string): boolean;
|
|
597
|
+
/**
|
|
598
|
+
* Props for the KuckitSlot component
|
|
599
|
+
*/
|
|
600
|
+
interface KuckitSlotProps {
|
|
601
|
+
/** The name of the slot to render */
|
|
602
|
+
name: string;
|
|
603
|
+
/** Content to show when no components are registered */
|
|
604
|
+
fallback?: ReactNode;
|
|
605
|
+
/** CSS class name for the wrapper element */
|
|
606
|
+
wrapperClassName?: string;
|
|
607
|
+
/** Tag name for the wrapper element (default: none, renders fragments) */
|
|
608
|
+
wrapperTag?: keyof JSX.IntrinsicElements;
|
|
609
|
+
/** Additional props to pass to all slot components */
|
|
610
|
+
slotProps?: Record<string, unknown>;
|
|
611
|
+
}
|
|
612
|
+
/**
|
|
613
|
+
* Component that renders all components registered to a named slot
|
|
614
|
+
*
|
|
615
|
+
* @example
|
|
616
|
+
* ```tsx
|
|
617
|
+
* // In host app layout
|
|
618
|
+
* <KuckitSlot name="dashboard.widgets" />
|
|
619
|
+
*
|
|
620
|
+
* // With fallback
|
|
621
|
+
* <KuckitSlot name="settings.tabs" fallback={<EmptyState />} />
|
|
622
|
+
*
|
|
623
|
+
* // With wrapper
|
|
624
|
+
* <KuckitSlot name="nav.items" wrapperTag="nav" wrapperClassName="flex gap-2" />
|
|
625
|
+
* ```
|
|
626
|
+
*/
|
|
627
|
+
declare function KuckitSlot({
|
|
628
|
+
name,
|
|
629
|
+
fallback,
|
|
630
|
+
wrapperClassName,
|
|
631
|
+
wrapperTag,
|
|
632
|
+
slotProps
|
|
633
|
+
}: KuckitSlotProps): ReactNode;
|
|
634
|
+
//#endregion
|
|
635
|
+
//#region src/rpc-context.d.ts
|
|
636
|
+
/**
|
|
637
|
+
* Provider component for Kuckit RPC client
|
|
638
|
+
*/
|
|
639
|
+
interface KuckitRpcProviderProps {
|
|
640
|
+
/** The oRPC client instance */
|
|
641
|
+
client: unknown;
|
|
642
|
+
children: ReactNode;
|
|
643
|
+
}
|
|
644
|
+
declare function KuckitRpcProvider({
|
|
645
|
+
client,
|
|
646
|
+
children
|
|
647
|
+
}: KuckitRpcProviderProps): ReactNode;
|
|
648
|
+
/**
|
|
649
|
+
* Hook to access the RPC client
|
|
650
|
+
*
|
|
651
|
+
* @example
|
|
652
|
+
* ```tsx
|
|
653
|
+
* import { useRpc } from '@kuckit/sdk-react'
|
|
654
|
+
* import type { AppRouterClient } from '@kuckit/api/routers/index'
|
|
655
|
+
*
|
|
656
|
+
* function MyComponent() {
|
|
657
|
+
* const rpc = useRpc<AppRouterClient>()
|
|
658
|
+
* const result = await rpc.myRouter.myProcedure({ input: 'value' })
|
|
659
|
+
* }
|
|
660
|
+
* ```
|
|
661
|
+
*/
|
|
662
|
+
declare function useRpc<T = unknown>(): T;
|
|
663
|
+
/**
|
|
664
|
+
* Hook to check if RPC client is available
|
|
665
|
+
*/
|
|
666
|
+
declare function useHasRpc(): boolean;
|
|
667
|
+
//#endregion
|
|
668
|
+
export { type BuiltInCapability, ClientModuleRegistry, type ClientModuleSpec, type ComponentRegistry, type KuckitClientModuleContext, type KuckitClientModuleDefinition, type KuckitClientModuleHooks, type KuckitClientModuleMeta, KuckitNavProvider, KuckitRpcProvider, type KuckitRpcProviderProps, KuckitSlot, type KuckitSlotProps, KuckitSlotProvider, type KuckitSlotProviderProps, type LoadClientModulesOptions, type LoadClientModulesResult, type LoadedClientModule, type LoadedClientModuleInfo, type ModuleCapability, type NavItem, NavRegistry, type NavTreeItem, type RouteDefinition, type RouteMeta, RouteRegistry, type SlotOptions, type SlotRegistration, SlotRegistry, createClientModuleUnloadHandler, createComponentRegistry, createRegistries, defineKuckitClientModule, getClientModuleRegistry, getClientModulesWithCapability, loadKuckitClientModules, resetClientModuleRegistry, useHasRpc, useHasSlot, useKuckitNav, useNavItems, useNavTree, useRpc, useSlot, useSlotRegistry };
|