@gravito/ion 3.0.1 → 4.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 CHANGED
@@ -1,201 +1,736 @@
1
1
  import { GravitoContext, GravitoVariables, GravitoOrbit, PlanetCore } from '@gravito/core';
2
2
 
3
3
  /**
4
- * @fileoverview Inertia.js Service for Gravito
4
+ * @fileoverview Type definitions for Inertia v2 protocol features.
5
5
  *
6
- * Provides server-side Inertia.js integration for building modern
7
- * single-page applications with server-side routing.
6
+ * This module provides type definitions for advanced Inertia features:
7
+ * - Deferred Props: Delay loading of specific props to initial render
8
+ * - Merge Props: Replace, prepend, or deep-merge props during partial reloads
9
+ * - History Encryption: Control browser history handling
10
+ * - Error Bags: Organize form validation errors by category
11
+ *
12
+ * @module @gravito/ion/types
13
+ */
14
+ /**
15
+ * Marks a prop for deferred loading.
16
+ *
17
+ * Deferred props are not executed during the initial page render, but are listed
18
+ * in the `deferredProps` field of the Inertia page object. The client fetches them
19
+ * separately after the initial render is complete.
20
+ *
21
+ * @template T - Type of the deferred value (inferred from factory return type).
22
+ *
23
+ * @example
24
+ * ```typescript
25
+ * inertia.render('Dashboard', {
26
+ * user: { id: 1, name: 'Carl' },
27
+ * // Heavy computation deferred to later
28
+ * slowStats: InertiaService.defer(() => calculateStats()),
29
+ * // Grouped deferred props
30
+ * notifications: InertiaService.defer(
31
+ * () => fetchNotifications(),
32
+ * 'notifications-group'
33
+ * )
34
+ * });
35
+ * ```
36
+ */
37
+ interface DeferredPropDefinition<T = unknown> {
38
+ readonly _type: 'deferred';
39
+ readonly factory: () => T | Promise<T>;
40
+ readonly group?: string;
41
+ }
42
+ /**
43
+ * Marks a prop for merging rather than replacement.
44
+ *
45
+ * Used during partial reloads (X-Inertia-Partial-Data) to control how props
46
+ * are combined with existing data on the client:
47
+ * - `merge`: Shallow merge at top level
48
+ * - `prepend`: Add items to the beginning of an array
49
+ * - `deepMerge`: Recursive merge for nested objects
50
+ *
51
+ * @template T - Type of the prop value.
52
+ *
53
+ * @example
54
+ * ```typescript
55
+ * inertia.render('Products/List', {
56
+ * // Deep merge filters with existing data
57
+ * filters: InertiaService.deepMerge({ status: 'active', price: 100 }),
58
+ * // Prepend new items to the beginning of the list
59
+ * items: InertiaService.prepend([newProduct]),
60
+ * // Shallow merge config with existing data
61
+ * config: InertiaService.merge({ sortBy: 'name' })
62
+ * });
63
+ * ```
64
+ */
65
+ interface MergedPropDefinition<T = unknown> {
66
+ readonly _type: 'merge' | 'prepend' | 'deepMerge';
67
+ readonly value: T;
68
+ readonly matchOn?: string | string[];
69
+ }
70
+ /**
71
+ * Configuration for error bags in form validation.
72
+ *
73
+ * Organizes form validation errors into named categories, allowing multiple
74
+ * validation failure scenarios to coexist (e.g., 'default' and 'import-csv').
75
+ *
76
+ * @example
77
+ * ```typescript
78
+ * inertia.withErrors({
79
+ * email: 'Email is required',
80
+ * password: 'Must be at least 8 characters'
81
+ * }, 'login'); // Bag name: 'login'
82
+ *
83
+ * inertia.withErrors({
84
+ * line_1: 'Invalid CSV at row 1',
85
+ * line_2: 'Invalid CSV at row 2'
86
+ * }, 'import'); // Bag name: 'import'
87
+ * ```
88
+ */
89
+ interface ErrorBagDefinition {
90
+ readonly bag: string;
91
+ readonly errors: Record<string, string | string[]>;
92
+ }
93
+ /**
94
+ * Inertia page object structure for the initial render response.
95
+ *
96
+ * This is the JSON structure sent to the frontend containing component metadata
97
+ * and all resolved props. Extended with Inertia v2 features.
98
+ *
99
+ * @template P - Shape of the props object.
100
+ */
101
+ interface InertiaPageObject<P extends Record<string, unknown> = Record<string, unknown>> {
102
+ /** Frontend component name (e.g., 'Pages/Dashboard') */
103
+ component: string;
104
+ /** Resolved and merged props for the component */
105
+ props: P;
106
+ /** Current URL without query string */
107
+ url: string;
108
+ /** Asset version (cache-busting identifier) */
109
+ version?: string;
110
+ /** Deferred prop groups and their factories (Inertia v2) */
111
+ deferredProps?: Record<string, string[]>;
112
+ /** Keys marked for merge/prepend/deepMerge (Inertia v2) */
113
+ mergeProps?: {
114
+ keys: string[];
115
+ mode: 'merge' | 'prepend' | 'deepMerge';
116
+ }[];
117
+ /** Whether to encrypt browser history (Inertia v2) */
118
+ encryptHistory?: boolean;
119
+ /** Whether to clear browser history (Inertia v2) */
120
+ clearHistory?: boolean;
121
+ /** Error bags organized by category (Inertia v2) */
122
+ errorBags?: Record<string, Record<string, string | string[]>>;
123
+ }
124
+ /**
125
+ * Inertia response metadata for partial reloads.
126
+ *
127
+ * Controls how the frontend should process the props update:
128
+ * - Handles reset scenarios (X-Inertia-Reset header)
129
+ * - Tracks which keys should be reset to undefined
130
+ */
131
+ interface PartialReloadMetadata {
132
+ /** Keys to reset to undefined before merging new props */
133
+ resetKeys?: string[];
134
+ /** Merge strategy for the reload response */
135
+ mergeStrategy?: 'replace' | 'merge' | 'deepMerge';
136
+ }
137
+
138
+ /**
139
+ * @fileoverview Inertia.js Service for Gravito.
140
+ *
141
+ * This service implements the Inertia.js server-side protocol, enabling
142
+ * seamless page transitions and data synchronization for monolith SPAs.
8
143
  *
9
144
  * @module @gravito/ion
10
- * @since 1.0.0
11
145
  */
12
146
 
13
147
  /**
14
- * Configuration options for InertiaService
148
+ * Configuration options for the InertiaService instance.
149
+ *
150
+ * Defines how the service interacts with the root template, manages asset versioning,
151
+ * and handles Server-Side Rendering (SSR).
15
152
  */
16
153
  interface InertiaConfig {
17
154
  /**
18
- * The root view template name
19
- * @default 'app'
155
+ * The name of the root view template used for the initial page load.
156
+ *
157
+ * This template must contain the `{{{ page }}}` placeholder to inject the
158
+ * Inertia page object.
159
+ *
160
+ * @defaultValue 'app'
20
161
  */
21
162
  rootView?: string;
22
163
  /**
23
- * Asset version for cache busting
164
+ * Asset version string or resolver.
165
+ *
166
+ * Used by Inertia to detect if the client-side assets are out of sync with the server.
167
+ * If the version sent by the client (X-Inertia-Version) doesn't match, the server
168
+ * triggers a full page reload via a 409 Conflict response.
24
169
  */
25
- version?: string;
170
+ version?: string | (() => string | Promise<string>);
171
+ /**
172
+ * Minimum logging level for internal operations.
173
+ *
174
+ * @defaultValue 'info'
175
+ */
176
+ logLevel?: 'debug' | 'info' | 'warn' | 'error' | 'silent';
177
+ /**
178
+ * Performance monitoring callback triggered after each render.
179
+ *
180
+ * Useful for tracking rendering latency and prop payload sizes in production.
181
+ */
182
+ onRender?: (metrics: RenderMetrics) => void;
183
+ /**
184
+ * SSR configuration options.
185
+ *
186
+ * Enables pre-rendering of components on the server to improve SEO and
187
+ * initial load performance.
188
+ */
189
+ ssr?: {
190
+ /** Whether SSR is enabled for the current environment. */
191
+ enabled: boolean;
192
+ /**
193
+ * Function to handle SSR rendering.
194
+ *
195
+ * Should interface with your frontend framework's SSR renderer (e.g., React's `renderToString`).
196
+ */
197
+ render?: (page: any) => Promise<{
198
+ head: string[];
199
+ body: string;
200
+ }>;
201
+ };
26
202
  }
27
203
  /**
28
- * InertiaService - Server-side Inertia.js adapter
204
+ * Encapsulates performance and status metrics for a single render operation.
29
205
  *
30
- * This service handles the Inertia.js protocol for seamless
31
- * SPA-like navigation with server-side routing.
206
+ * Provides insights into the rendering lifecycle, including component name,
207
+ * execution time, and payload complexity.
208
+ */
209
+ interface RenderMetrics {
210
+ /** Name of the frontend component rendered. */
211
+ component: string;
212
+ /** Time taken in milliseconds for the entire render lifecycle. */
213
+ duration: number;
214
+ /** Indicates if the request was an Inertia AJAX request (true) or a full page load (false). */
215
+ isInertiaRequest: boolean;
216
+ /** Number of top-level props passed to the component after resolution. */
217
+ propsCount: number;
218
+ /** Epoch timestamp of when the operation completed. */
219
+ timestamp: number;
220
+ /** Resulting HTTP status code of the response. */
221
+ status?: number;
222
+ }
223
+ /**
224
+ * Server-side adapter for the Inertia.js protocol.
225
+ *
226
+ * The `InertiaService` is responsible for:
227
+ * 1. Resolving component props (including lazy/async props).
228
+ * 2. Handling partial reloads (filtering props based on `X-Inertia-Partial-Data`).
229
+ * 3. Managing asset versioning to ensure client-server synchronization.
230
+ * 4. Orchestrating SSR pre-rendering when enabled.
231
+ * 5. Generating the final HTTP response (JSON for AJAX, HTML for initial load).
32
232
  *
33
233
  * @example
34
234
  * ```typescript
35
- * // In a controller
36
- * async index(ctx: GravitoContext) {
37
- * const inertia = ctx.get('inertia') as InertiaService
38
- * return inertia.render('Home', { users: await User.all() })
39
- * }
235
+ * const inertia = new InertiaService(ctx, {
236
+ * version: () => getGitHash(),
237
+ * rootView: 'main'
238
+ * });
239
+ *
240
+ * // Share global data
241
+ * inertia.share('user', ctx.get('user'));
242
+ *
243
+ * // Render a component
244
+ * return await inertia.render('Dashboard/Index', {
245
+ * stats: async () => await fetchStats() // Lazy prop
246
+ * });
40
247
  * ```
41
248
  */
42
249
  declare class InertiaService {
43
250
  private context;
44
251
  private config;
45
252
  private sharedProps;
253
+ private errorBags;
254
+ private encryptHistoryFlag;
255
+ private clearHistoryFlag;
256
+ private readonly logLevel;
257
+ private readonly onRenderCallback?;
258
+ /**
259
+ * Creates a deferred prop that will be loaded after the initial render.
260
+ *
261
+ * @param factory - Function that resolves to the prop value.
262
+ * @param group - Optional group name for organizing deferred props.
263
+ * @returns A deferred prop definition.
264
+ *
265
+ * @example
266
+ * ```typescript
267
+ * props: {
268
+ * user: { id: 1 },
269
+ * stats: InertiaService.defer(() => fetchStats())
270
+ * }
271
+ * ```
272
+ */
273
+ static defer<T = unknown>(factory: () => T | Promise<T>, group?: string): DeferredPropDefinition<T>;
274
+ /**
275
+ * Marks a prop to be merged (shallow) with existing data during partial reloads.
276
+ *
277
+ * @param value - The prop value to merge.
278
+ * @param matchOn - Optional key(s) to match on when merging arrays.
279
+ * @returns A merge prop definition.
280
+ */
281
+ static merge<T = unknown>(value: T, matchOn?: string | string[]): MergedPropDefinition<T>;
282
+ /**
283
+ * Marks a prop to prepend to an array during partial reloads.
284
+ *
285
+ * @param value - The prop value to prepend.
286
+ * @returns A prepend prop definition.
287
+ */
288
+ static prepend<T = unknown>(value: T): MergedPropDefinition<T>;
289
+ /**
290
+ * Marks a prop to be deep-merged with existing data during partial reloads.
291
+ *
292
+ * @param value - The prop value to deep merge.
293
+ * @returns A deep merge prop definition.
294
+ */
295
+ static deepMerge<T = unknown>(value: T): MergedPropDefinition<T>;
46
296
  /**
47
- * Create a new InertiaService instance
297
+ * Initializes a new instance of the Inertia service.
48
298
  *
49
- * @param context - The Gravito request context
50
- * @param config - Optional configuration
299
+ * @param context - The current Gravito request context.
300
+ * @param config - Instance configuration options.
51
301
  */
52
302
  constructor(context: GravitoContext<GravitoVariables>, config?: InertiaConfig);
53
303
  /**
54
- * Escape a string for safe use in HTML attributes
304
+ * Internal logging helper that respects the configured log level.
55
305
  *
56
- * Strategy: JSON.stringify already escapes special characters including
57
- * quotes as \". We need to escape these for HTML attributes, but we must
58
- * be careful not to break JSON escape sequences.
306
+ * Routes logs to the Gravito context logger if available.
59
307
  *
60
- * The solution: Escape backslash-quote sequences (\" from JSON.stringify)
61
- * as \\&quot; so they become \\&quot; in HTML, which the browser decodes
62
- * to \\" (valid JSON), not \&quot; (invalid JSON).
308
+ * @param level - Log severity level.
309
+ * @param message - Descriptive message.
310
+ * @param data - Optional metadata for the log.
311
+ */
312
+ private log;
313
+ /**
314
+ * Escapes a string for safe embedding into a single-quoted HTML attribute.
63
315
  *
64
- * @param value - The string to escape.
65
- * @returns The escaped string.
316
+ * This ensures that JSON strings can be safely passed to the frontend
317
+ * via the `data-page` attribute without breaking the HTML structure or
318
+ * introducing XSS vulnerabilities.
319
+ *
320
+ * @param value - Raw JSON or text string.
321
+ * @returns Safely escaped HTML attribute value.
66
322
  */
67
323
  private escapeForSingleQuotedHtmlAttribute;
68
324
  /**
69
- * Render an Inertia component
325
+ * Renders an Inertia component and returns the appropriate HTTP response.
326
+ *
327
+ * This method handles the entire Inertia lifecycle:
328
+ * - Detects if the request is an Inertia AJAX request.
329
+ * - Validates asset versions.
330
+ * - Resolves props (executes functions, handles partial reloads).
331
+ * - Performs SSR if configured.
332
+ * - Wraps the result in a JSON response or the root HTML template.
333
+ *
334
+ * @param component - Frontend component name (e.g., 'Users/Profile').
335
+ * @param props - Data passed to the component. Can include functions for lazy evaluation.
336
+ * @param rootVars - Variables passed to the root HTML template (only used on initial load).
337
+ * @param status - Optional HTTP status code.
338
+ * @returns A promise that resolves to a Gravito HTTP Response.
70
339
  *
71
- * @param component - The component name to render
72
- * @param props - Props to pass to the component
73
- * @param rootVars - Additional variables for the root template
74
- * @returns HTTP Response
340
+ * @throws {@link InertiaError}
341
+ * Thrown if:
342
+ * - The `ViewService` is missing from the context (required for initial load).
343
+ * - Prop serialization fails due to circular references or non-serializable data.
75
344
  *
76
345
  * @example
77
346
  * ```typescript
78
- * return inertia.render('Users/Index', {
79
- * users: await User.all(),
80
- * filters: { search: ctx.req.query('search') }
81
- * })
347
+ * // Standard render
348
+ * return await inertia.render('Welcome', { name: 'Guest' });
349
+ *
350
+ * // Partial reload support (only 'stats' will be resolved if requested)
351
+ * return await inertia.render('Dashboard', {
352
+ * user: auth.user,
353
+ * stats: () => db.getStats()
354
+ * });
82
355
  * ```
83
356
  */
84
- render(component: string, props?: Record<string, unknown>, rootVars?: Record<string, unknown>): Response;
357
+ render<T extends Record<string, unknown> = Record<string, unknown>>(component: string, props?: T, rootVars?: Record<string, unknown>, status?: number): Promise<Response>;
85
358
  /**
86
- * Share data with all Inertia responses
359
+ * Registers a piece of data to be shared with all Inertia responses for the current request.
87
360
  *
88
- * Shared props are merged with component-specific props on every render.
361
+ * Shared props are automatically merged with component-specific props during the render phase.
362
+ * This is the primary mechanism for providing global state like authentication details,
363
+ * flash messages, or configuration to the frontend.
89
364
  *
90
- * @param key - The prop key
91
- * @param value - The prop value
365
+ * @param key - Identifier for the shared prop.
366
+ * @param value - Value to share. Must be JSON serializable.
92
367
  *
93
368
  * @example
94
369
  * ```typescript
95
- * // In middleware
96
- * inertia.share('auth', { user: ctx.get('auth')?.user() })
97
- * inertia.share('flash', ctx.get('session')?.getFlash('message'))
370
+ * inertia.share('appName', 'Gravito Store');
371
+ * inertia.share('auth', { user: ctx.get('user') });
98
372
  * ```
99
373
  */
100
374
  share(key: string, value: unknown): void;
101
375
  /**
102
- * Share multiple props at once
376
+ * Shares multiple props in a single operation.
377
+ *
378
+ * Merges the provided object into the existing shared props state. Existing keys
379
+ * with the same name will be overwritten.
380
+ *
381
+ * @param props - Object containing key-value pairs to merge into the shared state.
103
382
  *
104
- * @param props - Object of props to share
383
+ * @example
384
+ * ```typescript
385
+ * inertia.shareAll({
386
+ * version: '1.2.0',
387
+ * environment: 'production',
388
+ * features: ['chat', 'search']
389
+ * });
390
+ * ```
105
391
  */
106
392
  shareAll(props: Record<string, unknown>): void;
107
393
  /**
108
- * Get all shared props
394
+ * Returns a shallow copy of the current shared props.
109
395
  *
110
- * @returns A shallow copy of the shared props object.
396
+ * Useful for inspecting the shared state or for manual prop merging in advanced scenarios.
397
+ *
398
+ * @returns A dictionary containing all currently registered shared props.
399
+ *
400
+ * @example
401
+ * ```typescript
402
+ * const shared = inertia.getSharedProps();
403
+ * if (!shared.auth) {
404
+ * console.warn('Authentication data is missing from shared props');
405
+ * }
406
+ * ```
111
407
  */
112
408
  getSharedProps(): Record<string, unknown>;
409
+ /**
410
+ * Instructs the Inertia client to navigate to a different URL.
411
+ *
412
+ * For Inertia AJAX requests, this returns a 409 Conflict with the `X-Inertia-Location` header.
413
+ * For regular page loads, this returns a 302 Found redirect.
414
+ *
415
+ * This is useful for server-side redirects triggered by authentication or authorization checks.
416
+ *
417
+ * @param url - The URL to redirect to.
418
+ * @returns A redirect response.
419
+ *
420
+ * @example
421
+ * ```typescript
422
+ * if (!ctx.get('user')) {
423
+ * return inertia.location('/login');
424
+ * }
425
+ * ```
426
+ */
427
+ location(url: string): Response;
428
+ /**
429
+ * Controls whether the Inertia client should encrypt browser history.
430
+ *
431
+ * When enabled, history is not written to the browser's History API,
432
+ * preventing users from using the browser back button to return to previous pages.
433
+ *
434
+ * @param encrypt - Whether to encrypt history (defaults to true).
435
+ * @returns The service instance for method chaining.
436
+ *
437
+ * @example
438
+ * ```typescript
439
+ * return await inertia.encryptHistory(true).render('SecurePage');
440
+ * ```
441
+ */
442
+ encryptHistory(encrypt?: boolean): this;
443
+ /**
444
+ * Clears the browser history after the page load.
445
+ *
446
+ * Useful for sensitive operations or multi-step wizards where you don't want
447
+ * users navigating back to previous states.
448
+ *
449
+ * @returns The service instance for method chaining.
450
+ *
451
+ * @example
452
+ * ```typescript
453
+ * return await inertia.clearHistory().render('SuccessPage');
454
+ * ```
455
+ */
456
+ clearHistory(): this;
457
+ /**
458
+ * Registers form validation errors organized into named bags.
459
+ *
460
+ * Error bags allow multiple validation failure scenarios to coexist.
461
+ * For example, you might have 'default' errors and 'import' errors from different forms.
462
+ *
463
+ * @param errors - Validation errors, with field names as keys and error messages as values.
464
+ * @param bag - The error bag name (defaults to 'default').
465
+ * @returns The service instance for method chaining.
466
+ *
467
+ * @example
468
+ * ```typescript
469
+ * inertia.withErrors({
470
+ * email: 'Email is required',
471
+ * password: 'Must be 8+ characters'
472
+ * }, 'login');
473
+ *
474
+ * inertia.withErrors({
475
+ * line_1: 'Invalid CSV format'
476
+ * }, 'import');
477
+ * ```
478
+ */
479
+ withErrors(errors: Record<string, string | string[]>, bag?: string): this;
113
480
  }
114
481
 
115
482
  /**
116
- * @fileoverview Orbit Inertia - Inertia.js integration for Gravito
483
+ * Base error class for all Inertia-related operations in Gravito.
484
+ */
485
+ declare class InertiaError extends Error {
486
+ readonly code: string;
487
+ readonly httpStatus: number;
488
+ readonly details?: Record<string, any> | undefined;
489
+ constructor(code: string, httpStatus?: number, details?: Record<string, any> | undefined);
490
+ toJSON(): {
491
+ name: string;
492
+ code: string;
493
+ httpStatus: number;
494
+ message: string;
495
+ details: Record<string, any> | undefined;
496
+ };
497
+ }
498
+ /**
499
+ * Configuration errors - e.g., missing services.
500
+ */
501
+ declare class InertiaConfigError extends InertiaError {
502
+ constructor(message: string, details?: Record<string, any>);
503
+ }
504
+ /**
505
+ * Data/Serialization errors - e.g., circular references or resolution failure.
506
+ */
507
+ declare class InertiaDataError extends InertiaError {
508
+ constructor(message: string, details?: Record<string, any>);
509
+ }
510
+ /**
511
+ * Template/Rendering errors.
512
+ */
513
+ declare class InertiaTemplateError extends InertiaError {
514
+ constructor(message: string, details?: Record<string, any>);
515
+ }
516
+
517
+ /**
518
+ * @fileoverview Orbit Inertia - Inertia.js integration for Gravito.
117
519
  *
118
- * Provides server-side Inertia.js integration for building modern
119
- * single-page applications with server-side routing.
520
+ * This module provides the core Orbit definition and helper interfaces for
521
+ * building modern single-page applications using server-side routing.
120
522
  *
121
523
  * @module @gravito/ion
122
- * @since 1.0.0
123
524
  */
124
525
 
125
526
  /**
126
- * InertiaHelper is a callable function and service suite injected into the Gravito context.
127
- * It allows you to render Inertia components directly or manage shared data.
527
+ * Enhanced helper interface for Inertia operations within the Gravito context.
528
+ *
529
+ * This interface is both a callable function for quick rendering and a
530
+ * service container for managing shared data and accessing the underlying service.
531
+ * It is typically accessed via `ctx.get('inertia')`.
128
532
  *
129
533
  * @example
130
534
  * ```typescript
131
- * // Direct call rendering
132
- * return ctx.get('inertia')('Welcome', { user });
535
+ * // 1. Direct rendering (Callable)
536
+ * export const index = async (ctx: Context) => {
537
+ * return await ctx.get('inertia')('Home', { title: 'Welcome' });
538
+ * };
539
+ *
540
+ * // 2. Sharing global data
541
+ * ctx.get('inertia').share('app_name', 'My Project');
133
542
  *
134
- * // Using shared data
135
- * ctx.get('inertia').share('appName', 'Gravito App');
543
+ * // 3. Accessing the underlying service
544
+ * const service = ctx.get('inertia').service;
136
545
  * ```
137
- * @public
138
546
  */
139
547
  interface InertiaHelper {
140
548
  /**
141
- * Render an Inertia component.
142
- * Shortcut for context.get('inertia').render()
549
+ * Renders an Inertia component.
550
+ *
551
+ * This is a shortcut for calling `render()` on the underlying service.
552
+ *
553
+ * @param component - Frontend component name (e.g., 'Pages/Dashboard').
554
+ * @param props - Data object passed to the component. Supports lazy/async props.
555
+ * @param rootVars - Variables passed to the root HTML template (initial load only).
556
+ * @param status - Optional HTTP status code (defaults to 200).
557
+ * @returns A promise resolving to a Gravito-compatible HTTP Response.
558
+ *
559
+ * @throws {@link InertiaError}
560
+ * Thrown if serialization fails or the ViewService is missing during initial load.
561
+ */
562
+ <T extends Record<string, unknown> = Record<string, unknown>>(component: string, props?: T, rootVars?: Record<string, unknown>, status?: number): Promise<Response>;
563
+ /**
564
+ * Shares a single piece of data with all subsequent Inertia responses for this request.
143
565
  *
144
- * @param component - The name of the frontend component (e.g., 'Pages/Home')
145
- * @param props - Data to pass to the component
146
- * @param rootVars - Variables for the root HTML template (e.g., meta tags)
566
+ * @param key - Unique identifier for the shared prop.
567
+ * @param value - Data value. Must be JSON serializable.
147
568
  */
148
- (component: string, props?: Record<string, unknown>, rootVars?: Record<string, unknown>): Response;
149
- /** Share data with all Inertia responses for the remainder of the request */
150
569
  share(key: string, value: unknown): void;
151
- /** Share multiple props at once */
570
+ /**
571
+ * Shares multiple props simultaneously by merging them into the shared state.
572
+ *
573
+ * @param props - Key-value pairs to merge into shared props.
574
+ */
152
575
  shareAll(props: Record<string, unknown>): void;
153
- /** Get all currently shared props */
576
+ /**
577
+ * Retrieves a copy of all currently shared props for the current request.
578
+ *
579
+ * @returns Current shared props dictionary.
580
+ */
154
581
  getSharedProps(): Record<string, unknown>;
155
- /** Explicitly render an Inertia component */
156
- render(component: string, props?: Record<string, unknown>, rootVars?: Record<string, unknown>): Response;
157
- /** Direct access to the low-level Inertia service instance */
582
+ /**
583
+ * Explicitly renders an Inertia component.
584
+ *
585
+ * Identical to the callable interface but provided for semantic clarity.
586
+ *
587
+ * @param component - Frontend component name.
588
+ * @param props - Component data.
589
+ * @param rootVars - Template variables.
590
+ * @param status - HTTP status code.
591
+ * @returns A promise resolving to an HTTP Response.
592
+ *
593
+ * @throws {@link InertiaError}
594
+ * Thrown if the rendering lifecycle encounters a fatal error.
595
+ */
596
+ render<T extends Record<string, unknown> = Record<string, unknown>>(component: string, props?: T, rootVars?: Record<string, unknown>, status?: number): Promise<Response>;
597
+ /**
598
+ * Instructs the client to navigate to a different URL.
599
+ *
600
+ * @param url - The URL to navigate to.
601
+ * @returns A redirect response.
602
+ */
603
+ location(url: string): Response;
604
+ /**
605
+ * Encrypts the browser history to prevent navigation via back button.
606
+ *
607
+ * @param encrypt - Whether to enable history encryption (defaults to true).
608
+ * @returns The helper for method chaining.
609
+ */
610
+ encryptHistory(encrypt?: boolean): InertiaHelper;
611
+ /**
612
+ * Clears the browser history after page load.
613
+ *
614
+ * @returns The helper for method chaining.
615
+ */
616
+ clearHistory(): InertiaHelper;
617
+ /**
618
+ * Registers form validation errors organized by bag name.
619
+ *
620
+ * @param errors - Error map with field names as keys.
621
+ * @param bag - The error bag name (defaults to 'default').
622
+ * @returns The helper for method chaining.
623
+ */
624
+ withErrors(errors: Record<string, string | string[]>, bag?: string): InertiaHelper;
625
+ /**
626
+ * Direct access to the low-level `InertiaService` instance.
627
+ *
628
+ * Use this for advanced operations not exposed by the helper interface.
629
+ */
158
630
  service: InertiaService;
159
631
  }
160
632
  /**
161
- * Options for configuring OrbitIon.
162
- * @public
633
+ * Configuration options for the OrbitIon extension.
634
+ *
635
+ * Controls how the Inertia protocol is integrated into the Gravito ecosystem.
163
636
  */
164
637
  interface OrbitIonOptions {
165
- /** Current asset version to detect staleness (X-Inertia-Version) */
166
- version?: string;
167
- /** The root HTML template view (default: 'app') */
638
+ /**
639
+ * Asset version string or resolver used for cache busting.
640
+ *
641
+ * If not provided, it defaults to the `APP_VERSION` defined in the core configuration.
642
+ *
643
+ * @defaultValue '1.0.0'
644
+ */
645
+ version?: string | (() => string | Promise<string>);
646
+ /**
647
+ * The name of the root HTML template file (without extension).
648
+ *
649
+ * This template is used for the initial page load.
650
+ *
651
+ * @defaultValue 'app'
652
+ */
168
653
  rootView?: string;
654
+ /**
655
+ * SSR configuration options.
656
+ *
657
+ * Enables server-side pre-rendering of components.
658
+ */
659
+ ssr?: {
660
+ /** Whether SSR is enabled for this application. */
661
+ enabled: boolean;
662
+ /**
663
+ * Function to handle SSR rendering.
664
+ *
665
+ * Receives the Inertia page object and should return the rendered HTML.
666
+ */
667
+ render?: (page: any) => Promise<{
668
+ head: string[];
669
+ body: string;
670
+ }>;
671
+ };
672
+ /**
673
+ * CSRF protection configuration.
674
+ *
675
+ * Automatically sets the XSRF-TOKEN cookie for CSRF protection.
676
+ *
677
+ * @defaultValue { enabled: true, cookieName: 'XSRF-TOKEN' }
678
+ */
679
+ csrf?: {
680
+ /** Whether CSRF protection is enabled. */
681
+ enabled?: boolean;
682
+ /** Name of the CSRF token cookie (commonly read by Axios). */
683
+ cookieName?: string;
684
+ };
169
685
  }
170
686
  /**
171
687
  * OrbitIon provides official Inertia.js integration for Gravito.
172
688
  *
173
- * It handles Inertia requests, partial reloads, asset versioning, and seamless
174
- * data sharing between the server and your frontend application (React, Vue, etc.).
175
- *
176
- * It injects an `InertiaHelper` into the context, allowing you to render
177
- * components with a simple function call: `c.get('inertia')('Page', { props })`.
689
+ * As an infrastructure extension (Orbit), it:
690
+ * 1. Registers a global middleware to handle the Inertia protocol.
691
+ * 2. Manages asset version synchronization (X-Inertia-Version).
692
+ * 3. Injects the `InertiaHelper` into the request context for easy access in controllers.
693
+ * 4. Supports partial reloads and SSR out of the box.
178
694
  *
179
695
  * @example
180
696
  * ```typescript
181
697
  * import { OrbitIon } from '@gravito/ion';
182
698
  *
699
+ * // In your application bootstrap
183
700
  * core.addOrbit(new OrbitIon({
184
- * version: '1.0.0',
185
- * rootView: 'app'
701
+ * version: 'v2.1.0',
702
+ * rootView: 'layouts/app',
703
+ * ssr: {
704
+ * enabled: process.env.SSR === 'true',
705
+ * render: async (page) => await mySsrRenderer(page)
706
+ * }
186
707
  * }));
187
708
  * ```
188
- *
189
- * @public
190
- * @since 3.0.0
191
709
  */
192
710
  declare class OrbitIon implements GravitoOrbit {
193
711
  private options;
712
+ /**
713
+ * Initializes the Orbit with custom configuration.
714
+ *
715
+ * @param options - Configuration overrides for the Inertia service.
716
+ */
194
717
  constructor(options?: OrbitIonOptions);
195
718
  /**
196
- * Install the inertia orbit into PlanetCore
719
+ * Registers the Inertia middleware and service factory into PlanetCore.
720
+ *
721
+ * This method is called automatically by Gravito during the boot process.
722
+ * It sets up the `InertiaService` for each request and attaches
723
+ * the `InertiaHelper` proxy to the context.
724
+ *
725
+ * @param core - The Gravito micro-kernel instance.
726
+ *
727
+ * @example
728
+ * ```typescript
729
+ * const ion = new OrbitIon({ version: '1.0' });
730
+ * ion.install(core);
731
+ * ```
197
732
  */
198
733
  install(core: PlanetCore): void;
199
734
  }
200
735
 
201
- export { type InertiaConfig, type InertiaHelper, InertiaService, OrbitIon, type OrbitIonOptions, OrbitIon as default };
736
+ export { type DeferredPropDefinition, type ErrorBagDefinition, type InertiaConfig, InertiaConfigError, InertiaDataError, InertiaError, type InertiaHelper, type InertiaPageObject, InertiaService, InertiaTemplateError, type MergedPropDefinition, OrbitIon, type OrbitIonOptions, type PartialReloadMetadata, type RenderMetrics, OrbitIon as default };