@adonisjs/inertia
Version:
Official Inertia.js adapter for AdonisJS
277 lines (276 loc) • 10.3 kB
TypeScript
import { type AsyncOrSync } from '@adonisjs/core/types/common';
import { type DeferProp, type PageProps, type AlwaysProp, type OptionalProp, type MergeableProp, type ComponentProps, type UnPackedPageProps } from './types.ts';
import { type ContainerResolver } from '@adonisjs/core/container';
/**
* Creates a deferred prop that is never included in standard visits but must be shared with
* the client during standard visits. Can be explicitly requested and supports merging.
*
* Deferred props are useful for expensive computations that should only be loaded when
* specifically requested by the client.
*
* @param fn - Function that computes the prop value when requested
* @returns A deferred prop object with compute and merge capabilities
*
* @example
* ```javascript
* // Create a deferred prop for expensive user statistics
* const userStats = defer(() => {
* return calculateExpensiveUserStats(userId)
* })
*
* // Use in page props
* return inertia.render('dashboard', {
* user: user,
* stats: userStats // Only loaded when explicitly requested
* })
* ```
*/
export declare function defer<T extends UnPackedPageProps>(fn: () => AsyncOrSync<T>, group?: string): DeferProp<T>;
/**
* Creates an optional prop that is never included in standard visits and can only be
* explicitly requested by the client. Unlike deferred props, optional props are not
* shared with the client during standard visits.
*
* Optional props are ideal for data that is rarely needed and should only be loaded
* on demand to optimize performance.
*
* @param fn - Function that computes the prop value when requested
* @returns An optional prop object that computes values lazily
*
* @example
* ```javascript
* // Create an optional prop for detailed audit logs
* const auditLogs = optional(() => {
* return fetchDetailedAuditLogs(resourceId)
* })
*
* // Use in page props
* return inertia.render('resource/show', {
* resource: resource,
* auditLogs: auditLogs // Only loaded when explicitly requested
* })
* ```
*/
export declare function optional<T extends UnPackedPageProps>(fn: () => AsyncOrSync<T>): OptionalProp<T>;
/**
* Creates a prop that is always included in responses and cannot be removed during
* cherry-picking. This ensures the prop is always available to the frontend component.
*
* Always props are useful for critical data that the frontend component must have
* to function properly, regardless of what props are specifically requested.
*
* @param value - The value to always include in the response
* @returns An always prop object that cannot be cherry-picked away
*
* @example
* ```javascript
* // Create an always prop for critical user permissions
* const userPermissions = always(user.permissions)
*
* // Use in page props
* return inertia.render('admin/dashboard', {
* users: users,
* permissions: userPermissions // Always included, never filtered out
* })
* ```
*/
export declare function always<T extends UnPackedPageProps>(value: T): AlwaysProp<T>;
/**
* Creates a prop that should be merged with existing props on the page rather than
* replaced. This is useful for incremental updates where you want to combine new
* data with existing data on the client side.
*
* Mergeable props enable efficient partial updates by allowing the client to
* merge new prop values with existing ones instead of replacing them entirely.
*
* @param value - The value to be merged with existing props
* @returns A mergeable prop object marked for merging behavior
*
* @example
* ```javascript
* // Create a mergeable prop for incremental notifications
* const newNotifications = merge([
* { id: 1, message: 'New message received' },
* { id: 2, message: 'Task completed' }
* ])
*
* // Use in page props - will merge with existing notifications
* return inertia.render('dashboard', {
* user: user,
* notifications: newNotifications // Merges with existing notifications array
* })
* ```
*/
export declare function merge<T extends UnPackedPageProps | DeferProp<UnPackedPageProps>>(value: T): MergeableProp<T>;
/**
* Creates a prop that should be deeply merged with existing props on the page.
*
* Unlike shallow merge, deep merge recursively merges nested objects and arrays,
* allowing for more granular updates to complex data structures.
*
* @param value - The value to be deeply merged with existing props
* @returns A mergeable prop object marked for deep merging behavior
*
* @example
* ```javascript
* // Create a deep mergeable prop for nested user settings
* const updatedSettings = deepMerge({
* notifications: {
* email: true,
* push: false
* },
* privacy: {
* profile: 'public'
* }
* })
*
* // Use in page props - will deeply merge with existing settings
* return inertia.render('settings', {
* user: user,
* settings: updatedSettings // Deep merges with existing settings object
* })
* ```
*/
export declare function deepMerge<T extends UnPackedPageProps | DeferProp<UnPackedPageProps>>(value: T): MergeableProp<T>;
/**
* Type guard that checks if a prop value is a deferred prop.
*
* Deferred props contain the DEFERRED_PROP symbol and have compute/merge capabilities.
* This function is useful for runtime type checking and conditional prop handling.
*
* @param propValue - The object to check for deferred prop characteristics
* @returns True if the prop value is a deferred prop
*
* @example
* ```js
* const prop = defer(() => ({ data: 'value' }))
*
* if (isDeferredProp(prop)) {
* // prop is now typed as DeferProp<T>
* const result = prop.compute()
* }
* ```
*/
export declare function isDeferredProp<T extends UnPackedPageProps>(propValue: Object): propValue is DeferProp<T>;
/**
* Type guard that checks if a prop value is a mergeable prop.
*
* Mergeable props contain the TO_BE_MERGED symbol and should be merged with
* existing props rather than replaced during updates.
*
* @param propValue - The object to check for mergeable prop characteristics
* @returns True if the prop value is a mergeable prop
*
* @example
* ```js
* const prop = merge({ items: [1, 2, 3] })
*
* if (isMergeableProp(prop)) {
* // prop is now typed as MergeableProp<T>
* const value = prop.value
* }
* ```
*/
export declare function isMergeableProp<T extends UnPackedPageProps | DeferProp<UnPackedPageProps>>(propValue: Object): propValue is MergeableProp<T>;
/**
* Type guard that checks if a prop value is an always prop.
*
* Always props contain the ALWAYS_PROP symbol and are always included in
* responses, regardless of cherry-picking or selective prop requests.
*
* @param propValue - The object to check for always prop characteristics
* @returns True if the prop value is an always prop
*
* @example
* ```js
* const prop = always({ userId: 123, permissions: ['read', 'write'] })
*
* if (isAlwaysProp(prop)) {
* // prop is now typed as AlwaysProp<T>
* const value = prop.value
* }
* ```
*/
export declare function isAlwaysProp<T extends UnPackedPageProps>(propValue: Object): propValue is AlwaysProp<T>;
/**
* Type guard that checks if a prop value is an optional prop.
*
* Optional props contain the OPTIONAL_PROP symbol and are only included
* when explicitly requested by the client, never in standard visits.
*
* @param propValue - The object to check for optional prop characteristics
* @returns True if the prop value is an optional prop
*
* @example
* ```js
* const prop = optional(() => ({ detailedData: 'expensive computation' }))
*
* if (isOptionalProp(prop)) {
* // prop is now typed as OptionalProp<T>
* const result = prop.compute()
* }
* ```
*/
export declare function isOptionalProp<T extends UnPackedPageProps>(propValue: Object): propValue is OptionalProp<T>;
/**
* Builds props for standard (non-partial) Inertia visits.
*
* This function processes page props and categorizes them based on their type:
* - Deferred props: Skipped but communicated to client
* - Optional props: Skipped entirely
* - Always props: Always included
* - Mergeable props: Included and marked for merging
* - Regular props: Included normally
*
* @param pageProps - The page props to process
* @param containerResolver - Container resolver for dependency injection
* @returns Promise resolving to object containing processed props, deferred props list, and merge props list
*
* @example
* ```js
* const result = await buildStandardVisitProps({
* user: { name: 'John' },
* posts: defer(() => getPosts()),
* settings: merge({ theme: 'dark' })
* })
* // Returns: { props: { user: {...} }, deferredProps: { default: ['posts'] }, mergeProps: ['settings'] }
* ```
*/
export declare function buildStandardVisitProps(pageProps: PageProps, containerResolver: ContainerResolver<any>): Promise<{
props: ComponentProps;
mergeProps: string[];
deepMergeProps: string[];
deferredProps: {
[group: string]: string[];
};
}>;
/**
* Builds props for partial (cherry-picked) Inertia requests.
*
* This function processes page props for partial requests where only specific
* props are requested. It handles:
* - Always props: Always included regardless of cherry picking
* - Cherry-picked props: Only included if in the cherryPickProps list
* - Mergeable props: Included and marked for merging
* - Regular props: Included if cherry-picked
*
* @param pageProps - The page props to process
* @param cherryPickProps - Array of prop names to include
* @param containerResolver - Container resolver for dependency injection
* @returns Promise resolving to object containing processed props and merge props list
*
* @example
* ```js
* const result = await buildPartialRequestProps(
* { user: { name: 'John' }, posts: defer(() => getPosts()), stats: optional(() => getStats()) },
* ['posts', 'stats']
* )
* // Returns: { props: { posts: [...], stats: [...] }, mergeProps: [], deferredProps: {} }
* ```
*/
export declare function buildPartialRequestProps(pageProps: PageProps, cherryPickProps: string[], containerResolver: ContainerResolver<any>): Promise<{
props: ComponentProps;
mergeProps: string[];
deepMergeProps: string[];
deferredProps: {};
}>;