{"version":3,"file":"pages/TreeShaking/utils.mjs","sources":["../../../src/pages/TreeShaking/utils.tsx"],"sourcesContent":["import { Module } from '@rsdoctor/graph';\nimport { SDK } from '@rsdoctor/types';\nimport { Space, Tag } from 'antd';\nimport { escape, get } from 'es-toolkit/compat';\nimport type { editor, Range as RangeClass } from 'monaco-editor';\nimport path from 'path-browserify';\nimport { useMemo } from 'react';\nimport { getSelectionRange } from 'src/components/base/CodeViewer/utils';\nimport { Keyword } from '../../components/Keyword';\nimport { createFileStructures, mapFileKey } from '../../utils';\nimport { getOpenTagText } from './open-tag';\nimport { Range } from './range';\n\nexport function useFileStructures(\n  modules: SDK.ModuleInstance[],\n  moduleGraph: SDK.ModuleGraphInstance,\n  searchInput: string,\n  selectedModule: SDK.ModuleInstance,\n  onItemClick: (file: string) => void,\n  cwd: string,\n) {\n  const files = useMemo(\n    () =>\n      createFileStructures({\n        files: modules.map((item) => item.path),\n        cwd,\n        fileTitle(file, basename) {\n          const module = moduleGraph\n            .getModules()\n            .find(\n              (item) => item.path === file && item.kind === Module.kind.Normal,\n            )!;\n          const mgm = moduleGraph.getModuleGraphModule(module)!;\n          const infos = mgm.getExports();\n          const unused = infos.filter(\n            (info) => info.getSideEffects().length === 0,\n          );\n          return (\n            <Space style={{ wordBreak: 'break-all' }}>\n              <Keyword\n                text={basename}\n                keyword={file}\n                onClick={() => onItemClick(file)}\n              />\n              {mgm.dynamic ? <Tag color=\"cyan\">dynamic</Tag> : ''}\n              {unused.length > 0 ? (\n                <Tag color=\"green\">{unused.length} Unused</Tag>\n              ) : (\n                ''\n              )}\n            </Space>\n          );\n        },\n      }),\n    [searchInput, selectedModule],\n  );\n\n  return files;\n}\n\nexport function getTreeFilesDefaultExpandedKeys(files: any[]) {\n  return mapFileKey(files, 3, (node) => {\n    const resourcePath: string = get(node, '__RESOURCEPATH__')!;\n    const isNodeModules = resourcePath.indexOf('/node_modules/') > -1;\n    return !isNodeModules;\n  });\n}\n\nexport function ellipsisPath(full: string) {\n  let result = '';\n  let current = full;\n\n  for (let i = 0; i < 3; i++) {\n    result = result\n      ? `${path.basename(current)}/${result}`\n      : path.basename(current);\n    current = path.dirname(current);\n  }\n\n  return `...${result}`;\n}\n\nexport function getModulePositionString(\n  statement: SDK.StatementInstance,\n  module: SDK.ModuleInstance,\n) {\n  const maxLen = 30;\n  const { path, isPreferSource } = module;\n  const start = isPreferSource\n    ? statement.position.source!.start\n    : statement.position.transformed.start;\n  const suffix = `:${start.line ?? 1}:${start.column ?? 0}`;\n\n  return path.length <= maxLen\n    ? `${path}${suffix}`\n    : `...${path.substring(path.length - 30)}${suffix}`;\n}\n\nexport function getHoverMessageInModule(\n  module: SDK.ModuleInstance,\n  moduleGraph: SDK.ModuleGraphInstance,\n) {\n  const mgm = moduleGraph.getModuleGraphModule(module);\n  /** 当前模块导出变量 */\n  const exportLocals = mgm.getOwnExports();\n  /** 当前模块声明变量 */\n  const variables = exportLocals\n    .map((item) => item.variable)\n    .filter((item): item is SDK.VariableInstance => Boolean(item));\n\n  if (exportLocals.length === 0 && variables.length === 0) {\n    return [];\n  }\n\n  function getVariableMessage(data: SDK.VariableInstance) {\n    const exportData = data.getExportInfo();\n\n    if (!exportData) {\n      return 'Can not find SideEffect info.';\n    }\n\n    const sideEffects = exportData.getSideEffects();\n\n    if (sideEffects.length === 0) {\n      return 'Have no sideEffect.';\n    }\n\n    /*\n     * monaco hover html 代码允许的元素和标签\n     * @link https://github.com/microsoft/vscode/blob/6d2920473c6f13759c978dd89104c4270a83422d/src/vs/base/browser/markdownRenderer.ts#L296-L317\n     */\n\n    let content = `Used **${sideEffects.length}** times:\\n\\n<div data-code=\"tree-shaking-hover\">\\n<li>`;\n\n    for (const sideEffect of sideEffects) {\n      if (!sideEffect) {\n        continue;\n      }\n\n      const { identifier, module } = sideEffect;\n\n      if (!module) {\n        continue;\n      }\n\n      const { id, isPreferSource } = module;\n      const lineCode = identifier.getLineCode();\n\n      content += `\\n<ol>\n      ${getOpenTagText(\n        id,\n        isPreferSource\n          ? identifier.position.source!\n          : identifier.position.transformed,\n        getModulePositionString(identifier, module),\n      )}\n      ${lineCode ? `<pre>${escape(lineCode)}</pre>` : ''}\n      </ol>`;\n    }\n\n    content += '\\n</li></div>';\n\n    return content;\n  }\n\n  const { isPreferSource } = module;\n\n  const declarationHovers = variables\n    .map((item) => {\n      const position = isPreferSource\n        ? item.identifier.position.source\n        : item.identifier.position.transformed;\n      const range =\n        position &&\n        getSelectionRange(position, Range as unknown as typeof RangeClass);\n\n      if (!position || !range) {\n        return;\n      }\n\n      return {\n        range,\n        options: {\n          stickiness: 1,\n          inlineClassName: 'tree-shaking-statement-declaration-identifier',\n          isWholeLine: false,\n          showIfCollapsed: true,\n          hoverMessage: {\n            supportHtml: true,\n            supportThemeIcons: true,\n            isTrusted: true,\n            value: getVariableMessage(item),\n          },\n        },\n      } as unknown as editor.IModelDecoration;\n    })\n    .filter((item): item is editor.IModelDecoration => Boolean(item));\n\n  /**\n   * 导出部分的信息，需要先过滤声明和导出位置重叠的部分\n   * export { foo };\n   * export { foo } from 'foo';\n   * export * as name from 'foo';\n   * export * from 'foo';\n   * 最后一种需要合并位置\n   */\n\n  return declarationHovers;\n}\n"],"names":["useFileStructures","modules","moduleGraph","searchInput","selectedModule","onItemClick","cwd","files","useMemo","createFileStructures","item","file","basename","module","Module","mgm","infos","unused","info","Space","Keyword","Tag","getTreeFilesDefaultExpandedKeys","mapFileKey","node","resourcePath","get","isNodeModules","ellipsisPath","full","result","current","i","path","getModulePositionString","statement","maxLen","isPreferSource","start","suffix","getHoverMessageInModule","exportLocals","variables","Boolean","getVariableMessage","data","exportData","sideEffects","content","sideEffect","identifier","id","lineCode","getOpenTagText","escape","declarationHovers","position","range","getSelectionRange","Range"],"mappings":"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"}