@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/README.md +131 -40
- package/README.zh-TW.md +172 -16
- package/dist/index.cjs +600 -81
- package/dist/index.d.cts +625 -90
- package/dist/index.d.ts +625 -90
- package/dist/index.js +596 -81
- package/package.json +8 -6
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
|
|
4
|
+
* @fileoverview Type definitions for Inertia v2 protocol features.
|
|
5
5
|
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
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
|
|
19
|
-
*
|
|
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
|
|
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
|
-
*
|
|
204
|
+
* Encapsulates performance and status metrics for a single render operation.
|
|
29
205
|
*
|
|
30
|
-
*
|
|
31
|
-
*
|
|
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
|
-
*
|
|
36
|
-
*
|
|
37
|
-
*
|
|
38
|
-
*
|
|
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
|
-
*
|
|
297
|
+
* Initializes a new instance of the Inertia service.
|
|
48
298
|
*
|
|
49
|
-
* @param context - The Gravito request context
|
|
50
|
-
* @param config -
|
|
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
|
-
*
|
|
304
|
+
* Internal logging helper that respects the configured log level.
|
|
55
305
|
*
|
|
56
|
-
*
|
|
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
|
-
*
|
|
61
|
-
*
|
|
62
|
-
*
|
|
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
|
-
*
|
|
65
|
-
*
|
|
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
|
-
*
|
|
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
|
-
* @
|
|
72
|
-
*
|
|
73
|
-
*
|
|
74
|
-
*
|
|
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
|
-
*
|
|
79
|
-
*
|
|
80
|
-
*
|
|
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?:
|
|
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
|
-
*
|
|
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
|
|
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 -
|
|
91
|
-
* @param 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
|
-
*
|
|
96
|
-
* inertia.share('auth', { user: ctx.get('
|
|
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
|
-
*
|
|
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
|
-
* @
|
|
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
|
-
*
|
|
394
|
+
* Returns a shallow copy of the current shared props.
|
|
109
395
|
*
|
|
110
|
-
*
|
|
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
|
-
*
|
|
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
|
-
*
|
|
119
|
-
* single-page applications
|
|
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
|
-
*
|
|
127
|
-
*
|
|
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
|
|
132
|
-
*
|
|
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
|
-
* //
|
|
135
|
-
* ctx.get('inertia').
|
|
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
|
-
*
|
|
142
|
-
*
|
|
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
|
|
145
|
-
* @param
|
|
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
|
-
/**
|
|
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
|
-
/**
|
|
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
|
-
/**
|
|
156
|
-
|
|
157
|
-
|
|
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
|
-
*
|
|
162
|
-
*
|
|
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
|
-
/**
|
|
166
|
-
|
|
167
|
-
|
|
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
|
-
*
|
|
174
|
-
*
|
|
175
|
-
*
|
|
176
|
-
*
|
|
177
|
-
*
|
|
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
|
|
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
|
-
*
|
|
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 };
|