@jfdevelops/react-layout 0.19.0 → 0.21.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.
Files changed (32) hide show
  1. package/dist/create-config/define-layout.cjs +180 -3
  2. package/dist/create-config/define-layout.cjs.map +1 -1
  3. package/dist/create-config/define-layout.d.cts +214 -33
  4. package/dist/create-config/define-layout.d.cts.map +1 -1
  5. package/dist/create-config/define-layout.d.mts +214 -33
  6. package/dist/create-config/define-layout.d.mts.map +1 -1
  7. package/dist/create-config/define-layout.mjs +181 -4
  8. package/dist/create-config/define-layout.mjs.map +1 -1
  9. package/dist/create-config/for-resources/create-component.d.mts +1 -1
  10. package/dist/create-config/for-resources/create-for-resources.cjs +1 -1
  11. package/dist/create-config/for-resources/create-for-resources.mjs +1 -1
  12. package/dist/create-config/index.d.cts +2 -1
  13. package/dist/create-config/index.d.mts +2 -1
  14. package/dist/create-config/shell-context.cjs +22 -0
  15. package/dist/create-config/shell-context.cjs.map +1 -0
  16. package/dist/create-config/shell-context.d.cts +18 -0
  17. package/dist/create-config/shell-context.d.cts.map +1 -0
  18. package/dist/create-config/shell-context.d.mts +18 -0
  19. package/dist/create-config/shell-context.d.mts.map +1 -0
  20. package/dist/create-config/shell-context.mjs +21 -0
  21. package/dist/create-config/shell-context.mjs.map +1 -0
  22. package/dist/index.d.cts +4 -3
  23. package/dist/index.d.mts +4 -3
  24. package/dist/resource.cjs.map +1 -1
  25. package/dist/resource.d.cts +1 -1
  26. package/dist/resource.d.cts.map +1 -1
  27. package/dist/resource.d.mts +2 -2
  28. package/dist/resource.d.mts.map +1 -1
  29. package/dist/resource.mjs.map +1 -1
  30. package/package.json +1 -1
  31. package/skills/build-react-layouts/SKILL.md +4 -0
  32. package/skills/build-react-layouts/references/architecture.md +92 -0
@@ -1 +1 @@
1
- {"version":3,"file":"define-layout.mjs","names":[],"sources":["../../src/create-config/define-layout.tsx"],"sourcesContent":["import type { JSX } from 'react';\nimport {\n type ComposableComponents,\n type ComposableNameContext,\n type ComposableResourceLayout,\n type CreateLayoutComposable,\n collectComposablePresetEntries,\n LayoutComposablePresetProvider,\n MakeComposable,\n makeComposable,\n MakeComposableOptions,\n RequiredPresetLayoutProps,\n resolveLayoutComposables,\n} from '@jfdevelops/react-layout-composables';\nimport {\n type AnyBuiltPropDefinition,\n createPrimitivePropBuilder,\n createProp,\n type ResolveLayoutProps,\n type ResolveProps,\n resolvePropDefinitionValues,\n validateProps,\n} from '@jfdevelops/react-layout-validator';\nimport {\n IncludedProps,\n type IncludedPropBehavior,\n InferredInProps,\n InPropsDefinition,\n InPropsObject,\n LayoutRenderProps,\n MergedLayoutInProps,\n ResolvedIncludedComponentProps,\n ResolvedIncludedConfigProps,\n ResolvedIncludedProps,\n} from '../props';\nimport {\n createIsValidResourceFn,\n normalizeResources,\n toResourceEnum,\n type LayoutResourceKey,\n type ResourceDefinition,\n} from '../resource';\nimport { BaseComponent, functionalUpdate, pick, Show, Updater } from '../utils';\nimport { capitalize } from '../utils/capitalize';\nimport { InvalidConfigError } from '../errors';\nimport { isResourceConfigComponentKey } from './component-keys';\nimport {\n type CreateResourceConfigFn,\n createResourceConfig,\n} from './get-component';\nimport type { AssertUnreservedResources } from './types';\nimport {\n createResourceLinksFn,\n type CreateResourceLinksFn,\n} from './create-resource-links';\nimport {\n createForResource,\n type CreateLayoutForResource,\n type CreateResourceLayoutOptions,\n type CreateResourceLayoutOptionsBase,\n} from './for-resource';\nimport {\n createForResources,\n type CreateResourceLayoutForResourcesFn,\n} from './for-resources';\n\nexport type LayoutIncludeProps<\n Resources extends ReadonlyArray<ResourceDefinition>,\n Options extends InPropsDefinition<Resources>,\n Composables extends ComposableComponents,\n> = IncludedProps<MergedLayoutInProps<Resources, Options, Composables>>;\n\nexport type LayoutProps<\n Resources extends ReadonlyArray<ResourceDefinition>,\n Options extends InPropsDefinition<Resources>,\n Composables extends ComposableComponents,\n IncludeProps extends LayoutIncludeProps<Resources, Options, Composables> = {},\n CustomProps extends InPropsObject = {},\n> = {\n /**\n * Props to include in the layout.\n */\n include?: LayoutIncludeProps<Resources, Options, Composables> & IncludeProps;\n /**\n * Custom props that the layout will receive.\n */\n custom?: CustomProps;\n};\n\ntype LayoutRenderContext<\n Resources extends ReadonlyArray<ResourceDefinition>,\n Composables extends ComposableComponents,\n> = {\n composables: LayoutRenderComposables<Composables>;\n inProps: Record<string, unknown>;\n /**\n * @deprecated Use `resources.current` instead. `resource` will be removed in\n * the next major version.\n */\n resource: LayoutResourceKey<Resources>;\n /**\n * Accessor for the resources bound to this definition. Read `resources.current`\n * for the resource this instance renders, call `resources()` for the raw\n * value, use `resources.pick(...)` / `resources.omit(...)` to filter, or\n * `resources.isResource(...)` to narrow an unknown value.\n */\n resources: LayoutRenderResourcesAccessor<Resources>;\n name: string;\n};\n\ntype PickResourceDefinitions<\n Resources extends ReadonlyArray<ResourceDefinition>,\n Keys extends LayoutResourceKey<Resources>,\n> = Array<Extract<Resources[number], Keys | { value: Keys }>>;\n\ntype OmitResourceDefinitions<\n Resources extends ReadonlyArray<ResourceDefinition>,\n Keys extends LayoutResourceKey<Resources>,\n> = Array<Exclude<Resources[number], Keys | { value: Keys }>>;\n\n/**\n * Accessor for the resources bound to a `defineResourceLayout` definition.\n *\n * - `resources()` returns the raw resources.\n * - `resources.omit(...keys)` returns the resources except for the omitted ones.\n * - `resources.pick(...keys)` returns only the picked resources.\n * - `resources.isResource(value)` narrows an unknown value to a resource key.\n */\nexport type LayoutResourcesAccessor<\n Resources extends ReadonlyArray<ResourceDefinition>,\n> = {\n /**\n * Returns the raw `resources` value passed to `defineResourceLayout`,\n * exactly as declared.\n */\n (): Resources;\n /**\n * Narrows an unknown value to one of this definition's top-level resource\n * keys.\n *\n * @param value - The value to test.\n */\n isResource(value: unknown): value is LayoutResourceKey<Resources>;\n /**\n * Returns the declared resources with the named ones removed, preserving the\n * order and shape of the remaining definitions.\n *\n * @param keys - Top-level resource names to exclude.\n */\n omit<Keys extends LayoutResourceKey<Resources>>(\n ...keys: Keys[]\n ): Show<OmitResourceDefinitions<Resources, Keys>>;\n /**\n * Returns only the declared resources matching the named ones, preserving the\n * order and shape of the selected definitions.\n *\n * @param keys - Top-level resource names to keep.\n */\n pick<Keys extends LayoutResourceKey<Resources>>(\n ...keys: Keys[]\n ): Show<PickResourceDefinitions<Resources, Keys>>;\n};\n\n/**\n * Render-scoped {@link LayoutResourcesAccessor}, extended with `current` — the\n * resource key the layout instance is rendering for.\n */\nexport type LayoutRenderResourcesAccessor<\n Resources extends ReadonlyArray<ResourceDefinition>,\n> = LayoutResourcesAccessor<Resources> & {\n /** The resource this layout instance is rendering for. */\n readonly current: LayoutResourceKey<Resources>;\n};\n\nfunction createLayoutResourcesAccessor<\n Resources extends ReadonlyArray<ResourceDefinition>,\n>(resources: Resources): LayoutResourcesAccessor<Resources> {\n const accessor = (() => resources) as LayoutResourcesAccessor<Resources>;\n\n accessor.isResource = createIsValidResourceFn(resources);\n accessor.omit = ((...keys: string[]) =>\n resources.filter(\n (resource) => !keys.includes(readResourceSlug(resource)),\n )) as LayoutResourcesAccessor<Resources>['omit'];\n accessor.pick = ((...keys: string[]) =>\n resources.filter((resource) =>\n keys.includes(readResourceSlug(resource)),\n )) as LayoutResourcesAccessor<Resources>['pick'];\n\n return accessor;\n}\n\nfunction createLayoutRenderResourcesAccessor<\n Resources extends ReadonlyArray<ResourceDefinition>,\n>(\n resources: Resources,\n current: LayoutResourceKey<Resources>,\n): LayoutRenderResourcesAccessor<Resources> {\n return Object.assign(createLayoutResourcesAccessor(resources), { current });\n}\ntype LayoutRenderComposables<Composables extends ComposableComponents> = [\n keyof Composables,\n] extends [never]\n ? undefined\n : Composables;\n\ntype SplitLayoutInPropDefinition<\n Props extends InPropsObject = {},\n Content = unknown,\n> = {\n props?: Props;\n render: ((props: ResolveProps<Props>) => Content) | Content;\n};\n\nfunction isBuiltPropDefinition(\n value: unknown,\n): value is AnyBuiltPropDefinition {\n return typeof value === 'function' && value !== null && 'visibility' in value;\n}\n\nfunction isSplitLayoutInPropDefinition(\n value: unknown,\n): value is SplitLayoutInPropDefinition {\n return (\n value !== null &&\n typeof value === 'object' &&\n 'render' in value &&\n (value as { render?: unknown }).render !== undefined\n );\n}\n\nfunction isJSXElementDefinition(\n definition: unknown,\n): definition is AnyBuiltPropDefinition & { type: 'JSX.Element' } {\n return (\n isBuiltPropDefinition(definition) &&\n 'type' in definition &&\n definition.type === 'JSX.Element'\n );\n}\n\nfunction toLayoutRenderPropKey(includeKey: string, definition: unknown) {\n return isJSXElementDefinition(definition)\n ? capitalize(includeKey)\n : includeKey;\n}\n\nfunction readLayoutOptionValue(\n includeKey: string,\n definition: unknown,\n sources: Record<string, unknown>,\n) {\n const layoutOptionKeys = isJSXElementDefinition(definition)\n ? [capitalize(includeKey), includeKey]\n : [includeKey, capitalize(includeKey)];\n\n for (const key of layoutOptionKeys) {\n if (key in sources) {\n return sources[key];\n }\n }\n\n return undefined;\n}\n\nfunction getIncludedPropBehavior(value: unknown): IncludedPropBehavior | null {\n if (\n value !== null &&\n typeof value === 'object' &&\n 'visibility' in value &&\n 'passthrough' in value\n ) {\n return value as IncludedPropBehavior;\n }\n\n return null;\n}\n\nfunction isIncludedPropRequired(value: unknown) {\n return (\n value === true ||\n value === 'required' ||\n getIncludedPropBehavior(value)?.visibility === 'required'\n );\n}\n\nfunction allowsConfigPassthrough(value: unknown) {\n const behavior = getIncludedPropBehavior(value);\n\n if (!behavior) {\n return true;\n }\n\n if (behavior.passthrough === 'config') {\n return true;\n }\n\n // optional + component passthrough still accepts create-time defaults\n return (\n behavior.passthrough === 'component' && behavior.visibility === 'optional'\n );\n}\n\nfunction allowsComponentPassthrough(value: unknown) {\n const behavior = getIncludedPropBehavior(value);\n\n return behavior ? behavior.passthrough === 'component' : value === 'optional';\n}\n\nfunction splitLayoutInProps(inProps: Record<string, unknown>) {\n const resolvedInProps: Record<string, AnyBuiltPropDefinition> = {};\n const splitInProps: Record<string, unknown> = {};\n\n for (const [key, value] of Object.entries(inProps)) {\n if (isBuiltPropDefinition(value)) {\n resolvedInProps[key] = value;\n continue;\n }\n\n if (isSplitLayoutInPropDefinition(value)) {\n splitInProps[key] = value.render;\n\n if (value.props && typeof value.props === 'object') {\n Object.assign(resolvedInProps, value.props);\n }\n }\n }\n\n return {\n resolvedInProps,\n splitInProps,\n };\n}\n\nfunction resolveLayoutOptionDefaults(\n defaults: Record<string, unknown>,\n options: Record<string, unknown>,\n) {\n const resolved = { ...options };\n\n for (const [key, defaultValue] of Object.entries(defaults)) {\n if (key in options) {\n if (typeof defaultValue === 'function') {\n resolved[key] = options[key];\n } else {\n resolved[key] = functionalUpdate(\n defaultValue,\n options[key] as Updater<unknown>,\n );\n }\n }\n }\n\n return resolved;\n}\n\ntype CreateViewMapOptions<\n Resources extends ReadonlyArray<ResourceDefinition>,\n Options extends InPropsDefinition<Resources> = {},\n Composables extends ComposableComponents = {},\n IncludeProps extends LayoutIncludeProps<Resources, Options, Composables> = {},\n CustomProps extends InPropsObject = {},\n> = {\n /**\n * An array of valid resource names to support. Nested sub-resource slugs that\n * collide with config keys (`component`, `detail`, `new`, …) are reserved.\n */\n resources: AssertUnreservedResources<Resources>;\n /**\n * The options that are passed into the created resource layout.\n */\n options?: Options;\n layout: {\n /**\n * The props to pass to the layout.\n */\n props?: LayoutProps<\n Resources,\n Options,\n Composables,\n IncludeProps,\n CustomProps\n >;\n /**\n * Components used to compose the layout. Invoked per layout instance with\n * a scoped `create` that resolves composable `name` callbacks using the\n * layout's `resource` and `name`.\n */\n composables?: (\n create: CreateLayoutComposable<LayoutResourceKey<Resources>>,\n ) => Composables;\n /**\n * The render function for the layout.\n */\n render: (\n props: LayoutRenderProps<\n Resources,\n Options,\n Composables,\n IncludeProps,\n CustomProps\n >,\n context: LayoutRenderContext<Resources, Composables>,\n ) => JSX.Element;\n };\n};\n\ntype ResourceLayoutComposition<\n Name extends string,\n Composables extends ComposableComponents,\n> = [keyof Composables] extends [never]\n ? {}\n : {\n makeComposable: MakeComposable<Composables, Name>;\n };\nexport type ResourceLayoutComponent<\n Name extends string,\n Props extends InPropsObject = {},\n Composables extends ComposableComponents = {},\n Resource extends string = string,\n IncludedCallProps extends object = {},\n> = ResourceLayoutComposition<Name, Composables> &\n BaseComponent<Name, Show<ResolveProps<Props> & IncludedCallProps>> & {\n (props: Show<ResolveProps<Props> & IncludedCallProps>): JSX.Element;\n /**\n * A type-only property containing the resource associated with this\n * component. This property is `undefined` at runtime.\n */\n readonly resource: Resource;\n };\n\nexport type LayoutPropsForResource<\n Resources extends ReadonlyArray<ResourceDefinition>,\n InProps extends InPropsDefinition<Resources>,\n Composables extends ComposableComponents = {},\n IncludeProps extends LayoutIncludeProps<Resources, InProps, Composables> = {},\n> = [keyof IncludeProps] extends [never]\n ? ResolveLayoutProps<InferredInProps<Resources, InProps>> &\n RequiredPresetLayoutProps<Composables>\n : ResolvedIncludedConfigProps<\n MergedLayoutInProps<Resources, InProps, Composables>,\n IncludeProps\n >;\n\ntype CreateResourceLayoutFnImpl<\n Resources extends ReadonlyArray<ResourceDefinition>,\n InProps extends InPropsDefinition<Resources>,\n Composables extends ComposableComponents,\n IncludeProps extends LayoutIncludeProps<Resources, InProps, Composables> = {},\n CustomProps extends InPropsObject = {},\n> = <\n Name extends string,\n Resource extends LayoutResourceKey<Resources>,\n Props extends InPropsObject = {},\n>(\n options: CreateResourceLayoutOptions<\n Resources,\n InProps,\n Composables,\n IncludeProps,\n Name,\n Resource,\n Props\n >,\n) => ResourceLayoutComponent<\n Name,\n CustomProps,\n Composables,\n Resource,\n ResolvedIncludedComponentProps<\n MergedLayoutInProps<Resources, InProps, Composables>,\n IncludeProps\n >\n>;\n\nexport type CreateResourceLayoutMakeComposableOptions<\n Resources extends ReadonlyArray<ResourceDefinition>,\n InProps extends InPropsDefinition<Resources>,\n Composables extends ComposableComponents,\n Name extends string,\n Resource extends LayoutResourceKey<Resources>,\n Props extends InPropsObject = {},\n IncludeProps extends LayoutIncludeProps<Resources, InProps, Composables> = {},\n> = CreateResourceLayoutOptionsBase<Resources, Name, Resource, Props> &\n Partial<\n LayoutPropsForResource<Resources, InProps, Composables, IncludeProps>\n >;\n\ntype CreateResourceLayoutMakeComposableFn<\n Resources extends ReadonlyArray<ResourceDefinition>,\n InProps extends InPropsDefinition<Resources>,\n Composables extends ComposableComponents,\n IncludeProps extends LayoutIncludeProps<Resources, InProps, Composables>,\n CustomProps extends InPropsObject,\n> = <\n Name extends string,\n Resource extends LayoutResourceKey<Resources>,\n Props extends InPropsObject = {},\n>(\n options: CreateResourceLayoutMakeComposableOptions<\n Resources,\n InProps,\n Composables,\n Name,\n Resource,\n Props,\n IncludeProps\n >,\n) => ComposableResourceLayout<Composables, Name, any, any, any>;\n\ntype CreateResourceLayoutFnBase<\n Resources extends ReadonlyArray<ResourceDefinition>,\n InProps extends InPropsDefinition<Resources>,\n Composables extends ComposableComponents = {},\n IncludeProps extends LayoutIncludeProps<Resources, InProps, Composables> = {},\n CustomProps extends InPropsObject = {},\n> = CreateResourceLayoutFnImpl<\n Resources,\n InProps,\n Composables,\n IncludeProps,\n CustomProps\n> & {\n /**\n * A function to create a resource layout for a specific resource.\n */\n forResource: CreateLayoutForResource<\n Resources,\n InProps,\n Composables,\n IncludeProps,\n CustomProps\n >;\n /**\n * Creates resource layout factories for multiple defined resources.\n */\n forResources: CreateResourceLayoutForResourcesFn<\n Resources,\n InProps,\n Composables,\n IncludeProps,\n CustomProps\n >;\n};\n\ntype CreateResourceLayoutMakeComposableMember<\n Resources extends ReadonlyArray<ResourceDefinition>,\n InProps extends InPropsDefinition<Resources>,\n Composables extends ComposableComponents,\n IncludeProps extends LayoutIncludeProps<Resources, InProps, Composables>,\n CustomProps extends InPropsObject,\n> = [keyof Composables] extends [never]\n ? {}\n : {\n makeComposable: CreateResourceLayoutMakeComposableFn<\n Resources,\n InProps,\n Composables,\n IncludeProps,\n CustomProps\n >;\n };\n\nexport type CreateResourceLayoutFn<\n Resources extends ReadonlyArray<ResourceDefinition>,\n InProps extends InPropsDefinition<Resources>,\n Composables extends ComposableComponents = {},\n IncludeProps extends LayoutIncludeProps<Resources, InProps, Composables> = {},\n CustomProps extends InPropsObject = {},\n> = CreateResourceLayoutFnBase<\n Resources,\n InProps,\n Composables,\n IncludeProps,\n CustomProps\n> &\n CreateResourceLayoutMakeComposableMember<\n Resources,\n InProps,\n Composables,\n IncludeProps,\n CustomProps\n >;\n\ntype DefinedResourceLayout<\n Resources extends ReadonlyArray<ResourceDefinition>,\n InProps extends InPropsDefinition<Resources>,\n Composables extends ComposableComponents = {},\n IncludeProps extends LayoutIncludeProps<Resources, InProps, Composables> = {},\n CustomProps extends InPropsObject = {},\n> = {\n createResourceConfig: CreateResourceConfigFn<Resources>;\n createResourceLayout: CreateResourceLayoutFn<\n Resources,\n InProps,\n Composables,\n IncludeProps,\n CustomProps\n >;\n createResourceLinks: CreateResourceLinksFn<Resources>;\n /**\n * Accessor for the resources bound to this definition. Call `resources()` for\n * the raw value, or `resources.pick(...)` / `resources.omit(...)` to filter.\n */\n resources: LayoutResourcesAccessor<Resources>;\n};\n\nfunction readResourceSlug(resource: ResourceDefinition) {\n return typeof resource === 'string' ? resource : resource.value;\n}\n\nfunction assertUnreservedResourceSlugs(\n resources: ReadonlyArray<ResourceDefinition>,\n owner?: string,\n) {\n for (const resource of resources) {\n const slug = readResourceSlug(resource);\n\n if (owner !== undefined && isResourceConfigComponentKey(slug)) {\n throw new InvalidConfigError({\n reason: `Sub-resource \"${slug}\" under \"${owner}\" collides with a reserved config key`,\n });\n }\n\n if (typeof resource !== 'string') {\n assertUnreservedResourceSlugs(resource.subResources, slug);\n }\n }\n}\n\nfunction defineResourceLayoutImpl<\n const Resources extends ReadonlyArray<ResourceDefinition>,\n InProps extends InPropsDefinition<Resources> = {},\n Composables extends ComposableComponents = {},\n const IncludeProps extends LayoutIncludeProps<\n Resources,\n InProps,\n Composables\n > = {},\n CustomProps extends InPropsObject = {},\n>(\n options: CreateViewMapOptions<\n Resources,\n InProps,\n Composables,\n IncludeProps,\n CustomProps\n >,\n): DefinedResourceLayout<\n Resources,\n InProps,\n Composables,\n IncludeProps,\n CustomProps\n> {\n const { options: inProps = {} as InProps, resources, layout } = options;\n\n assertUnreservedResourceSlugs(resources);\n\n const resourcesAccessor = createLayoutResourcesAccessor(resources);\n const normalizedResources = normalizeResources(resources);\n const resourcesEnum = createPrimitivePropBuilder('string').enum(\n toResourceEnum(normalizedResources),\n );\n const definedResourceLayout = (<\n Name extends string,\n Resource extends LayoutResourceKey<Resources>,\n Props extends InPropsObject = {},\n >(\n layoutOptions: CreateResourceLayoutOptions<\n Resources,\n InProps,\n Composables,\n IncludeProps,\n Name,\n Resource,\n Props\n >,\n ) => {\n const {\n name,\n props: instancePropDefinitions,\n ...layoutOptionProps\n } = layoutOptions;\n const createComposableLayout =\n makeComposable<\n LayoutRenderProps<\n Resources,\n InProps,\n Composables,\n IncludeProps,\n CustomProps\n >\n >();\n const nameProp = createProp.string().literal(name);\n const rawResolvedOptions =\n typeof inProps === 'function'\n ? inProps({\n resource: resourcesEnum,\n name: nameProp,\n })\n : inProps;\n const { resolvedInProps, splitInProps } = splitLayoutInProps({\n ...(rawResolvedOptions as Record<string, unknown>),\n ...(instancePropDefinitions as Record<string, unknown> | undefined),\n ...layoutOptionProps,\n });\n const { composables, render, props: layoutProps } = layout;\n const customLayoutProps = layoutProps?.custom;\n const includeLayoutProps = layoutProps?.include;\n const layoutOptionValues = layoutOptionProps as Record<string, unknown>;\n const resolvedLayoutProps = {\n ...customLayoutProps,\n };\n const layoutContext: ComposableNameContext<\n LayoutResourceKey<Resources>,\n typeof name\n > = {\n resource: layoutOptions.resource,\n name,\n capitalize,\n };\n const validationContext = {\n layoutName: name,\n resource: layoutContext.resource,\n };\n const resolvedComposables = composables\n ? resolveLayoutComposables(composables, layoutContext)\n : undefined;\n const mergedResolvedInProps = { ...resolvedInProps };\n\n for (const {\n props: presetPropDefinitions,\n } of collectComposablePresetEntries(resolvedComposables)) {\n Object.assign(mergedResolvedInProps, presetPropDefinitions);\n }\n\n const composablePresetProps = Object.fromEntries(\n collectComposablePresetEntries(resolvedComposables).map(\n ({ key, props: presetPropDefinitions }) => {\n const presetPropEntries = Object.entries(presetPropDefinitions);\n const validatedDefinitions = Object.fromEntries(\n presetPropEntries.filter(([propKey]) => {\n const includeBehavior = includeLayoutProps?.[propKey];\n\n return (\n includeBehavior === undefined ||\n (allowsConfigPassthrough(includeBehavior) &&\n (isIncludedPropRequired(includeBehavior) ||\n layoutOptionValues[propKey] !== undefined))\n );\n }),\n );\n const presetPropValues = Object.fromEntries(\n presetPropEntries.flatMap(([propKey]) =>\n propKey in layoutOptionValues\n ? [[propKey, layoutOptionValues[propKey]]]\n : [],\n ),\n );\n\n return [\n key,\n validateProps(\n validatedDefinitions as Record<string, AnyBuiltPropDefinition>,\n presetPropValues,\n validationContext,\n ),\n ];\n },\n ),\n );\n const mergedRenderContext = {\n composables: resolvedComposables as LayoutRenderComposables<Composables>,\n resource: layoutContext.resource,\n resources: createLayoutRenderResourcesAccessor(\n resources as Resources,\n layoutContext.resource,\n ),\n name: layoutContext.name,\n inProps: splitInProps,\n } as LayoutRenderContext<Resources, Composables>;\n\n function Component(\n props: Show<\n ResolveProps<CustomProps> &\n ResolvedIncludedComponentProps<\n MergedLayoutInProps<Resources, InProps, Composables>,\n IncludeProps\n >\n >,\n ) {\n const validatedProps = validateProps(resolvedLayoutProps, props, {\n ...validationContext,\n });\n const includedPropKeys = Object.keys(includeLayoutProps ?? {});\n const includedPropDefinitions = pick(\n mergedResolvedInProps,\n includedPropKeys,\n ) as Record<string, unknown>;\n const includedPropValues = {\n ...resolvePropDefinitionValues(includedPropDefinitions),\n } as Record<string, unknown>;\n\n for (const key of includedPropKeys) {\n const definition = mergedResolvedInProps[key];\n const includeBehavior = includeLayoutProps?.[key];\n const callSiteValue = allowsComponentPassthrough(includeBehavior)\n ? readLayoutOptionValue(\n key,\n definition,\n props as Record<string, unknown>,\n )\n : undefined;\n const layoutOptionValue = allowsConfigPassthrough(includeBehavior)\n ? readLayoutOptionValue(key, definition, layoutOptionValues)\n : undefined;\n const splitValue = key in splitInProps ? splitInProps[key] : undefined;\n const value = callSiteValue ?? layoutOptionValue ?? splitValue;\n\n if (value !== undefined) {\n includedPropValues[key] = value;\n }\n }\n\n const requiredIncludedPropDefinitions = Object.fromEntries(\n Object.entries(includedPropDefinitions).filter(([key]) =>\n isIncludedPropRequired(includeLayoutProps?.[key]),\n ),\n );\n const optionalIncludedPropDefinitions = Object.fromEntries(\n Object.entries(includedPropDefinitions).filter(\n ([key]) =>\n !isIncludedPropRequired(includeLayoutProps?.[key]) &&\n includedPropValues[key] !== undefined,\n ),\n );\n const validatedIncludedProps = validateProps(\n {\n ...requiredIncludedPropDefinitions,\n ...optionalIncludedPropDefinitions,\n } as Record<string, AnyBuiltPropDefinition>,\n includedPropValues,\n validationContext,\n );\n const layoutRenderIncludedProps = Object.fromEntries(\n includedPropKeys.flatMap((key) => {\n if (!(key in validatedIncludedProps)) {\n return [];\n }\n\n return [\n [\n toLayoutRenderPropKey(key, mergedResolvedInProps[key]),\n validatedIncludedProps[\n key as keyof typeof validatedIncludedProps\n ],\n ],\n ];\n }),\n );\n const layoutRenderProps = {\n ...validatedProps,\n ...layoutRenderIncludedProps,\n } as unknown as LayoutRenderProps<\n Resources,\n InProps,\n Composables,\n IncludeProps,\n CustomProps\n >;\n\n return (\n <LayoutComposablePresetProvider value={composablePresetProps}>\n {render(layoutRenderProps, mergedRenderContext)}\n </LayoutComposablePresetProvider>\n );\n }\n\n function createComposition<\n LayoutName extends string,\n const Defined extends MakeComposableOptions<Composables, LayoutName>,\n >(compositionOptions: Defined) {\n if (!compositionOptions.components) {\n return {} as ResourceLayoutComposition<LayoutName, Composables>;\n }\n\n return {\n makeComposable: createComposableLayout(\n compositionOptions,\n ) as MakeComposable<Composables, LayoutName>,\n };\n }\n\n return Object.assign(Component, {\n displayName: name,\n props: undefined as unknown as Show<\n ResolveProps<CustomProps> &\n ResolvedIncludedComponentProps<\n MergedLayoutInProps<Resources, InProps, Composables>,\n IncludeProps\n >\n >,\n resource: undefined as unknown as Resource,\n ...createComposition({\n components: resolvedComposables as Composables | undefined,\n name,\n }),\n });\n }) as CreateResourceLayoutFnImpl<\n Resources,\n InProps,\n Composables,\n IncludeProps,\n CustomProps\n >;\n const createTopLevelMakeComposable = () => {\n return (options: Record<string, unknown>) => {\n const layout = definedResourceLayout(options as never);\n\n if (\n !('makeComposable' in layout) ||\n typeof layout.makeComposable !== 'function'\n ) {\n throw new Error(\n 'makeComposable requires composables to be defined in the layout',\n );\n }\n\n return layout.makeComposable();\n };\n };\n\n function getComponentPropDefinitions(resource: LayoutResourceKey<Resources>) {\n const componentName = 'ScopedResourceComponent';\n const rawResolvedOptions =\n typeof inProps === 'function'\n ? inProps({\n resource: resourcesEnum,\n name: createProp.string().literal(componentName),\n })\n : inProps;\n const { resolvedInProps } = splitLayoutInProps(\n rawResolvedOptions as Record<string, unknown>,\n );\n const resolvedComposables = layout.composables\n ? resolveLayoutComposables(layout.composables, {\n resource,\n name: componentName,\n capitalize,\n })\n : undefined;\n\n for (const {\n props: presetPropDefinitions,\n } of collectComposablePresetEntries(resolvedComposables)) {\n Object.assign(resolvedInProps, presetPropDefinitions);\n }\n\n return {\n ...resolvedInProps,\n ...layout.props?.custom,\n };\n }\n\n const { createLayoutForResourceBuilder, forResource } = createForResource<\n Resources,\n InProps,\n Composables,\n IncludeProps,\n CustomProps\n >({\n createResourceLayout: definedResourceLayout as never,\n resolveLayoutOptionDefaults,\n });\n const forResources = createForResources<\n Resources,\n InProps,\n Composables,\n IncludeProps,\n CustomProps\n >({\n createLayoutForResource: createLayoutForResourceBuilder,\n ...(layout.composables\n ? { createMakeComposableLayout: createTopLevelMakeComposable }\n : {}),\n createResourceLayout: definedResourceLayout as never,\n getComponentPropDefinitions,\n });\n\n const createResourceLayoutExtras: {\n forResource: CreateLayoutForResource<\n Resources,\n InProps,\n Composables,\n IncludeProps,\n CustomProps\n >;\n forResources: CreateResourceLayoutForResourcesFn<\n Resources,\n InProps,\n Composables,\n IncludeProps,\n CustomProps\n >;\n makeComposable?: ReturnType<typeof createTopLevelMakeComposable>;\n } = {\n forResource,\n forResources,\n };\n\n if (layout.composables) {\n createResourceLayoutExtras.makeComposable = createTopLevelMakeComposable();\n }\n\n const createResourceLayout = Object.assign(\n definedResourceLayout,\n createResourceLayoutExtras,\n ) as CreateResourceLayoutFn<\n Resources,\n InProps,\n Composables,\n IncludeProps,\n CustomProps\n >;\n\n const createResourceLinks = createResourceLinksFn(resources);\n\n return {\n createResourceConfig,\n createResourceLayout,\n createResourceLinks,\n resources: resourcesAccessor,\n } as DefinedResourceLayout<\n Resources,\n InProps,\n Composables,\n IncludeProps,\n CustomProps\n >;\n}\n\ntype DefineResourceLayoutForResourcesOptions<\n Resources extends ReadonlyArray<ResourceDefinition>,\n InProps extends InPropsDefinition<Resources> = {},\n Composables extends ComposableComponents = {},\n IncludeProps extends LayoutIncludeProps<Resources, InProps, Composables> = {},\n CustomProps extends InPropsObject = {},\n ExtraResources extends ReadonlyArray<ResourceDefinition> = [],\n> = Omit<\n CreateViewMapOptions<\n Resources,\n InProps,\n Composables,\n IncludeProps,\n CustomProps\n >,\n 'resources'\n> & {\n /**\n * Additional resources to merge with those bound by\n * {@link defineResourceLayout.forResources}.\n */\n resources?: AssertUnreservedResources<ExtraResources>;\n};\n\ntype NonEmptyResourceDefinitions = readonly [\n ResourceDefinition,\n ...ResourceDefinition[],\n];\n\n/**\n * Factory returned by {@link DefineResourceLayout.forResources}.\n */\nexport type DefineResourceLayoutForResourcesFactory<\n BaseResources extends NonEmptyResourceDefinitions,\n> = <\n const ExtraResources extends ReadonlyArray<ResourceDefinition> = [],\n InProps extends InPropsDefinition<[...BaseResources, ...ExtraResources]> = {},\n Composables extends ComposableComponents = {},\n const IncludeProps extends LayoutIncludeProps<\n [...BaseResources, ...ExtraResources],\n InProps,\n Composables\n > = {},\n CustomProps extends InPropsObject = {},\n>(\n options: DefineResourceLayoutForResourcesOptions<\n [...BaseResources, ...ExtraResources],\n InProps,\n Composables,\n IncludeProps,\n CustomProps,\n ExtraResources\n >,\n) => DefinedResourceLayout<\n [...BaseResources, ...ExtraResources],\n InProps,\n Composables,\n IncludeProps,\n CustomProps\n>;\n\n/**\n * Binds one or more resources, then accepts the remaining\n * {@link defineResourceLayout} options (with optional extra `resources`).\n */\nexport type DefineResourceLayoutForResources = <\n const Resources extends NonEmptyResourceDefinitions,\n>(\n ...resources: Resources\n) => DefineResourceLayoutForResourcesFactory<Resources>;\n\n/**\n * Creates a resource layout definition for a set of resources.\n */\nexport type DefineResourceLayoutFn = {\n <\n const Resources extends ReadonlyArray<ResourceDefinition>,\n InProps extends InPropsDefinition<Resources> = {},\n Composables extends ComposableComponents = {},\n const IncludeProps extends LayoutIncludeProps<\n Resources,\n InProps,\n Composables\n > = {},\n CustomProps extends InPropsObject = {},\n >(\n options: CreateViewMapOptions<\n Resources,\n InProps,\n Composables,\n IncludeProps,\n CustomProps\n >,\n ): DefinedResourceLayout<\n Resources,\n InProps,\n Composables,\n IncludeProps,\n CustomProps\n >;\n};\n\n/**\n * Captures a `resources` array with its literal tuple type intact, so it can be\n * declared separately from the `defineResourceLayout` call without needing an\n * `as const` assertion.\n */\nexport type DefineResourcesFn = <\n const Resources extends ReadonlyArray<ResourceDefinition>,\n>(\n ...resources: Resources\n) => Resources;\n\nfunction defineResources<\n const Resources extends ReadonlyArray<ResourceDefinition>,\n>(...resources: Resources): Resources {\n return resources;\n}\n\nexport type DefineResourceLayout = DefineResourceLayoutFn & {\n forResources: DefineResourceLayoutForResources;\n /**\n * Builds a strongly-typed `resources` array to pass to `defineResourceLayout`\n * (or `defineResourceLayout.forResources`) without an `as const` assertion.\n */\n defineResources: DefineResourcesFn;\n};\n\nfunction defineResourceLayoutForResources<\n const Resources extends NonEmptyResourceDefinitions,\n>(\n ...baseResources: Resources\n): DefineResourceLayoutForResourcesFactory<Resources> {\n return ((options) => {\n const { resources: extraResources, ...rest } = options;\n const resources = extraResources\n ? [...baseResources, ...extraResources]\n : [...baseResources];\n\n return defineResourceLayoutImpl({\n ...rest,\n resources,\n } as never);\n }) as DefineResourceLayoutForResourcesFactory<Resources>;\n}\n\nexport const defineResourceLayout: DefineResourceLayout = Object.assign(\n defineResourceLayoutImpl as DefineResourceLayoutFn,\n {\n forResources: defineResourceLayoutForResources,\n defineResources,\n },\n);\n"],"mappings":"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"}
1
+ {"version":3,"file":"define-layout.mjs","names":[],"sources":["../../src/create-config/define-layout.tsx"],"sourcesContent":["import {\n type JSX,\n type ReactNode,\n useCallback,\n useLayoutEffect,\n useMemo,\n useRef,\n useState,\n} from 'react';\nimport {\n type ComposableComponents,\n type ComposableNameContext,\n type ComposableResourceLayout,\n type CreateLayoutComposable,\n collectComposablePresetEntries,\n LayoutComposablePresetProvider,\n MakeComposable,\n makeComposable,\n MakeComposableOptions,\n RequiredPresetLayoutProps,\n resolveLayoutComposables,\n} from '@jfdevelops/react-layout-composables';\nimport {\n type AnyBuiltPropDefinition,\n createPrimitivePropBuilder,\n createProp,\n type ResolveLayoutProps,\n type ResolveProps,\n resolvePropDefinitionValues,\n validateProps,\n} from '@jfdevelops/react-layout-validator';\nimport {\n IncludedProps,\n type IncludedPropBehavior,\n InferredInProps,\n InPropsDefinition,\n InPropsObject,\n LayoutRenderProps,\n MergedLayoutInProps,\n ResolvedIncludedComponentProps,\n ResolvedIncludedConfigProps,\n ResolvedIncludedProps,\n} from '../props';\nimport {\n createIsValidResourceFn,\n normalizeResources,\n toResourceEnum,\n type LayoutResourceKey,\n type ResourceDefinition,\n type ResourceDefinitionValue,\n} from '../resource';\nimport { BaseComponent, functionalUpdate, pick, Show, Updater } from '../utils';\nimport { capitalize } from '../utils/capitalize';\nimport { InvalidConfigError } from '../errors';\nimport { isResourceConfigComponentKey } from './component-keys';\nimport {\n type CreateResourceConfigFn,\n createResourceConfig,\n} from './get-component';\nimport type { AssertUnreservedResources } from './types';\nimport {\n createResourceLinksFn,\n type CreateResourceLinksFn,\n} from './create-resource-links';\nimport {\n createForResource,\n type CreateLayoutForResource,\n type CreateResourceLayoutOptions,\n type CreateResourceLayoutOptionsBase,\n} from './for-resource';\nimport {\n createForResources,\n type CreateResourceLayoutForResourcesFn,\n} from './for-resources';\nimport {\n type ResourceLayoutShellPublisher,\n ResourceLayoutShellPublisherContext,\n useResourceLayoutShellPublisher,\n} from './shell-context';\n\nexport type LayoutIncludeProps<\n Resources extends ReadonlyArray<ResourceDefinition>,\n Options extends InPropsDefinition<Resources>,\n Composables extends ComposableComponents,\n> = IncludedProps<MergedLayoutInProps<Resources, Options, Composables>>;\n\nexport type LayoutProps<\n Resources extends ReadonlyArray<ResourceDefinition>,\n Options extends InPropsDefinition<Resources>,\n Composables extends ComposableComponents,\n IncludeProps extends LayoutIncludeProps<Resources, Options, Composables> = {},\n CustomProps extends InPropsObject = {},\n> = {\n /**\n * Props to include in the layout.\n */\n include?: LayoutIncludeProps<Resources, Options, Composables> & IncludeProps;\n /**\n * Custom props that the layout will receive.\n */\n custom?: CustomProps;\n};\n\ntype LayoutRenderContext<\n Resources extends ReadonlyArray<ResourceDefinition>,\n Composables extends ComposableComponents,\n> = {\n composables: LayoutRenderComposables<Composables>;\n inProps: Record<string, unknown>;\n /**\n * @deprecated Use `resources.current` instead. `resource` will be removed in\n * the next major version.\n */\n resource: LayoutResourceKey<Resources>;\n /**\n * Accessor for the resources bound to this definition. Read `resources.current`\n * for the resource this instance renders, call `resources()` for the raw\n * value, use `resources.pick(...)` / `resources.omit(...)` to filter, or\n * `resources.isResource(...)` to narrow an unknown value.\n */\n resources: LayoutRenderResourcesAccessor<Resources>;\n name: string;\n};\n\n/**\n * A single {@link ResourceDefinition} kept by a `pick`, or `never` when it does\n * not match. Widened definitions (`string`, `{ value: string }`) are always\n * kept — the concrete keys are not known statically, so the runtime filter is\n * the source of truth.\n */\ntype PickResourceDefinition<\n Definition,\n Keys extends string,\n> = Definition extends ResourceDefinition\n ? string extends ResourceDefinitionValue<Definition>\n ? Definition\n : ResourceDefinitionValue<Definition> extends Keys\n ? Definition\n : never\n : never;\n\ntype PickResourceDefinitions<\n Resources extends ReadonlyArray<ResourceDefinition>,\n Keys extends LayoutResourceKey<Resources>,\n> = Array<PickResourceDefinition<Resources[number], Keys>>;\n\n/**\n * A single {@link ResourceDefinition} kept by an `omit`, or `never` when it is\n * one of the omitted keys. Widened definitions are always kept.\n */\ntype OmitResourceDefinition<\n Definition,\n Keys extends string,\n> = Definition extends ResourceDefinition\n ? string extends ResourceDefinitionValue<Definition>\n ? Definition\n : ResourceDefinitionValue<Definition> extends Keys\n ? never\n : Definition\n : never;\n\ntype OmitResourceDefinitions<\n Resources extends ReadonlyArray<ResourceDefinition>,\n Keys extends LayoutResourceKey<Resources>,\n> = Array<OmitResourceDefinition<Resources[number], Keys>>;\n\n/**\n * The result of `resources.pick(...)` / `resources.omit(...)`.\n *\n * - calling it returns the selected resource definitions.\n * - `.isResource(value)` narrows an unknown value to one of the selected keys.\n */\nexport type ResourceSelection<\n Definitions extends ReadonlyArray<ResourceDefinition>,\n> = {\n /** Returns the selected resource definitions. */\n (): Show<Definitions>;\n /**\n * Narrows an unknown value to one of the selected resource keys.\n *\n * @param value - The value to test.\n */\n isResource(value: unknown): value is LayoutResourceKey<Definitions>;\n};\n\n/**\n * Accessor for the resources bound to a `defineResourceLayout` definition.\n *\n * - `resources()` returns the raw resources.\n * - `resources.omit(key, ...rest)` selects every resource except the named ones.\n * - `resources.pick(key, ...rest)` selects only the named resources.\n * - `resources.isResource(value)` narrows an unknown value to a resource key.\n *\n * `pick` / `omit` return a {@link ResourceSelection} thunk: call it for the\n * definitions, or use its `isResource` guard.\n */\nexport type LayoutResourcesAccessor<\n Resources extends ReadonlyArray<ResourceDefinition>,\n> = {\n /**\n * Returns the raw `resources` value passed to `defineResourceLayout`,\n * exactly as declared.\n */\n (): Resources;\n /**\n * Narrows an unknown value to one of this definition's top-level resource\n * keys.\n *\n * @param value - The value to test.\n */\n isResource(value: unknown): value is LayoutResourceKey<Resources>;\n /**\n * Selects every declared resource except the named ones. Requires at least\n * one key.\n *\n * @param keys - Top-level resource names to exclude.\n */\n omit<\n Keys extends [\n LayoutResourceKey<Resources>,\n ...LayoutResourceKey<Resources>[],\n ],\n >(\n ...keys: Keys\n ): ResourceSelection<OmitResourceDefinitions<Resources, Keys[number]>>;\n /**\n * Selects only the named resources. Requires at least one key.\n *\n * @param keys - Top-level resource names to keep.\n */\n pick<\n Keys extends [\n LayoutResourceKey<Resources>,\n ...LayoutResourceKey<Resources>[],\n ],\n >(\n ...keys: Keys\n ): ResourceSelection<PickResourceDefinitions<Resources, Keys[number]>>;\n};\n\n/**\n * Render-scoped {@link LayoutResourcesAccessor}, extended with `current` — the\n * resource key the layout instance is rendering for.\n */\nexport type LayoutRenderResourcesAccessor<\n Resources extends ReadonlyArray<ResourceDefinition>,\n> = LayoutResourcesAccessor<Resources> & {\n /** The resource this layout instance is rendering for. */\n readonly current: LayoutResourceKey<Resources>;\n};\n\nfunction createResourceSelection(\n definitions: ReadonlyArray<ResourceDefinition>,\n): ResourceSelection<ReadonlyArray<ResourceDefinition>> {\n const selection = (() => definitions) as ResourceSelection<\n ReadonlyArray<ResourceDefinition>\n >;\n\n selection.isResource = createIsValidResourceFn(definitions);\n\n return selection;\n}\n\nfunction createLayoutResourcesAccessor<\n Resources extends ReadonlyArray<ResourceDefinition>,\n>(resources: Resources): LayoutResourcesAccessor<Resources> {\n const accessor = (() => resources) as LayoutResourcesAccessor<Resources>;\n\n accessor.isResource = createIsValidResourceFn(resources);\n accessor.omit = ((...keys: string[]) =>\n createResourceSelection(\n resources.filter(\n (resource) => !keys.includes(readResourceSlug(resource)),\n ),\n )) as LayoutResourcesAccessor<Resources>['omit'];\n accessor.pick = ((...keys: string[]) =>\n createResourceSelection(\n resources.filter((resource) =>\n keys.includes(readResourceSlug(resource)),\n ),\n )) as LayoutResourcesAccessor<Resources>['pick'];\n\n return accessor;\n}\n\nfunction createLayoutRenderResourcesAccessor<\n Resources extends ReadonlyArray<ResourceDefinition>,\n>(\n resources: Resources,\n current: LayoutResourceKey<Resources>,\n): LayoutRenderResourcesAccessor<Resources> {\n return Object.assign(createLayoutResourcesAccessor(resources), { current });\n}\ntype LayoutRenderComposables<Composables extends ComposableComponents> = [\n keyof Composables,\n] extends [never]\n ? undefined\n : Composables;\n\ntype SplitLayoutInPropDefinition<\n Props extends InPropsObject = {},\n Content = unknown,\n> = {\n props?: Props;\n render: ((props: ResolveProps<Props>) => Content) | Content;\n};\n\nfunction isBuiltPropDefinition(\n value: unknown,\n): value is AnyBuiltPropDefinition {\n return typeof value === 'function' && value !== null && 'visibility' in value;\n}\n\nfunction isSplitLayoutInPropDefinition(\n value: unknown,\n): value is SplitLayoutInPropDefinition {\n return (\n value !== null &&\n typeof value === 'object' &&\n 'render' in value &&\n (value as { render?: unknown }).render !== undefined\n );\n}\n\nfunction isJSXElementDefinition(\n definition: unknown,\n): definition is AnyBuiltPropDefinition & { type: 'JSX.Element' } {\n return (\n isBuiltPropDefinition(definition) &&\n 'type' in definition &&\n definition.type === 'JSX.Element'\n );\n}\n\nfunction toLayoutRenderPropKey(includeKey: string, definition: unknown) {\n return isJSXElementDefinition(definition)\n ? capitalize(includeKey)\n : includeKey;\n}\n\nfunction readLayoutOptionValue(\n includeKey: string,\n definition: unknown,\n sources: Record<string, unknown>,\n) {\n const layoutOptionKeys = isJSXElementDefinition(definition)\n ? [capitalize(includeKey), includeKey]\n : [includeKey, capitalize(includeKey)];\n\n for (const key of layoutOptionKeys) {\n if (key in sources) {\n return sources[key];\n }\n }\n\n return undefined;\n}\n\nfunction getIncludedPropBehavior(value: unknown): IncludedPropBehavior | null {\n if (\n value !== null &&\n typeof value === 'object' &&\n 'visibility' in value &&\n 'passthrough' in value\n ) {\n return value as IncludedPropBehavior;\n }\n\n return null;\n}\n\nfunction isIncludedPropRequired(value: unknown) {\n return (\n value === true ||\n value === 'required' ||\n getIncludedPropBehavior(value)?.visibility === 'required'\n );\n}\n\nfunction allowsConfigPassthrough(value: unknown) {\n const behavior = getIncludedPropBehavior(value);\n\n if (!behavior) {\n return true;\n }\n\n if (behavior.passthrough === 'config') {\n return true;\n }\n\n // optional + component passthrough still accepts create-time defaults\n return (\n behavior.passthrough === 'component' && behavior.visibility === 'optional'\n );\n}\n\nfunction allowsComponentPassthrough(value: unknown) {\n const behavior = getIncludedPropBehavior(value);\n\n return behavior ? behavior.passthrough === 'component' : value === 'optional';\n}\n\nfunction splitLayoutInProps(inProps: Record<string, unknown>) {\n const resolvedInProps: Record<string, AnyBuiltPropDefinition> = {};\n const splitInProps: Record<string, unknown> = {};\n\n for (const [key, value] of Object.entries(inProps)) {\n if (isBuiltPropDefinition(value)) {\n resolvedInProps[key] = value;\n continue;\n }\n\n if (isSplitLayoutInPropDefinition(value)) {\n splitInProps[key] = value.render;\n\n if (value.props && typeof value.props === 'object') {\n Object.assign(resolvedInProps, value.props);\n }\n }\n }\n\n return {\n resolvedInProps,\n splitInProps,\n };\n}\n\nfunction resolveLayoutOptionDefaults(\n defaults: Record<string, unknown>,\n options: Record<string, unknown>,\n) {\n const resolved = { ...options };\n\n for (const [key, defaultValue] of Object.entries(defaults)) {\n if (key in options) {\n if (typeof defaultValue === 'function') {\n resolved[key] = options[key];\n } else {\n resolved[key] = functionalUpdate(\n defaultValue,\n options[key] as Updater<unknown>,\n );\n }\n }\n }\n\n return resolved;\n}\n\n/**\n * The `layout` block of a {@link defineResourceLayout} call: the props, the\n * composable map, and the render for a per-resource page component.\n *\n * Extracted so {@link defineResourceLayout.withLayout} can reuse the exact same\n * shape while making `render` optional (see {@link ShellLayoutDefinition}).\n */\ntype LayoutDefinition<\n Resources extends ReadonlyArray<ResourceDefinition>,\n Options extends InPropsDefinition<Resources>,\n Composables extends ComposableComponents,\n IncludeProps extends LayoutIncludeProps<Resources, Options, Composables>,\n CustomProps extends InPropsObject,\n> = {\n /**\n * The props to pass to the layout.\n */\n props?: LayoutProps<Resources, Options, Composables, IncludeProps, CustomProps>;\n /**\n * Components used to compose the layout. Invoked per layout instance with\n * a scoped `create` that resolves composable `name` callbacks using the\n * layout's `resource` and `name`.\n */\n composables?: (\n create: CreateLayoutComposable<LayoutResourceKey<Resources>>,\n ) => Composables;\n /**\n * The render function for the layout.\n */\n render: (\n props: LayoutRenderProps<\n Resources,\n Options,\n Composables,\n IncludeProps,\n CustomProps\n >,\n context: LayoutRenderContext<Resources, Composables>,\n ) => JSX.Element;\n};\n\ntype CreateViewMapOptions<\n Resources extends ReadonlyArray<ResourceDefinition>,\n Options extends InPropsDefinition<Resources> = {},\n Composables extends ComposableComponents = {},\n IncludeProps extends LayoutIncludeProps<Resources, Options, Composables> = {},\n CustomProps extends InPropsObject = {},\n> = {\n /**\n * An array of valid resource names to support. Nested sub-resource slugs that\n * collide with config keys (`component`, `detail`, `new`, …) are reserved.\n */\n resources: AssertUnreservedResources<Resources>;\n /**\n * The options that are passed into the created resource layout.\n */\n options?: Options;\n layout: LayoutDefinition<\n Resources,\n Options,\n Composables,\n IncludeProps,\n CustomProps\n >;\n};\n\ntype ResourceLayoutComposition<\n Name extends string,\n Composables extends ComposableComponents,\n> = [keyof Composables] extends [never]\n ? {}\n : {\n makeComposable: MakeComposable<Composables, Name>;\n };\nexport type ResourceLayoutComponent<\n Name extends string,\n Props extends InPropsObject = {},\n Composables extends ComposableComponents = {},\n Resource extends string = string,\n IncludedCallProps extends object = {},\n> = ResourceLayoutComposition<Name, Composables> &\n BaseComponent<Name, Show<ResolveProps<Props> & IncludedCallProps>> & {\n (props: Show<ResolveProps<Props> & IncludedCallProps>): JSX.Element;\n /**\n * A type-only property containing the resource associated with this\n * component. This property is `undefined` at runtime.\n */\n readonly resource: Resource;\n };\n\nexport type LayoutPropsForResource<\n Resources extends ReadonlyArray<ResourceDefinition>,\n InProps extends InPropsDefinition<Resources>,\n Composables extends ComposableComponents = {},\n IncludeProps extends LayoutIncludeProps<Resources, InProps, Composables> = {},\n> = [keyof IncludeProps] extends [never]\n ? ResolveLayoutProps<InferredInProps<Resources, InProps>> &\n RequiredPresetLayoutProps<Composables>\n : ResolvedIncludedConfigProps<\n MergedLayoutInProps<Resources, InProps, Composables>,\n IncludeProps\n >;\n\ntype CreateResourceLayoutFnImpl<\n Resources extends ReadonlyArray<ResourceDefinition>,\n InProps extends InPropsDefinition<Resources>,\n Composables extends ComposableComponents,\n IncludeProps extends LayoutIncludeProps<Resources, InProps, Composables> = {},\n CustomProps extends InPropsObject = {},\n> = <\n Name extends string,\n Resource extends LayoutResourceKey<Resources>,\n Props extends InPropsObject = {},\n>(\n options: CreateResourceLayoutOptions<\n Resources,\n InProps,\n Composables,\n IncludeProps,\n Name,\n Resource,\n Props\n >,\n) => ResourceLayoutComponent<\n Name,\n CustomProps,\n Composables,\n Resource,\n ResolvedIncludedComponentProps<\n MergedLayoutInProps<Resources, InProps, Composables>,\n IncludeProps\n >\n>;\n\nexport type CreateResourceLayoutMakeComposableOptions<\n Resources extends ReadonlyArray<ResourceDefinition>,\n InProps extends InPropsDefinition<Resources>,\n Composables extends ComposableComponents,\n Name extends string,\n Resource extends LayoutResourceKey<Resources>,\n Props extends InPropsObject = {},\n IncludeProps extends LayoutIncludeProps<Resources, InProps, Composables> = {},\n> = CreateResourceLayoutOptionsBase<Resources, Name, Resource, Props> &\n Partial<\n LayoutPropsForResource<Resources, InProps, Composables, IncludeProps>\n >;\n\ntype CreateResourceLayoutMakeComposableFn<\n Resources extends ReadonlyArray<ResourceDefinition>,\n InProps extends InPropsDefinition<Resources>,\n Composables extends ComposableComponents,\n IncludeProps extends LayoutIncludeProps<Resources, InProps, Composables>,\n CustomProps extends InPropsObject,\n> = <\n Name extends string,\n Resource extends LayoutResourceKey<Resources>,\n Props extends InPropsObject = {},\n>(\n options: CreateResourceLayoutMakeComposableOptions<\n Resources,\n InProps,\n Composables,\n Name,\n Resource,\n Props,\n IncludeProps\n >,\n) => ComposableResourceLayout<Composables, Name, any, any, any>;\n\ntype CreateResourceLayoutFnBase<\n Resources extends ReadonlyArray<ResourceDefinition>,\n InProps extends InPropsDefinition<Resources>,\n Composables extends ComposableComponents = {},\n IncludeProps extends LayoutIncludeProps<Resources, InProps, Composables> = {},\n CustomProps extends InPropsObject = {},\n> = CreateResourceLayoutFnImpl<\n Resources,\n InProps,\n Composables,\n IncludeProps,\n CustomProps\n> & {\n /**\n * A function to create a resource layout for a specific resource.\n */\n forResource: CreateLayoutForResource<\n Resources,\n InProps,\n Composables,\n IncludeProps,\n CustomProps\n >;\n /**\n * Creates resource layout factories for multiple defined resources.\n */\n forResources: CreateResourceLayoutForResourcesFn<\n Resources,\n InProps,\n Composables,\n IncludeProps,\n CustomProps\n >;\n};\n\ntype CreateResourceLayoutMakeComposableMember<\n Resources extends ReadonlyArray<ResourceDefinition>,\n InProps extends InPropsDefinition<Resources>,\n Composables extends ComposableComponents,\n IncludeProps extends LayoutIncludeProps<Resources, InProps, Composables>,\n CustomProps extends InPropsObject,\n> = [keyof Composables] extends [never]\n ? {}\n : {\n makeComposable: CreateResourceLayoutMakeComposableFn<\n Resources,\n InProps,\n Composables,\n IncludeProps,\n CustomProps\n >;\n };\n\nexport type CreateResourceLayoutFn<\n Resources extends ReadonlyArray<ResourceDefinition>,\n InProps extends InPropsDefinition<Resources>,\n Composables extends ComposableComponents = {},\n IncludeProps extends LayoutIncludeProps<Resources, InProps, Composables> = {},\n CustomProps extends InPropsObject = {},\n> = CreateResourceLayoutFnBase<\n Resources,\n InProps,\n Composables,\n IncludeProps,\n CustomProps\n> &\n CreateResourceLayoutMakeComposableMember<\n Resources,\n InProps,\n Composables,\n IncludeProps,\n CustomProps\n >;\n\ntype DefinedResourceLayout<\n Resources extends ReadonlyArray<ResourceDefinition>,\n InProps extends InPropsDefinition<Resources>,\n Composables extends ComposableComponents = {},\n IncludeProps extends LayoutIncludeProps<Resources, InProps, Composables> = {},\n CustomProps extends InPropsObject = {},\n> = {\n createResourceConfig: CreateResourceConfigFn<Resources>;\n createResourceLayout: CreateResourceLayoutFn<\n Resources,\n InProps,\n Composables,\n IncludeProps,\n CustomProps\n >;\n createResourceLinks: CreateResourceLinksFn<Resources>;\n /**\n * Accessor for the resources bound to this definition. Call `resources()` for\n * the raw value, or `resources.pick(...)` / `resources.omit(...)` to filter.\n */\n resources: LayoutResourcesAccessor<Resources>;\n};\n\nfunction readResourceSlug(resource: ResourceDefinition) {\n return typeof resource === 'string' ? resource : resource.value;\n}\n\nfunction assertUnreservedResourceSlugs(\n resources: ReadonlyArray<ResourceDefinition>,\n owner?: string,\n) {\n for (const resource of resources) {\n const slug = readResourceSlug(resource);\n\n if (owner !== undefined && isResourceConfigComponentKey(slug)) {\n throw new InvalidConfigError({\n reason: `Sub-resource \"${slug}\" under \"${owner}\" collides with a reserved config key`,\n });\n }\n\n if (typeof resource !== 'string') {\n assertUnreservedResourceSlugs(resource.subResources, slug);\n }\n }\n}\n\nfunction defineResourceLayoutImpl<\n const Resources extends ReadonlyArray<ResourceDefinition>,\n InProps extends InPropsDefinition<Resources> = {},\n Composables extends ComposableComponents = {},\n const IncludeProps extends LayoutIncludeProps<\n Resources,\n InProps,\n Composables\n > = {},\n CustomProps extends InPropsObject = {},\n>(\n options: CreateViewMapOptions<\n Resources,\n InProps,\n Composables,\n IncludeProps,\n CustomProps\n >,\n): DefinedResourceLayout<\n Resources,\n InProps,\n Composables,\n IncludeProps,\n CustomProps\n> {\n const { options: inProps = {} as InProps, resources, layout } = options;\n // Internal, set only by `defineResourceLayout.withLayout`: the identity of the\n // owning definition, forwarded when a page reports its resource so the shell\n // can tell its own pages apart from ones belonging to another definition.\n const shellId = (options as { shellId?: symbol }).shellId;\n\n assertUnreservedResourceSlugs(resources);\n\n const resourcesAccessor = createLayoutResourcesAccessor(resources);\n const normalizedResources = normalizeResources(resources);\n const resourcesEnum = createPrimitivePropBuilder('string').enum(\n toResourceEnum(normalizedResources),\n );\n const definedResourceLayout = (<\n Name extends string,\n Resource extends LayoutResourceKey<Resources>,\n Props extends InPropsObject = {},\n >(\n layoutOptions: CreateResourceLayoutOptions<\n Resources,\n InProps,\n Composables,\n IncludeProps,\n Name,\n Resource,\n Props\n >,\n ) => {\n const {\n name,\n props: instancePropDefinitions,\n ...layoutOptionProps\n } = layoutOptions;\n const createComposableLayout =\n makeComposable<\n LayoutRenderProps<\n Resources,\n InProps,\n Composables,\n IncludeProps,\n CustomProps\n >\n >();\n const nameProp = createProp.string().literal(name);\n const rawResolvedOptions =\n typeof inProps === 'function'\n ? inProps({\n resource: resourcesEnum,\n name: nameProp,\n })\n : inProps;\n const { resolvedInProps, splitInProps } = splitLayoutInProps({\n ...(rawResolvedOptions as Record<string, unknown>),\n ...(instancePropDefinitions as Record<string, unknown> | undefined),\n ...layoutOptionProps,\n });\n const { composables, render, props: layoutProps } = layout;\n const customLayoutProps = layoutProps?.custom;\n const includeLayoutProps = layoutProps?.include;\n const layoutOptionValues = layoutOptionProps as Record<string, unknown>;\n const resolvedLayoutProps = {\n ...customLayoutProps,\n };\n const layoutContext: ComposableNameContext<\n LayoutResourceKey<Resources>,\n typeof name\n > = {\n resource: layoutOptions.resource,\n name,\n capitalize,\n };\n const validationContext = {\n layoutName: name,\n resource: layoutContext.resource,\n };\n const resolvedComposables = composables\n ? resolveLayoutComposables(composables, layoutContext)\n : undefined;\n const mergedResolvedInProps = { ...resolvedInProps };\n\n for (const {\n props: presetPropDefinitions,\n } of collectComposablePresetEntries(resolvedComposables)) {\n Object.assign(mergedResolvedInProps, presetPropDefinitions);\n }\n\n const composablePresetProps = Object.fromEntries(\n collectComposablePresetEntries(resolvedComposables).map(\n ({ key, props: presetPropDefinitions }) => {\n const presetPropEntries = Object.entries(presetPropDefinitions);\n const validatedDefinitions = Object.fromEntries(\n presetPropEntries.filter(([propKey]) => {\n const includeBehavior = includeLayoutProps?.[propKey];\n\n return (\n includeBehavior === undefined ||\n (allowsConfigPassthrough(includeBehavior) &&\n (isIncludedPropRequired(includeBehavior) ||\n layoutOptionValues[propKey] !== undefined))\n );\n }),\n );\n const presetPropValues = Object.fromEntries(\n presetPropEntries.flatMap(([propKey]) =>\n propKey in layoutOptionValues\n ? [[propKey, layoutOptionValues[propKey]]]\n : [],\n ),\n );\n\n return [\n key,\n validateProps(\n validatedDefinitions as Record<string, AnyBuiltPropDefinition>,\n presetPropValues,\n validationContext,\n ),\n ];\n },\n ),\n );\n const mergedRenderContext = {\n composables: resolvedComposables as LayoutRenderComposables<Composables>,\n resource: layoutContext.resource,\n resources: createLayoutRenderResourcesAccessor(\n resources as Resources,\n layoutContext.resource,\n ),\n name: layoutContext.name,\n inProps: splitInProps,\n } as LayoutRenderContext<Resources, Composables>;\n\n function Component(\n props: Show<\n ResolveProps<CustomProps> &\n ResolvedIncludedComponentProps<\n MergedLayoutInProps<Resources, InProps, Composables>,\n IncludeProps\n >\n >,\n ) {\n const publishResource = useResourceLayoutShellPublisher();\n\n // Report the resource this page renders for so an ancestor `Shell` (from\n // `defineResourceLayout.withLayout`) can resolve `resources.current` for\n // its own render without the consumer threading a route param down to it.\n // A layout effect, not a passive one, so the shell reflects the new\n // resource in the same commit the page mounts — a passive effect would\n // leave one painted frame of stale shell chrome mid-navigation. Degrades\n // to a no-op when rendered without a `Shell` (context defaults to null).\n useLayoutEffect(() => {\n publishResource?.(layoutContext.resource, shellId);\n\n return () => publishResource?.(undefined, shellId);\n }, [publishResource, layoutContext.resource]);\n\n const validatedProps = validateProps(resolvedLayoutProps, props, {\n ...validationContext,\n });\n const includedPropKeys = Object.keys(includeLayoutProps ?? {});\n const includedPropDefinitions = pick(\n mergedResolvedInProps,\n includedPropKeys,\n ) as Record<string, unknown>;\n const includedPropValues = {\n ...resolvePropDefinitionValues(includedPropDefinitions),\n } as Record<string, unknown>;\n\n for (const key of includedPropKeys) {\n const definition = mergedResolvedInProps[key];\n const includeBehavior = includeLayoutProps?.[key];\n const callSiteValue = allowsComponentPassthrough(includeBehavior)\n ? readLayoutOptionValue(\n key,\n definition,\n props as Record<string, unknown>,\n )\n : undefined;\n const layoutOptionValue = allowsConfigPassthrough(includeBehavior)\n ? readLayoutOptionValue(key, definition, layoutOptionValues)\n : undefined;\n const splitValue = key in splitInProps ? splitInProps[key] : undefined;\n const value = callSiteValue ?? layoutOptionValue ?? splitValue;\n\n if (value !== undefined) {\n includedPropValues[key] = value;\n }\n }\n\n const requiredIncludedPropDefinitions = Object.fromEntries(\n Object.entries(includedPropDefinitions).filter(([key]) =>\n isIncludedPropRequired(includeLayoutProps?.[key]),\n ),\n );\n const optionalIncludedPropDefinitions = Object.fromEntries(\n Object.entries(includedPropDefinitions).filter(\n ([key]) =>\n !isIncludedPropRequired(includeLayoutProps?.[key]) &&\n includedPropValues[key] !== undefined,\n ),\n );\n const validatedIncludedProps = validateProps(\n {\n ...requiredIncludedPropDefinitions,\n ...optionalIncludedPropDefinitions,\n } as Record<string, AnyBuiltPropDefinition>,\n includedPropValues,\n validationContext,\n );\n const layoutRenderIncludedProps = Object.fromEntries(\n includedPropKeys.flatMap((key) => {\n if (!(key in validatedIncludedProps)) {\n return [];\n }\n\n return [\n [\n toLayoutRenderPropKey(key, mergedResolvedInProps[key]),\n validatedIncludedProps[\n key as keyof typeof validatedIncludedProps\n ],\n ],\n ];\n }),\n );\n const layoutRenderProps = {\n ...validatedProps,\n ...layoutRenderIncludedProps,\n } as unknown as LayoutRenderProps<\n Resources,\n InProps,\n Composables,\n IncludeProps,\n CustomProps\n >;\n\n return (\n <LayoutComposablePresetProvider value={composablePresetProps}>\n {render(layoutRenderProps, mergedRenderContext)}\n </LayoutComposablePresetProvider>\n );\n }\n\n function createComposition<\n LayoutName extends string,\n const Defined extends MakeComposableOptions<Composables, LayoutName>,\n >(compositionOptions: Defined) {\n if (!compositionOptions.components) {\n return {} as ResourceLayoutComposition<LayoutName, Composables>;\n }\n\n return {\n makeComposable: createComposableLayout(\n compositionOptions,\n ) as MakeComposable<Composables, LayoutName>,\n };\n }\n\n return Object.assign(Component, {\n displayName: name,\n props: undefined as unknown as Show<\n ResolveProps<CustomProps> &\n ResolvedIncludedComponentProps<\n MergedLayoutInProps<Resources, InProps, Composables>,\n IncludeProps\n >\n >,\n resource: undefined as unknown as Resource,\n ...createComposition({\n components: resolvedComposables as Composables | undefined,\n name,\n }),\n });\n }) as CreateResourceLayoutFnImpl<\n Resources,\n InProps,\n Composables,\n IncludeProps,\n CustomProps\n >;\n const createTopLevelMakeComposable = () => {\n return (options: Record<string, unknown>) => {\n const layout = definedResourceLayout(options as never);\n\n if (\n !('makeComposable' in layout) ||\n typeof layout.makeComposable !== 'function'\n ) {\n throw new Error(\n 'makeComposable requires composables to be defined in the layout',\n );\n }\n\n return layout.makeComposable();\n };\n };\n\n function getComponentPropDefinitions(resource: LayoutResourceKey<Resources>) {\n const componentName = 'ScopedResourceComponent';\n const rawResolvedOptions =\n typeof inProps === 'function'\n ? inProps({\n resource: resourcesEnum,\n name: createProp.string().literal(componentName),\n })\n : inProps;\n const { resolvedInProps } = splitLayoutInProps(\n rawResolvedOptions as Record<string, unknown>,\n );\n const resolvedComposables = layout.composables\n ? resolveLayoutComposables(layout.composables, {\n resource,\n name: componentName,\n capitalize,\n })\n : undefined;\n\n for (const {\n props: presetPropDefinitions,\n } of collectComposablePresetEntries(resolvedComposables)) {\n Object.assign(resolvedInProps, presetPropDefinitions);\n }\n\n return {\n ...resolvedInProps,\n ...layout.props?.custom,\n };\n }\n\n const { createLayoutForResourceBuilder, forResource } = createForResource<\n Resources,\n InProps,\n Composables,\n IncludeProps,\n CustomProps\n >({\n createResourceLayout: definedResourceLayout as never,\n resolveLayoutOptionDefaults,\n });\n const forResources = createForResources<\n Resources,\n InProps,\n Composables,\n IncludeProps,\n CustomProps\n >({\n createLayoutForResource: createLayoutForResourceBuilder,\n ...(layout.composables\n ? { createMakeComposableLayout: createTopLevelMakeComposable }\n : {}),\n createResourceLayout: definedResourceLayout as never,\n getComponentPropDefinitions,\n });\n\n const createResourceLayoutExtras: {\n forResource: CreateLayoutForResource<\n Resources,\n InProps,\n Composables,\n IncludeProps,\n CustomProps\n >;\n forResources: CreateResourceLayoutForResourcesFn<\n Resources,\n InProps,\n Composables,\n IncludeProps,\n CustomProps\n >;\n makeComposable?: ReturnType<typeof createTopLevelMakeComposable>;\n } = {\n forResource,\n forResources,\n };\n\n if (layout.composables) {\n createResourceLayoutExtras.makeComposable = createTopLevelMakeComposable();\n }\n\n const createResourceLayout = Object.assign(\n definedResourceLayout,\n createResourceLayoutExtras,\n ) as CreateResourceLayoutFn<\n Resources,\n InProps,\n Composables,\n IncludeProps,\n CustomProps\n >;\n\n const createResourceLinks = createResourceLinksFn(resources);\n\n return {\n createResourceConfig,\n createResourceLayout,\n createResourceLinks,\n resources: resourcesAccessor,\n } as DefinedResourceLayout<\n Resources,\n InProps,\n Composables,\n IncludeProps,\n CustomProps\n >;\n}\n\ntype DefineResourceLayoutForResourcesOptions<\n Resources extends ReadonlyArray<ResourceDefinition>,\n InProps extends InPropsDefinition<Resources> = {},\n Composables extends ComposableComponents = {},\n IncludeProps extends LayoutIncludeProps<Resources, InProps, Composables> = {},\n CustomProps extends InPropsObject = {},\n ExtraResources extends ReadonlyArray<ResourceDefinition> = [],\n> = Omit<\n CreateViewMapOptions<\n Resources,\n InProps,\n Composables,\n IncludeProps,\n CustomProps\n >,\n 'resources'\n> & {\n /**\n * Additional resources to merge with those bound by\n * {@link defineResourceLayout.forResources}.\n */\n resources?: AssertUnreservedResources<ExtraResources>;\n};\n\ntype NonEmptyResourceDefinitions = readonly [\n ResourceDefinition,\n ...ResourceDefinition[],\n];\n\n/**\n * Factory returned by {@link DefineResourceLayout.forResources}.\n */\nexport type DefineResourceLayoutForResourcesFactory<\n BaseResources extends NonEmptyResourceDefinitions,\n> = <\n const ExtraResources extends ReadonlyArray<ResourceDefinition> = [],\n InProps extends InPropsDefinition<[...BaseResources, ...ExtraResources]> = {},\n Composables extends ComposableComponents = {},\n const IncludeProps extends LayoutIncludeProps<\n [...BaseResources, ...ExtraResources],\n InProps,\n Composables\n > = {},\n CustomProps extends InPropsObject = {},\n>(\n options: DefineResourceLayoutForResourcesOptions<\n [...BaseResources, ...ExtraResources],\n InProps,\n Composables,\n IncludeProps,\n CustomProps,\n ExtraResources\n >,\n) => DefinedResourceLayout<\n [...BaseResources, ...ExtraResources],\n InProps,\n Composables,\n IncludeProps,\n CustomProps\n>;\n\n/**\n * Binds one or more resources, then accepts the remaining\n * {@link defineResourceLayout} options (with optional extra `resources`).\n */\nexport type DefineResourceLayoutForResources = <\n const Resources extends NonEmptyResourceDefinitions,\n>(\n ...resources: Resources\n) => DefineResourceLayoutForResourcesFactory<Resources>;\n\n/**\n * Creates a resource layout definition for a set of resources.\n */\nexport type DefineResourceLayoutFn = {\n <\n const Resources extends ReadonlyArray<ResourceDefinition>,\n InProps extends InPropsDefinition<Resources> = {},\n Composables extends ComposableComponents = {},\n const IncludeProps extends LayoutIncludeProps<\n Resources,\n InProps,\n Composables\n > = {},\n CustomProps extends InPropsObject = {},\n >(\n options: CreateViewMapOptions<\n Resources,\n InProps,\n Composables,\n IncludeProps,\n CustomProps\n >,\n ): DefinedResourceLayout<\n Resources,\n InProps,\n Composables,\n IncludeProps,\n CustomProps\n >;\n};\n\n/**\n * Captures a `resources` array with its literal tuple type intact, so it can be\n * declared separately from the `defineResourceLayout` call without needing an\n * `as const` assertion.\n */\nexport type DefineResourcesFn = <\n const Resources extends ReadonlyArray<ResourceDefinition>,\n>(\n ...resources: Resources\n) => Resources;\n\nfunction defineResources<\n const Resources extends ReadonlyArray<ResourceDefinition>,\n>(...resources: Resources): Resources {\n return resources;\n}\n\nexport type DefineResourceLayout = DefineResourceLayoutFn & {\n forResources: DefineResourceLayoutForResources;\n /**\n * Builds a strongly-typed `resources` array to pass to `defineResourceLayout`\n * (or `defineResourceLayout.forResources`) without an `as const` assertion.\n */\n defineResources: DefineResourcesFn;\n /**\n * Like {@link defineResourceLayout}, but also returns a `Shell` component.\n *\n * With plain `defineResourceLayout`, every page is wrapped in its own\n * `createResourceLayout` component, so navigating between resources unmounts\n * one page component and mounts another — the shared chrome the `render`\n * produces (a sidebar, a header, subscriptions, observers) is rebuilt every\n * time. `withLayout` splits that chrome into a `shell` that mounts once,\n * above the router outlet, and stays mounted across navigation; pages mount\n * and unmount inside it and report their resource up automatically.\n */\n withLayout: DefineResourceLayoutWithLayoutFn;\n};\n\nfunction defineResourceLayoutForResources<\n const Resources extends NonEmptyResourceDefinitions,\n>(\n ...baseResources: Resources\n): DefineResourceLayoutForResourcesFactory<Resources> {\n return ((options) => {\n const { resources: extraResources, ...rest } = options;\n const resources = extraResources\n ? [...baseResources, ...extraResources]\n : [...baseResources];\n\n return defineResourceLayoutImpl({\n ...rest,\n resources,\n } as never);\n }) as DefineResourceLayoutForResourcesFactory<Resources>;\n}\n\n/* -------------------------------------------------------------------------- */\n/* defineResourceLayout.withLayout — a once-mounted application shell */\n/* -------------------------------------------------------------------------- */\n\n/**\n * Render context passed as the second argument to\n * {@link ShellLayoutDefinition.render}.\n *\n * The same shape as a per-resource `render` context (`composables`,\n * `resources`, `name`, `inProps`), with two differences that follow from the\n * shell being mounted once above the router outlet rather than per page:\n *\n * - `resource` / `resources.current` are `LayoutResourceKey | undefined`. The\n * shell outlives any single page, so the current resource is whatever the\n * mounted page last reported (or the `resource` prop, or nothing yet).\n * - `children` is the shell's content region. Render it where page content\n * belongs; it is already wrapped so mounted pages report their resource back.\n */\nexport type ShellRenderContext<\n Resources extends ReadonlyArray<ResourceDefinition>,\n ShellComposables extends ComposableComponents,\n> = {\n composables: LayoutRenderComposables<ShellComposables>;\n inProps: Record<string, unknown>;\n /**\n * The resource currently rendered in the outlet, or `undefined` when no\n * per-resource page is mounted and no `resource` prop was passed.\n */\n resource: LayoutResourceKey<Resources> | undefined;\n /**\n * Resources accessor for this definition. `current` follows `resource` above\n * and may be `undefined`.\n */\n resources: LayoutResourcesAccessor<Resources> & {\n readonly current: LayoutResourceKey<Resources> | undefined;\n };\n name: string;\n /**\n * The shell's content region — typically a router `<Outlet />`. Render it\n * where page content belongs.\n */\n children: ReactNode;\n};\n\n/**\n * The `shell` block of a {@link defineResourceLayout.withLayout} call: the\n * chrome that mounts once and stays mounted while pages navigate inside it.\n *\n * Mirrors {@link LayoutDefinition} (`props`, `composables`, `render`) so the\n * two blocks read the same, plus an optional `name`.\n */\nexport type ShellLayoutDefinition<\n Resources extends ReadonlyArray<ResourceDefinition>,\n Options extends InPropsDefinition<Resources>,\n ShellComposables extends ComposableComponents,\n ShellIncludeProps extends LayoutIncludeProps<\n Resources,\n Options,\n ShellComposables\n >,\n ShellCustomProps extends InPropsObject,\n> = {\n /**\n * Stable name for the shell component (React DevTools) and the base for any\n * resource-scoped composable names. Defaults to `'ResourceLayoutShell'`.\n */\n name?: string;\n props?: LayoutProps<\n Resources,\n Options,\n ShellComposables,\n ShellIncludeProps,\n ShellCustomProps\n >;\n composables?: (\n create: CreateLayoutComposable<LayoutResourceKey<Resources>>,\n ) => ShellComposables;\n render: (\n props: LayoutRenderProps<\n Resources,\n Options,\n ShellComposables,\n ShellIncludeProps,\n ShellCustomProps\n >,\n context: ShellRenderContext<Resources, ShellComposables>,\n ) => JSX.Element;\n};\n\n/**\n * Props accepted by the `Shell` component from\n * {@link defineResourceLayout.withLayout}.\n */\nexport type ResourceLayoutShellProps<\n Resources extends ReadonlyArray<ResourceDefinition>,\n Options extends InPropsDefinition<Resources>,\n ShellComposables extends ComposableComponents,\n ShellIncludeProps extends LayoutIncludeProps<\n Resources,\n Options,\n ShellComposables\n >,\n ShellCustomProps extends InPropsObject,\n> = Show<\n ResolveProps<ShellCustomProps> &\n ResolvedIncludedComponentProps<\n MergedLayoutInProps<Resources, Options, ShellComposables>,\n ShellIncludeProps\n > & {\n /**\n * The resource the shell renders for. Overrides the value reported by the\n * page mounted in `children`. Always available — pass it from tests,\n * stories, or a route that renders non-library content but still wants\n * the shell.\n */\n resource?: LayoutResourceKey<Resources>;\n /** The shell's content region — typically a router `<Outlet />`. */\n children: ReactNode;\n }\n>;\n\n/**\n * The once-mounted application shell returned from\n * {@link defineResourceLayout.withLayout}. Wrap the router outlet with it.\n */\nexport type ResourceLayoutShellComponent<\n Resources extends ReadonlyArray<ResourceDefinition>,\n Options extends InPropsDefinition<Resources>,\n ShellComposables extends ComposableComponents = {},\n ShellIncludeProps extends LayoutIncludeProps<\n Resources,\n Options,\n ShellComposables\n > = {},\n ShellCustomProps extends InPropsObject = {},\n> = BaseComponent<\n string,\n ResourceLayoutShellProps<\n Resources,\n Options,\n ShellComposables,\n ShellIncludeProps,\n ShellCustomProps\n >\n> & {\n (\n props: ResourceLayoutShellProps<\n Resources,\n Options,\n ShellComposables,\n ShellIncludeProps,\n ShellCustomProps\n >,\n ): JSX.Element;\n};\n\n/**\n * Options for {@link defineResourceLayout.withLayout}: everything\n * {@link defineResourceLayout} accepts, plus a required `shell`, and with the\n * per-resource `layout.render` made optional.\n */\nexport type CreateResourceLayoutWithLayoutOptions<\n Resources extends ReadonlyArray<ResourceDefinition>,\n Options extends InPropsDefinition<Resources> = {},\n Composables extends ComposableComponents = {},\n IncludeProps extends LayoutIncludeProps<Resources, Options, Composables> = {},\n CustomProps extends InPropsObject = {},\n ShellComposables extends ComposableComponents = {},\n ShellIncludeProps extends LayoutIncludeProps<\n Resources,\n Options,\n ShellComposables\n > = {},\n ShellCustomProps extends InPropsObject = {},\n> = {\n /**\n * An array of valid resource names to support. Nested sub-resource slugs that\n * collide with config keys (`component`, `detail`, `new`, …) are reserved.\n */\n resources: AssertUnreservedResources<Resources>;\n /**\n * The options that are passed into the created resource layout. Shared by the\n * shell and the per-resource layout, so an `include` on either side can draw\n * from the same definitions.\n */\n options?: Options;\n /**\n * The once-mounted shell. The returned `Shell` wraps the router outlet and\n * stays mounted across resource navigation, so its composables (a persistent\n * sidebar, header, breadcrumb container, …) keep their state and DOM while\n * pages mount and unmount inside it.\n */\n shell: ShellLayoutDefinition<\n Resources,\n Options,\n ShellComposables,\n ShellIncludeProps,\n ShellCustomProps\n >;\n /**\n * Per-resource content. Optional here: when the shell renders the whole\n * chrome, a page is just a slot — omit `render` and the generated component\n * renders its own `children` into the shell's outlet. Provide it to give a\n * resource its own header, actions, or per-page structure.\n */\n layout?: Omit<\n LayoutDefinition<Resources, Options, Composables, IncludeProps, CustomProps>,\n 'render'\n > & {\n render?: LayoutDefinition<\n Resources,\n Options,\n Composables,\n IncludeProps,\n CustomProps\n >['render'];\n };\n};\n\n/**\n * {@link DefinedResourceLayout} plus the once-mounted `Shell`.\n */\nexport type DefinedResourceLayoutWithShell<\n Resources extends ReadonlyArray<ResourceDefinition>,\n Options extends InPropsDefinition<Resources>,\n Composables extends ComposableComponents = {},\n IncludeProps extends LayoutIncludeProps<Resources, Options, Composables> = {},\n CustomProps extends InPropsObject = {},\n ShellComposables extends ComposableComponents = {},\n ShellIncludeProps extends LayoutIncludeProps<\n Resources,\n Options,\n ShellComposables\n > = {},\n ShellCustomProps extends InPropsObject = {},\n> = DefinedResourceLayout<\n Resources,\n Options,\n Composables,\n IncludeProps,\n CustomProps\n> & {\n /**\n * The application shell. Mount it once, wrapping the router outlet:\n *\n * ```tsx\n * function AdminRoute() {\n * const resource = Route.useParams({ select: (p) => p.resource });\n * return (\n * <Shell resource={resource}>\n * <Outlet />\n * </Shell>\n * );\n * }\n * ```\n *\n * Passing `resource` is optional: a page created by `createResourceLayout`\n * reports its own resource to the shell automatically. Pass it for routes\n * that render non-library content, or in tests and stories.\n */\n Shell: ResourceLayoutShellComponent<\n Resources,\n Options,\n ShellComposables,\n ShellIncludeProps,\n ShellCustomProps\n >;\n};\n\n/**\n * Signature of {@link defineResourceLayout.withLayout}.\n */\nexport type DefineResourceLayoutWithLayoutFn = <\n const Resources extends ReadonlyArray<ResourceDefinition>,\n Options extends InPropsDefinition<Resources> = {},\n Composables extends ComposableComponents = {},\n const IncludeProps extends LayoutIncludeProps<\n Resources,\n Options,\n Composables\n > = {},\n CustomProps extends InPropsObject = {},\n ShellComposables extends ComposableComponents = {},\n const ShellIncludeProps extends LayoutIncludeProps<\n Resources,\n Options,\n ShellComposables\n > = {},\n ShellCustomProps extends InPropsObject = {},\n>(\n options: CreateResourceLayoutWithLayoutOptions<\n Resources,\n Options,\n Composables,\n IncludeProps,\n CustomProps,\n ShellComposables,\n ShellIncludeProps,\n ShellCustomProps\n >,\n) => DefinedResourceLayoutWithShell<\n Resources,\n Options,\n Composables,\n IncludeProps,\n CustomProps,\n ShellComposables,\n ShellIncludeProps,\n ShellCustomProps\n>;\n\n/**\n * Loose runtime shape of a `shell` block, used by the impl below.\n */\ntype ShellLayoutRuntime = {\n name?: string;\n composables?: (create: unknown) => ComposableComponents;\n props?: {\n include?: Record<string, unknown>;\n custom?: Record<string, unknown>;\n };\n render: (\n props: Record<string, unknown>,\n context: Record<string, unknown>,\n ) => JSX.Element;\n};\n\n/**\n * Builds the `Shell` component. Kept beside {@link defineResourceLayoutImpl} so\n * it can reuse the same private prop-resolution helpers.\n *\n * Unlike a per-resource component, the shell re-reads the current resource on\n * every render (reported by the mounted page) so resource-scoped composable\n * *names* can update. Composable *component identities* are resolved once and\n * kept stable: React reconciles by element type, so recreating\n * `composables.Layout` each render would remount wrapWith targets, sidebar\n * state, and the outlet. Display names are synced onto those stable functions\n * when the resource changes.\n *\n * @param shellId - Identity of the owning `withLayout` definition. The shell\n * only accepts resource reports tagged with this id, so a page or pane from a\n * different definition rendered in the outlet cannot corrupt its state.\n */\nfunction createResourceLayoutShellComponent(\n resources: ReadonlyArray<ResourceDefinition>,\n inProps:\n | InPropsObject\n | ((opts: Record<string, unknown>) => InPropsObject),\n shell: ShellLayoutRuntime,\n shellId: symbol,\n) {\n const shellName = shell.name ?? 'ResourceLayoutShell';\n // `resources` is the wide `ResourceDefinition[]` here (not the const generic\n // that `defineResourceLayoutImpl` captures), so the normalize/enum types are\n // erased to keep TS from trying to instantiate them structurally. Only the\n // runtime key list matters — the shell validates against it, it does not\n // surface it in a public type.\n const resourceKeys = Object.keys(\n normalizeResources(resources as never) as Record<string, unknown>,\n );\n const resourcesEnum = createPrimitivePropBuilder('string').enum(\n resourceKeys as never,\n );\n\n // `options` may be a function of `{ resource, name }`. The shell has no single\n // resource, so — like the component path in `defineResourceLayoutImpl` — the\n // enum stands in for `resource` while resolving the definitions.\n const rawResolvedOptions =\n typeof inProps === 'function'\n ? inProps({\n resource: resourcesEnum,\n name: createProp.string().literal(shellName),\n })\n : inProps;\n const { resolvedInProps, splitInProps } = splitLayoutInProps(\n rawResolvedOptions as Record<string, unknown>,\n );\n\n const includeShellProps = shell.props?.include;\n const includeShellPropKeys = Object.keys(includeShellProps ?? {});\n const shellCustomDefinitions = {\n ...(shell.props?.custom ?? {}),\n } as Record<string, AnyBuiltPropDefinition>;\n\n function syncShellComposableDisplayNames(\n stable: ComposableComponents,\n resource: string,\n ) {\n if (!shell.composables) {\n return;\n }\n\n const named = resolveLayoutComposables(shell.composables as never, {\n resource,\n name: shellName,\n capitalize,\n } as never) as ComposableComponents;\n\n for (const [key, component] of Object.entries(named)) {\n const stableComponent = stable[key];\n\n if (\n typeof stableComponent === 'function' &&\n typeof component === 'function' &&\n 'displayName' in component\n ) {\n (stableComponent as { displayName?: string }).displayName = (\n component as { displayName?: string }\n ).displayName;\n }\n }\n }\n\n function Shell(props: Record<string, unknown>) {\n const { children: outlet, resource: resourceProp } = props as {\n children: ReactNode;\n resource?: string;\n };\n\n // Which resource is currently in the outlet. A per-resource page reports its\n // own resource here on mount (see the layout effect in `Component`);\n // `undefined` between pages or on a route with no per-resource layout. An\n // explicit `resource` prop always wins.\n const [reportedResource, setReportedResource] = useState<\n string | undefined\n >(undefined);\n const publishResource = useCallback<ResourceLayoutShellPublisher>(\n (resource, ownerId) => {\n // Ignore reports from components that belong to a different\n // `defineResourceLayout` definition — they share this context but their\n // resource is unrelated to this shell.\n if (ownerId !== shellId) {\n return;\n }\n\n setReportedResource(resource);\n },\n [],\n );\n const resource = resourceProp ?? reportedResource;\n\n // The outlet subtree must not re-render when `reportedResource` changes —\n // only the shell chrome should. Memoising the wrapped element lets React\n // bail out of reconciling the page while, say, the breadcrumb label updates.\n const shellChildren = useMemo(\n () => (\n <ResourceLayoutShellPublisherContext.Provider value={publishResource}>\n {outlet}\n </ResourceLayoutShellPublisherContext.Provider>\n ),\n [outlet, publishResource],\n );\n\n // Resolve composables once so `<composables.Layout>` keeps a stable element\n // type across Shell re-renders (including the layout-effect resource report).\n // Re-resolving every render would allocate new component functions and React\n // would remount the whole chrome tree. Names still track the live resource\n // via {@link syncShellComposableDisplayNames}.\n const composablesRef = useRef<ComposableComponents | undefined>(undefined);\n if (shell.composables) {\n const nameContextResource = resource ?? '';\n\n if (!composablesRef.current) {\n composablesRef.current = resolveLayoutComposables(\n shell.composables as never,\n {\n resource: nameContextResource,\n name: shellName,\n capitalize,\n } as never,\n ) as ComposableComponents;\n } else {\n syncShellComposableDisplayNames(\n composablesRef.current,\n nameContextResource,\n );\n }\n }\n const resolvedComposables = composablesRef.current;\n const validationContext = {\n layoutName: shellName,\n resource: resource ?? '',\n };\n\n const mergedResolvedInProps = { ...resolvedInProps } as Record<\n string,\n unknown\n >;\n for (const {\n props: presetPropDefinitions,\n } of collectComposablePresetEntries(resolvedComposables)) {\n Object.assign(mergedResolvedInProps, presetPropDefinitions);\n }\n\n // Included props: definition-time defaults from `options`, overridden by\n // anything passed to `<Shell>` (component passthrough). Computed before\n // preset validation so config-passthrough includes can reuse the defaults.\n const includedPropDefinitions = pick(\n mergedResolvedInProps,\n includeShellPropKeys,\n ) as Record<string, unknown>;\n const includedPropValues = {\n ...resolvePropDefinitionValues(includedPropDefinitions),\n } as Record<string, unknown>;\n\n for (const key of includeShellPropKeys) {\n const definition = mergedResolvedInProps[key];\n const behavior = includeShellProps?.[key];\n const callSiteValue = allowsComponentPassthrough(behavior)\n ? readLayoutOptionValue(key, definition, props)\n : undefined;\n // Config passthrough has no create-time call on Shell; still honour\n // literal / split defaults from `options` when present.\n const configValue = allowsConfigPassthrough(behavior)\n ? readLayoutOptionValue(key, definition, {\n ...includedPropValues,\n ...splitInProps,\n })\n : undefined;\n const splitValue = key in splitInProps ? splitInProps[key] : undefined;\n const value = callSiteValue ?? configValue ?? splitValue;\n\n if (value !== undefined) {\n includedPropValues[key] = value;\n }\n }\n\n // Preset props: Shell has no create-time call. Component-passthrough values\n // come from `<Shell>` props; config-passthrough values only from definition\n // defaults. Required config includes without a default are omitted from\n // validation — they are not typed on Shell and cannot be supplied.\n const composablePresetProps = Object.fromEntries(\n collectComposablePresetEntries(resolvedComposables).map(\n ({ key, props: presetPropDefinitions }) => {\n const entries = Object.entries(presetPropDefinitions);\n const validatedDefinitions = Object.fromEntries(\n entries.filter(([propKey]) => {\n const behavior = includeShellProps?.[propKey];\n\n if (behavior === undefined) {\n return true;\n }\n\n if (allowsComponentPassthrough(behavior)) {\n return true;\n }\n\n if (allowsConfigPassthrough(behavior)) {\n return includedPropValues[propKey] !== undefined;\n }\n\n return false;\n }),\n );\n const values = Object.fromEntries(\n entries.flatMap(([propKey]) => {\n if (propKey in props) {\n return [[propKey, props[propKey]]];\n }\n\n if (includedPropValues[propKey] !== undefined) {\n return [[propKey, includedPropValues[propKey]]];\n }\n\n return [];\n }),\n );\n\n return [\n key,\n validateProps(\n validatedDefinitions as Record<string, AnyBuiltPropDefinition>,\n values,\n validationContext,\n ),\n ];\n },\n ),\n );\n\n const validatedCustomProps = validateProps(\n shellCustomDefinitions,\n props,\n validationContext,\n );\n\n const requiredIncludedDefinitions = Object.fromEntries(\n Object.entries(includedPropDefinitions).filter(([key]) => {\n const behavior = includeShellProps?.[key];\n\n if (!isIncludedPropRequired(behavior)) {\n return false;\n }\n\n // Component passthrough stays required on `<Shell>` (and is typed there).\n if (allowsComponentPassthrough(behavior)) {\n return true;\n }\n\n // Config passthrough: only require when a definition-time value exists.\n return includedPropValues[key] !== undefined;\n }),\n );\n const optionalIncludedDefinitions = Object.fromEntries(\n Object.entries(includedPropDefinitions).filter(\n ([key]) =>\n !isIncludedPropRequired(includeShellProps?.[key]) &&\n includedPropValues[key] !== undefined,\n ),\n );\n const validatedIncludedProps = validateProps(\n {\n ...requiredIncludedDefinitions,\n ...optionalIncludedDefinitions,\n } as Record<string, AnyBuiltPropDefinition>,\n includedPropValues,\n validationContext,\n );\n const renderIncludedProps = Object.fromEntries(\n includeShellPropKeys.flatMap((key) =>\n key in validatedIncludedProps\n ? [\n [\n toLayoutRenderPropKey(key, mergedResolvedInProps[key]),\n validatedIncludedProps[\n key as keyof typeof validatedIncludedProps\n ],\n ],\n ]\n : [],\n ),\n );\n\n const renderProps = { ...validatedCustomProps, ...renderIncludedProps };\n const renderContext = {\n composables: resolvedComposables,\n resource,\n resources: createLayoutRenderResourcesAccessor(\n resources as ReadonlyArray<ResourceDefinition>,\n resource as never,\n ),\n name: shellName,\n inProps: splitInProps,\n children: shellChildren,\n };\n\n const rendered = shell.render(renderProps, renderContext);\n\n return resolvedComposables ? (\n <LayoutComposablePresetProvider value={composablePresetProps}>\n {rendered}\n </LayoutComposablePresetProvider>\n ) : (\n rendered\n );\n }\n\n return Object.assign(Shell, {\n displayName: shellName,\n props: undefined as never,\n });\n}\n\n/**\n * Implementation of {@link defineResourceLayout.withLayout}. Delegates the\n * config / links / `createResourceLayout` pieces to {@link defineResourceLayoutImpl}\n * and adds the {@link createResourceLayoutShellComponent | Shell}.\n */\nfunction defineResourceLayoutWithLayoutImpl(\n options: Record<string, unknown>,\n): Record<string, unknown> {\n const {\n shell,\n layout,\n resources,\n options: inProps,\n } = options as {\n shell: ShellLayoutRuntime;\n layout?: {\n composables?: unknown;\n props?: { include?: unknown; custom?: Record<string, unknown> };\n render?: (\n props: Record<string, unknown>,\n context: unknown,\n ) => JSX.Element;\n };\n resources: ReadonlyArray<ResourceDefinition>;\n options?:\n | InPropsObject\n | ((opts: Record<string, unknown>) => InPropsObject);\n };\n\n // The per-resource `render` is optional under `withLayout`. When omitted, the\n // page is a pure content slot: give it a `children` prop (so\n // `<UsersPage>{content}</UsersPage>` type-checks and works) and a render that\n // drops that content into the shell's outlet. An explicit `render` is passed\n // through untouched.\n const resolvedLayout = layout?.render\n ? layout\n : {\n ...layout,\n props: {\n ...layout?.props,\n custom: {\n children: createProp.component({ type: 'ReactNode' }).optional(),\n ...(layout?.props?.custom ?? {}),\n },\n },\n render: (pageProps: Record<string, unknown>) => (\n <>{(pageProps.children as ReactNode) ?? null}</>\n ),\n };\n\n // Ties the shell to the pages created by *its* `createResourceLayout`. Pages\n // from other definitions rendered in the outlet carry a different id (or\n // none) and are ignored by the shell's resource tracking.\n const shellId = Symbol('resourceLayoutShell');\n\n const base = defineResourceLayoutImpl({\n resources,\n options: inProps,\n layout: resolvedLayout,\n shellId,\n } as never) as Record<string, unknown>;\n\n const Shell = createResourceLayoutShellComponent(\n resources,\n (inProps ?? {}) as never,\n shell,\n shellId,\n );\n\n return { ...base, Shell };\n}\n\nexport const defineResourceLayout: DefineResourceLayout = Object.assign(\n defineResourceLayoutImpl as DefineResourceLayoutFn,\n {\n forResources: defineResourceLayoutForResources,\n defineResources,\n withLayout:\n defineResourceLayoutWithLayoutImpl as unknown as DefineResourceLayoutWithLayoutFn,\n },\n);\n"],"mappings":"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"}
@@ -5,8 +5,8 @@ import { SelectedLayoutResources } from "./resource-selection.mjs";
5
5
  import { ScopedRenderResult } from "./scoped-render.mjs";
6
6
  import { LayoutIncludeProps, LayoutProps } from "../define-layout.mjs";
7
7
  import { ComposableComponents } from "@jfdevelops/react-layout-composables";
8
- import { ResolveProps, ResolvedBuiltPropShape, SafeKeyOf } from "@jfdevelops/react-layout-validator";
9
8
  import { ComponentType, JSX, ReactNode } from "react";
9
+ import { ResolveProps, ResolvedBuiltPropShape, SafeKeyOf } from "@jfdevelops/react-layout-validator";
10
10
 
11
11
  //#region src/create-config/for-resources/create-component.d.ts
12
12
  type ScopedComponentAvailableProps<Resources extends ReadonlyArray<ResourceDefinition>, InProps extends InPropsDefinition<Resources>, Composables extends ComposableComponents, LayoutCustomProps extends InPropsObject> = MergedLayoutInProps<Resources, InProps, Composables> & LayoutCustomProps;
@@ -1,7 +1,7 @@
1
1
  const require_capitalize = require('../../utils/capitalize.cjs');
2
2
  const require_scoped_render = require('./scoped-render.cjs');
3
- let _jfdevelops_react_layout_validator = require("@jfdevelops/react-layout-validator");
4
3
  let react = require("react");
4
+ let _jfdevelops_react_layout_validator = require("@jfdevelops/react-layout-validator");
5
5
 
6
6
  //#region src/create-config/for-resources/create-for-resources.ts
7
7
  function createForResources({ createLayoutForResource, createMakeComposableLayout, createResourceLayout, getComponentPropDefinitions }) {
@@ -1,7 +1,7 @@
1
1
  import { capitalize } from "../../utils/capitalize.mjs";
2
2
  import { isRenderableComponentType, reservedScopedComponentNames, resolveScopedRenderResult, withScopedCompoundStatics } from "./scoped-render.mjs";
3
- import { validateProps } from "@jfdevelops/react-layout-validator";
4
3
  import { createContext, createElement, useContext } from "react";
4
+ import { validateProps } from "@jfdevelops/react-layout-validator";
5
5
 
6
6
  //#region src/create-config/for-resources/create-for-resources.ts
7
7
  function createForResources({ createLayoutForResource, createMakeComposableLayout, createResourceLayout, getComponentPropDefinitions }) {
@@ -6,4 +6,5 @@ import { ForPaths, ForPathsRenderContext, RenderedPathComponent, RenderedPathCom
6
6
  import { IsSubResourceKey, IsSubResourceKeyOptions, IsSubResourceKeyResult } from "./is-sub-resource-key.cjs";
7
7
  import { ComponentTypes, CreateResourceConfigFn, CreatedResourceConfig, GetComponent, GetComponentAtBound, GetComponentForResource, GetComponentForResourceOptions, GetComponentOptions, GetComponentOptionsForResource, ResourceConfigPath, ResourceFromGetComponentBound, SubResourceFromGetComponentBound, ValidateForResourceBound } from "./get-component.cjs";
8
8
  import { CreateResourceLinkConfig, CreateResourceLinkGroupInput, CreateResourceLinkGroupOptions, CreateResourceLinkOptions, CreateResourceLinksFn, CreateResourceLinksWithGroups, CreateResourceLinksWithGroupsFn, CreatedResourceHref, CreatedResourceLink, CreatedResourceLinkBase, InferHashFromResourceLinkHref, ResourceAnchorLinkFn, ResourceLinkHref } from "./create-resource-links.cjs";
9
- import { CreateResourceLayoutFn, CreateResourceLayoutMakeComposableOptions, DefineResourceLayout, DefineResourceLayoutFn, DefineResourceLayoutForResources, DefineResourceLayoutForResourcesFactory, DefineResourcesFn, LayoutRenderResourcesAccessor, LayoutResourcesAccessor, defineResourceLayout } from "./define-layout.cjs";
9
+ import { CreateResourceLayoutFn, CreateResourceLayoutMakeComposableOptions, CreateResourceLayoutWithLayoutOptions, DefineResourceLayout, DefineResourceLayoutFn, DefineResourceLayoutForResources, DefineResourceLayoutForResourcesFactory, DefineResourceLayoutWithLayoutFn, DefineResourcesFn, DefinedResourceLayoutWithShell, LayoutRenderResourcesAccessor, LayoutResourcesAccessor, ResourceLayoutShellComponent, ResourceLayoutShellProps, ResourceSelection, ShellLayoutDefinition, ShellRenderContext, defineResourceLayout } from "./define-layout.cjs";
10
+ import { ResourceLayoutShellPublisher } from "./shell-context.cjs";
@@ -6,4 +6,5 @@ import { ForPaths, ForPathsRenderContext, RenderedPathComponent, RenderedPathCom
6
6
  import { IsSubResourceKey, IsSubResourceKeyOptions, IsSubResourceKeyResult } from "./is-sub-resource-key.mjs";
7
7
  import { ComponentTypes, CreateResourceConfigFn, CreatedResourceConfig, GetComponent, GetComponentAtBound, GetComponentForResource, GetComponentForResourceOptions, GetComponentOptions, GetComponentOptionsForResource, ResourceConfigPath, ResourceFromGetComponentBound, SubResourceFromGetComponentBound, ValidateForResourceBound } from "./get-component.mjs";
8
8
  import { CreateResourceLinkConfig, CreateResourceLinkGroupInput, CreateResourceLinkGroupOptions, CreateResourceLinkOptions, CreateResourceLinksFn, CreateResourceLinksWithGroups, CreateResourceLinksWithGroupsFn, CreatedResourceHref, CreatedResourceLink, CreatedResourceLinkBase, InferHashFromResourceLinkHref, ResourceAnchorLinkFn, ResourceLinkHref } from "./create-resource-links.mjs";
9
- import { CreateResourceLayoutFn, CreateResourceLayoutMakeComposableOptions, DefineResourceLayout, DefineResourceLayoutFn, DefineResourceLayoutForResources, DefineResourceLayoutForResourcesFactory, DefineResourcesFn, LayoutRenderResourcesAccessor, LayoutResourcesAccessor, defineResourceLayout } from "./define-layout.mjs";
9
+ import { CreateResourceLayoutFn, CreateResourceLayoutMakeComposableOptions, CreateResourceLayoutWithLayoutOptions, DefineResourceLayout, DefineResourceLayoutFn, DefineResourceLayoutForResources, DefineResourceLayoutForResourcesFactory, DefineResourceLayoutWithLayoutFn, DefineResourcesFn, DefinedResourceLayoutWithShell, LayoutRenderResourcesAccessor, LayoutResourcesAccessor, ResourceLayoutShellComponent, ResourceLayoutShellProps, ResourceSelection, ShellLayoutDefinition, ShellRenderContext, defineResourceLayout } from "./define-layout.mjs";
10
+ import { ResourceLayoutShellPublisher } from "./shell-context.mjs";
@@ -0,0 +1,22 @@
1
+ let react = require("react");
2
+
3
+ //#region src/create-config/shell-context.tsx
4
+ /**
5
+ * Bridge between a `Shell` and the per-resource components rendered inside its
6
+ * `Outlet`. It is deliberately `null` by default: a per-resource component is
7
+ * still valid without a `Shell` ancestor (the pre-`withLayout` usage), so the
8
+ * publish must degrade to a no-op rather than assume a provider.
9
+ */
10
+ const ResourceLayoutShellPublisherContext = (0, react.createContext)(null);
11
+ /**
12
+ * Reads the {@link ResourceLayoutShellPublisher} installed by an ancestor
13
+ * `Shell`, or `null` when the component renders standalone.
14
+ */
15
+ function useResourceLayoutShellPublisher() {
16
+ return (0, react.useContext)(ResourceLayoutShellPublisherContext);
17
+ }
18
+
19
+ //#endregion
20
+ exports.ResourceLayoutShellPublisherContext = ResourceLayoutShellPublisherContext;
21
+ exports.useResourceLayoutShellPublisher = useResourceLayoutShellPublisher;
22
+ //# sourceMappingURL=shell-context.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"shell-context.cjs","names":[],"sources":["../../src/create-config/shell-context.tsx"],"sourcesContent":["import { createContext, useContext } from 'react';\n\n/**\n * Callback a per-resource layout component calls to report which resource it is\n * currently rendering. An ancestor `Shell` (from\n * {@link defineResourceLayout.withLayout}) installs one of these so it can\n * resolve `resources.current` for its own render without the consumer threading\n * a route param down to it.\n *\n * @param resource - The mounted resource, or `undefined` on unmount.\n * @param ownerId - Identity of the `defineResourceLayout` definition that\n * created the reporting component. The shell only accepts reports from its\n * own definition — a page or pane produced by a *different* definition shares\n * this context but its resource is unrelated, so the shell ignores it.\n */\nexport type ResourceLayoutShellPublisher = (\n resource: string | undefined,\n ownerId?: symbol,\n) => void;\n\n/**\n * Bridge between a `Shell` and the per-resource components rendered inside its\n * `Outlet`. It is deliberately `null` by default: a per-resource component is\n * still valid without a `Shell` ancestor (the pre-`withLayout` usage), so the\n * publish must degrade to a no-op rather than assume a provider.\n */\nexport const ResourceLayoutShellPublisherContext =\n createContext<ResourceLayoutShellPublisher | null>(null);\n\n/**\n * Reads the {@link ResourceLayoutShellPublisher} installed by an ancestor\n * `Shell`, or `null` when the component renders standalone.\n */\nexport function useResourceLayoutShellPublisher(): ResourceLayoutShellPublisher | null {\n return useContext(ResourceLayoutShellPublisherContext);\n}\n"],"mappings":";;;;;;;;;AA0BA,MAAa,+DACwC,IAAI;;;;;AAMzD,SAAgB,kCAAuE;CACrF,6BAAkB,mCAAmC;AACvD"}
@@ -0,0 +1,18 @@
1
+ //#region src/create-config/shell-context.d.ts
2
+ /**
3
+ * Callback a per-resource layout component calls to report which resource it is
4
+ * currently rendering. An ancestor `Shell` (from
5
+ * {@link defineResourceLayout.withLayout}) installs one of these so it can
6
+ * resolve `resources.current` for its own render without the consumer threading
7
+ * a route param down to it.
8
+ *
9
+ * @param resource - The mounted resource, or `undefined` on unmount.
10
+ * @param ownerId - Identity of the `defineResourceLayout` definition that
11
+ * created the reporting component. The shell only accepts reports from its
12
+ * own definition — a page or pane produced by a *different* definition shares
13
+ * this context but its resource is unrelated, so the shell ignores it.
14
+ */
15
+ type ResourceLayoutShellPublisher = (resource: string | undefined, ownerId?: symbol) => void;
16
+ //#endregion
17
+ export { ResourceLayoutShellPublisher };
18
+ //# sourceMappingURL=shell-context.d.cts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"shell-context.d.cts","names":[],"sources":["../../src/create-config/shell-context.tsx"],"mappings":";;AAeA;;;;AAEkB;;;;;;;;KAFN,4BAAA,IACV,QAAA,sBACA,OAAgB"}
@@ -0,0 +1,18 @@
1
+ //#region src/create-config/shell-context.d.ts
2
+ /**
3
+ * Callback a per-resource layout component calls to report which resource it is
4
+ * currently rendering. An ancestor `Shell` (from
5
+ * {@link defineResourceLayout.withLayout}) installs one of these so it can
6
+ * resolve `resources.current` for its own render without the consumer threading
7
+ * a route param down to it.
8
+ *
9
+ * @param resource - The mounted resource, or `undefined` on unmount.
10
+ * @param ownerId - Identity of the `defineResourceLayout` definition that
11
+ * created the reporting component. The shell only accepts reports from its
12
+ * own definition — a page or pane produced by a *different* definition shares
13
+ * this context but its resource is unrelated, so the shell ignores it.
14
+ */
15
+ type ResourceLayoutShellPublisher = (resource: string | undefined, ownerId?: symbol) => void;
16
+ //#endregion
17
+ export { ResourceLayoutShellPublisher };
18
+ //# sourceMappingURL=shell-context.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"shell-context.d.mts","names":[],"sources":["../../src/create-config/shell-context.tsx"],"mappings":";;AAeA;;;;AAEkB;;;;;;;;KAFN,4BAAA,IACV,QAAA,sBACA,OAAgB"}
@@ -0,0 +1,21 @@
1
+ import { createContext, useContext } from "react";
2
+
3
+ //#region src/create-config/shell-context.tsx
4
+ /**
5
+ * Bridge between a `Shell` and the per-resource components rendered inside its
6
+ * `Outlet`. It is deliberately `null` by default: a per-resource component is
7
+ * still valid without a `Shell` ancestor (the pre-`withLayout` usage), so the
8
+ * publish must degrade to a no-op rather than assume a provider.
9
+ */
10
+ const ResourceLayoutShellPublisherContext = createContext(null);
11
+ /**
12
+ * Reads the {@link ResourceLayoutShellPublisher} installed by an ancestor
13
+ * `Shell`, or `null` when the component renders standalone.
14
+ */
15
+ function useResourceLayoutShellPublisher() {
16
+ return useContext(ResourceLayoutShellPublisherContext);
17
+ }
18
+
19
+ //#endregion
20
+ export { ResourceLayoutShellPublisherContext, useResourceLayoutShellPublisher };
21
+ //# sourceMappingURL=shell-context.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"shell-context.mjs","names":[],"sources":["../../src/create-config/shell-context.tsx"],"sourcesContent":["import { createContext, useContext } from 'react';\n\n/**\n * Callback a per-resource layout component calls to report which resource it is\n * currently rendering. An ancestor `Shell` (from\n * {@link defineResourceLayout.withLayout}) installs one of these so it can\n * resolve `resources.current` for its own render without the consumer threading\n * a route param down to it.\n *\n * @param resource - The mounted resource, or `undefined` on unmount.\n * @param ownerId - Identity of the `defineResourceLayout` definition that\n * created the reporting component. The shell only accepts reports from its\n * own definition — a page or pane produced by a *different* definition shares\n * this context but its resource is unrelated, so the shell ignores it.\n */\nexport type ResourceLayoutShellPublisher = (\n resource: string | undefined,\n ownerId?: symbol,\n) => void;\n\n/**\n * Bridge between a `Shell` and the per-resource components rendered inside its\n * `Outlet`. It is deliberately `null` by default: a per-resource component is\n * still valid without a `Shell` ancestor (the pre-`withLayout` usage), so the\n * publish must degrade to a no-op rather than assume a provider.\n */\nexport const ResourceLayoutShellPublisherContext =\n createContext<ResourceLayoutShellPublisher | null>(null);\n\n/**\n * Reads the {@link ResourceLayoutShellPublisher} installed by an ancestor\n * `Shell`, or `null` when the component renders standalone.\n */\nexport function useResourceLayoutShellPublisher(): ResourceLayoutShellPublisher | null {\n return useContext(ResourceLayoutShellPublisherContext);\n}\n"],"mappings":";;;;;;;;;AA0BA,MAAa,sCACX,cAAmD,IAAI;;;;;AAMzD,SAAgB,kCAAuE;CACrF,OAAO,WAAW,mCAAmC;AACvD"}
package/dist/index.d.cts CHANGED
@@ -1,12 +1,13 @@
1
1
  import { BaseComponent, MergeIntersection, Show, UnionToIntersection, pick } from "./utils.cjs";
2
- import { LayoutResourceKey, NormalizeResource, NormalizeResources, ResourceDefinition, ResourceEnum, ResourceLayoutComponentProps, ResourceTree, normalizeResource, normalizeResources, toResourceEnum } from "./resource.cjs";
2
+ import { LayoutResourceKey, NormalizeResource, NormalizeResources, ResourceDefinition, ResourceDefinitionValue, ResourceEnum, ResourceLayoutComponentProps, ResourceTree, normalizeResource, normalizeResources, toResourceEnum } from "./resource.cjs";
3
3
  import { InPropsDefinition, InPropsFunction, InPropsObject, InPropsOptions, IncludedPropBehavior, IncludedProps, InferredInProps, LayoutRenderProps, MergedLayoutInProps, PropsContextRender, PropsRenderDefinition, ResolvedIncludedComponentProps, ResolvedIncludedConfigProps, ResolvedIncludedProps, ResolvedIncludedPropsAsDefined } from "./props.cjs";
4
4
  import { ParameterizedResourcePath, PathVariables } from "./create-config/paths/types.cjs";
5
5
  import { CreateGetComponentForPath, GetComponentForPath, ResolvedPathValue } from "./create-config/for-paths/get-component-for-path.cjs";
6
6
  import { ForPaths, ForPathsRenderContext, RenderedPathComponent, RenderedPathComponentHOF, TargetPathBuilder } from "./create-config/for-paths/builder.cjs";
7
7
  import { IsSubResourceKey } from "./create-config/is-sub-resource-key.cjs";
8
8
  import { ComponentTypes, CreatedResourceConfig } from "./create-config/get-component.cjs";
9
- import { DefineResourcesFn, LayoutRenderResourcesAccessor, LayoutResourcesAccessor, defineResourceLayout } from "./create-config/define-layout.cjs";
9
+ import { CreateResourceLayoutWithLayoutOptions, DefineResourceLayoutWithLayoutFn, DefineResourcesFn, DefinedResourceLayoutWithShell, LayoutRenderResourcesAccessor, LayoutResourcesAccessor, ResourceLayoutShellComponent, ResourceLayoutShellProps, ResourceSelection, ShellLayoutDefinition, ShellRenderContext, defineResourceLayout } from "./create-config/define-layout.cjs";
10
+ import { ResourceLayoutShellPublisher } from "./create-config/shell-context.cjs";
10
11
  import { CreateReactLayoutErrorOptions, CreatedReactLayoutError, ErrorMessageRenderer, ReactLayoutError, ReactLayoutErrorContext, ReactLayoutErrorRendererFactory, createReactLayoutError } from "./errors/react-layout-error.cjs";
11
12
  import { InvalidConfigContext, InvalidConfigError } from "./errors/invalid-config.cjs";
12
13
  import { InvalidPathContext, InvalidPathError } from "./errors/invalid-path.cjs";
@@ -16,4 +17,4 @@ import { InvalidComponentContext, InvalidComponentError } from "./errors/invalid
16
17
  import { MissingPathVariableContext, MissingPathVariableError } from "./errors/missing-path-variable.cjs";
17
18
  import { AnyComposableComponent, ComposableComponent, ComposableComponentCallable, ComposableComponents, ComposableNameContext, ComposablePresetComponent, ComposablePresetComponentCallProps, ComposablePresetMeta, ComposablePresetProps, ComposableResourceLayout, CreateLayoutComposable, DefinedComposableComponentRecord, LayoutComposablePresetProvider, LayoutComposablesFactory, MakeComposable, MakeComposableOptions, MergePresetProps, PresetPropsFromComposable, RequiredPresetLayoutProps, RequiredPresetRenderProps, ResolveLayoutComposables, collectComposablePresetEntries, createComposableComponent, createLayoutComposableFactory, defineComposableComponent, makeComposable, resolveComposablePresetProps, resolveLayoutComposables } from "@jfdevelops/react-layout-composables";
18
19
  import { AnyBuiltPropDefinition, ExtractDefinitionValue, PropError, PropErrorOptions, ResolveLayoutProps, ResolveLayoutPropsAsDefined, ResolveProps, ResolvedBuiltPropShape, createPrimitivePropBuilder, createProp, isPropDefinitionShape, resolvePropDefinitionValues, validateProps } from "@jfdevelops/react-layout-validator";
19
- export { type AnyBuiltPropDefinition, type AnyComposableComponent, type BaseComponent, type ComponentTypes, type ComposableComponent, type ComposableComponentCallable, type ComposableComponents, type ComposableNameContext, type ComposablePresetComponent, type ComposablePresetComponentCallProps, type ComposablePresetMeta, type ComposablePresetProps, type ComposableResourceLayout, type CreateGetComponentForPath, type CreateLayoutComposable, type CreateReactLayoutErrorOptions, type CreatedReactLayoutError, type CreatedResourceConfig, type DefineResourcesFn, type DefinedComposableComponentRecord, type ErrorMessageRenderer, type ExtractDefinitionValue, type ForPaths, type ForPathsRenderContext, type GetComponentForPath, type InPropsDefinition, type InPropsFunction, type InPropsObject, type InPropsOptions, type IncludedPropBehavior, type IncludedProps, type InferredInProps, type InvalidComponentContext, InvalidComponentError, type InvalidConfigContext, InvalidConfigError, type InvalidPathContext, InvalidPathError, type InvalidResourceContext, InvalidResourceError, type InvalidSubResourceContext, InvalidSubResourceError, type IsSubResourceKey, LayoutComposablePresetProvider, type LayoutComposablesFactory, type LayoutRenderProps, type LayoutRenderResourcesAccessor, type LayoutResourceKey, type LayoutResourcesAccessor, type MakeComposable, type MakeComposableOptions, type MergeIntersection, type MergePresetProps, type MergedLayoutInProps, type MissingPathVariableContext, MissingPathVariableError, type NormalizeResource, type NormalizeResources, type ParameterizedResourcePath, type PathVariables, type PresetPropsFromComposable, PropError, type PropErrorOptions, type PropsContextRender, type PropsRenderDefinition, ReactLayoutError, type ReactLayoutErrorContext, type ReactLayoutErrorRendererFactory, type RenderedPathComponent, type RenderedPathComponentHOF, type RequiredPresetLayoutProps, type RequiredPresetRenderProps, type ResolveLayoutComposables, type ResolveLayoutProps, type ResolveLayoutPropsAsDefined, type ResolveProps, type ResolvedBuiltPropShape, type ResolvedIncludedComponentProps, type ResolvedIncludedConfigProps, type ResolvedIncludedProps, type ResolvedIncludedPropsAsDefined, type ResolvedPathValue, type ResourceDefinition, type ResourceEnum, type ResourceLayoutComponentProps, type ResourceTree, type Show, type TargetPathBuilder, type UnionToIntersection, collectComposablePresetEntries, createComposableComponent, createLayoutComposableFactory, createPrimitivePropBuilder, createProp, createReactLayoutError, defineComposableComponent, defineResourceLayout, isPropDefinitionShape, makeComposable, normalizeResource, normalizeResources, pick, resolveComposablePresetProps, resolveLayoutComposables, resolvePropDefinitionValues, toResourceEnum, validateProps };
20
+ export { type AnyBuiltPropDefinition, type AnyComposableComponent, type BaseComponent, type ComponentTypes, type ComposableComponent, type ComposableComponentCallable, type ComposableComponents, type ComposableNameContext, type ComposablePresetComponent, type ComposablePresetComponentCallProps, type ComposablePresetMeta, type ComposablePresetProps, type ComposableResourceLayout, type CreateGetComponentForPath, type CreateLayoutComposable, type CreateReactLayoutErrorOptions, type CreateResourceLayoutWithLayoutOptions, type CreatedReactLayoutError, type CreatedResourceConfig, type DefineResourceLayoutWithLayoutFn, type DefineResourcesFn, type DefinedComposableComponentRecord, type DefinedResourceLayoutWithShell, type ErrorMessageRenderer, type ExtractDefinitionValue, type ForPaths, type ForPathsRenderContext, type GetComponentForPath, type InPropsDefinition, type InPropsFunction, type InPropsObject, type InPropsOptions, type IncludedPropBehavior, type IncludedProps, type InferredInProps, type InvalidComponentContext, InvalidComponentError, type InvalidConfigContext, InvalidConfigError, type InvalidPathContext, InvalidPathError, type InvalidResourceContext, InvalidResourceError, type InvalidSubResourceContext, InvalidSubResourceError, type IsSubResourceKey, LayoutComposablePresetProvider, type LayoutComposablesFactory, type LayoutRenderProps, type LayoutRenderResourcesAccessor, type LayoutResourceKey, type LayoutResourcesAccessor, type MakeComposable, type MakeComposableOptions, type MergeIntersection, type MergePresetProps, type MergedLayoutInProps, type MissingPathVariableContext, MissingPathVariableError, type NormalizeResource, type NormalizeResources, type ParameterizedResourcePath, type PathVariables, type PresetPropsFromComposable, PropError, type PropErrorOptions, type PropsContextRender, type PropsRenderDefinition, ReactLayoutError, type ReactLayoutErrorContext, type ReactLayoutErrorRendererFactory, type RenderedPathComponent, type RenderedPathComponentHOF, type RequiredPresetLayoutProps, type RequiredPresetRenderProps, type ResolveLayoutComposables, type ResolveLayoutProps, type ResolveLayoutPropsAsDefined, type ResolveProps, type ResolvedBuiltPropShape, type ResolvedIncludedComponentProps, type ResolvedIncludedConfigProps, type ResolvedIncludedProps, type ResolvedIncludedPropsAsDefined, type ResolvedPathValue, type ResourceDefinition, type ResourceDefinitionValue, type ResourceEnum, type ResourceLayoutComponentProps, type ResourceLayoutShellComponent, type ResourceLayoutShellProps, type ResourceLayoutShellPublisher, type ResourceSelection, type ResourceTree, type ShellLayoutDefinition, type ShellRenderContext, type Show, type TargetPathBuilder, type UnionToIntersection, collectComposablePresetEntries, createComposableComponent, createLayoutComposableFactory, createPrimitivePropBuilder, createProp, createReactLayoutError, defineComposableComponent, defineResourceLayout, isPropDefinitionShape, makeComposable, normalizeResource, normalizeResources, pick, resolveComposablePresetProps, resolveLayoutComposables, resolvePropDefinitionValues, toResourceEnum, validateProps };
package/dist/index.d.mts CHANGED
@@ -1,12 +1,13 @@
1
1
  import { BaseComponent, MergeIntersection, Show, UnionToIntersection, pick } from "./utils.mjs";
2
- import { LayoutResourceKey, NormalizeResource, NormalizeResources, ResourceDefinition, ResourceEnum, ResourceLayoutComponentProps, ResourceTree, normalizeResource, normalizeResources, toResourceEnum } from "./resource.mjs";
2
+ import { LayoutResourceKey, NormalizeResource, NormalizeResources, ResourceDefinition, ResourceDefinitionValue, ResourceEnum, ResourceLayoutComponentProps, ResourceTree, normalizeResource, normalizeResources, toResourceEnum } from "./resource.mjs";
3
3
  import { InPropsDefinition, InPropsFunction, InPropsObject, InPropsOptions, IncludedPropBehavior, IncludedProps, InferredInProps, LayoutRenderProps, MergedLayoutInProps, PropsContextRender, PropsRenderDefinition, ResolvedIncludedComponentProps, ResolvedIncludedConfigProps, ResolvedIncludedProps, ResolvedIncludedPropsAsDefined } from "./props.mjs";
4
4
  import { ParameterizedResourcePath, PathVariables } from "./create-config/paths/types.mjs";
5
5
  import { CreateGetComponentForPath, GetComponentForPath, ResolvedPathValue } from "./create-config/for-paths/get-component-for-path.mjs";
6
6
  import { ForPaths, ForPathsRenderContext, RenderedPathComponent, RenderedPathComponentHOF, TargetPathBuilder } from "./create-config/for-paths/builder.mjs";
7
7
  import { IsSubResourceKey } from "./create-config/is-sub-resource-key.mjs";
8
8
  import { ComponentTypes, CreatedResourceConfig } from "./create-config/get-component.mjs";
9
- import { DefineResourcesFn, LayoutRenderResourcesAccessor, LayoutResourcesAccessor, defineResourceLayout } from "./create-config/define-layout.mjs";
9
+ import { CreateResourceLayoutWithLayoutOptions, DefineResourceLayoutWithLayoutFn, DefineResourcesFn, DefinedResourceLayoutWithShell, LayoutRenderResourcesAccessor, LayoutResourcesAccessor, ResourceLayoutShellComponent, ResourceLayoutShellProps, ResourceSelection, ShellLayoutDefinition, ShellRenderContext, defineResourceLayout } from "./create-config/define-layout.mjs";
10
+ import { ResourceLayoutShellPublisher } from "./create-config/shell-context.mjs";
10
11
  import { CreateReactLayoutErrorOptions, CreatedReactLayoutError, ErrorMessageRenderer, ReactLayoutError, ReactLayoutErrorContext, ReactLayoutErrorRendererFactory, createReactLayoutError } from "./errors/react-layout-error.mjs";
11
12
  import { InvalidConfigContext, InvalidConfigError } from "./errors/invalid-config.mjs";
12
13
  import { InvalidPathContext, InvalidPathError } from "./errors/invalid-path.mjs";
@@ -16,4 +17,4 @@ import { InvalidComponentContext, InvalidComponentError } from "./errors/invalid
16
17
  import { MissingPathVariableContext, MissingPathVariableError } from "./errors/missing-path-variable.mjs";
17
18
  import { AnyComposableComponent, ComposableComponent, ComposableComponentCallable, ComposableComponents, ComposableNameContext, ComposablePresetComponent, ComposablePresetComponentCallProps, ComposablePresetMeta, ComposablePresetProps, ComposableResourceLayout, CreateLayoutComposable, DefinedComposableComponentRecord, LayoutComposablePresetProvider, LayoutComposablesFactory, MakeComposable, MakeComposableOptions, MergePresetProps, PresetPropsFromComposable, RequiredPresetLayoutProps, RequiredPresetRenderProps, ResolveLayoutComposables, collectComposablePresetEntries, createComposableComponent, createLayoutComposableFactory, defineComposableComponent, makeComposable, resolveComposablePresetProps, resolveLayoutComposables } from "@jfdevelops/react-layout-composables";
18
19
  import { AnyBuiltPropDefinition, ExtractDefinitionValue, PropError, PropErrorOptions, ResolveLayoutProps, ResolveLayoutPropsAsDefined, ResolveProps, ResolvedBuiltPropShape, createPrimitivePropBuilder, createProp, isPropDefinitionShape, resolvePropDefinitionValues, validateProps } from "@jfdevelops/react-layout-validator";
19
- export { type AnyBuiltPropDefinition, type AnyComposableComponent, type BaseComponent, type ComponentTypes, type ComposableComponent, type ComposableComponentCallable, type ComposableComponents, type ComposableNameContext, type ComposablePresetComponent, type ComposablePresetComponentCallProps, type ComposablePresetMeta, type ComposablePresetProps, type ComposableResourceLayout, type CreateGetComponentForPath, type CreateLayoutComposable, type CreateReactLayoutErrorOptions, type CreatedReactLayoutError, type CreatedResourceConfig, type DefineResourcesFn, type DefinedComposableComponentRecord, type ErrorMessageRenderer, type ExtractDefinitionValue, type ForPaths, type ForPathsRenderContext, type GetComponentForPath, type InPropsDefinition, type InPropsFunction, type InPropsObject, type InPropsOptions, type IncludedPropBehavior, type IncludedProps, type InferredInProps, type InvalidComponentContext, InvalidComponentError, type InvalidConfigContext, InvalidConfigError, type InvalidPathContext, InvalidPathError, type InvalidResourceContext, InvalidResourceError, type InvalidSubResourceContext, InvalidSubResourceError, type IsSubResourceKey, LayoutComposablePresetProvider, type LayoutComposablesFactory, type LayoutRenderProps, type LayoutRenderResourcesAccessor, type LayoutResourceKey, type LayoutResourcesAccessor, type MakeComposable, type MakeComposableOptions, type MergeIntersection, type MergePresetProps, type MergedLayoutInProps, type MissingPathVariableContext, MissingPathVariableError, type NormalizeResource, type NormalizeResources, type ParameterizedResourcePath, type PathVariables, type PresetPropsFromComposable, PropError, type PropErrorOptions, type PropsContextRender, type PropsRenderDefinition, ReactLayoutError, type ReactLayoutErrorContext, type ReactLayoutErrorRendererFactory, type RenderedPathComponent, type RenderedPathComponentHOF, type RequiredPresetLayoutProps, type RequiredPresetRenderProps, type ResolveLayoutComposables, type ResolveLayoutProps, type ResolveLayoutPropsAsDefined, type ResolveProps, type ResolvedBuiltPropShape, type ResolvedIncludedComponentProps, type ResolvedIncludedConfigProps, type ResolvedIncludedProps, type ResolvedIncludedPropsAsDefined, type ResolvedPathValue, type ResourceDefinition, type ResourceEnum, type ResourceLayoutComponentProps, type ResourceTree, type Show, type TargetPathBuilder, type UnionToIntersection, collectComposablePresetEntries, createComposableComponent, createLayoutComposableFactory, createPrimitivePropBuilder, createProp, createReactLayoutError, defineComposableComponent, defineResourceLayout, isPropDefinitionShape, makeComposable, normalizeResource, normalizeResources, pick, resolveComposablePresetProps, resolveLayoutComposables, resolvePropDefinitionValues, toResourceEnum, validateProps };
20
+ export { type AnyBuiltPropDefinition, type AnyComposableComponent, type BaseComponent, type ComponentTypes, type ComposableComponent, type ComposableComponentCallable, type ComposableComponents, type ComposableNameContext, type ComposablePresetComponent, type ComposablePresetComponentCallProps, type ComposablePresetMeta, type ComposablePresetProps, type ComposableResourceLayout, type CreateGetComponentForPath, type CreateLayoutComposable, type CreateReactLayoutErrorOptions, type CreateResourceLayoutWithLayoutOptions, type CreatedReactLayoutError, type CreatedResourceConfig, type DefineResourceLayoutWithLayoutFn, type DefineResourcesFn, type DefinedComposableComponentRecord, type DefinedResourceLayoutWithShell, type ErrorMessageRenderer, type ExtractDefinitionValue, type ForPaths, type ForPathsRenderContext, type GetComponentForPath, type InPropsDefinition, type InPropsFunction, type InPropsObject, type InPropsOptions, type IncludedPropBehavior, type IncludedProps, type InferredInProps, type InvalidComponentContext, InvalidComponentError, type InvalidConfigContext, InvalidConfigError, type InvalidPathContext, InvalidPathError, type InvalidResourceContext, InvalidResourceError, type InvalidSubResourceContext, InvalidSubResourceError, type IsSubResourceKey, LayoutComposablePresetProvider, type LayoutComposablesFactory, type LayoutRenderProps, type LayoutRenderResourcesAccessor, type LayoutResourceKey, type LayoutResourcesAccessor, type MakeComposable, type MakeComposableOptions, type MergeIntersection, type MergePresetProps, type MergedLayoutInProps, type MissingPathVariableContext, MissingPathVariableError, type NormalizeResource, type NormalizeResources, type ParameterizedResourcePath, type PathVariables, type PresetPropsFromComposable, PropError, type PropErrorOptions, type PropsContextRender, type PropsRenderDefinition, ReactLayoutError, type ReactLayoutErrorContext, type ReactLayoutErrorRendererFactory, type RenderedPathComponent, type RenderedPathComponentHOF, type RequiredPresetLayoutProps, type RequiredPresetRenderProps, type ResolveLayoutComposables, type ResolveLayoutProps, type ResolveLayoutPropsAsDefined, type ResolveProps, type ResolvedBuiltPropShape, type ResolvedIncludedComponentProps, type ResolvedIncludedConfigProps, type ResolvedIncludedProps, type ResolvedIncludedPropsAsDefined, type ResolvedPathValue, type ResourceDefinition, type ResourceDefinitionValue, type ResourceEnum, type ResourceLayoutComponentProps, type ResourceLayoutShellComponent, type ResourceLayoutShellProps, type ResourceLayoutShellPublisher, type ResourceSelection, type ResourceTree, type ShellLayoutDefinition, type ShellRenderContext, type Show, type TargetPathBuilder, type UnionToIntersection, collectComposablePresetEntries, createComposableComponent, createLayoutComposableFactory, createPrimitivePropBuilder, createProp, createReactLayoutError, defineComposableComponent, defineResourceLayout, isPropDefinitionShape, makeComposable, normalizeResource, normalizeResources, pick, resolveComposablePresetProps, resolveLayoutComposables, resolvePropDefinitionValues, toResourceEnum, validateProps };
@@ -1 +1 @@
1
- {"version":3,"file":"resource.cjs","names":[],"sources":["../src/resource.ts"],"sourcesContent":["import { ReactNode } from 'react';\nimport { NonEmptyReadonlyArray } from '@jfdevelops/react-layout-validator';\nimport { MergeIntersection, UnionToIntersection } from './utils';\n\nexport type ResourceDefinition =\n | string\n | {\n value: string;\n subResources: ReadonlyArray<\n ResourceDefinition & {\n /**\n * Whether to allow any string as a sub resource.\n *\n * @default false\n */\n allowAnyString?: boolean;\n }\n >;\n };\n\nexport type ResourceTree = Record<\n string,\n {\n subResources: ResourceTree;\n }\n>;\n\nexport type NormalizeResource<Resource extends ResourceDefinition> =\n Resource extends string\n ? {\n [Key in Resource]: {\n subResources: {};\n };\n }\n : Resource extends {\n value: infer Value extends string;\n subResources: infer SubResources extends\n ReadonlyArray<ResourceDefinition>;\n }\n ? {\n [Key in Value]: {\n subResources: NormalizeResources<SubResources>;\n };\n }\n : never;\n\nexport type NormalizeResources<\n Resources extends ReadonlyArray<ResourceDefinition>,\n> = MergeIntersection<\n UnionToIntersection<NormalizeResource<Resources[number]>>\n>;\nexport type ResourceLayoutComponentProps = {\n children: ReactNode;\n};\n\nfunction normalizeResourceTree(resource: ResourceDefinition): ResourceTree {\n if (typeof resource === 'string') {\n return {\n [resource]: {\n subResources: {},\n },\n };\n }\n\n const { value, subResources } = resource;\n\n return {\n [value]: {\n subResources: normalizeResourcesTree(subResources),\n },\n };\n}\n\nfunction normalizeResourcesTree(\n resources: ReadonlyArray<ResourceDefinition>,\n): ResourceTree {\n const normalizedResources: ResourceTree = {};\n\n for (const resource of resources) {\n Object.assign(normalizedResources, normalizeResourceTree(resource));\n }\n\n return normalizedResources;\n}\n\nexport function normalizeResource(resource: ResourceDefinition): ResourceTree {\n return normalizeResourceTree(resource);\n}\n\nexport function normalizeResources<\n Resources extends ReadonlyArray<ResourceDefinition>,\n>(resources: Resources): NormalizeResources<Resources> {\n return normalizeResourcesTree(resources) as NormalizeResources<Resources>;\n}\n\nexport function createIsValidResourceFn<\n Resources extends ReadonlyArray<ResourceDefinition>,\n>(resources: Resources) {\n return (value: unknown): value is LayoutResourceKey<Resources> => {\n return (\n typeof value === 'string' &&\n Object.keys(normalizeResources(resources)).includes(value)\n );\n };\n}\n\ntype ResourceDefinitionValue<Resource extends ResourceDefinition> =\n Resource extends string\n ? Resource\n : Resource extends { value: infer Value extends string }\n ? Value\n : never;\n\n/**\n * Top-level resource names declared in a `resources` array. Preserves string\n * literal unions for const resource definitions (unlike `keyof` on the\n * normalized resource tree, which tends to widen to `string` in hovers).\n */\nexport type LayoutResourceKey<\n Resources extends ReadonlyArray<ResourceDefinition>,\n> = ResourceDefinitionValue<Resources[number]>;\n\nexport type ResourceDefinitionForKey<\n Resources extends ReadonlyArray<ResourceDefinition>,\n Key extends string,\n> = Extract<Resources[number], Key | { value: Key }>;\n\n/** `subResources` array declared on a layout resource. */\nexport type SubResourceDefinitionsFor<\n Resources extends ReadonlyArray<ResourceDefinition>,\n Resource extends LayoutResourceKey<Resources>,\n> =\n ResourceDefinitionForKey<Resources, Resource> extends {\n subResources: infer SubResources extends ReadonlyArray<ResourceDefinition>;\n }\n ? SubResources\n : readonly [];\n\ntype CanNestSubResourceParam<\n MaxDepth extends number,\n DepthAcc extends readonly unknown[],\n> = [...DepthAcc, unknown]['length'] extends MaxDepth ? false : true;\n\n/**\n * `subResource` route param: a slug at the current depth, or `{ value, subResource }`\n * when that slug has nested `subResources` in the layout tree and `MaxDepth` allows it.\n */\nexport type RecursiveSubResourceParam<\n Resources extends ReadonlyArray<ResourceDefinition>,\n SubDefs extends ReadonlyArray<ResourceDefinition>,\n MaxDepth extends number = 6,\n DepthAcc extends readonly unknown[] = readonly [],\n> =\n LayoutResourceKey<SubDefs> extends infer Key\n ? Key extends LayoutResourceKey<SubDefs>\n ? CanNestSubResourceParam<MaxDepth, DepthAcc> extends true\n ? ResourceDefinitionForKey<SubDefs, Key> extends {\n subResources: infer Nested extends\n ReadonlyArray<ResourceDefinition>;\n }\n ? [LayoutResourceKey<Nested>] extends [never]\n ? Key\n :\n | Key\n | {\n value: Key;\n subResource: RecursiveSubResourceParam<\n Resources,\n Nested,\n MaxDepth,\n readonly [...DepthAcc, unknown]\n >;\n }\n : Key\n : Key\n : never\n : never;\n\n/** Recursive `subResource` values for a layout resource (full tree depth). */\nexport type SubResourceParamForResource<\n Resources extends ReadonlyArray<ResourceDefinition>,\n Resource extends LayoutResourceKey<Resources>,\n> = [SubResourceDefinitionsFor<Resources, Resource>] extends [readonly []]\n ? never\n : RecursiveSubResourceParam<\n Resources,\n SubResourceDefinitionsFor<Resources, Resource>\n >;\n\nexport type GetSubResourceKeys<\n Resources extends ReadonlyArray<ResourceDefinition>,\n Resource extends LayoutResourceKey<Resources>,\n> =\n ResourceDefinitionForKey<Resources, Resource> extends {\n subResources: infer SubResources extends ReadonlyArray<ResourceDefinition>;\n }\n ? LayoutResourceKey<SubResources>\n : never;\nexport type ResourceEnum<Resources extends ReadonlyArray<ResourceDefinition>> =\n NonEmptyReadonlyArray<LayoutResourceKey<Resources>>;\nexport function toResourceEnum<\n Resources extends ReadonlyArray<ResourceDefinition>,\n>(resources: NormalizeResources<Resources>) {\n const keys = Object.keys(resources);\n\n if (keys.length === 0) {\n throw new Error('No resources provided');\n }\n\n return keys as unknown as ResourceEnum<Resources>;\n}\n"],"mappings":";;AAuDA,SAAS,sBAAsB,UAA4C;CACzE,IAAI,OAAO,aAAa,UACtB,OAAO,GACJ,WAAW,EACV,cAAc,CAAC,EACjB,EACF;CAGF,MAAM,EAAE,OAAO,iBAAiB;CAEhC,OAAO,GACJ,QAAQ,EACP,cAAc,uBAAuB,YAAY,EACnD,EACF;AACF;AAEA,SAAS,uBACP,WACc;CACd,MAAM,sBAAoC,CAAC;CAE3C,KAAK,MAAM,YAAY,WACrB,OAAO,OAAO,qBAAqB,sBAAsB,QAAQ,CAAC;CAGpE,OAAO;AACT;AAEA,SAAgB,kBAAkB,UAA4C;CAC5E,OAAO,sBAAsB,QAAQ;AACvC;AAEA,SAAgB,mBAEd,WAAqD;CACrD,OAAO,uBAAuB,SAAS;AACzC;AAEA,SAAgB,wBAEd,WAAsB;CACtB,QAAQ,UAA0D;EAChE,OACE,OAAO,UAAU,YACjB,OAAO,KAAK,mBAAmB,SAAS,CAAC,EAAE,SAAS,KAAK;CAE7D;AACF;AAgGA,SAAgB,eAEd,WAA0C;CAC1C,MAAM,OAAO,OAAO,KAAK,SAAS;CAElC,IAAI,KAAK,WAAW,GAClB,MAAM,IAAI,MAAM,uBAAuB;CAGzC,OAAO;AACT"}
1
+ {"version":3,"file":"resource.cjs","names":[],"sources":["../src/resource.ts"],"sourcesContent":["import { ReactNode } from 'react';\nimport { NonEmptyReadonlyArray } from '@jfdevelops/react-layout-validator';\nimport { MergeIntersection, UnionToIntersection } from './utils';\n\nexport type ResourceDefinition =\n | string\n | {\n value: string;\n subResources: ReadonlyArray<\n ResourceDefinition & {\n /**\n * Whether to allow any string as a sub resource.\n *\n * @default false\n */\n allowAnyString?: boolean;\n }\n >;\n };\n\nexport type ResourceTree = Record<\n string,\n {\n subResources: ResourceTree;\n }\n>;\n\nexport type NormalizeResource<Resource extends ResourceDefinition> =\n Resource extends string\n ? {\n [Key in Resource]: {\n subResources: {};\n };\n }\n : Resource extends {\n value: infer Value extends string;\n subResources: infer SubResources extends\n ReadonlyArray<ResourceDefinition>;\n }\n ? {\n [Key in Value]: {\n subResources: NormalizeResources<SubResources>;\n };\n }\n : never;\n\nexport type NormalizeResources<\n Resources extends ReadonlyArray<ResourceDefinition>,\n> = MergeIntersection<\n UnionToIntersection<NormalizeResource<Resources[number]>>\n>;\nexport type ResourceLayoutComponentProps = {\n children: ReactNode;\n};\n\nfunction normalizeResourceTree(resource: ResourceDefinition): ResourceTree {\n if (typeof resource === 'string') {\n return {\n [resource]: {\n subResources: {},\n },\n };\n }\n\n const { value, subResources } = resource;\n\n return {\n [value]: {\n subResources: normalizeResourcesTree(subResources),\n },\n };\n}\n\nfunction normalizeResourcesTree(\n resources: ReadonlyArray<ResourceDefinition>,\n): ResourceTree {\n const normalizedResources: ResourceTree = {};\n\n for (const resource of resources) {\n Object.assign(normalizedResources, normalizeResourceTree(resource));\n }\n\n return normalizedResources;\n}\n\nexport function normalizeResource(resource: ResourceDefinition): ResourceTree {\n return normalizeResourceTree(resource);\n}\n\nexport function normalizeResources<\n Resources extends ReadonlyArray<ResourceDefinition>,\n>(resources: Resources): NormalizeResources<Resources> {\n return normalizeResourcesTree(resources) as NormalizeResources<Resources>;\n}\n\nexport function createIsValidResourceFn<\n Resources extends ReadonlyArray<ResourceDefinition>,\n>(resources: Resources) {\n return (value: unknown): value is LayoutResourceKey<Resources> => {\n return (\n typeof value === 'string' &&\n Object.keys(normalizeResources(resources)).includes(value)\n );\n };\n}\n\nexport type ResourceDefinitionValue<Resource extends ResourceDefinition> =\n Resource extends string\n ? Resource\n : Resource extends { value: infer Value extends string }\n ? Value\n : never;\n\n/**\n * Top-level resource names declared in a `resources` array. Preserves string\n * literal unions for const resource definitions (unlike `keyof` on the\n * normalized resource tree, which tends to widen to `string` in hovers).\n */\nexport type LayoutResourceKey<\n Resources extends ReadonlyArray<ResourceDefinition>,\n> = ResourceDefinitionValue<Resources[number]>;\n\nexport type ResourceDefinitionForKey<\n Resources extends ReadonlyArray<ResourceDefinition>,\n Key extends string,\n> = Extract<Resources[number], Key | { value: Key }>;\n\n/** `subResources` array declared on a layout resource. */\nexport type SubResourceDefinitionsFor<\n Resources extends ReadonlyArray<ResourceDefinition>,\n Resource extends LayoutResourceKey<Resources>,\n> =\n ResourceDefinitionForKey<Resources, Resource> extends {\n subResources: infer SubResources extends ReadonlyArray<ResourceDefinition>;\n }\n ? SubResources\n : readonly [];\n\ntype CanNestSubResourceParam<\n MaxDepth extends number,\n DepthAcc extends readonly unknown[],\n> = [...DepthAcc, unknown]['length'] extends MaxDepth ? false : true;\n\n/**\n * `subResource` route param: a slug at the current depth, or `{ value, subResource }`\n * when that slug has nested `subResources` in the layout tree and `MaxDepth` allows it.\n */\nexport type RecursiveSubResourceParam<\n Resources extends ReadonlyArray<ResourceDefinition>,\n SubDefs extends ReadonlyArray<ResourceDefinition>,\n MaxDepth extends number = 6,\n DepthAcc extends readonly unknown[] = readonly [],\n> =\n LayoutResourceKey<SubDefs> extends infer Key\n ? Key extends LayoutResourceKey<SubDefs>\n ? CanNestSubResourceParam<MaxDepth, DepthAcc> extends true\n ? ResourceDefinitionForKey<SubDefs, Key> extends {\n subResources: infer Nested extends\n ReadonlyArray<ResourceDefinition>;\n }\n ? [LayoutResourceKey<Nested>] extends [never]\n ? Key\n :\n | Key\n | {\n value: Key;\n subResource: RecursiveSubResourceParam<\n Resources,\n Nested,\n MaxDepth,\n readonly [...DepthAcc, unknown]\n >;\n }\n : Key\n : Key\n : never\n : never;\n\n/** Recursive `subResource` values for a layout resource (full tree depth). */\nexport type SubResourceParamForResource<\n Resources extends ReadonlyArray<ResourceDefinition>,\n Resource extends LayoutResourceKey<Resources>,\n> = [SubResourceDefinitionsFor<Resources, Resource>] extends [readonly []]\n ? never\n : RecursiveSubResourceParam<\n Resources,\n SubResourceDefinitionsFor<Resources, Resource>\n >;\n\nexport type GetSubResourceKeys<\n Resources extends ReadonlyArray<ResourceDefinition>,\n Resource extends LayoutResourceKey<Resources>,\n> =\n ResourceDefinitionForKey<Resources, Resource> extends {\n subResources: infer SubResources extends ReadonlyArray<ResourceDefinition>;\n }\n ? LayoutResourceKey<SubResources>\n : never;\nexport type ResourceEnum<Resources extends ReadonlyArray<ResourceDefinition>> =\n NonEmptyReadonlyArray<LayoutResourceKey<Resources>>;\nexport function toResourceEnum<\n Resources extends ReadonlyArray<ResourceDefinition>,\n>(resources: NormalizeResources<Resources>) {\n const keys = Object.keys(resources);\n\n if (keys.length === 0) {\n throw new Error('No resources provided');\n }\n\n return keys as unknown as ResourceEnum<Resources>;\n}\n"],"mappings":";;AAuDA,SAAS,sBAAsB,UAA4C;CACzE,IAAI,OAAO,aAAa,UACtB,OAAO,GACJ,WAAW,EACV,cAAc,CAAC,EACjB,EACF;CAGF,MAAM,EAAE,OAAO,iBAAiB;CAEhC,OAAO,GACJ,QAAQ,EACP,cAAc,uBAAuB,YAAY,EACnD,EACF;AACF;AAEA,SAAS,uBACP,WACc;CACd,MAAM,sBAAoC,CAAC;CAE3C,KAAK,MAAM,YAAY,WACrB,OAAO,OAAO,qBAAqB,sBAAsB,QAAQ,CAAC;CAGpE,OAAO;AACT;AAEA,SAAgB,kBAAkB,UAA4C;CAC5E,OAAO,sBAAsB,QAAQ;AACvC;AAEA,SAAgB,mBAEd,WAAqD;CACrD,OAAO,uBAAuB,SAAS;AACzC;AAEA,SAAgB,wBAEd,WAAsB;CACtB,QAAQ,UAA0D;EAChE,OACE,OAAO,UAAU,YACjB,OAAO,KAAK,mBAAmB,SAAS,CAAC,EAAE,SAAS,KAAK;CAE7D;AACF;AAgGA,SAAgB,eAEd,WAA0C;CAC1C,MAAM,OAAO,OAAO,KAAK,SAAS;CAElC,IAAI,KAAK,WAAW,GAClB,MAAM,IAAI,MAAM,uBAAuB;CAGzC,OAAO;AACT"}
@@ -63,5 +63,5 @@ type SubResourceParamForResource<Resources extends ReadonlyArray<ResourceDefinit
63
63
  type ResourceEnum<Resources extends ReadonlyArray<ResourceDefinition>> = NonEmptyReadonlyArray<LayoutResourceKey<Resources>>;
64
64
  declare function toResourceEnum<Resources extends ReadonlyArray<ResourceDefinition>>(resources: NormalizeResources<Resources>): ResourceEnum<Resources>;
65
65
  //#endregion
66
- export { LayoutResourceKey, NormalizeResource, NormalizeResources, ResourceDefinition, ResourceDefinitionForKey, ResourceEnum, ResourceLayoutComponentProps, ResourceTree, SubResourceDefinitionsFor, SubResourceParamForResource, normalizeResource, normalizeResources, toResourceEnum };
66
+ export { LayoutResourceKey, NormalizeResource, NormalizeResources, ResourceDefinition, ResourceDefinitionForKey, ResourceDefinitionValue, ResourceEnum, ResourceLayoutComponentProps, ResourceTree, SubResourceDefinitionsFor, SubResourceParamForResource, normalizeResource, normalizeResources, toResourceEnum };
67
67
  //# sourceMappingURL=resource.d.cts.map
@@ -1 +1 @@
1
- {"version":3,"file":"resource.d.cts","names":[],"sources":["../src/resource.ts"],"mappings":";;;;;KAIY,kBAAA;EAGN,KAAA;EACA,YAAA,EAAc,aAAa,CACzB,kBAAA;IALsB;;;;;IAWpB,cAAA;EAAA;AAAA;AAAA,KAKE,YAAA,GAAe,MAAM;EAG7B,YAAA,EAAc,YAAA;AAAA;AAAA,KAIN,iBAAA,kBAAmC,kBAAA,IAC7C,QAAA,4BAEc,QAAA;EACN,YAAA;AAAA,MAGJ,QAAA;EACI,KAAA;EACA,YAAA,6BACE,aAAA,CAAc,kBAAA;AAAA,cAGR,KAAA;EACN,YAAA,EAAc,kBAAA,CAAmB,YAAA;AAAA;AAAA,KAKjC,kBAAA,mBACQ,aAAA,CAAc,kBAAA,KAC9B,iBAAA,CACF,mBAAA,CAAoB,iBAAA,CAAkB,SAAA;AAAA,KAE5B,4BAAA;EACV,QAAA,EAAU,SAAS;AAAA;AAAA,iBAiCL,iBAAA,CAAkB,QAAA,EAAU,kBAAA,GAAqB,YAAY;AAAA,iBAI7D,kBAAA,mBACI,aAAA,CAAc,kBAAA,GAChC,SAAA,EAAW,SAAA,GAAY,kBAAA,CAAmB,SAAA;AAAA,KAevC,uBAAA,kBAAyC,kBAAA,IAC5C,QAAA,kBACI,QAAA,GACA,QAAA;EAAmB,KAAA;AAAA,IACjB,KAAA;;;;;;KAQI,iBAAA,mBACQ,aAAA,CAAc,kBAAA,KAC9B,uBAAA,CAAwB,SAAA;AAAA,KAEhB,wBAAA,mBACQ,aAAA,CAAc,kBAAA,yBAE9B,OAAA,CAAQ,SAAA,UAAmB,GAAA;EAAQ,KAAA,EAAO,GAAA;AAAA;;KAGlC,yBAAA,mBACQ,aAAA,CAAc,kBAAA,oBACf,iBAAA,CAAkB,SAAA,KAEnC,wBAAA,CAAyB,SAAA,EAAW,QAAA;EAClC,YAAA,6BAAyC,aAAA,CAAc,kBAAA;AAAA,IAErD,YAAA;AAAA,KAGD,uBAAA,qEAGG,QAAA,6BAAqC,QAAQ;;;;;KAMzC,yBAAA,mBACQ,aAAA,CAAc,kBAAA,mBAChB,aAAA,CAAc,kBAAA,qFAI9B,iBAAA,CAAkB,OAAA,sBACd,GAAA,SAAY,iBAAA,CAAkB,OAAA,IAC5B,uBAAA,CAAwB,QAAA,EAAU,QAAA,iBAChC,wBAAA,CAAyB,OAAA,EAAS,GAAA;EAChC,YAAA,uBACE,aAAA,CAAc,kBAAA;AAAA,KAEf,iBAAA,CAAkB,MAAA,qBACjB,GAAA,GAEI,GAAA;EAEE,KAAA,EAAO,GAAA;EACP,WAAA,EAAa,yBAAA,CACX,SAAA,EACA,MAAA,EACA,QAAA,eACa,QAAA;AAAA,IAGvB,GAAA,GACF,GAAA;;KAKE,2BAAA,mBACQ,aAAA,CAAc,kBAAA,oBACf,iBAAA,CAAkB,SAAA,MAChC,yBAAA,CAA0B,SAAA,EAAW,QAAA,mCAEtC,yBAAA,CACE,SAAA,EACA,yBAAA,CAA0B,SAAA,EAAW,QAAA;AAAA,KAY/B,YAAA,mBAA+B,aAAA,CAAc,kBAAA,KACvD,qBAAA,CAAsB,iBAAA,CAAkB,SAAA;AAAA,iBAC1B,cAAA,mBACI,aAAA,CAAc,kBAAA,GAChC,SAAA,EAAW,kBAAA,CAAmB,SAAA,IAOJ,YAAA,CAAa,SAAA"}
1
+ {"version":3,"file":"resource.d.cts","names":[],"sources":["../src/resource.ts"],"mappings":";;;;;KAIY,kBAAA;EAGN,KAAA;EACA,YAAA,EAAc,aAAa,CACzB,kBAAA;IALsB;;;;;IAWpB,cAAA;EAAA;AAAA;AAAA,KAKE,YAAA,GAAe,MAAM;EAG7B,YAAA,EAAc,YAAA;AAAA;AAAA,KAIN,iBAAA,kBAAmC,kBAAA,IAC7C,QAAA,4BAEc,QAAA;EACN,YAAA;AAAA,MAGJ,QAAA;EACI,KAAA;EACA,YAAA,6BACE,aAAA,CAAc,kBAAA;AAAA,cAGR,KAAA;EACN,YAAA,EAAc,kBAAA,CAAmB,YAAA;AAAA;AAAA,KAKjC,kBAAA,mBACQ,aAAA,CAAc,kBAAA,KAC9B,iBAAA,CACF,mBAAA,CAAoB,iBAAA,CAAkB,SAAA;AAAA,KAE5B,4BAAA;EACV,QAAA,EAAU,SAAS;AAAA;AAAA,iBAiCL,iBAAA,CAAkB,QAAA,EAAU,kBAAA,GAAqB,YAAY;AAAA,iBAI7D,kBAAA,mBACI,aAAA,CAAc,kBAAA,GAChC,SAAA,EAAW,SAAA,GAAY,kBAAA,CAAmB,SAAA;AAAA,KAehC,uBAAA,kBAAyC,kBAAA,IACnD,QAAA,kBACI,QAAA,GACA,QAAA;EAAmB,KAAA;AAAA,IACjB,KAAA;;;;;;KAQI,iBAAA,mBACQ,aAAA,CAAc,kBAAA,KAC9B,uBAAA,CAAwB,SAAA;AAAA,KAEhB,wBAAA,mBACQ,aAAA,CAAc,kBAAA,yBAE9B,OAAA,CAAQ,SAAA,UAAmB,GAAA;EAAQ,KAAA,EAAO,GAAA;AAAA;;KAGlC,yBAAA,mBACQ,aAAA,CAAc,kBAAA,oBACf,iBAAA,CAAkB,SAAA,KAEnC,wBAAA,CAAyB,SAAA,EAAW,QAAA;EAClC,YAAA,6BAAyC,aAAA,CAAc,kBAAA;AAAA,IAErD,YAAA;AAAA,KAGD,uBAAA,qEAGG,QAAA,6BAAqC,QAAQ;;;;;KAMzC,yBAAA,mBACQ,aAAA,CAAc,kBAAA,mBAChB,aAAA,CAAc,kBAAA,qFAI9B,iBAAA,CAAkB,OAAA,sBACd,GAAA,SAAY,iBAAA,CAAkB,OAAA,IAC5B,uBAAA,CAAwB,QAAA,EAAU,QAAA,iBAChC,wBAAA,CAAyB,OAAA,EAAS,GAAA;EAChC,YAAA,uBACE,aAAA,CAAc,kBAAA;AAAA,KAEf,iBAAA,CAAkB,MAAA,qBACjB,GAAA,GAEI,GAAA;EAEE,KAAA,EAAO,GAAA;EACP,WAAA,EAAa,yBAAA,CACX,SAAA,EACA,MAAA,EACA,QAAA,eACa,QAAA;AAAA,IAGvB,GAAA,GACF,GAAA;;KAKE,2BAAA,mBACQ,aAAA,CAAc,kBAAA,oBACf,iBAAA,CAAkB,SAAA,MAChC,yBAAA,CAA0B,SAAA,EAAW,QAAA,mCAEtC,yBAAA,CACE,SAAA,EACA,yBAAA,CAA0B,SAAA,EAAW,QAAA;AAAA,KAY/B,YAAA,mBAA+B,aAAA,CAAc,kBAAA,KACvD,qBAAA,CAAsB,iBAAA,CAAkB,SAAA;AAAA,iBAC1B,cAAA,mBACI,aAAA,CAAc,kBAAA,GAChC,SAAA,EAAW,kBAAA,CAAmB,SAAA,IAOJ,YAAA,CAAa,SAAA"}