@jfdevelops/react-layout 0.25.0 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (47) hide show
  1. package/dist/create-config/create-defined-resource-layout.cjs +42 -37
  2. package/dist/create-config/create-defined-resource-layout.cjs.map +1 -1
  3. package/dist/create-config/create-defined-resource-layout.d.cts +64 -44
  4. package/dist/create-config/create-defined-resource-layout.d.cts.map +1 -1
  5. package/dist/create-config/create-defined-resource-layout.d.mts +64 -44
  6. package/dist/create-config/create-defined-resource-layout.d.mts.map +1 -1
  7. package/dist/create-config/create-defined-resource-layout.mjs +44 -39
  8. package/dist/create-config/create-defined-resource-layout.mjs.map +1 -1
  9. package/dist/create-config/define-layout.cjs +12 -1
  10. package/dist/create-config/define-layout.cjs.map +1 -1
  11. package/dist/create-config/define-layout.d.cts +20 -8
  12. package/dist/create-config/define-layout.d.cts.map +1 -1
  13. package/dist/create-config/define-layout.d.mts +20 -8
  14. package/dist/create-config/define-layout.d.mts.map +1 -1
  15. package/dist/create-config/define-layout.mjs +13 -3
  16. package/dist/create-config/define-layout.mjs.map +1 -1
  17. package/dist/create-config/get-component.cjs +22 -1
  18. package/dist/create-config/get-component.cjs.map +1 -1
  19. package/dist/create-config/get-component.d.cts +25 -3
  20. package/dist/create-config/get-component.d.cts.map +1 -1
  21. package/dist/create-config/get-component.d.mts +25 -3
  22. package/dist/create-config/get-component.d.mts.map +1 -1
  23. package/dist/create-config/get-component.mjs +22 -1
  24. package/dist/create-config/get-component.mjs.map +1 -1
  25. package/dist/create-config/index.d.cts +2 -2
  26. package/dist/create-config/index.d.mts +2 -2
  27. package/dist/create-config/render-state.cjs +1 -14
  28. package/dist/create-config/render-state.cjs.map +1 -1
  29. package/dist/create-config/render-state.d.cts +12 -11
  30. package/dist/create-config/render-state.d.cts.map +1 -1
  31. package/dist/create-config/render-state.d.mts +12 -11
  32. package/dist/create-config/render-state.d.mts.map +1 -1
  33. package/dist/create-config/render-state.mjs +1 -14
  34. package/dist/create-config/render-state.mjs.map +1 -1
  35. package/dist/index.cjs +1 -0
  36. package/dist/index.d.cts +4 -4
  37. package/dist/index.d.mts +4 -4
  38. package/dist/index.mjs +2 -2
  39. package/dist/resource.cjs +17 -0
  40. package/dist/resource.cjs.map +1 -1
  41. package/dist/resource.d.cts +27 -1
  42. package/dist/resource.d.cts.map +1 -1
  43. package/dist/resource.d.mts +27 -1
  44. package/dist/resource.d.mts.map +1 -1
  45. package/dist/resource.mjs +17 -1
  46. package/dist/resource.mjs.map +1 -1
  47. package/package.json +1 -1
@@ -80,7 +80,7 @@ function createGetComponent(config) {
80
80
  };
81
81
  return Object.assign(getComponent, { forResource });
82
82
  }
83
- function createResourceConfig(config) {
83
+ function createResourceConfigImpl(config) {
84
84
  const configRecord = config;
85
85
  if (require_introspect.collectConfigResources(configRecord).length === 0) throw new require_invalid_config.InvalidConfigError({
86
86
  reason: "A resource config must configure at least one resource",
@@ -95,6 +95,27 @@ function createResourceConfig(config) {
95
95
  subResources: require_introspect.collectAllSubResourceKeys(configRecord)
96
96
  };
97
97
  }
98
+ function createResourceConfigForResource(resource, config) {
99
+ return { [resource]: config };
100
+ }
101
+ /**
102
+ * Creates a validated resource configuration. Use `.forResource()` to build
103
+ * independently declared, type-safe fragments that can be spread into the
104
+ * complete configuration object.
105
+ *
106
+ * @param config - Resource entries to validate and expose through lookup helpers.
107
+ * @returns The original config plus typed component and path lookup helpers.
108
+ *
109
+ * @example
110
+ * ```tsx
111
+ * const users = createResourceConfig.forResource('users', {
112
+ * component: <Users />,
113
+ * });
114
+ *
115
+ * const config = createResourceConfig({ ...users });
116
+ * ```
117
+ */
118
+ const createResourceConfig = Object.assign(createResourceConfigImpl, { forResource: createResourceConfigForResource });
98
119
 
99
120
  //#endregion
100
121
  exports.createResourceConfig = createResourceConfig;
@@ -1 +1 @@
1
- {"version":3,"file":"get-component.cjs","names":["InvalidSubResourceError","readSubResourceKeys","InvalidComponentError","readComponentKeys","InvalidResourceError","collectConfigResources","InvalidPathError","InvalidConfigError","createGetComponentForPath","createForPaths","createIsSubResourceKey","collectAllSubResourceKeys"],"sources":["../../src/create-config/get-component.ts"],"sourcesContent":["import type { JSX } from 'react';\nimport {\n InvalidComponentError,\n InvalidConfigError,\n InvalidPathError,\n InvalidResourceError,\n InvalidSubResourceError,\n} from '../errors';\nimport type {\n LayoutResourceKey,\n ResourceDefinition,\n ResourceDefinitionForKey,\n SubResourceDefinitionsFor,\n SubResourceParamForResource,\n} from '../resource';\nimport {\n createForPaths,\n createGetComponentForPath,\n type CreateGetComponentForPath,\n type ForPaths,\n} from './for-paths';\nimport {\n createIsSubResourceKey,\n type IsSubResourceKey,\n} from './is-sub-resource-key';\nimport {\n readComponentKeys,\n readSubResourceKeys,\n} from './component-keys';\nimport {\n collectAllSubResourceKeys,\n collectConfigResources,\n} from './paths';\nimport type {\n ConfigSubResourceKeys,\n ParameterizedResourcePath,\n} from './paths';\nimport type {\n BaseResourceConfigComponents,\n ResourceConfigComponentKey,\n ResourceConfigComponents,\n ResourceConfigEntry,\n ResourceConfigMap,\n ResourceConfigInput,\n SharedResourceConfigOptions,\n} from './types';\n\ntype ResourceHasLayoutSubResources<\n Resources extends ReadonlyArray<ResourceDefinition>,\n Resource extends LayoutResourceKey<Resources>,\n> = [SubResourceDefinitionsFor<Resources, Resource>] extends [readonly []]\n ? false\n : true;\n\ntype SubResourceOptionForGenerics<\n Resources extends ReadonlyArray<ResourceDefinition>,\n Resource extends LayoutResourceKey<Resources>,\n SubResource extends\n | SubResourceParamForResource<Resources, Resource>\n | undefined,\n> = [SubResource] extends [undefined]\n ? ResourceHasLayoutSubResources<Resources, Resource> extends true\n ? {\n subResource?: SubResourceParamForResource<Resources, Resource>;\n }\n : {}\n : ResourceHasLayoutSubResources<Resources, Resource> extends true\n ? { subResource?: SubResource }\n : {};\n\n/** Options for one layout resource passed to {@link GetComponent}. */\nexport type GetComponentOptionsForResource<\n Resources extends ReadonlyArray<ResourceDefinition>,\n Resource extends LayoutResourceKey<Resources>,\n SubResource extends\n | SubResourceParamForResource<Resources, Resource>\n | undefined = undefined,\n> = SubResourceOptionForGenerics<Resources, Resource, SubResource> & {\n resource: Resource;\n /**\n * The component to get.\n *\n * @default 'component'\n */\n component?: ResourceConfigComponentKey;\n};\n\n/** Union of valid `getComponent` option shapes for each declared layout resource. */\nexport type GetComponentOptions<\n Resources extends ReadonlyArray<ResourceDefinition>,\n> =\n LayoutResourceKey<Resources> extends infer Resource\n ? Resource extends LayoutResourceKey<Resources>\n ? GetComponentOptionsForResource<Resources, Resource>\n : never\n : never;\n\ntype ComponentSlotPathKey = keyof BaseResourceConfigComponents;\n\n/** `detail.errorComponent`, `new.component`, … — component slots inside a shared branch. */\ntype SharedBranchPath = {\n [Branch in keyof SharedResourceConfigOptions]: `${Branch}.${ComponentSlotPathKey}`;\n}[keyof SharedResourceConfigOptions];\n\ntype NestedSubResourceDefinitions<Def extends ResourceDefinition> = Def extends {\n subResources: infer Nested extends ReadonlyArray<ResourceDefinition>;\n}\n ? Nested\n : readonly [];\n\ntype SubResourceEntryPaths<\n SubDefs extends ReadonlyArray<ResourceDefinition>,\n DepthAcc extends readonly unknown[],\n> =\n LayoutResourceKey<SubDefs> extends infer Key extends string\n ? Key extends LayoutResourceKey<SubDefs>\n ?\n | Key\n | `${Key}.${ResourceConfigEntryPath<\n NestedSubResourceDefinitions<\n ResourceDefinitionForKey<SubDefs, Key>\n >,\n readonly [...DepthAcc, unknown]\n >}`\n : never\n : never;\n\n/** Dot-separated keys below one config node: component slots and nested sub-resources. */\ntype ResourceConfigEntryPath<\n SubDefs extends ReadonlyArray<ResourceDefinition>,\n DepthAcc extends readonly unknown[] = readonly [],\n> =\n | ComponentSlotPathKey\n | SharedBranchPath\n | ([SubDefs] extends [readonly []]\n ? never\n : DepthAcc['length'] extends 6\n ? never\n : SubResourceEntryPaths<SubDefs, DepthAcc>);\n\n/**\n * Deep config paths accepted by {@link GetComponent}, e.g.\n * `'templates.deleted.expired.errorComponent'`. Sub-resource segments come from the\n * layout tree, so only declared sub-resources are allowed at each depth.\n */\nexport type ResourceConfigPath<\n Resources extends ReadonlyArray<ResourceDefinition>,\n> =\n LayoutResourceKey<Resources> extends infer Resource extends string\n ? Resource extends LayoutResourceKey<Resources>\n ?\n | Resource\n | `${Resource}.${ResourceConfigEntryPath<\n SubResourceDefinitionsFor<Resources, Resource>\n >}`\n : never\n : never;\n\n/** `subResource` bound by {@link GetComponentForResource}. */\nexport type SubResourceFromGetComponentBound<Bound> = Bound extends {\n subResource: infer SubResource;\n}\n ? SubResource\n : undefined;\n\n/** Options for {@link GetComponentForResource} — binds `resource` and optional `subResource`. */\nexport type GetComponentForResourceOptions<\n Resources extends ReadonlyArray<ResourceDefinition>,\n Resource extends LayoutResourceKey<Resources>,\n SubResource extends\n | SubResourceParamForResource<Resources, Resource>\n | undefined = undefined,\n> = {\n resource: Resource;\n} & SubResourceOptionForGenerics<Resources, Resource, SubResource>;\n\n/** Valid bind shapes for {@link GetComponentForResource}. */\nexport type GetComponentForResourceBound<\n Resources extends ReadonlyArray<ResourceDefinition>,\n> =\n LayoutResourceKey<Resources> extends infer Resource\n ? Resource extends LayoutResourceKey<Resources>\n ? GetComponentForResourceOptions<Resources, Resource>\n : never\n : never;\n\ntype GetComponentForResourceOptionsForBound<\n Resources extends ReadonlyArray<ResourceDefinition>,\n Bound extends { resource: LayoutResourceKey<Resources> },\n> = GetComponentForResourceOptions<\n Resources,\n Bound['resource'],\n SubResourceFromGetComponentBound<Bound>\n>;\n\n/**\n * Rejects bind objects with keys (e.g. `subResource`) that are invalid for the\n * given `resource`. Union assignability alone is too permissive for excess keys.\n */\nexport type ValidateForResourceBound<\n Resources extends ReadonlyArray<ResourceDefinition>,\n Bound extends { resource: LayoutResourceKey<Resources> },\n> = Bound extends GetComponentForResourceOptionsForBound<Resources, Bound>\n ? keyof Bound extends keyof GetComponentForResourceOptionsForBound<\n Resources,\n Bound\n >\n ? Bound\n : never\n : never;\n\n/** `resource` inferred from a {@link GetComponentForResource} bind argument. */\nexport type ResourceFromGetComponentBound<\n Resources extends ReadonlyArray<ResourceDefinition>,\n Bound,\n> = Bound extends {\n resource: infer Resource extends LayoutResourceKey<Resources>;\n}\n ? Resource\n : never;\n\n/** Reusable getter returned by {@link GetComponentForResource} (only `component` remains). */\nexport type GetComponentAtBound<\n Resources extends ReadonlyArray<ResourceDefinition>,\n Resource extends LayoutResourceKey<Resources>,\n SubResource extends\n | SubResourceParamForResource<Resources, Resource>\n | undefined = undefined,\n> = (\n options?: Pick<\n GetComponentOptionsForResource<Resources, Resource, SubResource>,\n 'component'\n >,\n) => JSX.Element;\n\nexport type GetComponentForResource<\n Resources extends ReadonlyArray<ResourceDefinition>,\n> = <\n const Bound extends {\n resource: LayoutResourceKey<Resources>;\n },\n>(\n bound: ValidateForResourceBound<Resources, Bound>,\n) => GetComponentAtBound<\n Resources,\n ResourceFromGetComponentBound<Resources, Bound>,\n SubResourceFromGetComponentBound<Bound>\n>;\n\nexport interface GetComponent<\n Resources extends ReadonlyArray<ResourceDefinition>,\n> {\n /** Looks up a component by resource / optional sub-resource / optional component slot. */\n <const Options extends GetComponentOptions<Resources>>(\n options: Options,\n ): JSX.Element;\n /**\n * Looks up a component by a deep config path.\n * A path ending on a branch (e.g. `'templates.deleted.expired'`) returns that branch's\n * `component`; a path ending on a slot returns that slot.\n */\n <const Path extends ResourceConfigPath<Resources>>(path: Path): JSX.Element;\n forResource: GetComponentForResource<Resources>;\n}\n\nexport interface CreatedResourceConfig<\n Resources extends ReadonlyArray<ResourceDefinition>,\n Config extends ResourceConfigMap<Resources> = ResourceConfigMap<Resources>,\n> {\n config: Config;\n getComponent: GetComponent<Resources>;\n /**\n * Creates a reusable getter bound to one path. Variables the path leaves open become\n * the getter's arguments.\n *\n * @example\n * ```ts\n * const getDetail = createGetComponent('$resource.detail.$component');\n *\n * getDetail({ resource: 'templates', component: 'errorComponent' });\n * ```\n */\n createGetComponent: CreateGetComponentForPath<\n Resources,\n Config,\n ParameterizedResourcePath<Resources>\n >;\n /**\n * Builds a component for one or more paths. Declare which params the component takes,\n * then render it.\n *\n * @example\n * ```ts\n * const ResourceDetail = forPaths('$resource.detail.$component')\n * .addPathParams()\n * .render(({ params, getComponentForPath }) =>\n * getComponentForPath('$resource.detail.$component')(params),\n * );\n * ```\n */\n forPaths: ForPaths<\n Resources,\n Config,\n ParameterizedResourcePath<Resources>\n >;\n /** Narrows an unknown value to a sub-resource key configured for a path or resource. */\n isSubResourceKey: IsSubResourceKey<\n Resources,\n Config,\n ParameterizedResourcePath<Resources>\n >;\n /** Every sub-resource key configured in this config, at any depth. */\n subResources: ReadonlyArray<ConfigSubResourceKeys<Resources, Config>>;\n}\n\ntype ComponentTypesFromEntry<Entry> = Entry extends JSX.Element\n ? never\n : Entry extends object\n ?\n | Extract<keyof Entry, ResourceConfigComponentKey>\n | {\n [Key in keyof Entry]: NonNullable<Entry[Key]> extends JSX.Element\n ? never\n : ComponentTypesFromEntry<NonNullable<Entry[Key]>>;\n }[keyof Entry]\n : never;\n\n/**\n * Component selector keys actually defined anywhere in a created resource config.\n *\n * @example\n * ```ts\n * ComponentTypes<typeof resourceConfig>\n * // ^? may resolve to:`'component' | 'errorComponent' | 'detail'`.\n * ```\n */\nexport type ComponentTypes<Created> = Created extends {\n config: infer Config extends object;\n}\n ? {\n [Resource in keyof Config]: ComponentTypesFromEntry<\n NonNullable<Config[Resource]>\n >;\n }[keyof Config]\n : never;\n\nexport type CreateResourceConfigFn<\n Resources extends ReadonlyArray<ResourceDefinition>,\n> = <const Config extends ResourceConfigMap<Resources>>(\n config: ResourceConfigInput<Resources, Config>,\n) => CreatedResourceConfig<Resources, Config>;\n\ntype SubResourceParam =\n | string\n | {\n value: string;\n subResource: SubResourceParam;\n };\n\nfunction isResourceConfigEntry(value: unknown): value is ResourceConfigEntry {\n return typeof value === 'object' && value !== null;\n}\n\nfunction resolveResourceConfigEntry(\n entry: ResourceConfigEntry,\n subResource: SubResourceParam,\n): ResourceConfigEntry {\n const key = typeof subResource === 'string' ? subResource : subResource.value;\n const next = entry[key];\n\n if (!isResourceConfigEntry(next)) {\n throw new InvalidSubResourceError({\n subResource: key,\n validSubResources: readSubResourceKeys(entry),\n });\n }\n\n if (typeof subResource === 'string') {\n return next;\n }\n\n return resolveResourceConfigEntry(next, subResource.subResource);\n}\n\nfunction readResourceConfigComponent(\n entry: ResourceConfigComponents,\n componentKey: ResourceConfigComponentKey,\n): JSX.Element {\n if (componentKey === 'new' || componentKey === 'detail') {\n const branch = entry[componentKey];\n\n if (!branch?.component) {\n throw new InvalidComponentError({\n component: `${componentKey}.component`,\n validComponents: readComponentKeys(entry),\n });\n }\n\n return branch.component;\n }\n\n const value = entry[componentKey];\n\n if (!value) {\n throw new InvalidComponentError({\n component: componentKey,\n validComponents: readComponentKeys(entry),\n });\n }\n\n return value;\n}\n\nfunction getComponentFromOptions<\n Resources extends ReadonlyArray<ResourceDefinition>,\n>(\n config: ResourceConfigMap<Resources>,\n options: GetComponentOptions<Resources>,\n): JSX.Element {\n const { resource, component: componentKey = 'component' } = options;\n const resourceEntry = config[resource];\n\n if (!resourceEntry) {\n throw new InvalidResourceError({\n resource,\n validResources: collectConfigResources(config as Record<string, unknown>),\n });\n }\n\n let entry = resourceEntry as ResourceConfigEntry;\n\n if ('subResource' in options && options.subResource !== undefined) {\n entry = resolveResourceConfigEntry(entry, options.subResource);\n }\n\n return readResourceConfigComponent(entry, componentKey);\n}\n\nfunction getComponentFromPath<\n Resources extends ReadonlyArray<ResourceDefinition>,\n>(config: ResourceConfigMap<Resources>, path: string): JSX.Element {\n let cursor: unknown = config;\n\n for (const segment of path.split('.')) {\n if (!isResourceConfigEntry(cursor)) {\n throw new InvalidPathError({\n path,\n reason: `\"${segment}\" cannot be read because the value before it is not a config branch`,\n });\n }\n\n const next: unknown = (cursor as Record<string, unknown>)[segment];\n\n if (next === undefined || next === null) {\n throw new InvalidPathError({\n path,\n reason: `\"${segment}\" is not configured`,\n });\n }\n\n cursor = next;\n }\n\n if (isResourceConfigEntry(cursor) && 'component' in cursor) {\n return readResourceConfigComponent(cursor, 'component');\n }\n\n return cursor as JSX.Element;\n}\n\nexport function createGetComponent<\n Resources extends ReadonlyArray<ResourceDefinition>,\n>(config: ResourceConfigMap<Resources>): GetComponent<Resources> {\n function getComponent(options: GetComponentOptions<Resources>): JSX.Element;\n function getComponent(path: ResourceConfigPath<Resources>): JSX.Element;\n function getComponent(\n options: GetComponentOptions<Resources> | ResourceConfigPath<Resources>,\n ): JSX.Element {\n if (typeof options === 'string') {\n return getComponentFromPath(config, options);\n }\n\n return getComponentFromOptions(config, options);\n }\n\n const forResource: GetComponentForResource<Resources> = (bound) => {\n return (options) =>\n getComponentFromOptions(config, {\n ...bound,\n ...options,\n } as unknown as GetComponentOptions<Resources>);\n };\n\n return Object.assign(getComponent, { forResource });\n}\n\nexport function createResourceConfig<\n Resources extends ReadonlyArray<ResourceDefinition>,\n const Config extends ResourceConfigMap<Resources>,\n>(\n config: ResourceConfigInput<Resources, Config>,\n): CreatedResourceConfig<Resources, Config> {\n const configRecord = config as Record<string, unknown>;\n\n if (collectConfigResources(configRecord).length === 0) {\n throw new InvalidConfigError({\n reason: 'A resource config must configure at least one resource',\n config,\n });\n }\n\n type Created = CreatedResourceConfig<Resources, Config>;\n\n return {\n config,\n getComponent: createGetComponent(config),\n createGetComponent: ((path: string) =>\n createGetComponentForPath(\n configRecord,\n path,\n )) as unknown as Created['createGetComponent'],\n forPaths: createForPaths(configRecord) as unknown as Created['forPaths'],\n isSubResourceKey: createIsSubResourceKey(\n configRecord,\n ) as unknown as Created['isSubResourceKey'],\n subResources: collectAllSubResourceKeys(\n configRecord,\n ) as unknown as Created['subResources'],\n };\n}\n"],"mappings":";;;;;;;;;;;;AAuWA,SAAS,sBAAsB,OAA8C;CAC3E,OAAO,OAAO,UAAU,YAAY,UAAU;AAChD;AAEA,SAAS,2BACP,OACA,aACqB;CACrB,MAAM,MAAM,OAAO,gBAAgB,WAAW,cAAc,YAAY;CACxE,MAAM,OAAO,MAAM;CAEnB,IAAI,CAAC,sBAAsB,IAAI,GAC7B,MAAM,IAAIA,qDAAwB;EAChC,aAAa;EACb,mBAAmBC,2CAAoB,KAAK;CAC9C,CAAC;CAGH,IAAI,OAAO,gBAAgB,UACzB,OAAO;CAGT,OAAO,2BAA2B,MAAM,YAAY,WAAW;AACjE;AAEA,SAAS,4BACP,OACA,cACa;CACb,IAAI,iBAAiB,SAAS,iBAAiB,UAAU;EACvD,MAAM,SAAS,MAAM;EAErB,IAAI,CAAC,QAAQ,WACX,MAAM,IAAIC,gDAAsB;GAC9B,WAAW,GAAG,aAAa;GAC3B,iBAAiBC,yCAAkB,KAAK;EAC1C,CAAC;EAGH,OAAO,OAAO;CAChB;CAEA,MAAM,QAAQ,MAAM;CAEpB,IAAI,CAAC,OACH,MAAM,IAAID,gDAAsB;EAC9B,WAAW;EACX,iBAAiBC,yCAAkB,KAAK;CAC1C,CAAC;CAGH,OAAO;AACT;AAEA,SAAS,wBAGP,QACA,SACa;CACb,MAAM,EAAE,UAAU,WAAW,eAAe,gBAAgB;CAC5D,MAAM,gBAAgB,OAAO;CAE7B,IAAI,CAAC,eACH,MAAM,IAAIC,8CAAqB;EAC7B;EACA,gBAAgBC,0CAAuB,MAAiC;CAC1E,CAAC;CAGH,IAAI,QAAQ;CAEZ,IAAI,iBAAiB,WAAW,QAAQ,gBAAgB,QACtD,QAAQ,2BAA2B,OAAO,QAAQ,WAAW;CAG/D,OAAO,4BAA4B,OAAO,YAAY;AACxD;AAEA,SAAS,qBAEP,QAAsC,MAA2B;CACjE,IAAI,SAAkB;CAEtB,KAAK,MAAM,WAAW,KAAK,MAAM,GAAG,GAAG;EACrC,IAAI,CAAC,sBAAsB,MAAM,GAC/B,MAAM,IAAIC,sCAAiB;GACzB;GACA,QAAQ,IAAI,QAAQ;EACtB,CAAC;EAGH,MAAM,OAAiB,OAAmC;EAE1D,IAAI,SAAS,UAAa,SAAS,MACjC,MAAM,IAAIA,sCAAiB;GACzB;GACA,QAAQ,IAAI,QAAQ;EACtB,CAAC;EAGH,SAAS;CACX;CAEA,IAAI,sBAAsB,MAAM,KAAK,eAAe,QAClD,OAAO,4BAA4B,QAAQ,WAAW;CAGxD,OAAO;AACT;AAEA,SAAgB,mBAEd,QAA+D;CAG/D,SAAS,aACP,SACa;EACb,IAAI,OAAO,YAAY,UACrB,OAAO,qBAAqB,QAAQ,OAAO;EAG7C,OAAO,wBAAwB,QAAQ,OAAO;CAChD;CAEA,MAAM,eAAmD,UAAU;EACjE,QAAQ,YACN,wBAAwB,QAAQ;GAC9B,GAAG;GACH,GAAG;EACL,CAA8C;CAClD;CAEA,OAAO,OAAO,OAAO,cAAc,EAAE,YAAY,CAAC;AACpD;AAEA,SAAgB,qBAId,QAC0C;CAC1C,MAAM,eAAe;CAErB,IAAID,0CAAuB,YAAY,EAAE,WAAW,GAClD,MAAM,IAAIE,0CAAmB;EAC3B,QAAQ;EACR;CACF,CAAC;CAKH,OAAO;EACL;EACA,cAAc,mBAAmB,MAAM;EACvC,sBAAsB,SACpBC,yDACE,cACA,IACF;EACF,UAAUC,+BAAe,YAAY;EACrC,kBAAkBC,mDAChB,YACF;EACA,cAAcC,6CACZ,YACF;CACF;AACF"}
1
+ {"version":3,"file":"get-component.cjs","names":["InvalidSubResourceError","readSubResourceKeys","InvalidComponentError","readComponentKeys","InvalidResourceError","collectConfigResources","InvalidPathError","InvalidConfigError","createGetComponentForPath","createForPaths","createIsSubResourceKey","collectAllSubResourceKeys"],"sources":["../../src/create-config/get-component.ts"],"sourcesContent":["import type { JSX } from 'react';\nimport {\n InvalidComponentError,\n InvalidConfigError,\n InvalidPathError,\n InvalidResourceError,\n InvalidSubResourceError,\n} from '../errors';\nimport type {\n LayoutResourceKey,\n ResourceDefinition,\n ResourceDefinitionForKey,\n SubResourceDefinitionsFor,\n SubResourceParamForResource,\n} from '../resource';\nimport {\n createForPaths,\n createGetComponentForPath,\n type CreateGetComponentForPath,\n type ForPaths,\n} from './for-paths';\nimport {\n createIsSubResourceKey,\n type IsSubResourceKey,\n} from './is-sub-resource-key';\nimport {\n readComponentKeys,\n readSubResourceKeys,\n} from './component-keys';\nimport {\n collectAllSubResourceKeys,\n collectConfigResources,\n} from './paths';\nimport type {\n ConfigSubResourceKeys,\n ParameterizedResourcePath,\n} from './paths';\nimport type {\n BaseResourceConfigComponents,\n ResourceConfig,\n ResourceConfigComponentKey,\n ResourceConfigComponents,\n ResourceConfigEntry,\n ResourceConfigMap,\n ResourceConfigInput,\n SharedResourceConfigOptions,\n} from './types';\n\ntype ResourceHasLayoutSubResources<\n Resources extends ReadonlyArray<ResourceDefinition>,\n Resource extends LayoutResourceKey<Resources>,\n> = [SubResourceDefinitionsFor<Resources, Resource>] extends [readonly []]\n ? false\n : true;\n\ntype SubResourceOptionForGenerics<\n Resources extends ReadonlyArray<ResourceDefinition>,\n Resource extends LayoutResourceKey<Resources>,\n SubResource extends\n | SubResourceParamForResource<Resources, Resource>\n | undefined,\n> = [SubResource] extends [undefined]\n ? ResourceHasLayoutSubResources<Resources, Resource> extends true\n ? {\n subResource?: SubResourceParamForResource<Resources, Resource>;\n }\n : {}\n : ResourceHasLayoutSubResources<Resources, Resource> extends true\n ? { subResource?: SubResource }\n : {};\n\n/** Options for one layout resource passed to {@link GetComponent}. */\nexport type GetComponentOptionsForResource<\n Resources extends ReadonlyArray<ResourceDefinition>,\n Resource extends LayoutResourceKey<Resources>,\n SubResource extends\n | SubResourceParamForResource<Resources, Resource>\n | undefined = undefined,\n> = SubResourceOptionForGenerics<Resources, Resource, SubResource> & {\n resource: Resource;\n /**\n * The component to get.\n *\n * @default 'component'\n */\n component?: ResourceConfigComponentKey;\n};\n\n/** Union of valid `getComponent` option shapes for each declared layout resource. */\nexport type GetComponentOptions<\n Resources extends ReadonlyArray<ResourceDefinition>,\n> =\n LayoutResourceKey<Resources> extends infer Resource\n ? Resource extends LayoutResourceKey<Resources>\n ? GetComponentOptionsForResource<Resources, Resource>\n : never\n : never;\n\ntype ComponentSlotPathKey = keyof BaseResourceConfigComponents;\n\n/** `detail.errorComponent`, `new.component`, … — component slots inside a shared branch. */\ntype SharedBranchPath = {\n [Branch in keyof SharedResourceConfigOptions]: `${Branch}.${ComponentSlotPathKey}`;\n}[keyof SharedResourceConfigOptions];\n\ntype NestedSubResourceDefinitions<Def extends ResourceDefinition> = Def extends {\n subResources: infer Nested extends ReadonlyArray<ResourceDefinition>;\n}\n ? Nested\n : readonly [];\n\ntype SubResourceEntryPaths<\n SubDefs extends ReadonlyArray<ResourceDefinition>,\n DepthAcc extends readonly unknown[],\n> =\n LayoutResourceKey<SubDefs> extends infer Key extends string\n ? Key extends LayoutResourceKey<SubDefs>\n ?\n | Key\n | `${Key}.${ResourceConfigEntryPath<\n NestedSubResourceDefinitions<\n ResourceDefinitionForKey<SubDefs, Key>\n >,\n readonly [...DepthAcc, unknown]\n >}`\n : never\n : never;\n\n/** Dot-separated keys below one config node: component slots and nested sub-resources. */\ntype ResourceConfigEntryPath<\n SubDefs extends ReadonlyArray<ResourceDefinition>,\n DepthAcc extends readonly unknown[] = readonly [],\n> =\n | ComponentSlotPathKey\n | SharedBranchPath\n | ([SubDefs] extends [readonly []]\n ? never\n : DepthAcc['length'] extends 6\n ? never\n : SubResourceEntryPaths<SubDefs, DepthAcc>);\n\n/**\n * Deep config paths accepted by {@link GetComponent}, e.g.\n * `'templates.deleted.expired.errorComponent'`. Sub-resource segments come from the\n * layout tree, so only declared sub-resources are allowed at each depth.\n */\nexport type ResourceConfigPath<\n Resources extends ReadonlyArray<ResourceDefinition>,\n> =\n LayoutResourceKey<Resources> extends infer Resource extends string\n ? Resource extends LayoutResourceKey<Resources>\n ?\n | Resource\n | `${Resource}.${ResourceConfigEntryPath<\n SubResourceDefinitionsFor<Resources, Resource>\n >}`\n : never\n : never;\n\n/** `subResource` bound by {@link GetComponentForResource}. */\nexport type SubResourceFromGetComponentBound<Bound> = Bound extends {\n subResource: infer SubResource;\n}\n ? SubResource\n : undefined;\n\n/** Options for {@link GetComponentForResource} — binds `resource` and optional `subResource`. */\nexport type GetComponentForResourceOptions<\n Resources extends ReadonlyArray<ResourceDefinition>,\n Resource extends LayoutResourceKey<Resources>,\n SubResource extends\n | SubResourceParamForResource<Resources, Resource>\n | undefined = undefined,\n> = {\n resource: Resource;\n} & SubResourceOptionForGenerics<Resources, Resource, SubResource>;\n\n/** Valid bind shapes for {@link GetComponentForResource}. */\nexport type GetComponentForResourceBound<\n Resources extends ReadonlyArray<ResourceDefinition>,\n> =\n LayoutResourceKey<Resources> extends infer Resource\n ? Resource extends LayoutResourceKey<Resources>\n ? GetComponentForResourceOptions<Resources, Resource>\n : never\n : never;\n\ntype GetComponentForResourceOptionsForBound<\n Resources extends ReadonlyArray<ResourceDefinition>,\n Bound extends { resource: LayoutResourceKey<Resources> },\n> = GetComponentForResourceOptions<\n Resources,\n Bound['resource'],\n SubResourceFromGetComponentBound<Bound>\n>;\n\n/**\n * Rejects bind objects with keys (e.g. `subResource`) that are invalid for the\n * given `resource`. Union assignability alone is too permissive for excess keys.\n */\nexport type ValidateForResourceBound<\n Resources extends ReadonlyArray<ResourceDefinition>,\n Bound extends { resource: LayoutResourceKey<Resources> },\n> = Bound extends GetComponentForResourceOptionsForBound<Resources, Bound>\n ? keyof Bound extends keyof GetComponentForResourceOptionsForBound<\n Resources,\n Bound\n >\n ? Bound\n : never\n : never;\n\n/** `resource` inferred from a {@link GetComponentForResource} bind argument. */\nexport type ResourceFromGetComponentBound<\n Resources extends ReadonlyArray<ResourceDefinition>,\n Bound,\n> = Bound extends {\n resource: infer Resource extends LayoutResourceKey<Resources>;\n}\n ? Resource\n : never;\n\n/** Reusable getter returned by {@link GetComponentForResource} (only `component` remains). */\nexport type GetComponentAtBound<\n Resources extends ReadonlyArray<ResourceDefinition>,\n Resource extends LayoutResourceKey<Resources>,\n SubResource extends\n | SubResourceParamForResource<Resources, Resource>\n | undefined = undefined,\n> = (\n options?: Pick<\n GetComponentOptionsForResource<Resources, Resource, SubResource>,\n 'component'\n >,\n) => JSX.Element;\n\nexport type GetComponentForResource<\n Resources extends ReadonlyArray<ResourceDefinition>,\n> = <\n const Bound extends {\n resource: LayoutResourceKey<Resources>;\n },\n>(\n bound: ValidateForResourceBound<Resources, Bound>,\n) => GetComponentAtBound<\n Resources,\n ResourceFromGetComponentBound<Resources, Bound>,\n SubResourceFromGetComponentBound<Bound>\n>;\n\nexport interface GetComponent<\n Resources extends ReadonlyArray<ResourceDefinition>,\n> {\n /** Looks up a component by resource / optional sub-resource / optional component slot. */\n <const Options extends GetComponentOptions<Resources>>(\n options: Options,\n ): JSX.Element;\n /**\n * Looks up a component by a deep config path.\n * A path ending on a branch (e.g. `'templates.deleted.expired'`) returns that branch's\n * `component`; a path ending on a slot returns that slot.\n */\n <const Path extends ResourceConfigPath<Resources>>(path: Path): JSX.Element;\n forResource: GetComponentForResource<Resources>;\n}\n\nexport interface CreatedResourceConfig<\n Resources extends ReadonlyArray<ResourceDefinition>,\n Config extends ResourceConfigMap<Resources> = ResourceConfigMap<Resources>,\n> {\n config: Config;\n getComponent: GetComponent<Resources>;\n /**\n * Creates a reusable getter bound to one path. Variables the path leaves open become\n * the getter's arguments.\n *\n * @example\n * ```ts\n * const getDetail = createGetComponent('$resource.detail.$component');\n *\n * getDetail({ resource: 'templates', component: 'errorComponent' });\n * ```\n */\n createGetComponent: CreateGetComponentForPath<\n Resources,\n Config,\n ParameterizedResourcePath<Resources>\n >;\n /**\n * Builds a component for one or more paths. Declare which params the component takes,\n * then render it.\n *\n * @example\n * ```ts\n * const ResourceDetail = forPaths('$resource.detail.$component')\n * .addPathParams()\n * .render(({ params, getComponentForPath }) =>\n * getComponentForPath('$resource.detail.$component')(params),\n * );\n * ```\n */\n forPaths: ForPaths<\n Resources,\n Config,\n ParameterizedResourcePath<Resources>\n >;\n /** Narrows an unknown value to a sub-resource key configured for a path or resource. */\n isSubResourceKey: IsSubResourceKey<\n Resources,\n Config,\n ParameterizedResourcePath<Resources>\n >;\n /** Every sub-resource key configured in this config, at any depth. */\n subResources: ReadonlyArray<ConfigSubResourceKeys<Resources, Config>>;\n}\n\ntype ComponentTypesFromEntry<Entry> = Entry extends JSX.Element\n ? never\n : Entry extends object\n ?\n | Extract<keyof Entry, ResourceConfigComponentKey>\n | {\n [Key in keyof Entry]: NonNullable<Entry[Key]> extends JSX.Element\n ? never\n : ComponentTypesFromEntry<NonNullable<Entry[Key]>>;\n }[keyof Entry]\n : never;\n\n/**\n * Component selector keys actually defined anywhere in a created resource config.\n *\n * @example\n * ```ts\n * ComponentTypes<typeof resourceConfig>\n * // ^? may resolve to:`'component' | 'errorComponent' | 'detail'`.\n * ```\n */\nexport type ComponentTypes<Created> = Created extends {\n config: infer Config extends object;\n}\n ? {\n [Resource in keyof Config]: ComponentTypesFromEntry<\n NonNullable<Config[Resource]>\n >;\n }[keyof Config]\n : never;\n\n/**\n * One resource entry keyed for direct spreading into a resource config.\n * Preserves the precise component slots and sub-resource branches in `Config`.\n */\nexport type ResourceConfigFragment<\n Resource extends string,\n Config,\n> = { [Key in Resource]: Config };\n\n/**\n * Creates one keyed config fragment for spreading into a resource config.\n *\n * @param resource - A top-level resource supported by the layout definition.\n * @param config - Components and declared sub-resource branches for that resource.\n */\nexport type CreateResourceConfigForResource<\n Resources extends ReadonlyArray<ResourceDefinition>,\n> = <\n const Resource extends LayoutResourceKey<Resources>,\n const Config extends ResourceConfig<Resources>[Resource],\n>(\n resource: Resource,\n config: Config,\n) => ResourceConfigFragment<Resource, Config>;\n\n/** Creates a validated resource config and exposes helpers for config fragments. */\nexport type CreateResourceConfigFn<\n Resources extends ReadonlyArray<ResourceDefinition>,\n> = {\n /**\n * Validates and indexes a complete configuration assembled from one or more\n * resource entries.\n *\n * @param config - At least one resource entry supported by the layout.\n */\n <const Config extends ResourceConfigMap<Resources>>(\n config: ResourceConfigInput<Resources, Config>,\n ): CreatedResourceConfig<Resources, Config>;\n /** Creates a typed fragment that can be spread into the complete config. */\n forResource: CreateResourceConfigForResource<Resources>;\n};\n\ntype SubResourceParam =\n | string\n | {\n value: string;\n subResource: SubResourceParam;\n };\n\nfunction isResourceConfigEntry(value: unknown): value is ResourceConfigEntry {\n return typeof value === 'object' && value !== null;\n}\n\nfunction resolveResourceConfigEntry(\n entry: ResourceConfigEntry,\n subResource: SubResourceParam,\n): ResourceConfigEntry {\n const key = typeof subResource === 'string' ? subResource : subResource.value;\n const next = entry[key];\n\n if (!isResourceConfigEntry(next)) {\n throw new InvalidSubResourceError({\n subResource: key,\n validSubResources: readSubResourceKeys(entry),\n });\n }\n\n if (typeof subResource === 'string') {\n return next;\n }\n\n return resolveResourceConfigEntry(next, subResource.subResource);\n}\n\nfunction readResourceConfigComponent(\n entry: ResourceConfigComponents,\n componentKey: ResourceConfigComponentKey,\n): JSX.Element {\n if (componentKey === 'new' || componentKey === 'detail') {\n const branch = entry[componentKey];\n\n if (!branch?.component) {\n throw new InvalidComponentError({\n component: `${componentKey}.component`,\n validComponents: readComponentKeys(entry),\n });\n }\n\n return branch.component;\n }\n\n const value = entry[componentKey];\n\n if (!value) {\n throw new InvalidComponentError({\n component: componentKey,\n validComponents: readComponentKeys(entry),\n });\n }\n\n return value;\n}\n\nfunction getComponentFromOptions<\n Resources extends ReadonlyArray<ResourceDefinition>,\n>(\n config: ResourceConfigMap<Resources>,\n options: GetComponentOptions<Resources>,\n): JSX.Element {\n const { resource, component: componentKey = 'component' } = options;\n const resourceEntry = config[resource];\n\n if (!resourceEntry) {\n throw new InvalidResourceError({\n resource,\n validResources: collectConfigResources(config as Record<string, unknown>),\n });\n }\n\n let entry = resourceEntry as ResourceConfigEntry;\n\n if ('subResource' in options && options.subResource !== undefined) {\n entry = resolveResourceConfigEntry(entry, options.subResource);\n }\n\n return readResourceConfigComponent(entry, componentKey);\n}\n\nfunction getComponentFromPath<\n Resources extends ReadonlyArray<ResourceDefinition>,\n>(config: ResourceConfigMap<Resources>, path: string): JSX.Element {\n let cursor: unknown = config;\n\n for (const segment of path.split('.')) {\n if (!isResourceConfigEntry(cursor)) {\n throw new InvalidPathError({\n path,\n reason: `\"${segment}\" cannot be read because the value before it is not a config branch`,\n });\n }\n\n const next: unknown = (cursor as Record<string, unknown>)[segment];\n\n if (next === undefined || next === null) {\n throw new InvalidPathError({\n path,\n reason: `\"${segment}\" is not configured`,\n });\n }\n\n cursor = next;\n }\n\n if (isResourceConfigEntry(cursor) && 'component' in cursor) {\n return readResourceConfigComponent(cursor, 'component');\n }\n\n return cursor as JSX.Element;\n}\n\nexport function createGetComponent<\n Resources extends ReadonlyArray<ResourceDefinition>,\n>(config: ResourceConfigMap<Resources>): GetComponent<Resources> {\n function getComponent(options: GetComponentOptions<Resources>): JSX.Element;\n function getComponent(path: ResourceConfigPath<Resources>): JSX.Element;\n function getComponent(\n options: GetComponentOptions<Resources> | ResourceConfigPath<Resources>,\n ): JSX.Element {\n if (typeof options === 'string') {\n return getComponentFromPath(config, options);\n }\n\n return getComponentFromOptions(config, options);\n }\n\n const forResource: GetComponentForResource<Resources> = (bound) => {\n return (options) =>\n getComponentFromOptions(config, {\n ...bound,\n ...options,\n } as unknown as GetComponentOptions<Resources>);\n };\n\n return Object.assign(getComponent, { forResource });\n}\n\nfunction createResourceConfigImpl<\n Resources extends ReadonlyArray<ResourceDefinition>,\n const Config extends ResourceConfigMap<Resources>,\n>(\n config: ResourceConfigInput<Resources, Config>,\n): CreatedResourceConfig<Resources, Config> {\n const configRecord = config as Record<string, unknown>;\n\n if (collectConfigResources(configRecord).length === 0) {\n throw new InvalidConfigError({\n reason: 'A resource config must configure at least one resource',\n config,\n });\n }\n\n type Created = CreatedResourceConfig<Resources, Config>;\n\n return {\n config,\n getComponent: createGetComponent(config),\n createGetComponent: ((path: string) =>\n createGetComponentForPath(\n configRecord,\n path,\n )) as unknown as Created['createGetComponent'],\n forPaths: createForPaths(configRecord) as unknown as Created['forPaths'],\n isSubResourceKey: createIsSubResourceKey(\n configRecord,\n ) as unknown as Created['isSubResourceKey'],\n subResources: collectAllSubResourceKeys(\n configRecord,\n ) as unknown as Created['subResources'],\n };\n}\n\nfunction createResourceConfigForResource<\n Resources extends ReadonlyArray<ResourceDefinition>,\n const Resource extends LayoutResourceKey<Resources>,\n const Config extends ResourceConfig<Resources>[Resource],\n>(\n resource: Resource,\n config: Config,\n): ResourceConfigFragment<Resource, Config> {\n return { [resource]: config } as ResourceConfigFragment<Resource, Config>;\n}\n\n/**\n * Creates a validated resource configuration. Use `.forResource()` to build\n * independently declared, type-safe fragments that can be spread into the\n * complete configuration object.\n *\n * @param config - Resource entries to validate and expose through lookup helpers.\n * @returns The original config plus typed component and path lookup helpers.\n *\n * @example\n * ```tsx\n * const users = createResourceConfig.forResource('users', {\n * component: <Users />,\n * });\n *\n * const config = createResourceConfig({ ...users });\n * ```\n */\nexport const createResourceConfig = Object.assign(createResourceConfigImpl, {\n forResource: createResourceConfigForResource,\n});\n"],"mappings":";;;;;;;;;;;;AA4YA,SAAS,sBAAsB,OAA8C;CAC3E,OAAO,OAAO,UAAU,YAAY,UAAU;AAChD;AAEA,SAAS,2BACP,OACA,aACqB;CACrB,MAAM,MAAM,OAAO,gBAAgB,WAAW,cAAc,YAAY;CACxE,MAAM,OAAO,MAAM;CAEnB,IAAI,CAAC,sBAAsB,IAAI,GAC7B,MAAM,IAAIA,qDAAwB;EAChC,aAAa;EACb,mBAAmBC,2CAAoB,KAAK;CAC9C,CAAC;CAGH,IAAI,OAAO,gBAAgB,UACzB,OAAO;CAGT,OAAO,2BAA2B,MAAM,YAAY,WAAW;AACjE;AAEA,SAAS,4BACP,OACA,cACa;CACb,IAAI,iBAAiB,SAAS,iBAAiB,UAAU;EACvD,MAAM,SAAS,MAAM;EAErB,IAAI,CAAC,QAAQ,WACX,MAAM,IAAIC,gDAAsB;GAC9B,WAAW,GAAG,aAAa;GAC3B,iBAAiBC,yCAAkB,KAAK;EAC1C,CAAC;EAGH,OAAO,OAAO;CAChB;CAEA,MAAM,QAAQ,MAAM;CAEpB,IAAI,CAAC,OACH,MAAM,IAAID,gDAAsB;EAC9B,WAAW;EACX,iBAAiBC,yCAAkB,KAAK;CAC1C,CAAC;CAGH,OAAO;AACT;AAEA,SAAS,wBAGP,QACA,SACa;CACb,MAAM,EAAE,UAAU,WAAW,eAAe,gBAAgB;CAC5D,MAAM,gBAAgB,OAAO;CAE7B,IAAI,CAAC,eACH,MAAM,IAAIC,8CAAqB;EAC7B;EACA,gBAAgBC,0CAAuB,MAAiC;CAC1E,CAAC;CAGH,IAAI,QAAQ;CAEZ,IAAI,iBAAiB,WAAW,QAAQ,gBAAgB,QACtD,QAAQ,2BAA2B,OAAO,QAAQ,WAAW;CAG/D,OAAO,4BAA4B,OAAO,YAAY;AACxD;AAEA,SAAS,qBAEP,QAAsC,MAA2B;CACjE,IAAI,SAAkB;CAEtB,KAAK,MAAM,WAAW,KAAK,MAAM,GAAG,GAAG;EACrC,IAAI,CAAC,sBAAsB,MAAM,GAC/B,MAAM,IAAIC,sCAAiB;GACzB;GACA,QAAQ,IAAI,QAAQ;EACtB,CAAC;EAGH,MAAM,OAAiB,OAAmC;EAE1D,IAAI,SAAS,UAAa,SAAS,MACjC,MAAM,IAAIA,sCAAiB;GACzB;GACA,QAAQ,IAAI,QAAQ;EACtB,CAAC;EAGH,SAAS;CACX;CAEA,IAAI,sBAAsB,MAAM,KAAK,eAAe,QAClD,OAAO,4BAA4B,QAAQ,WAAW;CAGxD,OAAO;AACT;AAEA,SAAgB,mBAEd,QAA+D;CAG/D,SAAS,aACP,SACa;EACb,IAAI,OAAO,YAAY,UACrB,OAAO,qBAAqB,QAAQ,OAAO;EAG7C,OAAO,wBAAwB,QAAQ,OAAO;CAChD;CAEA,MAAM,eAAmD,UAAU;EACjE,QAAQ,YACN,wBAAwB,QAAQ;GAC9B,GAAG;GACH,GAAG;EACL,CAA8C;CAClD;CAEA,OAAO,OAAO,OAAO,cAAc,EAAE,YAAY,CAAC;AACpD;AAEA,SAAS,yBAIP,QAC0C;CAC1C,MAAM,eAAe;CAErB,IAAID,0CAAuB,YAAY,EAAE,WAAW,GAClD,MAAM,IAAIE,0CAAmB;EAC3B,QAAQ;EACR;CACF,CAAC;CAKH,OAAO;EACL;EACA,cAAc,mBAAmB,MAAM;EACvC,sBAAsB,SACpBC,yDACE,cACA,IACF;EACF,UAAUC,+BAAe,YAAY;EACrC,kBAAkBC,mDAChB,YACF;EACA,cAAcC,6CACZ,YACF;CACF;AACF;AAEA,SAAS,gCAKP,UACA,QAC0C;CAC1C,OAAO,GAAG,WAAW,OAAO;AAC9B;;;;;;;;;;;;;;;;;;AAmBA,MAAa,uBAAuB,OAAO,OAAO,0BAA0B,EAC1E,aAAa,gCACf,CAAC"}
@@ -1,5 +1,5 @@
1
1
  import { LayoutResourceKey, ResourceDefinition, ResourceDefinitionForKey, SubResourceDefinitionsFor, SubResourceParamForResource } from "../resource.cjs";
2
- import { BaseResourceConfigComponents, ResourceConfigComponentKey, ResourceConfigInput, ResourceConfigMap, SharedResourceConfigOptions } from "./types.cjs";
2
+ import { BaseResourceConfigComponents, ResourceConfig, ResourceConfigComponentKey, ResourceConfigInput, ResourceConfigMap, SharedResourceConfigOptions } from "./types.cjs";
3
3
  import { ConfigSubResourceKeys, ParameterizedResourcePath } from "./paths/types.cjs";
4
4
  import { CreateGetComponentForPath } from "./for-paths/get-component-for-path.cjs";
5
5
  import { ForPaths } from "./for-paths/builder.cjs";
@@ -125,7 +125,29 @@ type ComponentTypesFromEntry<Entry> = Entry extends JSX.Element ? never : Entry
125
125
  type ComponentTypes<Created> = Created extends {
126
126
  config: infer Config extends object;
127
127
  } ? { [Resource in keyof Config]: ComponentTypesFromEntry<NonNullable<Config[Resource]>> }[keyof Config] : never;
128
- type CreateResourceConfigFn<Resources extends ReadonlyArray<ResourceDefinition>> = <const Config extends ResourceConfigMap<Resources>>(config: ResourceConfigInput<Resources, Config>) => CreatedResourceConfig<Resources, Config>;
128
+ /**
129
+ * One resource entry keyed for direct spreading into a resource config.
130
+ * Preserves the precise component slots and sub-resource branches in `Config`.
131
+ */
132
+ type ResourceConfigFragment<Resource extends string, Config> = { [Key in Resource]: Config };
133
+ /**
134
+ * Creates one keyed config fragment for spreading into a resource config.
135
+ *
136
+ * @param resource - A top-level resource supported by the layout definition.
137
+ * @param config - Components and declared sub-resource branches for that resource.
138
+ */
139
+ type CreateResourceConfigForResource<Resources extends ReadonlyArray<ResourceDefinition>> = <const Resource extends LayoutResourceKey<Resources>, const Config extends ResourceConfig<Resources>[Resource]>(resource: Resource, config: Config) => ResourceConfigFragment<Resource, Config>;
140
+ /** Creates a validated resource config and exposes helpers for config fragments. */
141
+ type CreateResourceConfigFn<Resources extends ReadonlyArray<ResourceDefinition>> = {
142
+ /**
143
+ * Validates and indexes a complete configuration assembled from one or more
144
+ * resource entries.
145
+ *
146
+ * @param config - At least one resource entry supported by the layout.
147
+ */
148
+ <const Config extends ResourceConfigMap<Resources>>(config: ResourceConfigInput<Resources, Config>): CreatedResourceConfig<Resources, Config>; /** Creates a typed fragment that can be spread into the complete config. */
149
+ forResource: CreateResourceConfigForResource<Resources>;
150
+ };
129
151
  //#endregion
130
- export { ComponentTypes, CreateResourceConfigFn, CreatedResourceConfig, GetComponent, GetComponentAtBound, GetComponentForResource, GetComponentForResourceOptions, GetComponentOptions, GetComponentOptionsForResource, ResourceConfigPath, ResourceFromGetComponentBound, SubResourceFromGetComponentBound, ValidateForResourceBound };
152
+ export { ComponentTypes, CreateResourceConfigFn, CreateResourceConfigForResource, CreatedResourceConfig, GetComponent, GetComponentAtBound, GetComponentForResource, GetComponentForResourceOptions, GetComponentOptions, GetComponentOptionsForResource, ResourceConfigFragment, ResourceConfigPath, ResourceFromGetComponentBound, SubResourceFromGetComponentBound, ValidateForResourceBound };
131
153
  //# sourceMappingURL=get-component.d.cts.map
@@ -1 +1 @@
1
- {"version":3,"file":"get-component.d.cts","names":[],"sources":["../../src/create-config/get-component.ts"],"mappings":"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"}
1
+ {"version":3,"file":"get-component.d.cts","names":[],"sources":["../../src/create-config/get-component.ts"],"mappings":"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"}
@@ -1,5 +1,5 @@
1
1
  import { LayoutResourceKey, ResourceDefinition, ResourceDefinitionForKey, SubResourceDefinitionsFor, SubResourceParamForResource } from "../resource.mjs";
2
- import { BaseResourceConfigComponents, ResourceConfigComponentKey, ResourceConfigInput, ResourceConfigMap, SharedResourceConfigOptions } from "./types.mjs";
2
+ import { BaseResourceConfigComponents, ResourceConfig, ResourceConfigComponentKey, ResourceConfigInput, ResourceConfigMap, SharedResourceConfigOptions } from "./types.mjs";
3
3
  import { ConfigSubResourceKeys, ParameterizedResourcePath } from "./paths/types.mjs";
4
4
  import { CreateGetComponentForPath } from "./for-paths/get-component-for-path.mjs";
5
5
  import { ForPaths } from "./for-paths/builder.mjs";
@@ -125,7 +125,29 @@ type ComponentTypesFromEntry<Entry> = Entry extends JSX.Element ? never : Entry
125
125
  type ComponentTypes<Created> = Created extends {
126
126
  config: infer Config extends object;
127
127
  } ? { [Resource in keyof Config]: ComponentTypesFromEntry<NonNullable<Config[Resource]>> }[keyof Config] : never;
128
- type CreateResourceConfigFn<Resources extends ReadonlyArray<ResourceDefinition>> = <const Config extends ResourceConfigMap<Resources>>(config: ResourceConfigInput<Resources, Config>) => CreatedResourceConfig<Resources, Config>;
128
+ /**
129
+ * One resource entry keyed for direct spreading into a resource config.
130
+ * Preserves the precise component slots and sub-resource branches in `Config`.
131
+ */
132
+ type ResourceConfigFragment<Resource extends string, Config> = { [Key in Resource]: Config };
133
+ /**
134
+ * Creates one keyed config fragment for spreading into a resource config.
135
+ *
136
+ * @param resource - A top-level resource supported by the layout definition.
137
+ * @param config - Components and declared sub-resource branches for that resource.
138
+ */
139
+ type CreateResourceConfigForResource<Resources extends ReadonlyArray<ResourceDefinition>> = <const Resource extends LayoutResourceKey<Resources>, const Config extends ResourceConfig<Resources>[Resource]>(resource: Resource, config: Config) => ResourceConfigFragment<Resource, Config>;
140
+ /** Creates a validated resource config and exposes helpers for config fragments. */
141
+ type CreateResourceConfigFn<Resources extends ReadonlyArray<ResourceDefinition>> = {
142
+ /**
143
+ * Validates and indexes a complete configuration assembled from one or more
144
+ * resource entries.
145
+ *
146
+ * @param config - At least one resource entry supported by the layout.
147
+ */
148
+ <const Config extends ResourceConfigMap<Resources>>(config: ResourceConfigInput<Resources, Config>): CreatedResourceConfig<Resources, Config>; /** Creates a typed fragment that can be spread into the complete config. */
149
+ forResource: CreateResourceConfigForResource<Resources>;
150
+ };
129
151
  //#endregion
130
- export { ComponentTypes, CreateResourceConfigFn, CreatedResourceConfig, GetComponent, GetComponentAtBound, GetComponentForResource, GetComponentForResourceOptions, GetComponentOptions, GetComponentOptionsForResource, ResourceConfigPath, ResourceFromGetComponentBound, SubResourceFromGetComponentBound, ValidateForResourceBound };
152
+ export { ComponentTypes, CreateResourceConfigFn, CreateResourceConfigForResource, CreatedResourceConfig, GetComponent, GetComponentAtBound, GetComponentForResource, GetComponentForResourceOptions, GetComponentOptions, GetComponentOptionsForResource, ResourceConfigFragment, ResourceConfigPath, ResourceFromGetComponentBound, SubResourceFromGetComponentBound, ValidateForResourceBound };
131
153
  //# sourceMappingURL=get-component.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"get-component.d.mts","names":[],"sources":["../../src/create-config/get-component.ts"],"mappings":"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"}
1
+ {"version":3,"file":"get-component.d.mts","names":[],"sources":["../../src/create-config/get-component.ts"],"mappings":"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"}
@@ -80,7 +80,7 @@ function createGetComponent(config) {
80
80
  };
81
81
  return Object.assign(getComponent, { forResource });
82
82
  }
83
- function createResourceConfig(config) {
83
+ function createResourceConfigImpl(config) {
84
84
  const configRecord = config;
85
85
  if (collectConfigResources(configRecord).length === 0) throw new InvalidConfigError({
86
86
  reason: "A resource config must configure at least one resource",
@@ -95,6 +95,27 @@ function createResourceConfig(config) {
95
95
  subResources: collectAllSubResourceKeys(configRecord)
96
96
  };
97
97
  }
98
+ function createResourceConfigForResource(resource, config) {
99
+ return { [resource]: config };
100
+ }
101
+ /**
102
+ * Creates a validated resource configuration. Use `.forResource()` to build
103
+ * independently declared, type-safe fragments that can be spread into the
104
+ * complete configuration object.
105
+ *
106
+ * @param config - Resource entries to validate and expose through lookup helpers.
107
+ * @returns The original config plus typed component and path lookup helpers.
108
+ *
109
+ * @example
110
+ * ```tsx
111
+ * const users = createResourceConfig.forResource('users', {
112
+ * component: <Users />,
113
+ * });
114
+ *
115
+ * const config = createResourceConfig({ ...users });
116
+ * ```
117
+ */
118
+ const createResourceConfig = Object.assign(createResourceConfigImpl, { forResource: createResourceConfigForResource });
98
119
 
99
120
  //#endregion
100
121
  export { createResourceConfig };
@@ -1 +1 @@
1
- {"version":3,"file":"get-component.mjs","names":[],"sources":["../../src/create-config/get-component.ts"],"sourcesContent":["import type { JSX } from 'react';\nimport {\n InvalidComponentError,\n InvalidConfigError,\n InvalidPathError,\n InvalidResourceError,\n InvalidSubResourceError,\n} from '../errors';\nimport type {\n LayoutResourceKey,\n ResourceDefinition,\n ResourceDefinitionForKey,\n SubResourceDefinitionsFor,\n SubResourceParamForResource,\n} from '../resource';\nimport {\n createForPaths,\n createGetComponentForPath,\n type CreateGetComponentForPath,\n type ForPaths,\n} from './for-paths';\nimport {\n createIsSubResourceKey,\n type IsSubResourceKey,\n} from './is-sub-resource-key';\nimport {\n readComponentKeys,\n readSubResourceKeys,\n} from './component-keys';\nimport {\n collectAllSubResourceKeys,\n collectConfigResources,\n} from './paths';\nimport type {\n ConfigSubResourceKeys,\n ParameterizedResourcePath,\n} from './paths';\nimport type {\n BaseResourceConfigComponents,\n ResourceConfigComponentKey,\n ResourceConfigComponents,\n ResourceConfigEntry,\n ResourceConfigMap,\n ResourceConfigInput,\n SharedResourceConfigOptions,\n} from './types';\n\ntype ResourceHasLayoutSubResources<\n Resources extends ReadonlyArray<ResourceDefinition>,\n Resource extends LayoutResourceKey<Resources>,\n> = [SubResourceDefinitionsFor<Resources, Resource>] extends [readonly []]\n ? false\n : true;\n\ntype SubResourceOptionForGenerics<\n Resources extends ReadonlyArray<ResourceDefinition>,\n Resource extends LayoutResourceKey<Resources>,\n SubResource extends\n | SubResourceParamForResource<Resources, Resource>\n | undefined,\n> = [SubResource] extends [undefined]\n ? ResourceHasLayoutSubResources<Resources, Resource> extends true\n ? {\n subResource?: SubResourceParamForResource<Resources, Resource>;\n }\n : {}\n : ResourceHasLayoutSubResources<Resources, Resource> extends true\n ? { subResource?: SubResource }\n : {};\n\n/** Options for one layout resource passed to {@link GetComponent}. */\nexport type GetComponentOptionsForResource<\n Resources extends ReadonlyArray<ResourceDefinition>,\n Resource extends LayoutResourceKey<Resources>,\n SubResource extends\n | SubResourceParamForResource<Resources, Resource>\n | undefined = undefined,\n> = SubResourceOptionForGenerics<Resources, Resource, SubResource> & {\n resource: Resource;\n /**\n * The component to get.\n *\n * @default 'component'\n */\n component?: ResourceConfigComponentKey;\n};\n\n/** Union of valid `getComponent` option shapes for each declared layout resource. */\nexport type GetComponentOptions<\n Resources extends ReadonlyArray<ResourceDefinition>,\n> =\n LayoutResourceKey<Resources> extends infer Resource\n ? Resource extends LayoutResourceKey<Resources>\n ? GetComponentOptionsForResource<Resources, Resource>\n : never\n : never;\n\ntype ComponentSlotPathKey = keyof BaseResourceConfigComponents;\n\n/** `detail.errorComponent`, `new.component`, … — component slots inside a shared branch. */\ntype SharedBranchPath = {\n [Branch in keyof SharedResourceConfigOptions]: `${Branch}.${ComponentSlotPathKey}`;\n}[keyof SharedResourceConfigOptions];\n\ntype NestedSubResourceDefinitions<Def extends ResourceDefinition> = Def extends {\n subResources: infer Nested extends ReadonlyArray<ResourceDefinition>;\n}\n ? Nested\n : readonly [];\n\ntype SubResourceEntryPaths<\n SubDefs extends ReadonlyArray<ResourceDefinition>,\n DepthAcc extends readonly unknown[],\n> =\n LayoutResourceKey<SubDefs> extends infer Key extends string\n ? Key extends LayoutResourceKey<SubDefs>\n ?\n | Key\n | `${Key}.${ResourceConfigEntryPath<\n NestedSubResourceDefinitions<\n ResourceDefinitionForKey<SubDefs, Key>\n >,\n readonly [...DepthAcc, unknown]\n >}`\n : never\n : never;\n\n/** Dot-separated keys below one config node: component slots and nested sub-resources. */\ntype ResourceConfigEntryPath<\n SubDefs extends ReadonlyArray<ResourceDefinition>,\n DepthAcc extends readonly unknown[] = readonly [],\n> =\n | ComponentSlotPathKey\n | SharedBranchPath\n | ([SubDefs] extends [readonly []]\n ? never\n : DepthAcc['length'] extends 6\n ? never\n : SubResourceEntryPaths<SubDefs, DepthAcc>);\n\n/**\n * Deep config paths accepted by {@link GetComponent}, e.g.\n * `'templates.deleted.expired.errorComponent'`. Sub-resource segments come from the\n * layout tree, so only declared sub-resources are allowed at each depth.\n */\nexport type ResourceConfigPath<\n Resources extends ReadonlyArray<ResourceDefinition>,\n> =\n LayoutResourceKey<Resources> extends infer Resource extends string\n ? Resource extends LayoutResourceKey<Resources>\n ?\n | Resource\n | `${Resource}.${ResourceConfigEntryPath<\n SubResourceDefinitionsFor<Resources, Resource>\n >}`\n : never\n : never;\n\n/** `subResource` bound by {@link GetComponentForResource}. */\nexport type SubResourceFromGetComponentBound<Bound> = Bound extends {\n subResource: infer SubResource;\n}\n ? SubResource\n : undefined;\n\n/** Options for {@link GetComponentForResource} — binds `resource` and optional `subResource`. */\nexport type GetComponentForResourceOptions<\n Resources extends ReadonlyArray<ResourceDefinition>,\n Resource extends LayoutResourceKey<Resources>,\n SubResource extends\n | SubResourceParamForResource<Resources, Resource>\n | undefined = undefined,\n> = {\n resource: Resource;\n} & SubResourceOptionForGenerics<Resources, Resource, SubResource>;\n\n/** Valid bind shapes for {@link GetComponentForResource}. */\nexport type GetComponentForResourceBound<\n Resources extends ReadonlyArray<ResourceDefinition>,\n> =\n LayoutResourceKey<Resources> extends infer Resource\n ? Resource extends LayoutResourceKey<Resources>\n ? GetComponentForResourceOptions<Resources, Resource>\n : never\n : never;\n\ntype GetComponentForResourceOptionsForBound<\n Resources extends ReadonlyArray<ResourceDefinition>,\n Bound extends { resource: LayoutResourceKey<Resources> },\n> = GetComponentForResourceOptions<\n Resources,\n Bound['resource'],\n SubResourceFromGetComponentBound<Bound>\n>;\n\n/**\n * Rejects bind objects with keys (e.g. `subResource`) that are invalid for the\n * given `resource`. Union assignability alone is too permissive for excess keys.\n */\nexport type ValidateForResourceBound<\n Resources extends ReadonlyArray<ResourceDefinition>,\n Bound extends { resource: LayoutResourceKey<Resources> },\n> = Bound extends GetComponentForResourceOptionsForBound<Resources, Bound>\n ? keyof Bound extends keyof GetComponentForResourceOptionsForBound<\n Resources,\n Bound\n >\n ? Bound\n : never\n : never;\n\n/** `resource` inferred from a {@link GetComponentForResource} bind argument. */\nexport type ResourceFromGetComponentBound<\n Resources extends ReadonlyArray<ResourceDefinition>,\n Bound,\n> = Bound extends {\n resource: infer Resource extends LayoutResourceKey<Resources>;\n}\n ? Resource\n : never;\n\n/** Reusable getter returned by {@link GetComponentForResource} (only `component` remains). */\nexport type GetComponentAtBound<\n Resources extends ReadonlyArray<ResourceDefinition>,\n Resource extends LayoutResourceKey<Resources>,\n SubResource extends\n | SubResourceParamForResource<Resources, Resource>\n | undefined = undefined,\n> = (\n options?: Pick<\n GetComponentOptionsForResource<Resources, Resource, SubResource>,\n 'component'\n >,\n) => JSX.Element;\n\nexport type GetComponentForResource<\n Resources extends ReadonlyArray<ResourceDefinition>,\n> = <\n const Bound extends {\n resource: LayoutResourceKey<Resources>;\n },\n>(\n bound: ValidateForResourceBound<Resources, Bound>,\n) => GetComponentAtBound<\n Resources,\n ResourceFromGetComponentBound<Resources, Bound>,\n SubResourceFromGetComponentBound<Bound>\n>;\n\nexport interface GetComponent<\n Resources extends ReadonlyArray<ResourceDefinition>,\n> {\n /** Looks up a component by resource / optional sub-resource / optional component slot. */\n <const Options extends GetComponentOptions<Resources>>(\n options: Options,\n ): JSX.Element;\n /**\n * Looks up a component by a deep config path.\n * A path ending on a branch (e.g. `'templates.deleted.expired'`) returns that branch's\n * `component`; a path ending on a slot returns that slot.\n */\n <const Path extends ResourceConfigPath<Resources>>(path: Path): JSX.Element;\n forResource: GetComponentForResource<Resources>;\n}\n\nexport interface CreatedResourceConfig<\n Resources extends ReadonlyArray<ResourceDefinition>,\n Config extends ResourceConfigMap<Resources> = ResourceConfigMap<Resources>,\n> {\n config: Config;\n getComponent: GetComponent<Resources>;\n /**\n * Creates a reusable getter bound to one path. Variables the path leaves open become\n * the getter's arguments.\n *\n * @example\n * ```ts\n * const getDetail = createGetComponent('$resource.detail.$component');\n *\n * getDetail({ resource: 'templates', component: 'errorComponent' });\n * ```\n */\n createGetComponent: CreateGetComponentForPath<\n Resources,\n Config,\n ParameterizedResourcePath<Resources>\n >;\n /**\n * Builds a component for one or more paths. Declare which params the component takes,\n * then render it.\n *\n * @example\n * ```ts\n * const ResourceDetail = forPaths('$resource.detail.$component')\n * .addPathParams()\n * .render(({ params, getComponentForPath }) =>\n * getComponentForPath('$resource.detail.$component')(params),\n * );\n * ```\n */\n forPaths: ForPaths<\n Resources,\n Config,\n ParameterizedResourcePath<Resources>\n >;\n /** Narrows an unknown value to a sub-resource key configured for a path or resource. */\n isSubResourceKey: IsSubResourceKey<\n Resources,\n Config,\n ParameterizedResourcePath<Resources>\n >;\n /** Every sub-resource key configured in this config, at any depth. */\n subResources: ReadonlyArray<ConfigSubResourceKeys<Resources, Config>>;\n}\n\ntype ComponentTypesFromEntry<Entry> = Entry extends JSX.Element\n ? never\n : Entry extends object\n ?\n | Extract<keyof Entry, ResourceConfigComponentKey>\n | {\n [Key in keyof Entry]: NonNullable<Entry[Key]> extends JSX.Element\n ? never\n : ComponentTypesFromEntry<NonNullable<Entry[Key]>>;\n }[keyof Entry]\n : never;\n\n/**\n * Component selector keys actually defined anywhere in a created resource config.\n *\n * @example\n * ```ts\n * ComponentTypes<typeof resourceConfig>\n * // ^? may resolve to:`'component' | 'errorComponent' | 'detail'`.\n * ```\n */\nexport type ComponentTypes<Created> = Created extends {\n config: infer Config extends object;\n}\n ? {\n [Resource in keyof Config]: ComponentTypesFromEntry<\n NonNullable<Config[Resource]>\n >;\n }[keyof Config]\n : never;\n\nexport type CreateResourceConfigFn<\n Resources extends ReadonlyArray<ResourceDefinition>,\n> = <const Config extends ResourceConfigMap<Resources>>(\n config: ResourceConfigInput<Resources, Config>,\n) => CreatedResourceConfig<Resources, Config>;\n\ntype SubResourceParam =\n | string\n | {\n value: string;\n subResource: SubResourceParam;\n };\n\nfunction isResourceConfigEntry(value: unknown): value is ResourceConfigEntry {\n return typeof value === 'object' && value !== null;\n}\n\nfunction resolveResourceConfigEntry(\n entry: ResourceConfigEntry,\n subResource: SubResourceParam,\n): ResourceConfigEntry {\n const key = typeof subResource === 'string' ? subResource : subResource.value;\n const next = entry[key];\n\n if (!isResourceConfigEntry(next)) {\n throw new InvalidSubResourceError({\n subResource: key,\n validSubResources: readSubResourceKeys(entry),\n });\n }\n\n if (typeof subResource === 'string') {\n return next;\n }\n\n return resolveResourceConfigEntry(next, subResource.subResource);\n}\n\nfunction readResourceConfigComponent(\n entry: ResourceConfigComponents,\n componentKey: ResourceConfigComponentKey,\n): JSX.Element {\n if (componentKey === 'new' || componentKey === 'detail') {\n const branch = entry[componentKey];\n\n if (!branch?.component) {\n throw new InvalidComponentError({\n component: `${componentKey}.component`,\n validComponents: readComponentKeys(entry),\n });\n }\n\n return branch.component;\n }\n\n const value = entry[componentKey];\n\n if (!value) {\n throw new InvalidComponentError({\n component: componentKey,\n validComponents: readComponentKeys(entry),\n });\n }\n\n return value;\n}\n\nfunction getComponentFromOptions<\n Resources extends ReadonlyArray<ResourceDefinition>,\n>(\n config: ResourceConfigMap<Resources>,\n options: GetComponentOptions<Resources>,\n): JSX.Element {\n const { resource, component: componentKey = 'component' } = options;\n const resourceEntry = config[resource];\n\n if (!resourceEntry) {\n throw new InvalidResourceError({\n resource,\n validResources: collectConfigResources(config as Record<string, unknown>),\n });\n }\n\n let entry = resourceEntry as ResourceConfigEntry;\n\n if ('subResource' in options && options.subResource !== undefined) {\n entry = resolveResourceConfigEntry(entry, options.subResource);\n }\n\n return readResourceConfigComponent(entry, componentKey);\n}\n\nfunction getComponentFromPath<\n Resources extends ReadonlyArray<ResourceDefinition>,\n>(config: ResourceConfigMap<Resources>, path: string): JSX.Element {\n let cursor: unknown = config;\n\n for (const segment of path.split('.')) {\n if (!isResourceConfigEntry(cursor)) {\n throw new InvalidPathError({\n path,\n reason: `\"${segment}\" cannot be read because the value before it is not a config branch`,\n });\n }\n\n const next: unknown = (cursor as Record<string, unknown>)[segment];\n\n if (next === undefined || next === null) {\n throw new InvalidPathError({\n path,\n reason: `\"${segment}\" is not configured`,\n });\n }\n\n cursor = next;\n }\n\n if (isResourceConfigEntry(cursor) && 'component' in cursor) {\n return readResourceConfigComponent(cursor, 'component');\n }\n\n return cursor as JSX.Element;\n}\n\nexport function createGetComponent<\n Resources extends ReadonlyArray<ResourceDefinition>,\n>(config: ResourceConfigMap<Resources>): GetComponent<Resources> {\n function getComponent(options: GetComponentOptions<Resources>): JSX.Element;\n function getComponent(path: ResourceConfigPath<Resources>): JSX.Element;\n function getComponent(\n options: GetComponentOptions<Resources> | ResourceConfigPath<Resources>,\n ): JSX.Element {\n if (typeof options === 'string') {\n return getComponentFromPath(config, options);\n }\n\n return getComponentFromOptions(config, options);\n }\n\n const forResource: GetComponentForResource<Resources> = (bound) => {\n return (options) =>\n getComponentFromOptions(config, {\n ...bound,\n ...options,\n } as unknown as GetComponentOptions<Resources>);\n };\n\n return Object.assign(getComponent, { forResource });\n}\n\nexport function createResourceConfig<\n Resources extends ReadonlyArray<ResourceDefinition>,\n const Config extends ResourceConfigMap<Resources>,\n>(\n config: ResourceConfigInput<Resources, Config>,\n): CreatedResourceConfig<Resources, Config> {\n const configRecord = config as Record<string, unknown>;\n\n if (collectConfigResources(configRecord).length === 0) {\n throw new InvalidConfigError({\n reason: 'A resource config must configure at least one resource',\n config,\n });\n }\n\n type Created = CreatedResourceConfig<Resources, Config>;\n\n return {\n config,\n getComponent: createGetComponent(config),\n createGetComponent: ((path: string) =>\n createGetComponentForPath(\n configRecord,\n path,\n )) as unknown as Created['createGetComponent'],\n forPaths: createForPaths(configRecord) as unknown as Created['forPaths'],\n isSubResourceKey: createIsSubResourceKey(\n configRecord,\n ) as unknown as Created['isSubResourceKey'],\n subResources: collectAllSubResourceKeys(\n configRecord,\n ) as unknown as Created['subResources'],\n };\n}\n"],"mappings":";;;;;;;;;;;;AAuWA,SAAS,sBAAsB,OAA8C;CAC3E,OAAO,OAAO,UAAU,YAAY,UAAU;AAChD;AAEA,SAAS,2BACP,OACA,aACqB;CACrB,MAAM,MAAM,OAAO,gBAAgB,WAAW,cAAc,YAAY;CACxE,MAAM,OAAO,MAAM;CAEnB,IAAI,CAAC,sBAAsB,IAAI,GAC7B,MAAM,IAAI,wBAAwB;EAChC,aAAa;EACb,mBAAmB,oBAAoB,KAAK;CAC9C,CAAC;CAGH,IAAI,OAAO,gBAAgB,UACzB,OAAO;CAGT,OAAO,2BAA2B,MAAM,YAAY,WAAW;AACjE;AAEA,SAAS,4BACP,OACA,cACa;CACb,IAAI,iBAAiB,SAAS,iBAAiB,UAAU;EACvD,MAAM,SAAS,MAAM;EAErB,IAAI,CAAC,QAAQ,WACX,MAAM,IAAI,sBAAsB;GAC9B,WAAW,GAAG,aAAa;GAC3B,iBAAiB,kBAAkB,KAAK;EAC1C,CAAC;EAGH,OAAO,OAAO;CAChB;CAEA,MAAM,QAAQ,MAAM;CAEpB,IAAI,CAAC,OACH,MAAM,IAAI,sBAAsB;EAC9B,WAAW;EACX,iBAAiB,kBAAkB,KAAK;CAC1C,CAAC;CAGH,OAAO;AACT;AAEA,SAAS,wBAGP,QACA,SACa;CACb,MAAM,EAAE,UAAU,WAAW,eAAe,gBAAgB;CAC5D,MAAM,gBAAgB,OAAO;CAE7B,IAAI,CAAC,eACH,MAAM,IAAI,qBAAqB;EAC7B;EACA,gBAAgB,uBAAuB,MAAiC;CAC1E,CAAC;CAGH,IAAI,QAAQ;CAEZ,IAAI,iBAAiB,WAAW,QAAQ,gBAAgB,QACtD,QAAQ,2BAA2B,OAAO,QAAQ,WAAW;CAG/D,OAAO,4BAA4B,OAAO,YAAY;AACxD;AAEA,SAAS,qBAEP,QAAsC,MAA2B;CACjE,IAAI,SAAkB;CAEtB,KAAK,MAAM,WAAW,KAAK,MAAM,GAAG,GAAG;EACrC,IAAI,CAAC,sBAAsB,MAAM,GAC/B,MAAM,IAAI,iBAAiB;GACzB;GACA,QAAQ,IAAI,QAAQ;EACtB,CAAC;EAGH,MAAM,OAAiB,OAAmC;EAE1D,IAAI,SAAS,UAAa,SAAS,MACjC,MAAM,IAAI,iBAAiB;GACzB;GACA,QAAQ,IAAI,QAAQ;EACtB,CAAC;EAGH,SAAS;CACX;CAEA,IAAI,sBAAsB,MAAM,KAAK,eAAe,QAClD,OAAO,4BAA4B,QAAQ,WAAW;CAGxD,OAAO;AACT;AAEA,SAAgB,mBAEd,QAA+D;CAG/D,SAAS,aACP,SACa;EACb,IAAI,OAAO,YAAY,UACrB,OAAO,qBAAqB,QAAQ,OAAO;EAG7C,OAAO,wBAAwB,QAAQ,OAAO;CAChD;CAEA,MAAM,eAAmD,UAAU;EACjE,QAAQ,YACN,wBAAwB,QAAQ;GAC9B,GAAG;GACH,GAAG;EACL,CAA8C;CAClD;CAEA,OAAO,OAAO,OAAO,cAAc,EAAE,YAAY,CAAC;AACpD;AAEA,SAAgB,qBAId,QAC0C;CAC1C,MAAM,eAAe;CAErB,IAAI,uBAAuB,YAAY,EAAE,WAAW,GAClD,MAAM,IAAI,mBAAmB;EAC3B,QAAQ;EACR;CACF,CAAC;CAKH,OAAO;EACL;EACA,cAAc,mBAAmB,MAAM;EACvC,sBAAsB,SACpB,0BACE,cACA,IACF;EACF,UAAU,eAAe,YAAY;EACrC,kBAAkB,uBAChB,YACF;EACA,cAAc,0BACZ,YACF;CACF;AACF"}
1
+ {"version":3,"file":"get-component.mjs","names":[],"sources":["../../src/create-config/get-component.ts"],"sourcesContent":["import type { JSX } from 'react';\nimport {\n InvalidComponentError,\n InvalidConfigError,\n InvalidPathError,\n InvalidResourceError,\n InvalidSubResourceError,\n} from '../errors';\nimport type {\n LayoutResourceKey,\n ResourceDefinition,\n ResourceDefinitionForKey,\n SubResourceDefinitionsFor,\n SubResourceParamForResource,\n} from '../resource';\nimport {\n createForPaths,\n createGetComponentForPath,\n type CreateGetComponentForPath,\n type ForPaths,\n} from './for-paths';\nimport {\n createIsSubResourceKey,\n type IsSubResourceKey,\n} from './is-sub-resource-key';\nimport {\n readComponentKeys,\n readSubResourceKeys,\n} from './component-keys';\nimport {\n collectAllSubResourceKeys,\n collectConfigResources,\n} from './paths';\nimport type {\n ConfigSubResourceKeys,\n ParameterizedResourcePath,\n} from './paths';\nimport type {\n BaseResourceConfigComponents,\n ResourceConfig,\n ResourceConfigComponentKey,\n ResourceConfigComponents,\n ResourceConfigEntry,\n ResourceConfigMap,\n ResourceConfigInput,\n SharedResourceConfigOptions,\n} from './types';\n\ntype ResourceHasLayoutSubResources<\n Resources extends ReadonlyArray<ResourceDefinition>,\n Resource extends LayoutResourceKey<Resources>,\n> = [SubResourceDefinitionsFor<Resources, Resource>] extends [readonly []]\n ? false\n : true;\n\ntype SubResourceOptionForGenerics<\n Resources extends ReadonlyArray<ResourceDefinition>,\n Resource extends LayoutResourceKey<Resources>,\n SubResource extends\n | SubResourceParamForResource<Resources, Resource>\n | undefined,\n> = [SubResource] extends [undefined]\n ? ResourceHasLayoutSubResources<Resources, Resource> extends true\n ? {\n subResource?: SubResourceParamForResource<Resources, Resource>;\n }\n : {}\n : ResourceHasLayoutSubResources<Resources, Resource> extends true\n ? { subResource?: SubResource }\n : {};\n\n/** Options for one layout resource passed to {@link GetComponent}. */\nexport type GetComponentOptionsForResource<\n Resources extends ReadonlyArray<ResourceDefinition>,\n Resource extends LayoutResourceKey<Resources>,\n SubResource extends\n | SubResourceParamForResource<Resources, Resource>\n | undefined = undefined,\n> = SubResourceOptionForGenerics<Resources, Resource, SubResource> & {\n resource: Resource;\n /**\n * The component to get.\n *\n * @default 'component'\n */\n component?: ResourceConfigComponentKey;\n};\n\n/** Union of valid `getComponent` option shapes for each declared layout resource. */\nexport type GetComponentOptions<\n Resources extends ReadonlyArray<ResourceDefinition>,\n> =\n LayoutResourceKey<Resources> extends infer Resource\n ? Resource extends LayoutResourceKey<Resources>\n ? GetComponentOptionsForResource<Resources, Resource>\n : never\n : never;\n\ntype ComponentSlotPathKey = keyof BaseResourceConfigComponents;\n\n/** `detail.errorComponent`, `new.component`, … — component slots inside a shared branch. */\ntype SharedBranchPath = {\n [Branch in keyof SharedResourceConfigOptions]: `${Branch}.${ComponentSlotPathKey}`;\n}[keyof SharedResourceConfigOptions];\n\ntype NestedSubResourceDefinitions<Def extends ResourceDefinition> = Def extends {\n subResources: infer Nested extends ReadonlyArray<ResourceDefinition>;\n}\n ? Nested\n : readonly [];\n\ntype SubResourceEntryPaths<\n SubDefs extends ReadonlyArray<ResourceDefinition>,\n DepthAcc extends readonly unknown[],\n> =\n LayoutResourceKey<SubDefs> extends infer Key extends string\n ? Key extends LayoutResourceKey<SubDefs>\n ?\n | Key\n | `${Key}.${ResourceConfigEntryPath<\n NestedSubResourceDefinitions<\n ResourceDefinitionForKey<SubDefs, Key>\n >,\n readonly [...DepthAcc, unknown]\n >}`\n : never\n : never;\n\n/** Dot-separated keys below one config node: component slots and nested sub-resources. */\ntype ResourceConfigEntryPath<\n SubDefs extends ReadonlyArray<ResourceDefinition>,\n DepthAcc extends readonly unknown[] = readonly [],\n> =\n | ComponentSlotPathKey\n | SharedBranchPath\n | ([SubDefs] extends [readonly []]\n ? never\n : DepthAcc['length'] extends 6\n ? never\n : SubResourceEntryPaths<SubDefs, DepthAcc>);\n\n/**\n * Deep config paths accepted by {@link GetComponent}, e.g.\n * `'templates.deleted.expired.errorComponent'`. Sub-resource segments come from the\n * layout tree, so only declared sub-resources are allowed at each depth.\n */\nexport type ResourceConfigPath<\n Resources extends ReadonlyArray<ResourceDefinition>,\n> =\n LayoutResourceKey<Resources> extends infer Resource extends string\n ? Resource extends LayoutResourceKey<Resources>\n ?\n | Resource\n | `${Resource}.${ResourceConfigEntryPath<\n SubResourceDefinitionsFor<Resources, Resource>\n >}`\n : never\n : never;\n\n/** `subResource` bound by {@link GetComponentForResource}. */\nexport type SubResourceFromGetComponentBound<Bound> = Bound extends {\n subResource: infer SubResource;\n}\n ? SubResource\n : undefined;\n\n/** Options for {@link GetComponentForResource} — binds `resource` and optional `subResource`. */\nexport type GetComponentForResourceOptions<\n Resources extends ReadonlyArray<ResourceDefinition>,\n Resource extends LayoutResourceKey<Resources>,\n SubResource extends\n | SubResourceParamForResource<Resources, Resource>\n | undefined = undefined,\n> = {\n resource: Resource;\n} & SubResourceOptionForGenerics<Resources, Resource, SubResource>;\n\n/** Valid bind shapes for {@link GetComponentForResource}. */\nexport type GetComponentForResourceBound<\n Resources extends ReadonlyArray<ResourceDefinition>,\n> =\n LayoutResourceKey<Resources> extends infer Resource\n ? Resource extends LayoutResourceKey<Resources>\n ? GetComponentForResourceOptions<Resources, Resource>\n : never\n : never;\n\ntype GetComponentForResourceOptionsForBound<\n Resources extends ReadonlyArray<ResourceDefinition>,\n Bound extends { resource: LayoutResourceKey<Resources> },\n> = GetComponentForResourceOptions<\n Resources,\n Bound['resource'],\n SubResourceFromGetComponentBound<Bound>\n>;\n\n/**\n * Rejects bind objects with keys (e.g. `subResource`) that are invalid for the\n * given `resource`. Union assignability alone is too permissive for excess keys.\n */\nexport type ValidateForResourceBound<\n Resources extends ReadonlyArray<ResourceDefinition>,\n Bound extends { resource: LayoutResourceKey<Resources> },\n> = Bound extends GetComponentForResourceOptionsForBound<Resources, Bound>\n ? keyof Bound extends keyof GetComponentForResourceOptionsForBound<\n Resources,\n Bound\n >\n ? Bound\n : never\n : never;\n\n/** `resource` inferred from a {@link GetComponentForResource} bind argument. */\nexport type ResourceFromGetComponentBound<\n Resources extends ReadonlyArray<ResourceDefinition>,\n Bound,\n> = Bound extends {\n resource: infer Resource extends LayoutResourceKey<Resources>;\n}\n ? Resource\n : never;\n\n/** Reusable getter returned by {@link GetComponentForResource} (only `component` remains). */\nexport type GetComponentAtBound<\n Resources extends ReadonlyArray<ResourceDefinition>,\n Resource extends LayoutResourceKey<Resources>,\n SubResource extends\n | SubResourceParamForResource<Resources, Resource>\n | undefined = undefined,\n> = (\n options?: Pick<\n GetComponentOptionsForResource<Resources, Resource, SubResource>,\n 'component'\n >,\n) => JSX.Element;\n\nexport type GetComponentForResource<\n Resources extends ReadonlyArray<ResourceDefinition>,\n> = <\n const Bound extends {\n resource: LayoutResourceKey<Resources>;\n },\n>(\n bound: ValidateForResourceBound<Resources, Bound>,\n) => GetComponentAtBound<\n Resources,\n ResourceFromGetComponentBound<Resources, Bound>,\n SubResourceFromGetComponentBound<Bound>\n>;\n\nexport interface GetComponent<\n Resources extends ReadonlyArray<ResourceDefinition>,\n> {\n /** Looks up a component by resource / optional sub-resource / optional component slot. */\n <const Options extends GetComponentOptions<Resources>>(\n options: Options,\n ): JSX.Element;\n /**\n * Looks up a component by a deep config path.\n * A path ending on a branch (e.g. `'templates.deleted.expired'`) returns that branch's\n * `component`; a path ending on a slot returns that slot.\n */\n <const Path extends ResourceConfigPath<Resources>>(path: Path): JSX.Element;\n forResource: GetComponentForResource<Resources>;\n}\n\nexport interface CreatedResourceConfig<\n Resources extends ReadonlyArray<ResourceDefinition>,\n Config extends ResourceConfigMap<Resources> = ResourceConfigMap<Resources>,\n> {\n config: Config;\n getComponent: GetComponent<Resources>;\n /**\n * Creates a reusable getter bound to one path. Variables the path leaves open become\n * the getter's arguments.\n *\n * @example\n * ```ts\n * const getDetail = createGetComponent('$resource.detail.$component');\n *\n * getDetail({ resource: 'templates', component: 'errorComponent' });\n * ```\n */\n createGetComponent: CreateGetComponentForPath<\n Resources,\n Config,\n ParameterizedResourcePath<Resources>\n >;\n /**\n * Builds a component for one or more paths. Declare which params the component takes,\n * then render it.\n *\n * @example\n * ```ts\n * const ResourceDetail = forPaths('$resource.detail.$component')\n * .addPathParams()\n * .render(({ params, getComponentForPath }) =>\n * getComponentForPath('$resource.detail.$component')(params),\n * );\n * ```\n */\n forPaths: ForPaths<\n Resources,\n Config,\n ParameterizedResourcePath<Resources>\n >;\n /** Narrows an unknown value to a sub-resource key configured for a path or resource. */\n isSubResourceKey: IsSubResourceKey<\n Resources,\n Config,\n ParameterizedResourcePath<Resources>\n >;\n /** Every sub-resource key configured in this config, at any depth. */\n subResources: ReadonlyArray<ConfigSubResourceKeys<Resources, Config>>;\n}\n\ntype ComponentTypesFromEntry<Entry> = Entry extends JSX.Element\n ? never\n : Entry extends object\n ?\n | Extract<keyof Entry, ResourceConfigComponentKey>\n | {\n [Key in keyof Entry]: NonNullable<Entry[Key]> extends JSX.Element\n ? never\n : ComponentTypesFromEntry<NonNullable<Entry[Key]>>;\n }[keyof Entry]\n : never;\n\n/**\n * Component selector keys actually defined anywhere in a created resource config.\n *\n * @example\n * ```ts\n * ComponentTypes<typeof resourceConfig>\n * // ^? may resolve to:`'component' | 'errorComponent' | 'detail'`.\n * ```\n */\nexport type ComponentTypes<Created> = Created extends {\n config: infer Config extends object;\n}\n ? {\n [Resource in keyof Config]: ComponentTypesFromEntry<\n NonNullable<Config[Resource]>\n >;\n }[keyof Config]\n : never;\n\n/**\n * One resource entry keyed for direct spreading into a resource config.\n * Preserves the precise component slots and sub-resource branches in `Config`.\n */\nexport type ResourceConfigFragment<\n Resource extends string,\n Config,\n> = { [Key in Resource]: Config };\n\n/**\n * Creates one keyed config fragment for spreading into a resource config.\n *\n * @param resource - A top-level resource supported by the layout definition.\n * @param config - Components and declared sub-resource branches for that resource.\n */\nexport type CreateResourceConfigForResource<\n Resources extends ReadonlyArray<ResourceDefinition>,\n> = <\n const Resource extends LayoutResourceKey<Resources>,\n const Config extends ResourceConfig<Resources>[Resource],\n>(\n resource: Resource,\n config: Config,\n) => ResourceConfigFragment<Resource, Config>;\n\n/** Creates a validated resource config and exposes helpers for config fragments. */\nexport type CreateResourceConfigFn<\n Resources extends ReadonlyArray<ResourceDefinition>,\n> = {\n /**\n * Validates and indexes a complete configuration assembled from one or more\n * resource entries.\n *\n * @param config - At least one resource entry supported by the layout.\n */\n <const Config extends ResourceConfigMap<Resources>>(\n config: ResourceConfigInput<Resources, Config>,\n ): CreatedResourceConfig<Resources, Config>;\n /** Creates a typed fragment that can be spread into the complete config. */\n forResource: CreateResourceConfigForResource<Resources>;\n};\n\ntype SubResourceParam =\n | string\n | {\n value: string;\n subResource: SubResourceParam;\n };\n\nfunction isResourceConfigEntry(value: unknown): value is ResourceConfigEntry {\n return typeof value === 'object' && value !== null;\n}\n\nfunction resolveResourceConfigEntry(\n entry: ResourceConfigEntry,\n subResource: SubResourceParam,\n): ResourceConfigEntry {\n const key = typeof subResource === 'string' ? subResource : subResource.value;\n const next = entry[key];\n\n if (!isResourceConfigEntry(next)) {\n throw new InvalidSubResourceError({\n subResource: key,\n validSubResources: readSubResourceKeys(entry),\n });\n }\n\n if (typeof subResource === 'string') {\n return next;\n }\n\n return resolveResourceConfigEntry(next, subResource.subResource);\n}\n\nfunction readResourceConfigComponent(\n entry: ResourceConfigComponents,\n componentKey: ResourceConfigComponentKey,\n): JSX.Element {\n if (componentKey === 'new' || componentKey === 'detail') {\n const branch = entry[componentKey];\n\n if (!branch?.component) {\n throw new InvalidComponentError({\n component: `${componentKey}.component`,\n validComponents: readComponentKeys(entry),\n });\n }\n\n return branch.component;\n }\n\n const value = entry[componentKey];\n\n if (!value) {\n throw new InvalidComponentError({\n component: componentKey,\n validComponents: readComponentKeys(entry),\n });\n }\n\n return value;\n}\n\nfunction getComponentFromOptions<\n Resources extends ReadonlyArray<ResourceDefinition>,\n>(\n config: ResourceConfigMap<Resources>,\n options: GetComponentOptions<Resources>,\n): JSX.Element {\n const { resource, component: componentKey = 'component' } = options;\n const resourceEntry = config[resource];\n\n if (!resourceEntry) {\n throw new InvalidResourceError({\n resource,\n validResources: collectConfigResources(config as Record<string, unknown>),\n });\n }\n\n let entry = resourceEntry as ResourceConfigEntry;\n\n if ('subResource' in options && options.subResource !== undefined) {\n entry = resolveResourceConfigEntry(entry, options.subResource);\n }\n\n return readResourceConfigComponent(entry, componentKey);\n}\n\nfunction getComponentFromPath<\n Resources extends ReadonlyArray<ResourceDefinition>,\n>(config: ResourceConfigMap<Resources>, path: string): JSX.Element {\n let cursor: unknown = config;\n\n for (const segment of path.split('.')) {\n if (!isResourceConfigEntry(cursor)) {\n throw new InvalidPathError({\n path,\n reason: `\"${segment}\" cannot be read because the value before it is not a config branch`,\n });\n }\n\n const next: unknown = (cursor as Record<string, unknown>)[segment];\n\n if (next === undefined || next === null) {\n throw new InvalidPathError({\n path,\n reason: `\"${segment}\" is not configured`,\n });\n }\n\n cursor = next;\n }\n\n if (isResourceConfigEntry(cursor) && 'component' in cursor) {\n return readResourceConfigComponent(cursor, 'component');\n }\n\n return cursor as JSX.Element;\n}\n\nexport function createGetComponent<\n Resources extends ReadonlyArray<ResourceDefinition>,\n>(config: ResourceConfigMap<Resources>): GetComponent<Resources> {\n function getComponent(options: GetComponentOptions<Resources>): JSX.Element;\n function getComponent(path: ResourceConfigPath<Resources>): JSX.Element;\n function getComponent(\n options: GetComponentOptions<Resources> | ResourceConfigPath<Resources>,\n ): JSX.Element {\n if (typeof options === 'string') {\n return getComponentFromPath(config, options);\n }\n\n return getComponentFromOptions(config, options);\n }\n\n const forResource: GetComponentForResource<Resources> = (bound) => {\n return (options) =>\n getComponentFromOptions(config, {\n ...bound,\n ...options,\n } as unknown as GetComponentOptions<Resources>);\n };\n\n return Object.assign(getComponent, { forResource });\n}\n\nfunction createResourceConfigImpl<\n Resources extends ReadonlyArray<ResourceDefinition>,\n const Config extends ResourceConfigMap<Resources>,\n>(\n config: ResourceConfigInput<Resources, Config>,\n): CreatedResourceConfig<Resources, Config> {\n const configRecord = config as Record<string, unknown>;\n\n if (collectConfigResources(configRecord).length === 0) {\n throw new InvalidConfigError({\n reason: 'A resource config must configure at least one resource',\n config,\n });\n }\n\n type Created = CreatedResourceConfig<Resources, Config>;\n\n return {\n config,\n getComponent: createGetComponent(config),\n createGetComponent: ((path: string) =>\n createGetComponentForPath(\n configRecord,\n path,\n )) as unknown as Created['createGetComponent'],\n forPaths: createForPaths(configRecord) as unknown as Created['forPaths'],\n isSubResourceKey: createIsSubResourceKey(\n configRecord,\n ) as unknown as Created['isSubResourceKey'],\n subResources: collectAllSubResourceKeys(\n configRecord,\n ) as unknown as Created['subResources'],\n };\n}\n\nfunction createResourceConfigForResource<\n Resources extends ReadonlyArray<ResourceDefinition>,\n const Resource extends LayoutResourceKey<Resources>,\n const Config extends ResourceConfig<Resources>[Resource],\n>(\n resource: Resource,\n config: Config,\n): ResourceConfigFragment<Resource, Config> {\n return { [resource]: config } as ResourceConfigFragment<Resource, Config>;\n}\n\n/**\n * Creates a validated resource configuration. Use `.forResource()` to build\n * independently declared, type-safe fragments that can be spread into the\n * complete configuration object.\n *\n * @param config - Resource entries to validate and expose through lookup helpers.\n * @returns The original config plus typed component and path lookup helpers.\n *\n * @example\n * ```tsx\n * const users = createResourceConfig.forResource('users', {\n * component: <Users />,\n * });\n *\n * const config = createResourceConfig({ ...users });\n * ```\n */\nexport const createResourceConfig = Object.assign(createResourceConfigImpl, {\n forResource: createResourceConfigForResource,\n});\n"],"mappings":";;;;;;;;;;;;AA4YA,SAAS,sBAAsB,OAA8C;CAC3E,OAAO,OAAO,UAAU,YAAY,UAAU;AAChD;AAEA,SAAS,2BACP,OACA,aACqB;CACrB,MAAM,MAAM,OAAO,gBAAgB,WAAW,cAAc,YAAY;CACxE,MAAM,OAAO,MAAM;CAEnB,IAAI,CAAC,sBAAsB,IAAI,GAC7B,MAAM,IAAI,wBAAwB;EAChC,aAAa;EACb,mBAAmB,oBAAoB,KAAK;CAC9C,CAAC;CAGH,IAAI,OAAO,gBAAgB,UACzB,OAAO;CAGT,OAAO,2BAA2B,MAAM,YAAY,WAAW;AACjE;AAEA,SAAS,4BACP,OACA,cACa;CACb,IAAI,iBAAiB,SAAS,iBAAiB,UAAU;EACvD,MAAM,SAAS,MAAM;EAErB,IAAI,CAAC,QAAQ,WACX,MAAM,IAAI,sBAAsB;GAC9B,WAAW,GAAG,aAAa;GAC3B,iBAAiB,kBAAkB,KAAK;EAC1C,CAAC;EAGH,OAAO,OAAO;CAChB;CAEA,MAAM,QAAQ,MAAM;CAEpB,IAAI,CAAC,OACH,MAAM,IAAI,sBAAsB;EAC9B,WAAW;EACX,iBAAiB,kBAAkB,KAAK;CAC1C,CAAC;CAGH,OAAO;AACT;AAEA,SAAS,wBAGP,QACA,SACa;CACb,MAAM,EAAE,UAAU,WAAW,eAAe,gBAAgB;CAC5D,MAAM,gBAAgB,OAAO;CAE7B,IAAI,CAAC,eACH,MAAM,IAAI,qBAAqB;EAC7B;EACA,gBAAgB,uBAAuB,MAAiC;CAC1E,CAAC;CAGH,IAAI,QAAQ;CAEZ,IAAI,iBAAiB,WAAW,QAAQ,gBAAgB,QACtD,QAAQ,2BAA2B,OAAO,QAAQ,WAAW;CAG/D,OAAO,4BAA4B,OAAO,YAAY;AACxD;AAEA,SAAS,qBAEP,QAAsC,MAA2B;CACjE,IAAI,SAAkB;CAEtB,KAAK,MAAM,WAAW,KAAK,MAAM,GAAG,GAAG;EACrC,IAAI,CAAC,sBAAsB,MAAM,GAC/B,MAAM,IAAI,iBAAiB;GACzB;GACA,QAAQ,IAAI,QAAQ;EACtB,CAAC;EAGH,MAAM,OAAiB,OAAmC;EAE1D,IAAI,SAAS,UAAa,SAAS,MACjC,MAAM,IAAI,iBAAiB;GACzB;GACA,QAAQ,IAAI,QAAQ;EACtB,CAAC;EAGH,SAAS;CACX;CAEA,IAAI,sBAAsB,MAAM,KAAK,eAAe,QAClD,OAAO,4BAA4B,QAAQ,WAAW;CAGxD,OAAO;AACT;AAEA,SAAgB,mBAEd,QAA+D;CAG/D,SAAS,aACP,SACa;EACb,IAAI,OAAO,YAAY,UACrB,OAAO,qBAAqB,QAAQ,OAAO;EAG7C,OAAO,wBAAwB,QAAQ,OAAO;CAChD;CAEA,MAAM,eAAmD,UAAU;EACjE,QAAQ,YACN,wBAAwB,QAAQ;GAC9B,GAAG;GACH,GAAG;EACL,CAA8C;CAClD;CAEA,OAAO,OAAO,OAAO,cAAc,EAAE,YAAY,CAAC;AACpD;AAEA,SAAS,yBAIP,QAC0C;CAC1C,MAAM,eAAe;CAErB,IAAI,uBAAuB,YAAY,EAAE,WAAW,GAClD,MAAM,IAAI,mBAAmB;EAC3B,QAAQ;EACR;CACF,CAAC;CAKH,OAAO;EACL;EACA,cAAc,mBAAmB,MAAM;EACvC,sBAAsB,SACpB,0BACE,cACA,IACF;EACF,UAAU,eAAe,YAAY;EACrC,kBAAkB,uBAChB,YACF;EACA,cAAc,0BACZ,YACF;CACF;AACF;AAEA,SAAS,gCAKP,UACA,QAC0C;CAC1C,OAAO,GAAG,WAAW,OAAO;AAC9B;;;;;;;;;;;;;;;;;;AAmBA,MAAa,uBAAuB,OAAO,OAAO,0BAA0B,EAC1E,aAAa,gCACf,CAAC"}
@@ -5,9 +5,9 @@ import { ConfigResourceKeys, ConfigSubResourceKeys, ParameterizedEntryPath, Para
5
5
  import { CreateGetComponentForPath, GetComponentForPath, GetComponentForPathApi, PathValueComponentGetter, PathVariableGuards, ResolvedPathValue } from "./for-paths/get-component-for-path.cjs";
6
6
  import { ForPaths, ForPathsRenderContext, RenderedPathComponent, RenderedPathComponentHOF, TargetPathBuilder } from "./for-paths/builder.cjs";
7
7
  import { IsSubResourceKey, IsSubResourceKeyOptions, IsSubResourceKeyResult } from "./is-sub-resource-key.cjs";
8
- import { ComponentTypes, CreateResourceConfigFn, CreatedResourceConfig, GetComponent, GetComponentAtBound, GetComponentForResource, GetComponentForResourceOptions, GetComponentOptions, GetComponentOptionsForResource, ResourceConfigPath, ResourceFromGetComponentBound, SubResourceFromGetComponentBound, ValidateForResourceBound } from "./get-component.cjs";
8
+ import { ComponentTypes, CreateResourceConfigFn, CreateResourceConfigForResource, CreatedResourceConfig, GetComponent, GetComponentAtBound, GetComponentForResource, GetComponentForResourceOptions, GetComponentOptions, GetComponentOptionsForResource, ResourceConfigFragment, ResourceConfigPath, ResourceFromGetComponentBound, SubResourceFromGetComponentBound, ValidateForResourceBound } from "./get-component.cjs";
9
9
  import { CreateResourceLinkConfig, CreateResourceLinkGroupInput, CreateResourceLinkGroupOptions, CreateResourceLinkOptions, CreateResourceLinksFn, CreateResourceLinksWithGroups, CreateResourceLinksWithGroupsFn, CreateResourceLinksWithGroupsResult, CreateResourceMap, CreateResourceMapFn, CreatedResourceHref, CreatedResourceLink, CreatedResourceLinkBase, CreatedResourceMap, DefineResourceIconFn, DefineResourceIconInputHelpers, DefineResourceIconInputResult, FindResolvedResourceGroupResult, FindResourceGroupResult, InferHashFromResourceLinkHref, ResolveResourceIconInput, ResolvedResourceLinksWithGroups, ResolvedResourceLinksWithGroupsResult, ResourceAnchorLinkFn, ResourceIcon, ResourceIconFn, ResourceLinkHref, ValidateResource } from "./create-resource-links.cjs";
10
10
  import { ContextualInlineRenderState, ContextualInlineRenderStates, CreateResourceLayoutFn, CreateResourceLayoutMakeComposableOptions, CreateResourceLayoutWithLayoutOptions, CreateViewMapBuiltInRenderStatesOptions, CreateViewMapFunctionRenderOptions, CreateViewMapInlineRenderStatesOptions, CreateViewMapOptions, CreateViewMapRenderStatesOptions, DefineResourceLayout, DefineResourceLayoutFn, DefineResourceLayoutForResources, DefineResourceLayoutForResourcesFactory, DefineResourceLayoutWithLayoutFn, DefineResourcesFn, DefinedResourceLayout, DefinedResourceLayoutWithShell, LayoutDefinition, LayoutIncludeProps, LayoutRenderResourcesAccessor, LayoutResourcesAccessor, ResourceLayoutProvider, ResourceLayoutProviderProps, ResourceLayoutShellComponent, ResourceLayoutShellProps, ResourceSelection, ShellLayoutDefinition, ShellRenderContext, TypedBuiltInRenderStates, TypedInlineRenderState, defineResourceLayout } from "./define-layout.cjs";
11
11
  import { LazyResourceErrorComponent, LazyResourceLayoutComponent, LazyResourceLayoutOptions, LazyResourceLoadingComponent, LazyResourceStates } from "./lazy-resource-layout.cjs";
12
- import { BoundDefineResourceLayout, CreateDefinedResourceLayoutResult, DefineLazyDefaults, DefineOptions, DefinedResourceLayoutBuilder, DefinedResourceLayoutInput, NonEmptyResources, createDefinedResourceLayout } from "./create-defined-resource-layout.cjs";
12
+ import { BoundDefineResourceLayout, CreateDefinedResourceLayoutOptions, CreateDefinedResourceLayoutResult, DefineLazyDefaults, DefinedResourceLayoutInput, NonEmptyResources, createDefinedResourceLayout } from "./create-defined-resource-layout.cjs";
13
13
  import { ResourceLayoutShellPublisher } from "./shell-context.cjs";
@@ -5,9 +5,9 @@ import { ConfigResourceKeys, ConfigSubResourceKeys, ParameterizedEntryPath, Para
5
5
  import { CreateGetComponentForPath, GetComponentForPath, GetComponentForPathApi, PathValueComponentGetter, PathVariableGuards, ResolvedPathValue } from "./for-paths/get-component-for-path.mjs";
6
6
  import { ForPaths, ForPathsRenderContext, RenderedPathComponent, RenderedPathComponentHOF, TargetPathBuilder } from "./for-paths/builder.mjs";
7
7
  import { IsSubResourceKey, IsSubResourceKeyOptions, IsSubResourceKeyResult } from "./is-sub-resource-key.mjs";
8
- import { ComponentTypes, CreateResourceConfigFn, CreatedResourceConfig, GetComponent, GetComponentAtBound, GetComponentForResource, GetComponentForResourceOptions, GetComponentOptions, GetComponentOptionsForResource, ResourceConfigPath, ResourceFromGetComponentBound, SubResourceFromGetComponentBound, ValidateForResourceBound } from "./get-component.mjs";
8
+ import { ComponentTypes, CreateResourceConfigFn, CreateResourceConfigForResource, CreatedResourceConfig, GetComponent, GetComponentAtBound, GetComponentForResource, GetComponentForResourceOptions, GetComponentOptions, GetComponentOptionsForResource, ResourceConfigFragment, ResourceConfigPath, ResourceFromGetComponentBound, SubResourceFromGetComponentBound, ValidateForResourceBound } from "./get-component.mjs";
9
9
  import { CreateResourceLinkConfig, CreateResourceLinkGroupInput, CreateResourceLinkGroupOptions, CreateResourceLinkOptions, CreateResourceLinksFn, CreateResourceLinksWithGroups, CreateResourceLinksWithGroupsFn, CreateResourceLinksWithGroupsResult, CreateResourceMap, CreateResourceMapFn, CreatedResourceHref, CreatedResourceLink, CreatedResourceLinkBase, CreatedResourceMap, DefineResourceIconFn, DefineResourceIconInputHelpers, DefineResourceIconInputResult, FindResolvedResourceGroupResult, FindResourceGroupResult, InferHashFromResourceLinkHref, ResolveResourceIconInput, ResolvedResourceLinksWithGroups, ResolvedResourceLinksWithGroupsResult, ResourceAnchorLinkFn, ResourceIcon, ResourceIconFn, ResourceLinkHref, ValidateResource } from "./create-resource-links.mjs";
10
10
  import { ContextualInlineRenderState, ContextualInlineRenderStates, CreateResourceLayoutFn, CreateResourceLayoutMakeComposableOptions, CreateResourceLayoutWithLayoutOptions, CreateViewMapBuiltInRenderStatesOptions, CreateViewMapFunctionRenderOptions, CreateViewMapInlineRenderStatesOptions, CreateViewMapOptions, CreateViewMapRenderStatesOptions, DefineResourceLayout, DefineResourceLayoutFn, DefineResourceLayoutForResources, DefineResourceLayoutForResourcesFactory, DefineResourceLayoutWithLayoutFn, DefineResourcesFn, DefinedResourceLayout, DefinedResourceLayoutWithShell, LayoutDefinition, LayoutIncludeProps, LayoutRenderResourcesAccessor, LayoutResourcesAccessor, ResourceLayoutProvider, ResourceLayoutProviderProps, ResourceLayoutShellComponent, ResourceLayoutShellProps, ResourceSelection, ShellLayoutDefinition, ShellRenderContext, TypedBuiltInRenderStates, TypedInlineRenderState, defineResourceLayout } from "./define-layout.mjs";
11
11
  import { LazyResourceErrorComponent, LazyResourceLayoutComponent, LazyResourceLayoutOptions, LazyResourceLoadingComponent, LazyResourceStates } from "./lazy-resource-layout.mjs";
12
- import { BoundDefineResourceLayout, CreateDefinedResourceLayoutResult, DefineLazyDefaults, DefineOptions, DefinedResourceLayoutBuilder, DefinedResourceLayoutInput, NonEmptyResources, createDefinedResourceLayout } from "./create-defined-resource-layout.mjs";
12
+ import { BoundDefineResourceLayout, CreateDefinedResourceLayoutOptions, CreateDefinedResourceLayoutResult, DefineLazyDefaults, DefinedResourceLayoutInput, NonEmptyResources, createDefinedResourceLayout } from "./create-defined-resource-layout.mjs";
13
13
  import { ResourceLayoutShellPublisher } from "./shell-context.mjs";
@@ -50,22 +50,9 @@ function findDefinedRenderState(module) {
50
50
  if (definitions.length !== 1) throw new Error(`A lazy render-state module must export exactly one defined render state; received ${definitions.length}.`);
51
51
  return definitions[0][definedRenderStateSymbol];
52
52
  }
53
- /**
54
- * Creates the reusable `composables` and `createRenderState` helpers without
55
- * introducing an identity wrapper around the layout object itself.
56
- */
57
- function createLayoutBuildingBlocks(arguments_) {
58
- function composables(definition) {
59
- return definition;
60
- }
61
- return {
62
- composables,
63
- createRenderState: createRenderStateBuilder(arguments_)
64
- };
65
- }
66
53
 
67
54
  //#endregion
68
- exports.createLayoutBuildingBlocks = createLayoutBuildingBlocks;
55
+ exports.createRenderStateBuilder = createRenderStateBuilder;
69
56
  exports.deferredRenderStateSymbol = deferredRenderStateSymbol;
70
57
  exports.definedResourceLayoutComponentSymbol = definedResourceLayoutComponentSymbol;
71
58
  exports.findDefinedRenderState = findDefinedRenderState;
@@ -1 +1 @@
1
- {"version":3,"file":"render-state.cjs","names":[],"sources":["../../src/create-config/render-state.ts"],"sourcesContent":["import type { JSX } from 'react';\nimport type {\n ComposableComponents,\n CreateLayoutComposable,\n} from '@jfdevelops/react-layout-composables';\nimport type { InPropsObject } from '../props';\nimport type {\n IncludedProps,\n InPropsDefinition,\n LayoutRenderProps,\n MergedLayoutInProps,\n} from '../props';\nimport type { LayoutResourceKey, ResourceDefinition } from '../resource';\n\nexport const deferredRenderStateSymbol: unique symbol = Symbol(\n 'deferredRenderState',\n) as never;\nexport const lazyRenderStateSymbol: unique symbol = Symbol(\n 'lazyRenderState',\n) as never;\nexport const definedRenderStateSymbol: unique symbol = Symbol.for(\n '@jfdevelops/react-layout/render-state',\n) as never;\nexport const definedResourceLayoutComponentSymbol: unique symbol = Symbol.for(\n '@jfdevelops/react-layout/resource-layout-component',\n) as never;\n\n/** Runtime-compatible render-state shape used when inspecting lazy modules. */\nexport type AnyRenderStateDefinition = {\n composables?: (create: CreateLayoutComposable<any>) => ComposableComponents;\n props?: {\n include?: Record<string, unknown>;\n custom?: InPropsObject;\n };\n render: (props: any, context: any) => JSX.Element;\n state?: string;\n};\n\n/** An inline state whose first render is scheduled through `React.lazy`. */\nexport type DeferredRenderState<Definition extends AnyRenderStateDefinition> = {\n readonly [deferredRenderStateSymbol]: Definition;\n};\n\n/** A state definition supplied by a separately imported module. */\nexport type LazyRenderState<Definition extends AnyRenderStateDefinition> = {\n readonly [lazyRenderStateSymbol]: () => Promise<Record<string, unknown>>;\n readonly definition?: Definition;\n};\n\n/** Callback shorthand for a render state with no local configuration. */\nexport type RenderStateCallback = (props: any, context: any) => JSX.Element;\n\n/**\n * Defines state-local composable components with a `create` helper narrowed to\n * the resources bound to the surrounding builder.\n */\nexport type RenderStateComposablesDefinition<\n Resources extends ReadonlyArray<ResourceDefinition>,\n Composables extends ComposableComponents,\n> = (\n create: CreateLayoutComposable<LayoutResourceKey<Resources>>,\n) => Composables;\n\n/**\n * Defines reusable layout-level composables while preserving their inferred\n * names, props, and bound resource union.\n */\nexport type LayoutComposablesDefinition<\n Resources extends ReadonlyArray<ResourceDefinition>,\n Composables extends ComposableComponents,\n> = RenderStateComposablesDefinition<Resources, Composables>;\n\ntype BuilderRenderComposables<Composables extends ComposableComponents> = [\n keyof Composables,\n] extends [never]\n ? undefined\n : Composables;\n\n/** Values available as the second argument of a created state's `render`. */\nexport type RenderStateContext<\n Composables extends ComposableComponents,\n> = {\n composables: BuilderRenderComposables<Composables>;\n retry?: () => void;\n};\n\n/**\n * Resolves one state's custom props and explicitly included option/composable\n * props to the values received by its render callback.\n */\nexport type RenderStateProps<\n Resources extends ReadonlyArray<ResourceDefinition>,\n Options extends InPropsDefinition<Resources>,\n Composables extends ComposableComponents,\n IncludeProps extends IncludedProps<\n MergedLayoutInProps<Resources, Options, Composables>\n >,\n CustomProps extends InPropsObject,\n> = LayoutRenderProps<\n Resources,\n Options,\n Composables,\n IncludeProps,\n CustomProps\n>;\n\ntype TypedRenderStateDefinition<\n Resources extends ReadonlyArray<ResourceDefinition>,\n Options extends InPropsDefinition<Resources>,\n State extends string,\n CustomProps extends InPropsObject,\n Composables extends ComposableComponents,\n IncludeProps extends IncludedProps<\n MergedLayoutInProps<Resources, Options, Composables>\n >,\n> = {\n composables?: RenderStateComposablesDefinition<Resources, Composables>;\n props?: {\n include?: IncludeProps;\n custom?: CustomProps;\n };\n render: (\n props: RenderStateProps<\n Resources,\n Options,\n Composables,\n IncludeProps,\n CustomProps\n >,\n context: RenderStateContext<Composables>,\n ) => JSX.Element;\n state: State;\n};\n\ntype NormalizeRenderStateDefinition<Input> =\n Input extends DeferredRenderState<infer Definition>\n ? Definition\n : Input extends RenderStateCallback\n ? { render: Input; state: 'default' }\n : Input extends AnyRenderStateDefinition\n ? Input\n : never;\n\ntype StateName<Definition> = Definition extends DeferredRenderState<\n infer DeferredDefinition\n>\n ? StateName<DeferredDefinition>\n : Definition extends { state?: infer State extends string }\n ? State\n : 'default';\n\n/**\n * A spreadable state entry keyed by its literal state name. Spreading this into\n * `layout.render` is what creates compound members such as `Users.Loading`.\n */\nexport type RenderStateFragment<Definition> = {\n [State in StateName<NormalizeRenderStateDefinition<Definition>>]: Definition;\n} & {\n readonly [definedRenderStateSymbol]: NormalizeRenderStateDefinition<Definition>;\n};\n\ntype DefinedRenderStateFromModule<Module> = Extract<\n Module[keyof Module],\n { readonly [definedRenderStateSymbol]: AnyRenderStateDefinition }\n>[typeof definedRenderStateSymbol];\n\n/**\n * Creates independently typed render-state fragments.\n *\n * - Calling it directly creates an eager state.\n * - `.defer(...)` schedules an inline definition through `React.lazy`, but\n * does not create a separate JavaScript chunk.\n * - `.lazy(() => import(...))` imports a complete named state definition as a\n * separate chunk.\n */\nexport type CreateRenderState<\n Resources extends ReadonlyArray<ResourceDefinition> = ReadonlyArray<ResourceDefinition>,\n Options extends InPropsDefinition<Resources> = {},\n> = {\n <\n const State extends string = 'default',\n const CustomProps extends InPropsObject = {},\n const Composables extends ComposableComponents = {},\n const IncludeProps extends IncludedProps<\n MergedLayoutInProps<Resources, Options, Composables>\n > = {},\n >(\n definition: TypedRenderStateDefinition<\n Resources,\n Options,\n State,\n CustomProps,\n Composables,\n IncludeProps\n >,\n ): RenderStateFragment<\n TypedRenderStateDefinition<\n Resources,\n Options,\n State,\n CustomProps,\n Composables,\n IncludeProps\n >\n >;\n <\n const CustomProps extends InPropsObject = {},\n const Composables extends ComposableComponents = {},\n const IncludeProps extends IncludedProps<\n MergedLayoutInProps<Resources, Options, Composables>\n > = {},\n >(\n definition: Omit<\n TypedRenderStateDefinition<\n Resources,\n Options,\n 'default',\n CustomProps,\n Composables,\n IncludeProps\n >,\n 'state'\n >,\n ): RenderStateFragment<\n TypedRenderStateDefinition<\n Resources,\n Options,\n 'default',\n CustomProps,\n Composables,\n IncludeProps\n >\n >;\n <const Render extends RenderStateCallback>(\n render: Render,\n ): RenderStateFragment<Render>;\n defer<\n const State extends string = 'default',\n const CustomProps extends InPropsObject = {},\n const Composables extends ComposableComponents = {},\n const IncludeProps extends IncludedProps<\n MergedLayoutInProps<Resources, Options, Composables>\n > = {},\n >(\n definition: TypedRenderStateDefinition<\n Resources,\n Options,\n State,\n CustomProps,\n Composables,\n IncludeProps\n >,\n ): RenderStateFragment<\n DeferredRenderState<\n TypedRenderStateDefinition<\n Resources,\n Options,\n State,\n CustomProps,\n Composables,\n IncludeProps\n >\n >\n >;\n defer<\n const CustomProps extends InPropsObject = {},\n const Composables extends ComposableComponents = {},\n const IncludeProps extends IncludedProps<\n MergedLayoutInProps<Resources, Options, Composables>\n > = {},\n >(\n definition: Omit<\n TypedRenderStateDefinition<\n Resources,\n Options,\n 'default',\n CustomProps,\n Composables,\n IncludeProps\n >,\n 'state'\n >,\n ): RenderStateFragment<\n DeferredRenderState<\n TypedRenderStateDefinition<\n Resources,\n Options,\n 'default',\n CustomProps,\n Composables,\n IncludeProps\n >\n >\n >;\n defer<const Render extends RenderStateCallback>(\n render: Render,\n ): RenderStateFragment<DeferredRenderState<{ render: Render; state: 'default' }>>;\n lazy<Module extends Record<string, unknown>>(\n load: () => Promise<Module>,\n ): LazyRenderState<DefinedRenderStateFromModule<Module>>;\n};\n\nfunction normalizeDefinition(\n input: AnyRenderStateDefinition | RenderStateCallback,\n): AnyRenderStateDefinition {\n return typeof input === 'function'\n ? { render: input, state: 'default' }\n : input;\n}\n\nfunction toFragment<Definition extends AnyRenderStateDefinition>(\n definition: Definition,\n) {\n const fragment = {\n [definition.state ?? 'default']: definition,\n } as RenderStateFragment<Definition>;\n\n Object.defineProperty(fragment, definedRenderStateSymbol, {\n enumerable: false,\n value: definition,\n });\n\n return fragment;\n}\n\n/** Inputs used internally to bind resource and option types to a state builder. */\nexport type CreateRenderStateBuilderArguments<\n Resources extends ReadonlyArray<ResourceDefinition>,\n Options extends InPropsDefinition<Resources>,\n> = {\n options: Options;\n resources: Resources;\n};\n\n/** The state factory produced for a particular resource and option definition. */\nexport type CreateRenderStateBuilderResult<\n Resources extends ReadonlyArray<ResourceDefinition>,\n Options extends InPropsDefinition<Resources>,\n> = CreateRenderState<Resources, Options>;\n\n/**\n * Creates a state factory whose `props.include` keys are constrained by the\n * supplied resources and options.\n */\nexport function createRenderStateBuilder<\n Resources extends ReadonlyArray<ResourceDefinition>,\n Options extends InPropsDefinition<Resources>,\n>(\n _arguments: CreateRenderStateBuilderArguments<Resources, Options>,\n): CreateRenderStateBuilderResult<Resources, Options> {\n function createRenderState(\n input: AnyRenderStateDefinition | RenderStateCallback,\n ) {\n return toFragment(normalizeDefinition(input));\n }\n\n createRenderState.defer = (\n input: AnyRenderStateDefinition | RenderStateCallback,\n ) => {\n const definition = normalizeDefinition(input);\n\n return {\n [definition.state ?? 'default']: {\n [deferredRenderStateSymbol]: definition,\n },\n };\n };\n createRenderState.lazy = (\n load: () => Promise<Record<string, unknown>>,\n ) => ({\n [lazyRenderStateSymbol]: load,\n });\n\n return createRenderState as CreateRenderStateBuilderResult<Resources, Options>;\n}\n\n/** Type guard for states created with `createRenderState.defer(...)`. */\nexport function isDeferredRenderState(\n value: unknown,\n): value is DeferredRenderState<AnyRenderStateDefinition> {\n return (\n typeof value === 'object' &&\n value !== null &&\n deferredRenderStateSymbol in value\n );\n}\n\n/** Type guard for states created with `createRenderState.lazy(...)`. */\nexport function isLazyRenderState(\n value: unknown,\n): value is LazyRenderState<AnyRenderStateDefinition> {\n return (\n typeof value === 'object' && value !== null && lazyRenderStateSymbol in value\n );\n}\n\n/**\n * Selects the single state definition exported by a lazy module. Throws when\n * the module exports none or more than one, avoiding ambiguous selection.\n */\nexport function findDefinedRenderState(\n module: Record<string, unknown>,\n): AnyRenderStateDefinition {\n const definitions = Object.values(module).filter(\n (value) =>\n typeof value === 'object' && value !== null && definedRenderStateSymbol in value,\n ) as Array<Record<typeof definedRenderStateSymbol, AnyRenderStateDefinition>>;\n\n if (definitions.length !== 1) {\n throw new Error(\n `A lazy render-state module must export exactly one defined render state; received ${definitions.length}.`,\n );\n }\n\n return definitions[0][definedRenderStateSymbol];\n}\n\n/** Identity helper that contextually types a reusable composables callback. */\nexport type DefineLayoutComposables<\n Resources extends ReadonlyArray<ResourceDefinition>,\n> = <const Composables extends ComposableComponents>(\n definition: LayoutComposablesDefinition<Resources, Composables>,\n) => LayoutComposablesDefinition<Resources, Composables>;\n\n/** Public cross-file building blocks returned by a defined layout builder. */\nexport type CreateLayoutBuildingBlocks<\n Resources extends ReadonlyArray<ResourceDefinition>,\n Options extends InPropsDefinition<Resources>,\n> = {\n composables: DefineLayoutComposables<Resources>;\n createRenderState: CreateRenderState<Resources, Options>;\n};\n\n/** Resource and option bindings used to create layout building blocks. */\nexport type CreateLayoutBuildingBlocksArguments<\n Resources extends ReadonlyArray<ResourceDefinition>,\n Options extends InPropsDefinition<Resources>,\n> = CreateRenderStateBuilderArguments<Resources, Options>;\n\n/** Layout helpers produced for the supplied resource and option bindings. */\nexport type CreateLayoutBuildingBlocksResult<\n Resources extends ReadonlyArray<ResourceDefinition>,\n Options extends InPropsDefinition<Resources>,\n> = CreateLayoutBuildingBlocks<Resources, Options>;\n\n/**\n * Creates the reusable `composables` and `createRenderState` helpers without\n * introducing an identity wrapper around the layout object itself.\n */\nexport function createLayoutBuildingBlocks<\n Resources extends ReadonlyArray<ResourceDefinition>,\n Options extends InPropsDefinition<Resources>,\n>(\n arguments_: CreateLayoutBuildingBlocksArguments<Resources, Options>,\n): CreateLayoutBuildingBlocksResult<Resources, Options> {\n function composables<const Composables extends ComposableComponents>(\n definition: LayoutComposablesDefinition<Resources, Composables>,\n ): LayoutComposablesDefinition<Resources, Composables> {\n return definition;\n }\n\n return {\n composables,\n createRenderState: createRenderStateBuilder(arguments_),\n };\n}\n\n/** Preserves a bound resource tuple for consumers that need to re-export it. */\nexport type BoundResources<\n Resources extends ReadonlyArray<ResourceDefinition>,\n> = Resources;\n"],"mappings":";;AAcA,MAAa,4BAA2C,OACtD,qBACF;AACA,MAAa,wBAAuC,OAClD,iBACF;AACA,MAAa,2BAA0C,OAAO,IAC5D,uCACF;AACA,MAAa,uCAAsD,OAAO,IACxE,oDACF;AAqRA,SAAS,oBACP,OAC0B;CAC1B,OAAO,OAAO,UAAU,aACpB;EAAE,QAAQ;EAAO,OAAO;CAAU,IAClC;AACN;AAEA,SAAS,WACP,YACA;CACA,MAAM,WAAW,GACd,WAAW,SAAS,YAAY,WACnC;CAEA,OAAO,eAAe,UAAU,0BAA0B;EACxD,YAAY;EACZ,OAAO;CACT,CAAC;CAED,OAAO;AACT;;;;;AAqBA,SAAgB,yBAId,YACoD;CACpD,SAAS,kBACP,OACA;EACA,OAAO,WAAW,oBAAoB,KAAK,CAAC;CAC9C;CAEA,kBAAkB,SAChB,UACG;EACH,MAAM,aAAa,oBAAoB,KAAK;EAE5C,OAAO,GACJ,WAAW,SAAS,YAAY,GAC9B,4BAA4B,WAC/B,EACF;CACF;CACA,kBAAkB,QAChB,UACI,GACH,wBAAwB,KAC3B;CAEA,OAAO;AACT;;AAGA,SAAgB,sBACd,OACwD;CACxD,OACE,OAAO,UAAU,YACjB,UAAU,QACV,6BAA6B;AAEjC;;AAGA,SAAgB,kBACd,OACoD;CACpD,OACE,OAAO,UAAU,YAAY,UAAU,QAAQ,yBAAyB;AAE5E;;;;;AAMA,SAAgB,uBACd,QAC0B;CAC1B,MAAM,cAAc,OAAO,OAAO,MAAM,EAAE,QACvC,UACC,OAAO,UAAU,YAAY,UAAU,QAAQ,4BAA4B,KAC/E;CAEA,IAAI,YAAY,WAAW,GACzB,MAAM,IAAI,MACR,qFAAqF,YAAY,OAAO,EAC1G;CAGF,OAAO,YAAY,GAAG;AACxB;;;;;AAkCA,SAAgB,2BAId,YACsD;CACtD,SAAS,YACP,YACqD;EACrD,OAAO;CACT;CAEA,OAAO;EACL;EACA,mBAAmB,yBAAyB,UAAU;CACxD;AACF"}
1
+ {"version":3,"file":"render-state.cjs","names":[],"sources":["../../src/create-config/render-state.ts"],"sourcesContent":["import type { JSX } from 'react';\nimport type {\n ComposableComponents,\n CreateLayoutComposable,\n} from '@jfdevelops/react-layout-composables';\nimport type { InPropsObject } from '../props';\nimport type {\n IncludedProps,\n InPropsDefinition,\n LayoutRenderProps,\n MergedLayoutInProps,\n} from '../props';\nimport type { LayoutResourceKey, ResourceDefinition } from '../resource';\n\nexport const deferredRenderStateSymbol: unique symbol = Symbol(\n 'deferredRenderState',\n) as never;\nexport const lazyRenderStateSymbol: unique symbol = Symbol(\n 'lazyRenderState',\n) as never;\nexport const definedRenderStateSymbol: unique symbol = Symbol.for(\n '@jfdevelops/react-layout/render-state',\n) as never;\nexport const definedResourceLayoutComponentSymbol: unique symbol = Symbol.for(\n '@jfdevelops/react-layout/resource-layout-component',\n) as never;\n\n/** Runtime-compatible render-state shape used when inspecting lazy modules. */\nexport type AnyRenderStateDefinition = {\n composables?: (create: CreateLayoutComposable<any>) => ComposableComponents;\n props?: {\n include?: Record<string, unknown>;\n custom?: InPropsObject;\n };\n render: (props: any, context: any) => JSX.Element;\n state?: string;\n};\n\n/** An inline state whose first render is scheduled through `React.lazy`. */\nexport type DeferredRenderState<Definition extends AnyRenderStateDefinition> = {\n readonly [deferredRenderStateSymbol]: Definition;\n};\n\n/** A state definition supplied by a separately imported module. */\nexport type LazyRenderState<Definition extends AnyRenderStateDefinition> = {\n readonly [lazyRenderStateSymbol]: () => Promise<Record<string, unknown>>;\n readonly definition?: Definition;\n};\n\n/** Callback shorthand for a render state with no local configuration. */\nexport type RenderStateCallback = (props: any, context: any) => JSX.Element;\n\n/**\n * Defines state-local composable components with a `create` helper narrowed to\n * the resources bound to the surrounding builder.\n */\nexport type RenderStateComposablesDefinition<\n Resources extends ReadonlyArray<ResourceDefinition>,\n Composables extends ComposableComponents,\n> = (\n create: CreateLayoutComposable<LayoutResourceKey<Resources>>,\n) => Composables;\n\n/**\n * Defines reusable layout-level composables while preserving their inferred\n * names, props, and bound resource union.\n */\nexport type LayoutComposablesDefinition<\n Resources extends ReadonlyArray<ResourceDefinition>,\n Composables extends ComposableComponents,\n> = RenderStateComposablesDefinition<Resources, Composables>;\n\ntype BuilderRenderComposables<Composables extends ComposableComponents> = [\n keyof Composables,\n] extends [never]\n ? undefined\n : Composables;\n\n/** Values available as the second argument of a created state's `render`. */\nexport type RenderStateContext<\n Composables extends ComposableComponents,\n> = {\n composables: BuilderRenderComposables<Composables>;\n retry?: () => void;\n};\n\n/**\n * Resolves one state's custom props and explicitly included option/composable\n * props to the values received by its render callback.\n */\nexport type RenderStateProps<\n Resources extends ReadonlyArray<ResourceDefinition>,\n Options extends InPropsDefinition<Resources>,\n Composables extends ComposableComponents,\n IncludeProps extends IncludedProps<\n MergedLayoutInProps<Resources, Options, Composables>\n >,\n CustomProps extends InPropsObject,\n> = LayoutRenderProps<\n Resources,\n Options,\n Composables,\n IncludeProps,\n CustomProps\n>;\n\ntype TypedRenderStateDefinition<\n Resources extends ReadonlyArray<ResourceDefinition>,\n Options extends InPropsDefinition<Resources>,\n State extends string,\n CustomProps extends InPropsObject,\n SharedComposables extends ComposableComponents,\n StateComposables extends ComposableComponents,\n IncludeProps extends IncludedProps<\n MergedLayoutInProps<\n Resources,\n Options,\n SharedComposables & StateComposables\n >\n >,\n> = {\n composables?: RenderStateComposablesDefinition<Resources, StateComposables>;\n props?: {\n include?: IncludeProps;\n custom?: CustomProps;\n };\n render: (\n props: RenderStateProps<\n Resources,\n Options,\n SharedComposables & StateComposables,\n IncludeProps,\n CustomProps\n >,\n context: RenderStateContext<SharedComposables & StateComposables>,\n ) => JSX.Element;\n state: State;\n};\n\ntype NormalizeRenderStateDefinition<Input> =\n Input extends DeferredRenderState<infer Definition>\n ? Definition\n : Input extends RenderStateCallback\n ? { render: Input; state: 'default' }\n : Input extends AnyRenderStateDefinition\n ? Input\n : never;\n\ntype StateName<Definition> = Definition extends DeferredRenderState<\n infer DeferredDefinition\n>\n ? StateName<DeferredDefinition>\n : Definition extends { state?: infer State extends string }\n ? State\n : 'default';\n\n/**\n * A spreadable state entry keyed by its literal state name. Spreading this into\n * `layout.render` is what creates compound members such as `Users.Loading`.\n */\nexport type RenderStateFragment<Definition> = {\n [State in StateName<NormalizeRenderStateDefinition<Definition>>]: Definition;\n} & {\n readonly [definedRenderStateSymbol]: NormalizeRenderStateDefinition<Definition>;\n};\n\ntype DefinedRenderStateFromModule<Module> = Extract<\n Module[keyof Module],\n { readonly [definedRenderStateSymbol]: AnyRenderStateDefinition }\n>[typeof definedRenderStateSymbol];\n\n/**\n * Creates independently typed render-state fragments.\n *\n * - Calling it directly creates an eager state.\n * - `.defer(...)` schedules an inline definition through `React.lazy`, but\n * does not create a separate JavaScript chunk.\n * - `.lazy(() => import(...))` imports a complete named state definition as a\n * separate chunk.\n */\nexport type CreateRenderState<\n Resources extends ReadonlyArray<ResourceDefinition> = ReadonlyArray<ResourceDefinition>,\n Options extends InPropsDefinition<Resources> = {},\n SharedComposables extends ComposableComponents = {},\n> = {\n <\n const State extends string = 'default',\n const CustomProps extends InPropsObject = {},\n const StateComposables extends ComposableComponents = {},\n const IncludeProps extends IncludedProps<\n MergedLayoutInProps<\n Resources,\n Options,\n SharedComposables & StateComposables\n >\n > = {},\n >(\n definition: TypedRenderStateDefinition<\n Resources,\n Options,\n State,\n CustomProps,\n SharedComposables,\n StateComposables,\n IncludeProps\n >,\n ): RenderStateFragment<\n TypedRenderStateDefinition<\n Resources,\n Options,\n State,\n CustomProps,\n SharedComposables,\n StateComposables,\n IncludeProps\n >\n >;\n <\n const CustomProps extends InPropsObject = {},\n const StateComposables extends ComposableComponents = {},\n const IncludeProps extends IncludedProps<\n MergedLayoutInProps<\n Resources,\n Options,\n SharedComposables & StateComposables\n >\n > = {},\n >(\n definition: Omit<\n TypedRenderStateDefinition<\n Resources,\n Options,\n 'default',\n CustomProps,\n SharedComposables,\n StateComposables,\n IncludeProps\n >,\n 'state'\n >,\n ): RenderStateFragment<\n TypedRenderStateDefinition<\n Resources,\n Options,\n 'default',\n CustomProps,\n SharedComposables,\n StateComposables,\n IncludeProps\n >\n >;\n <const Render extends RenderStateCallback>(\n render: Render,\n ): RenderStateFragment<Render>;\n defer<\n const State extends string = 'default',\n const CustomProps extends InPropsObject = {},\n const StateComposables extends ComposableComponents = {},\n const IncludeProps extends IncludedProps<\n MergedLayoutInProps<\n Resources,\n Options,\n SharedComposables & StateComposables\n >\n > = {},\n >(\n definition: TypedRenderStateDefinition<\n Resources,\n Options,\n State,\n CustomProps,\n SharedComposables,\n StateComposables,\n IncludeProps\n >,\n ): RenderStateFragment<\n DeferredRenderState<\n TypedRenderStateDefinition<\n Resources,\n Options,\n State,\n CustomProps,\n SharedComposables,\n StateComposables,\n IncludeProps\n >\n >\n >;\n defer<\n const CustomProps extends InPropsObject = {},\n const StateComposables extends ComposableComponents = {},\n const IncludeProps extends IncludedProps<\n MergedLayoutInProps<\n Resources,\n Options,\n SharedComposables & StateComposables\n >\n > = {},\n >(\n definition: Omit<\n TypedRenderStateDefinition<\n Resources,\n Options,\n 'default',\n CustomProps,\n SharedComposables,\n StateComposables,\n IncludeProps\n >,\n 'state'\n >,\n ): RenderStateFragment<\n DeferredRenderState<\n TypedRenderStateDefinition<\n Resources,\n Options,\n 'default',\n CustomProps,\n SharedComposables,\n StateComposables,\n IncludeProps\n >\n >\n >;\n defer<const Render extends RenderStateCallback>(\n render: Render,\n ): RenderStateFragment<DeferredRenderState<{ render: Render; state: 'default' }>>;\n lazy<Module extends Record<string, unknown>>(\n load: () => Promise<Module>,\n ): LazyRenderState<DefinedRenderStateFromModule<Module>>;\n};\n\nfunction normalizeDefinition(\n input: AnyRenderStateDefinition | RenderStateCallback,\n): AnyRenderStateDefinition {\n return typeof input === 'function'\n ? { render: input, state: 'default' }\n : input;\n}\n\nfunction toFragment<Definition extends AnyRenderStateDefinition>(\n definition: Definition,\n) {\n const fragment = {\n [definition.state ?? 'default']: definition,\n } as RenderStateFragment<Definition>;\n\n Object.defineProperty(fragment, definedRenderStateSymbol, {\n enumerable: false,\n value: definition,\n });\n\n return fragment;\n}\n\n/** Inputs used internally to bind resource and option types to a state builder. */\nexport type CreateRenderStateBuilderArguments<\n Resources extends ReadonlyArray<ResourceDefinition>,\n Options extends InPropsDefinition<Resources>,\n SharedComposables extends ComposableComponents = {},\n> = {\n /** Shared composables whose components and preset props every state can use. */\n composables?: LayoutComposablesDefinition<Resources, SharedComposables>;\n /** Option props that individual states can expose through `props.include`. */\n options: Options;\n /** Resources used to constrain composable names and resource-specific props. */\n resources: Resources;\n};\n\n/** The state factory produced for a particular resource and option definition. */\nexport type CreateRenderStateBuilderResult<\n Resources extends ReadonlyArray<ResourceDefinition>,\n Options extends InPropsDefinition<Resources>,\n SharedComposables extends ComposableComponents = {},\n> = CreateRenderState<Resources, Options, SharedComposables>;\n\n/**\n * Creates a state factory whose `props.include` keys are constrained by the\n * supplied resources and options.\n */\nexport function createRenderStateBuilder<\n Resources extends ReadonlyArray<ResourceDefinition>,\n Options extends InPropsDefinition<Resources>,\n SharedComposables extends ComposableComponents = {},\n>(\n _arguments: CreateRenderStateBuilderArguments<\n Resources,\n Options,\n SharedComposables\n >,\n): CreateRenderStateBuilderResult<Resources, Options, SharedComposables> {\n function createRenderState(\n input: AnyRenderStateDefinition | RenderStateCallback,\n ) {\n return toFragment(normalizeDefinition(input));\n }\n\n createRenderState.defer = (\n input: AnyRenderStateDefinition | RenderStateCallback,\n ) => {\n const definition = normalizeDefinition(input);\n\n return {\n [definition.state ?? 'default']: {\n [deferredRenderStateSymbol]: definition,\n },\n };\n };\n createRenderState.lazy = (\n load: () => Promise<Record<string, unknown>>,\n ) => ({\n [lazyRenderStateSymbol]: load,\n });\n\n return createRenderState as CreateRenderStateBuilderResult<\n Resources,\n Options,\n SharedComposables\n >;\n}\n\n/** Type guard for states created with `createRenderState.defer(...)`. */\nexport function isDeferredRenderState(\n value: unknown,\n): value is DeferredRenderState<AnyRenderStateDefinition> {\n return (\n typeof value === 'object' &&\n value !== null &&\n deferredRenderStateSymbol in value\n );\n}\n\n/** Type guard for states created with `createRenderState.lazy(...)`. */\nexport function isLazyRenderState(\n value: unknown,\n): value is LazyRenderState<AnyRenderStateDefinition> {\n return (\n typeof value === 'object' && value !== null && lazyRenderStateSymbol in value\n );\n}\n\n/**\n * Selects the single state definition exported by a lazy module. Throws when\n * the module exports none or more than one, avoiding ambiguous selection.\n */\nexport function findDefinedRenderState(\n module: Record<string, unknown>,\n): AnyRenderStateDefinition {\n const definitions = Object.values(module).filter(\n (value) =>\n typeof value === 'object' && value !== null && definedRenderStateSymbol in value,\n ) as Array<Record<typeof definedRenderStateSymbol, AnyRenderStateDefinition>>;\n\n if (definitions.length !== 1) {\n throw new Error(\n `A lazy render-state module must export exactly one defined render state; received ${definitions.length}.`,\n );\n }\n\n return definitions[0][definedRenderStateSymbol];\n}\n\n/** Identity helper that contextually types a reusable composables callback. */\nexport type DefineLayoutComposables<\n Resources extends ReadonlyArray<ResourceDefinition>,\n> = <const Composables extends ComposableComponents>(\n definition: LayoutComposablesDefinition<Resources, Composables>,\n) => LayoutComposablesDefinition<Resources, Composables>;\n\n/** Public cross-file building blocks returned by a defined layout builder. */\nexport type CreateLayoutBuildingBlocks<\n Resources extends ReadonlyArray<ResourceDefinition>,\n Options extends InPropsDefinition<Resources>,\n> = {\n composables: DefineLayoutComposables<Resources>;\n createRenderState: CreateRenderState<Resources, Options>;\n};\n\n/** Resource and option bindings used to create layout building blocks. */\nexport type CreateLayoutBuildingBlocksArguments<\n Resources extends ReadonlyArray<ResourceDefinition>,\n Options extends InPropsDefinition<Resources>,\n> = CreateRenderStateBuilderArguments<Resources, Options>;\n\n/** Layout helpers produced for the supplied resource and option bindings. */\nexport type CreateLayoutBuildingBlocksResult<\n Resources extends ReadonlyArray<ResourceDefinition>,\n Options extends InPropsDefinition<Resources>,\n> = CreateLayoutBuildingBlocks<Resources, Options>;\n\n/**\n * Creates the reusable `composables` and `createRenderState` helpers without\n * introducing an identity wrapper around the layout object itself.\n */\nexport function createLayoutBuildingBlocks<\n Resources extends ReadonlyArray<ResourceDefinition>,\n Options extends InPropsDefinition<Resources>,\n>(\n arguments_: CreateLayoutBuildingBlocksArguments<Resources, Options>,\n): CreateLayoutBuildingBlocksResult<Resources, Options> {\n function composables<const Composables extends ComposableComponents>(\n definition: LayoutComposablesDefinition<Resources, Composables>,\n ): LayoutComposablesDefinition<Resources, Composables> {\n return definition;\n }\n\n return {\n composables,\n createRenderState: createRenderStateBuilder(arguments_),\n };\n}\n\n/** Preserves a bound resource tuple for consumers that need to re-export it. */\nexport type BoundResources<\n Resources extends ReadonlyArray<ResourceDefinition>,\n> = Resources;\n"],"mappings":";;AAcA,MAAa,4BAA2C,OACtD,qBACF;AACA,MAAa,wBAAuC,OAClD,iBACF;AACA,MAAa,2BAA0C,OAAO,IAC5D,uCACF;AACA,MAAa,uCAAsD,OAAO,IACxE,oDACF;AAmTA,SAAS,oBACP,OAC0B;CAC1B,OAAO,OAAO,UAAU,aACpB;EAAE,QAAQ;EAAO,OAAO;CAAU,IAClC;AACN;AAEA,SAAS,WACP,YACA;CACA,MAAM,WAAW,GACd,WAAW,SAAS,YAAY,WACnC;CAEA,OAAO,eAAe,UAAU,0BAA0B;EACxD,YAAY;EACZ,OAAO;CACT,CAAC;CAED,OAAO;AACT;;;;;AA2BA,SAAgB,yBAKd,YAKuE;CACvE,SAAS,kBACP,OACA;EACA,OAAO,WAAW,oBAAoB,KAAK,CAAC;CAC9C;CAEA,kBAAkB,SAChB,UACG;EACH,MAAM,aAAa,oBAAoB,KAAK;EAE5C,OAAO,GACJ,WAAW,SAAS,YAAY,GAC9B,4BAA4B,WAC/B,EACF;CACF;CACA,kBAAkB,QAChB,UACI,GACH,wBAAwB,KAC3B;CAEA,OAAO;AAKT;;AAGA,SAAgB,sBACd,OACwD;CACxD,OACE,OAAO,UAAU,YACjB,UAAU,QACV,6BAA6B;AAEjC;;AAGA,SAAgB,kBACd,OACoD;CACpD,OACE,OAAO,UAAU,YAAY,UAAU,QAAQ,yBAAyB;AAE5E;;;;;AAMA,SAAgB,uBACd,QAC0B;CAC1B,MAAM,cAAc,OAAO,OAAO,MAAM,EAAE,QACvC,UACC,OAAO,UAAU,YAAY,UAAU,QAAQ,4BAA4B,KAC/E;CAEA,IAAI,YAAY,WAAW,GACzB,MAAM,IAAI,MACR,qFAAqF,YAAY,OAAO,EAC1G;CAGF,OAAO,YAAY,GAAG;AACxB"}