@rsdoctor/components 1.5.12 → 2.0.0-alpha.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 (73) hide show
  1. package/dist/components/Charts/done.mjs +2 -2
  2. package/dist/components/Charts/done.mjs.map +1 -1
  3. package/dist/components/Charts/minify.mjs +2 -2
  4. package/dist/components/Charts/minify.mjs.map +1 -1
  5. package/dist/components/Layout/menus.mjs +7 -7
  6. package/dist/components/Layout/menus.mjs.map +1 -1
  7. package/dist/components/Manifest/api.mjs +2 -2
  8. package/dist/components/Manifest/api.mjs.map +1 -1
  9. package/dist/components/Plugins/plugins.d.ts +18 -0
  10. package/dist/components/Plugins/{webpack.mjs → plugins.mjs} +4 -4
  11. package/dist/components/Plugins/plugins.mjs.map +1 -0
  12. package/dist/pages/{WebpackLoaders → Loaders}/Analysis/constants.d.ts +1 -1
  13. package/dist/pages/{WebpackLoaders → Loaders}/Analysis/constants.mjs +1 -1
  14. package/dist/pages/Loaders/Analysis/constants.mjs.map +1 -0
  15. package/dist/pages/Loaders/Analysis/index.mjs.map +1 -0
  16. package/dist/pages/{WebpackLoaders → Loaders}/Overall/constants.d.ts +1 -1
  17. package/dist/pages/{WebpackLoaders → Loaders}/Overall/constants.mjs +1 -1
  18. package/dist/pages/Loaders/Overall/constants.mjs.map +1 -0
  19. package/dist/pages/Loaders/Overall/index.mjs.map +1 -0
  20. package/dist/pages/Loaders/constants.d.ts +2 -0
  21. package/dist/pages/{WebpackLoaders → Loaders}/constants.mjs +1 -1
  22. package/dist/pages/Loaders/constants.mjs.map +1 -0
  23. package/dist/pages/{WebpackPlugins → Plugins}/constants.d.ts +1 -1
  24. package/dist/pages/{WebpackPlugins → Plugins}/constants.mjs +1 -1
  25. package/dist/pages/Plugins/constants.mjs.map +1 -0
  26. package/dist/pages/Plugins/index.css.map +1 -0
  27. package/dist/pages/{WebpackPlugins → Plugins}/index.mjs +2 -2
  28. package/dist/pages/Plugins/index.mjs.map +1 -0
  29. package/dist/pages/Resources/BundleDiff/DiffContainer/modules.mjs +2 -2
  30. package/dist/pages/Resources/BundleDiff/DiffContainer/modules.mjs.map +1 -1
  31. package/dist/pages/Resources/BundleDiff/DiffContainer/row.mjs +1 -1
  32. package/dist/pages/Resources/BundleDiff/DiffContainer/row.mjs.map +1 -1
  33. package/dist/pages/index.d.ts +3 -3
  34. package/dist/pages/index.mjs +4 -4
  35. package/dist/utils/data/base.d.ts +2 -2
  36. package/dist/utils/data/base.mjs.map +1 -1
  37. package/dist/utils/data/local.d.ts +10 -3
  38. package/dist/utils/data/local.mjs +37 -24
  39. package/dist/utils/data/local.mjs.map +1 -1
  40. package/dist/utils/data/local.test.d.ts +1 -0
  41. package/dist/utils/data/local.test.mjs +89 -0
  42. package/dist/utils/data/local.test.mjs.map +1 -0
  43. package/dist/utils/hooks.d.ts +1 -1
  44. package/dist/utils/request.mjs +4 -3
  45. package/dist/utils/request.mjs.map +1 -1
  46. package/dist/utils/request.test.mjs +23 -0
  47. package/dist/utils/request.test.mjs.map +1 -1
  48. package/dist/utils/routes.mjs +1 -1
  49. package/dist/utils/routes.mjs.map +1 -1
  50. package/dist/utils/socket.d.ts +12 -2
  51. package/dist/utils/socket.mjs +155 -23
  52. package/dist/utils/socket.mjs.map +1 -1
  53. package/dist/utils/socket.test.d.ts +1 -0
  54. package/dist/utils/socket.test.mjs +167 -0
  55. package/dist/utils/socket.test.mjs.map +1 -0
  56. package/package.json +5 -6
  57. package/dist/components/Plugins/webpack.d.ts +0 -18
  58. package/dist/components/Plugins/webpack.mjs.map +0 -1
  59. package/dist/pages/WebpackLoaders/Analysis/constants.mjs.map +0 -1
  60. package/dist/pages/WebpackLoaders/Analysis/index.mjs.map +0 -1
  61. package/dist/pages/WebpackLoaders/Overall/constants.mjs.map +0 -1
  62. package/dist/pages/WebpackLoaders/Overall/index.mjs.map +0 -1
  63. package/dist/pages/WebpackLoaders/constants.d.ts +0 -2
  64. package/dist/pages/WebpackLoaders/constants.mjs.map +0 -1
  65. package/dist/pages/WebpackPlugins/constants.mjs.map +0 -1
  66. package/dist/pages/WebpackPlugins/index.css.map +0 -1
  67. package/dist/pages/WebpackPlugins/index.mjs.map +0 -1
  68. /package/dist/pages/{WebpackLoaders → Loaders}/Analysis/index.d.ts +0 -0
  69. /package/dist/pages/{WebpackLoaders → Loaders}/Analysis/index.mjs +0 -0
  70. /package/dist/pages/{WebpackLoaders → Loaders}/Overall/index.d.ts +0 -0
  71. /package/dist/pages/{WebpackLoaders → Loaders}/Overall/index.mjs +0 -0
  72. /package/dist/pages/{WebpackPlugins → Plugins}/index.css +0 -0
  73. /package/dist/pages/{WebpackPlugins → Plugins}/index.d.ts +0 -0
@@ -1 +1 @@
1
- {"version":3,"file":"pages/Resources/BundleDiff/DiffContainer/row.mjs","sources":["../../../../../src/pages/Resources/BundleDiff/DiffContainer/row.tsx"],"sourcesContent":["import { InfoCircleOutlined, SearchOutlined } from '@ant-design/icons';\nimport {\n Button,\n Divider,\n Input,\n InputRef,\n Space,\n Table,\n Tag,\n Tooltip,\n Typography,\n} from 'antd';\nimport {\n ColumnGroupType,\n ColumnType,\n FilterConfirmProps,\n} from 'antd/es/table/interface';\nimport { upperFirst } from 'es-toolkit/compat';\nimport React, { useMemo, useRef, useState } from 'react';\nimport { Client } from '@rsdoctor/types';\nimport { CompareFn } from 'antd/lib/table/interface';\nimport { Color } from '../../../../constants';\nimport {\n beautifyModulePath,\n formatPercent,\n formatSize,\n} from '../../../../utils';\nimport { ViewChanges } from './changes';\nimport { FileUpdateTypeTag, getUpdateType } from './modules';\nimport {\n BundleDiffComponentCardProps,\n BundleDiffTableAssetsData,\n BundleDiffTableModulesData,\n} from './types';\nimport { UpdateType } from './constants';\nimport { formatDiffSize } from './utils';\nimport { Graph } from '@rsdoctor/utils/common';\n\nexport const ModuleHashPattern = /[a-fA-F0-9]{20,}/;\n\nexport const getSizeColumnPropsForModuleRow = (\n key: 'baseline' | 'current',\n sizeKey: 'parsedSize' | 'sourceSize',\n sortByChanged?: boolean,\n): ColumnType<BundleDiffTableModulesData> => {\n const sortByChangedFn: CompareFn<any> = (a, b) =>\n (a.current?.size[sizeKey] || 0) -\n (a.baseline?.size[sizeKey] || 0) -\n (b.current?.size[sizeKey] || 0) +\n (b.baseline?.size[sizeKey] || 0);\n\n const sorterFn: CompareFn<any> = sortByChanged\n ? (a, b) => sortByChangedFn(a, b)\n : (a, b) => (a[key]?.size[sizeKey] || 0) - (b[key]?.size[sizeKey] || 0);\n\n return {\n width: 200,\n sorter: (a, b) => sorterFn(a, b),\n render: (_v, r) => {\n if (!r[key]) return '-';\n const size = r[key]!.size[sizeKey];\n return (\n <Space>\n <Typography.Text>{formatSize(size)}</Typography.Text>\n {key === 'current'\n ? formatDiffSize(\n r.baseline?.size[sizeKey] || 0,\n size,\n (r.baseline?.size[sizeKey] || 0) > size\n ? Client.RsdoctorClientDiffState.Down\n : Client.RsdoctorClientDiffState.Up,\n )\n : null}\n </Space>\n );\n },\n };\n};\n\nexport const getTargetColumnPropsForModuleRow = (\n key: 'baseline' | 'current',\n bModulesCount: number,\n cModulesCount: number,\n): ColumnGroupType<BundleDiffTableModulesData> => {\n const [sortByChanged, setSortByChanged] = useState(false);\n\n const isB = key === 'baseline';\n return {\n title: () => {\n const count = isB ? bModulesCount : cModulesCount;\n const title = upperFirst(key);\n const diff = Graph.diffSize(bModulesCount, cModulesCount);\n return (\n <div>\n <Typography.Text>{title}</Typography.Text>\n <Divider type=\"vertical\" />\n <Tooltip\n title={\n <Space direction=\"vertical\">\n <Typography.Text style={{ color: 'inherit' }}>\n {title} modules is {count}\n </Typography.Text>\n {isB ? null : (\n <Typography.Text style={{ color: 'inherit' }}>\n Percent is {formatPercent(diff.percent)}\n </Typography.Text>\n )}\n </Space>\n }\n >\n <Space>\n <Typography.Text\n type=\"secondary\"\n style={{ fontSize: 10, fontWeight: 400 }}\n >\n {count}\n </Typography.Text>\n <InfoCircleOutlined />\n </Space>\n </Tooltip>\n </div>\n );\n },\n children: [\n {\n title: 'Source Size',\n ...getSizeColumnPropsForModuleRow(key, 'sourceSize', sortByChanged),\n },\n {\n title: 'Parsed Size',\n defaultSortOrder: isB ? undefined : 'descend',\n ...getSizeColumnPropsForModuleRow(key, 'parsedSize', sortByChanged),\n },\n ],\n filterSearch: true,\n filters: [\n {\n text: 'Show Changed',\n value: UpdateType.NotChanged,\n },\n {\n text: 'Show All',\n value: 'All',\n },\n ],\n onFilter(v, r) {\n if (v === UpdateType.NotChanged) {\n setSortByChanged(true);\n } else {\n setSortByChanged(false);\n }\n return v === UpdateType.NotChanged ? getUpdateType(r) !== v : true;\n },\n };\n};\n\nexport const ModuleRowForAsset: React.FC<\n { data: BundleDiffTableAssetsData } & Pick<\n BundleDiffComponentCardProps,\n 'baseline' | 'current'\n >\n> = ({ data, baseline, current }) => {\n const { modules: bTotalModules } = baseline.moduleGraph;\n const { modules: cTotalModules } = current.moduleGraph;\n const { chunks: bToTalChunks } = baseline.chunkGraph;\n const { chunks: cToTalChunks } = current.chunkGraph;\n const bRoot = baseline.root;\n const cRoot = current.root;\n\n const [searchText, setSearchText] = useState('');\n const searchInput = useRef<InputRef>(null);\n\n const handleSearch = (\n selectedKeys: string[],\n confirm: (param?: FilterConfirmProps) => void,\n ) => {\n confirm();\n setSearchText(selectedKeys[0]);\n };\n\n const handleReset = (clearFilters: () => void) => {\n clearFilters();\n setSearchText('');\n };\n\n const isBaseline = '__is_baseline__' as const;\n\n const bModules = useMemo(\n () =>\n data.baseline\n ? Graph.getModulesByAsset(data.baseline, bToTalChunks, bTotalModules)\n .map((e) => ({\n ...e,\n [isBaseline]: true,\n }))\n .filter((cModule) => !cModule.concatenationModules?.length)\n : [],\n [data, baseline],\n );\n const cModules = useMemo(\n () =>\n data.current\n ? Graph.getModulesByAsset(data.current, cToTalChunks, cTotalModules)\n .map((e) => ({\n ...e,\n [isBaseline]: false,\n }))\n .filter((cModule) => !cModule.concatenationModules?.length)\n : [],\n [data, current],\n );\n\n const getPathInfo = (r: BundleDiffTableModulesData) =>\n beautifyModulePath(r.path, r.__is_baseline__ ? bRoot : cRoot);\n\n const dataSource: BundleDiffTableModulesData[] = useMemo(() => {\n const mods = [...bModules, ...cModules];\n const map = new Map<string, BundleDiffTableModulesData>();\n\n // group by module.path\n mods.forEach((mod) => {\n const modPath =\n mod.webpackId?.replace(ModuleHashPattern, '') ||\n mod.path?.replace(ModuleHashPattern, '');\n let t: BundleDiffTableModulesData = map.get(modPath)!;\n\n if (!t) {\n t = { path: modPath };\n }\n\n if (mod[isBaseline]) {\n t.baseline = mod;\n } else {\n t.current = mod;\n }\n map.set(modPath, t);\n });\n\n return [...map.values()];\n }, [bModules, cModules, searchText]);\n\n const { bModulesCount, cModulesCount, totalCount } = useMemo(() => {\n const fileNameFilter = (e: BundleDiffTableModulesData) =>\n getPathInfo(e).alias.indexOf(searchText) > -1;\n\n let b = dataSource.filter((e) => e.baseline);\n let c = dataSource.filter((e) => e.current);\n let totalCount = dataSource.length;\n\n if (searchText) {\n b = b.filter(fileNameFilter);\n c = c.filter(fileNameFilter);\n totalCount = dataSource.filter(fileNameFilter).length;\n }\n\n return {\n bModulesCount: b.length,\n cModulesCount: c.length,\n totalCount,\n };\n }, [dataSource, searchText]);\n\n return (\n <Table\n dataSource={dataSource}\n rowKey={(e) => e.path}\n size=\"small\"\n pagination={{\n size: 'small',\n }}\n bordered\n scroll={{ x: 1500 }}\n columns={[\n {\n fixed: 'left',\n title: () => {\n return (\n <div>\n <Typography.Text>\n Modules of {`\"${data.alias}\"`}\n </Typography.Text>\n <Divider type=\"vertical\" />\n <Tooltip\n title={\n <Space direction=\"vertical\">\n <Typography.Text style={{ color: 'inherit' }}>\n filtered modules: {totalCount}\n </Typography.Text>\n <Typography.Text style={{ color: 'inherit' }}>\n total modules: {dataSource.length}\n </Typography.Text>\n </Space>\n }\n >\n <Typography.Text\n type=\"secondary\"\n style={{ fontSize: 10, fontWeight: 400, marginRight: 4 }}\n >\n {totalCount}/{dataSource.length}\n </Typography.Text>\n <InfoCircleOutlined />\n </Tooltip>\n </div>\n );\n },\n filterDropdown({\n setSelectedKeys,\n selectedKeys,\n confirm,\n clearFilters,\n }) {\n return (\n <div\n style={{ padding: 8 }}\n onKeyDown={(e) => e.stopPropagation()}\n >\n <Input\n ref={searchInput}\n placeholder={`Search by file name`}\n value={selectedKeys[0]}\n onChange={(e) =>\n setSelectedKeys(e.target.value ? [e.target.value] : [])\n }\n onPressEnter={() =>\n handleSearch(selectedKeys as string[], confirm)\n }\n style={{ marginBottom: 8, display: 'block' }}\n />\n <Space>\n <Button\n type=\"primary\"\n onClick={() =>\n handleSearch(selectedKeys as string[], confirm)\n }\n icon={<SearchOutlined />}\n size=\"small\"\n style={{ width: 90 }}\n >\n Search\n </Button>\n <Button\n onClick={() => {\n if (clearFilters) {\n handleReset(clearFilters);\n }\n setSelectedKeys([]);\n handleSearch([], confirm);\n }}\n size=\"small\"\n style={{ width: 90 }}\n >\n Reset\n </Button>\n </Space>\n </div>\n );\n },\n filterSearch: true,\n filterIcon: (filtered) => (\n <Space>\n <Typography.Text\n type={searchText ? undefined : 'secondary'}\n style={{ fontWeight: 400 }}\n >\n {searchText || 'Search by file name'}\n </Typography.Text>\n <SearchOutlined\n style={{ color: filtered ? Color.Blue : undefined }}\n />\n </Space>\n ),\n onFilterDropdownOpenChange: (visible) => {\n if (visible) {\n setTimeout(() => searchInput.current?.focus(), 100);\n }\n },\n onFilter(v, r) {\n return getPathInfo(r).alias.indexOf(v as string) > -1;\n },\n render: (_v, r) => {\n const { alias, inNodeModules } = getPathInfo(r);\n return (\n <Space>\n <Tooltip title={r.path}>\n <Typography.Text copyable={{ text: r.path }}>\n {alias}\n </Typography.Text>\n </Tooltip>\n {inNodeModules ? <Tag color=\"warning\">node_modules</Tag> : null}\n <FileUpdateTypeTag type={getUpdateType(r)} />\n </Space>\n );\n },\n },\n getTargetColumnPropsForModuleRow(\n 'current',\n bModulesCount,\n cModulesCount,\n ),\n getTargetColumnPropsForModuleRow(\n 'baseline',\n bModulesCount,\n cModulesCount,\n ),\n {\n title: 'Actions',\n width: 200,\n render: (_v, r) => {\n return (\n <Space direction=\"vertical\" style={{ maxWidth: 170 }}>\n <ViewChanges\n text=\"View Changes\"\n file={r.path}\n data={[\n {\n baseline:\n baseline.moduleCodeMap[r.baseline?.id as number]\n ?.source,\n current:\n current.moduleCodeMap[r.current?.id as number]?.source,\n group: 'Source',\n },\n {\n baseline:\n baseline.moduleCodeMap[r.baseline?.id as number]\n ?.transformed,\n current:\n current.moduleCodeMap[r.current?.id as number]\n ?.transformed,\n group: 'Transformed Source',\n },\n {\n baseline:\n baseline.moduleCodeMap[r.baseline?.id as number]\n ?.parsedSource,\n current:\n current.moduleCodeMap[r.current?.id as number]\n ?.parsedSource,\n group: 'Parsed Source',\n },\n ]}\n />\n </Space>\n );\n },\n },\n ]}\n />\n );\n};\n"],"names":["ModuleHashPattern","getSizeColumnPropsForModuleRow","key","sizeKey","sortByChanged","sortByChangedFn","a","b","sorterFn","_v","r","size","Space","Typography","formatSize","formatDiffSize","Client","getTargetColumnPropsForModuleRow","bModulesCount","cModulesCount","setSortByChanged","useState","isB","count","title","upperFirst","diff","Graph","Divider","Tooltip","formatPercent","InfoCircleOutlined","undefined","UpdateType","v","getUpdateType","ModuleRowForAsset","data","baseline","current","bTotalModules","cTotalModules","bToTalChunks","cToTalChunks","bRoot","cRoot","searchText","setSearchText","searchInput","useRef","handleSearch","selectedKeys","confirm","handleReset","clearFilters","isBaseline","bModules","useMemo","e","cModule","cModules","getPathInfo","beautifyModulePath","dataSource","mods","map","Map","mod","modPath","t","totalCount","fileNameFilter","c","Table","setSelectedKeys","Input","Button","SearchOutlined","filtered","Color","visible","setTimeout","alias","inNodeModules","Tag","FileUpdateTypeTag","ViewChanges"],"mappings":"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"}
1
+ {"version":3,"file":"pages/Resources/BundleDiff/DiffContainer/row.mjs","sources":["../../../../../src/pages/Resources/BundleDiff/DiffContainer/row.tsx"],"sourcesContent":["import { InfoCircleOutlined, SearchOutlined } from '@ant-design/icons';\nimport {\n Button,\n Divider,\n Input,\n InputRef,\n Space,\n Table,\n Tag,\n Tooltip,\n Typography,\n} from 'antd';\nimport {\n ColumnGroupType,\n ColumnType,\n FilterConfirmProps,\n} from 'antd/es/table/interface';\nimport { upperFirst } from 'es-toolkit/compat';\nimport React, { useMemo, useRef, useState } from 'react';\nimport { Client } from '@rsdoctor/types';\nimport { CompareFn } from 'antd/lib/table/interface';\nimport { Color } from '../../../../constants';\nimport {\n beautifyModulePath,\n formatPercent,\n formatSize,\n} from '../../../../utils';\nimport { ViewChanges } from './changes';\nimport { FileUpdateTypeTag, getUpdateType } from './modules';\nimport {\n BundleDiffComponentCardProps,\n BundleDiffTableAssetsData,\n BundleDiffTableModulesData,\n} from './types';\nimport { UpdateType } from './constants';\nimport { formatDiffSize } from './utils';\nimport { Graph } from '@rsdoctor/utils/common';\n\nexport const ModuleHashPattern = /[a-fA-F0-9]{20,}/;\n\nexport const getSizeColumnPropsForModuleRow = (\n key: 'baseline' | 'current',\n sizeKey: 'parsedSize' | 'sourceSize',\n sortByChanged?: boolean,\n): ColumnType<BundleDiffTableModulesData> => {\n const sortByChangedFn: CompareFn<any> = (a, b) =>\n (a.current?.size[sizeKey] || 0) -\n (a.baseline?.size[sizeKey] || 0) -\n (b.current?.size[sizeKey] || 0) +\n (b.baseline?.size[sizeKey] || 0);\n\n const sorterFn: CompareFn<any> = sortByChanged\n ? (a, b) => sortByChangedFn(a, b)\n : (a, b) => (a[key]?.size[sizeKey] || 0) - (b[key]?.size[sizeKey] || 0);\n\n return {\n width: 200,\n sorter: (a, b) => sorterFn(a, b),\n render: (_v, r) => {\n if (!r[key]) return '-';\n const size = r[key]!.size[sizeKey];\n return (\n <Space>\n <Typography.Text>{formatSize(size)}</Typography.Text>\n {key === 'current'\n ? formatDiffSize(\n r.baseline?.size[sizeKey] || 0,\n size,\n (r.baseline?.size[sizeKey] || 0) > size\n ? Client.RsdoctorClientDiffState.Down\n : Client.RsdoctorClientDiffState.Up,\n )\n : null}\n </Space>\n );\n },\n };\n};\n\nexport const getTargetColumnPropsForModuleRow = (\n key: 'baseline' | 'current',\n bModulesCount: number,\n cModulesCount: number,\n): ColumnGroupType<BundleDiffTableModulesData> => {\n const [sortByChanged, setSortByChanged] = useState(false);\n\n const isB = key === 'baseline';\n return {\n title: () => {\n const count = isB ? bModulesCount : cModulesCount;\n const title = upperFirst(key);\n const diff = Graph.diffSize(bModulesCount, cModulesCount);\n return (\n <div>\n <Typography.Text>{title}</Typography.Text>\n <Divider type=\"vertical\" />\n <Tooltip\n title={\n <Space direction=\"vertical\">\n <Typography.Text style={{ color: 'inherit' }}>\n {title} modules is {count}\n </Typography.Text>\n {isB ? null : (\n <Typography.Text style={{ color: 'inherit' }}>\n Percent is {formatPercent(diff.percent)}\n </Typography.Text>\n )}\n </Space>\n }\n >\n <Space>\n <Typography.Text\n type=\"secondary\"\n style={{ fontSize: 10, fontWeight: 400 }}\n >\n {count}\n </Typography.Text>\n <InfoCircleOutlined />\n </Space>\n </Tooltip>\n </div>\n );\n },\n children: [\n {\n title: 'Source Size',\n ...getSizeColumnPropsForModuleRow(key, 'sourceSize', sortByChanged),\n },\n {\n title: 'Parsed Size',\n defaultSortOrder: isB ? undefined : 'descend',\n ...getSizeColumnPropsForModuleRow(key, 'parsedSize', sortByChanged),\n },\n ],\n filterSearch: true,\n filters: [\n {\n text: 'Show Changed',\n value: UpdateType.NotChanged,\n },\n {\n text: 'Show All',\n value: 'All',\n },\n ],\n onFilter(v, r) {\n if (v === UpdateType.NotChanged) {\n setSortByChanged(true);\n } else {\n setSortByChanged(false);\n }\n return v === UpdateType.NotChanged ? getUpdateType(r) !== v : true;\n },\n };\n};\n\nexport const ModuleRowForAsset: React.FC<\n { data: BundleDiffTableAssetsData } & Pick<\n BundleDiffComponentCardProps,\n 'baseline' | 'current'\n >\n> = ({ data, baseline, current }) => {\n const { modules: bTotalModules } = baseline.moduleGraph;\n const { modules: cTotalModules } = current.moduleGraph;\n const { chunks: bToTalChunks } = baseline.chunkGraph;\n const { chunks: cToTalChunks } = current.chunkGraph;\n const bRoot = baseline.root;\n const cRoot = current.root;\n\n const [searchText, setSearchText] = useState('');\n const searchInput = useRef<InputRef>(null);\n\n const handleSearch = (\n selectedKeys: string[],\n confirm: (param?: FilterConfirmProps) => void,\n ) => {\n confirm();\n setSearchText(selectedKeys[0]);\n };\n\n const handleReset = (clearFilters: () => void) => {\n clearFilters();\n setSearchText('');\n };\n\n const isBaseline = '__is_baseline__' as const;\n\n const bModules = useMemo(\n () =>\n data.baseline\n ? Graph.getModulesByAsset(data.baseline, bToTalChunks, bTotalModules)\n .map((e) => ({\n ...e,\n [isBaseline]: true,\n }))\n .filter((cModule) => !cModule.concatenationModules?.length)\n : [],\n [data, baseline],\n );\n const cModules = useMemo(\n () =>\n data.current\n ? Graph.getModulesByAsset(data.current, cToTalChunks, cTotalModules)\n .map((e) => ({\n ...e,\n [isBaseline]: false,\n }))\n .filter((cModule) => !cModule.concatenationModules?.length)\n : [],\n [data, current],\n );\n\n const getPathInfo = (r: BundleDiffTableModulesData) =>\n beautifyModulePath(r.path, r.__is_baseline__ ? bRoot : cRoot);\n\n const dataSource: BundleDiffTableModulesData[] = useMemo(() => {\n const mods = [...bModules, ...cModules];\n const map = new Map<string, BundleDiffTableModulesData>();\n\n // group by module.path\n mods.forEach((mod) => {\n const modPath =\n mod.identifier?.replace(ModuleHashPattern, '') ||\n mod.path?.replace(ModuleHashPattern, '');\n let t: BundleDiffTableModulesData = map.get(modPath)!;\n\n if (!t) {\n t = { path: modPath };\n }\n\n if (mod[isBaseline]) {\n t.baseline = mod;\n } else {\n t.current = mod;\n }\n map.set(modPath, t);\n });\n\n return [...map.values()];\n }, [bModules, cModules, searchText]);\n\n const { bModulesCount, cModulesCount, totalCount } = useMemo(() => {\n const fileNameFilter = (e: BundleDiffTableModulesData) =>\n getPathInfo(e).alias.indexOf(searchText) > -1;\n\n let b = dataSource.filter((e) => e.baseline);\n let c = dataSource.filter((e) => e.current);\n let totalCount = dataSource.length;\n\n if (searchText) {\n b = b.filter(fileNameFilter);\n c = c.filter(fileNameFilter);\n totalCount = dataSource.filter(fileNameFilter).length;\n }\n\n return {\n bModulesCount: b.length,\n cModulesCount: c.length,\n totalCount,\n };\n }, [dataSource, searchText]);\n\n return (\n <Table\n dataSource={dataSource}\n rowKey={(e) => e.path}\n size=\"small\"\n pagination={{\n size: 'small',\n }}\n bordered\n scroll={{ x: 1500 }}\n columns={[\n {\n fixed: 'left',\n title: () => {\n return (\n <div>\n <Typography.Text>\n Modules of {`\"${data.alias}\"`}\n </Typography.Text>\n <Divider type=\"vertical\" />\n <Tooltip\n title={\n <Space direction=\"vertical\">\n <Typography.Text style={{ color: 'inherit' }}>\n filtered modules: {totalCount}\n </Typography.Text>\n <Typography.Text style={{ color: 'inherit' }}>\n total modules: {dataSource.length}\n </Typography.Text>\n </Space>\n }\n >\n <Typography.Text\n type=\"secondary\"\n style={{ fontSize: 10, fontWeight: 400, marginRight: 4 }}\n >\n {totalCount}/{dataSource.length}\n </Typography.Text>\n <InfoCircleOutlined />\n </Tooltip>\n </div>\n );\n },\n filterDropdown({\n setSelectedKeys,\n selectedKeys,\n confirm,\n clearFilters,\n }) {\n return (\n <div\n style={{ padding: 8 }}\n onKeyDown={(e) => e.stopPropagation()}\n >\n <Input\n ref={searchInput}\n placeholder={`Search by file name`}\n value={selectedKeys[0]}\n onChange={(e) =>\n setSelectedKeys(e.target.value ? [e.target.value] : [])\n }\n onPressEnter={() =>\n handleSearch(selectedKeys as string[], confirm)\n }\n style={{ marginBottom: 8, display: 'block' }}\n />\n <Space>\n <Button\n type=\"primary\"\n onClick={() =>\n handleSearch(selectedKeys as string[], confirm)\n }\n icon={<SearchOutlined />}\n size=\"small\"\n style={{ width: 90 }}\n >\n Search\n </Button>\n <Button\n onClick={() => {\n if (clearFilters) {\n handleReset(clearFilters);\n }\n setSelectedKeys([]);\n handleSearch([], confirm);\n }}\n size=\"small\"\n style={{ width: 90 }}\n >\n Reset\n </Button>\n </Space>\n </div>\n );\n },\n filterSearch: true,\n filterIcon: (filtered) => (\n <Space>\n <Typography.Text\n type={searchText ? undefined : 'secondary'}\n style={{ fontWeight: 400 }}\n >\n {searchText || 'Search by file name'}\n </Typography.Text>\n <SearchOutlined\n style={{ color: filtered ? Color.Blue : undefined }}\n />\n </Space>\n ),\n onFilterDropdownOpenChange: (visible) => {\n if (visible) {\n setTimeout(() => searchInput.current?.focus(), 100);\n }\n },\n onFilter(v, r) {\n return getPathInfo(r).alias.indexOf(v as string) > -1;\n },\n render: (_v, r) => {\n const { alias, inNodeModules } = getPathInfo(r);\n return (\n <Space>\n <Tooltip title={r.path}>\n <Typography.Text copyable={{ text: r.path }}>\n {alias}\n </Typography.Text>\n </Tooltip>\n {inNodeModules ? <Tag color=\"warning\">node_modules</Tag> : null}\n <FileUpdateTypeTag type={getUpdateType(r)} />\n </Space>\n );\n },\n },\n getTargetColumnPropsForModuleRow(\n 'current',\n bModulesCount,\n cModulesCount,\n ),\n getTargetColumnPropsForModuleRow(\n 'baseline',\n bModulesCount,\n cModulesCount,\n ),\n {\n title: 'Actions',\n width: 200,\n render: (_v, r) => {\n return (\n <Space direction=\"vertical\" style={{ maxWidth: 170 }}>\n <ViewChanges\n text=\"View Changes\"\n file={r.path}\n data={[\n {\n baseline:\n baseline.moduleCodeMap[r.baseline?.id as number]\n ?.source,\n current:\n current.moduleCodeMap[r.current?.id as number]?.source,\n group: 'Source',\n },\n {\n baseline:\n baseline.moduleCodeMap[r.baseline?.id as number]\n ?.transformed,\n current:\n current.moduleCodeMap[r.current?.id as number]\n ?.transformed,\n group: 'Transformed Source',\n },\n {\n baseline:\n baseline.moduleCodeMap[r.baseline?.id as number]\n ?.parsedSource,\n current:\n current.moduleCodeMap[r.current?.id as number]\n ?.parsedSource,\n group: 'Parsed Source',\n },\n ]}\n />\n </Space>\n );\n },\n },\n ]}\n />\n );\n};\n"],"names":["ModuleHashPattern","getSizeColumnPropsForModuleRow","key","sizeKey","sortByChanged","sortByChangedFn","a","b","sorterFn","_v","r","size","Space","Typography","formatSize","formatDiffSize","Client","getTargetColumnPropsForModuleRow","bModulesCount","cModulesCount","setSortByChanged","useState","isB","count","title","upperFirst","diff","Graph","Divider","Tooltip","formatPercent","InfoCircleOutlined","undefined","UpdateType","v","getUpdateType","ModuleRowForAsset","data","baseline","current","bTotalModules","cTotalModules","bToTalChunks","cToTalChunks","bRoot","cRoot","searchText","setSearchText","searchInput","useRef","handleSearch","selectedKeys","confirm","handleReset","clearFilters","isBaseline","bModules","useMemo","e","cModule","cModules","getPathInfo","beautifyModulePath","dataSource","mods","map","Map","mod","modPath","t","totalCount","fileNameFilter","c","Table","setSelectedKeys","Input","Button","SearchOutlined","filtered","Color","visible","setTimeout","alias","inNodeModules","Tag","FileUpdateTypeTag","ViewChanges"],"mappings":"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"}
@@ -1,9 +1,9 @@
1
1
  export * as Overall from './Overall/index.js';
2
2
  export * as BundleSize from './BundleSize/index.js';
3
3
  export * as ModuleAnalyze from './ModuleAnalyze/index.js';
4
- export * as LoaderTimeline from './WebpackLoaders/Overall/index.js';
5
- export * as LoaderFiles from './WebpackLoaders/Analysis/index.js';
6
- export * as PluginsAnalyze from './WebpackPlugins/index.js';
4
+ export * as LoaderTimeline from './Loaders/Overall/index.js';
5
+ export * as LoaderFiles from './Loaders/Analysis/index.js';
6
+ export * as PluginsAnalyze from './Plugins/index.js';
7
7
  export * as ModuleResolve from './ModuleResolve/index.js';
8
8
  export * as RuleIndex from './Resources/RuleIndex/index.js';
9
9
  export * as TreeShaking from './TreeShaking/index.js';
@@ -1,12 +1,12 @@
1
1
  import * as __rspack_external__Overall_index_mjs_0ded43f9 from "./Overall/index.mjs";
2
2
  import * as __rspack_external__BundleSize_index_mjs_d0a2fb23 from "./BundleSize/index.mjs";
3
3
  import * as __rspack_external__ModuleAnalyze_index_mjs_4385c65f from "./ModuleAnalyze/index.mjs";
4
- import * as __rspack_external__WebpackLoaders_Overall_index_mjs_7fb4d495 from "./WebpackLoaders/Overall/index.mjs";
5
- import * as __rspack_external__WebpackLoaders_Analysis_index_mjs_a1d3659a from "./WebpackLoaders/Analysis/index.mjs";
6
- import * as __rspack_external__WebpackPlugins_index_mjs_a5b22b8e from "./WebpackPlugins/index.mjs";
4
+ import * as __rspack_external__Loaders_Overall_index_mjs_40901be5 from "./Loaders/Overall/index.mjs";
5
+ import * as __rspack_external__Loaders_Analysis_index_mjs_617e53eb from "./Loaders/Analysis/index.mjs";
6
+ import * as __rspack_external__Plugins_index_mjs_7b6a192c from "./Plugins/index.mjs";
7
7
  import * as __rspack_external__ModuleResolve_index_mjs_2463b148 from "./ModuleResolve/index.mjs";
8
8
  import * as __rspack_external__Resources_RuleIndex_index_mjs_458631cc from "./Resources/RuleIndex/index.mjs";
9
9
  import * as __rspack_external__TreeShaking_index_mjs_1daf5cdb from "./TreeShaking/index.mjs";
10
10
  import * as __rspack_external__Resources_BundleDiff_index_mjs_3b739fff from "./Resources/BundleDiff/index.mjs";
11
11
  import * as __rspack_external__Uploader_index_mjs_e3f3ea84 from "./Uploader/index.mjs";
12
- export { __rspack_external__BundleSize_index_mjs_d0a2fb23 as BundleSize, __rspack_external__ModuleAnalyze_index_mjs_4385c65f as ModuleAnalyze, __rspack_external__ModuleResolve_index_mjs_2463b148 as ModuleResolve, __rspack_external__Overall_index_mjs_0ded43f9 as Overall, __rspack_external__Resources_BundleDiff_index_mjs_3b739fff as BundleDiff, __rspack_external__Resources_RuleIndex_index_mjs_458631cc as RuleIndex, __rspack_external__TreeShaking_index_mjs_1daf5cdb as TreeShaking, __rspack_external__Uploader_index_mjs_e3f3ea84 as Uploader, __rspack_external__WebpackLoaders_Analysis_index_mjs_a1d3659a as LoaderFiles, __rspack_external__WebpackLoaders_Overall_index_mjs_7fb4d495 as LoaderTimeline, __rspack_external__WebpackPlugins_index_mjs_a5b22b8e as PluginsAnalyze };
12
+ export { __rspack_external__BundleSize_index_mjs_d0a2fb23 as BundleSize, __rspack_external__Loaders_Analysis_index_mjs_617e53eb as LoaderFiles, __rspack_external__Loaders_Overall_index_mjs_40901be5 as LoaderTimeline, __rspack_external__ModuleAnalyze_index_mjs_4385c65f as ModuleAnalyze, __rspack_external__ModuleResolve_index_mjs_2463b148 as ModuleResolve, __rspack_external__Overall_index_mjs_0ded43f9 as Overall, __rspack_external__Plugins_index_mjs_7b6a192c as PluginsAnalyze, __rspack_external__Resources_BundleDiff_index_mjs_3b739fff as BundleDiff, __rspack_external__Resources_RuleIndex_index_mjs_458631cc as RuleIndex, __rspack_external__TreeShaking_index_mjs_1daf5cdb as TreeShaking, __rspack_external__Uploader_index_mjs_e3f3ea84 as Uploader };
@@ -19,6 +19,6 @@ export declare abstract class BaseDataLoader implements Manifest.ManifestDataLoa
19
19
  abstract loadData<T extends Manifest.RsdoctorManifestMappingKeys>(key: T): Promise<void | Manifest.InferManifestDataValue<T>>;
20
20
  abstract isLocal(): boolean;
21
21
  abstract loadAPI<T extends SDK.ServerAPI.API, B extends SDK.ServerAPI.InferRequestBodyType<T> = SDK.ServerAPI.InferRequestBodyType<T>, R extends SDK.ServerAPI.InferResponseType<T> = SDK.ServerAPI.InferResponseType<T>>(...args: B extends void ? [api: T] : [api: T, body: B]): Promise<R>;
22
- abstract onDataUpdate<T extends SDK.ServerAPI.API | SDK.ServerAPI.APIExtends>(api: T, fn: (response: SDK.ServerAPI.SocketResponseType<T>) => void): void;
23
- abstract removeOnDataUpdate<T extends SDK.ServerAPI.API | SDK.ServerAPI.APIExtends>(api: T, fn: (response: SDK.ServerAPI.SocketResponseType<T>) => void): void;
22
+ abstract onDataUpdate<T extends SDK.ServerAPI.API | SDK.ServerAPI.APIExtends>(api: T, body: SDK.ServerAPI.InferRequestBodyType<T, null> | null, fn: (response: SDK.ServerAPI.SocketResponseType<T>) => void): void;
23
+ abstract removeOnDataUpdate<T extends SDK.ServerAPI.API | SDK.ServerAPI.APIExtends>(api: T, body: SDK.ServerAPI.InferRequestBodyType<T, null> | null, fn: (response: SDK.ServerAPI.SocketResponseType<T>) => void): void;
24
24
  }
@@ -1 +1 @@
1
- {"version":3,"file":"utils/data/base.mjs","sources":["../../../src/utils/data/base.ts"],"sourcesContent":["import { Common, Manifest, SDK } from '@rsdoctor/types';\nimport { Data } from '@rsdoctor/utils/common';\n\nexport abstract class BaseDataLoader implements Manifest.ManifestDataLoader {\n protected pool = new Map<string, Promise<unknown>>();\n\n protected loader: Data.APIDataLoader;\n\n protected disposed = false;\n\n protected shardingDataMap = new Map<\n keyof Manifest.RsdoctorManifestData | string,\n Promise<Manifest.RsdoctorManifestData[keyof Manifest.RsdoctorManifestData]>\n >();\n\n constructor(protected manifest: Manifest.RsdoctorManifestWithShardingFiles) {\n this.loader = new Data.APIDataLoader(this);\n console.log('[DataLoader] isLocal: ', this.isLocal());\n }\n\n protected get<T extends keyof Manifest.RsdoctorManifestWithShardingFiles>(\n key: T,\n ): void | Manifest.RsdoctorManifestWithShardingFiles[T] {\n if (!this.manifest) return;\n return this.manifest[key];\n }\n\n protected getData<T extends keyof Manifest.RsdoctorManifestData>(\n key: T,\n scope: 'data' | 'cloudData' = 'data',\n ): void | Manifest.RsdoctorManifestWithShardingFiles['data'][T] {\n const data = this.get(scope);\n if (!data) return;\n return data[key];\n }\n\n protected getKeys(key: string) {\n return key.split('.');\n }\n\n protected joinKeys(keys: string[]) {\n return keys.join('.');\n }\n\n public dispose() {\n this.disposed = true;\n }\n\n public limit<T>(\n key: string,\n fn: Common.Function<unknown[], Promise<T>>,\n ): Promise<T> {\n if (this.pool.has(key)) {\n return this.pool.get(key) as Promise<T>;\n }\n const res = fn().finally(() => this.pool.delete(key));\n this.pool.set(key, res);\n return res;\n }\n\n public log(...args: unknown[]) {\n console.log(`[${this.constructor.name}]`, ...args);\n }\n\n public async loadManifest() {\n return this.manifest;\n }\n\n abstract loadData<T extends string, P>(key: T): Promise<void | P>;\n\n abstract loadData<T extends Manifest.RsdoctorManifestMappingKeys>(\n key: T,\n ): Promise<void | Manifest.InferManifestDataValue<T>>;\n\n abstract isLocal(): boolean;\n\n abstract loadAPI<\n T extends SDK.ServerAPI.API,\n B extends\n SDK.ServerAPI.InferRequestBodyType<T> = SDK.ServerAPI.InferRequestBodyType<T>,\n R extends\n SDK.ServerAPI.InferResponseType<T> = SDK.ServerAPI.InferResponseType<T>,\n >(...args: B extends void ? [api: T] : [api: T, body: B]): Promise<R>;\n\n public abstract onDataUpdate<\n T extends SDK.ServerAPI.API | SDK.ServerAPI.APIExtends,\n >(api: T, fn: (response: SDK.ServerAPI.SocketResponseType<T>) => void): void;\n\n public abstract removeOnDataUpdate<\n T extends SDK.ServerAPI.API | SDK.ServerAPI.APIExtends,\n >(api: T, fn: (response: SDK.ServerAPI.SocketResponseType<T>) => void): void;\n}\n"],"names":["BaseDataLoader","key","scope","data","keys","fn","res","args","console","manifest","Map","Data"],"mappings":";;;;;;;;;;;AAGO,MAAeA;IAiBV,IACRC,GAAM,EACgD;QACtD,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE;QACpB,OAAO,IAAI,CAAC,QAAQ,CAACA,IAAI;IAC3B;IAEU,QACRA,GAAM,EACNC,QAA8B,MAAM,EAC0B;QAC9D,MAAMC,OAAO,IAAI,CAAC,GAAG,CAACD;QACtB,IAAI,CAACC,MAAM;QACX,OAAOA,IAAI,CAACF,IAAI;IAClB;IAEU,QAAQA,GAAW,EAAE;QAC7B,OAAOA,IAAI,KAAK,CAAC;IACnB;IAEU,SAASG,IAAc,EAAE;QACjC,OAAOA,KAAK,IAAI,CAAC;IACnB;IAEO,UAAU;QACf,IAAI,CAAC,QAAQ,GAAG;IAClB;IAEO,MACLH,GAAW,EACXI,EAA0C,EAC9B;QACZ,IAAI,IAAI,CAAC,IAAI,CAAC,GAAG,CAACJ,MAChB,OAAO,IAAI,CAAC,IAAI,CAAC,GAAG,CAACA;QAEvB,MAAMK,MAAMD,KAAK,OAAO,CAAC,IAAM,IAAI,CAAC,IAAI,CAAC,MAAM,CAACJ;QAChD,IAAI,CAAC,IAAI,CAAC,GAAG,CAACA,KAAKK;QACnB,OAAOA;IACT;IAEO,IAAI,GAAGC,IAAe,EAAE;QAC7BC,QAAQ,GAAG,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC,KAAKD;IAC/C;IAEA,MAAa,eAAe;QAC1B,OAAO,IAAI,CAAC,QAAQ;IACtB;IAnDA,YAAsBE,QAAoD,CAAE;;QAX5E,uBAAU,QAAV;QAEA,uBAAU,UAAV;QAEA,uBAAU,YAAV;QAEA,uBAAU,mBAAV;aAKsBA,QAAQ,GAARA;aAXZ,IAAI,GAAG,IAAIC;aAIX,QAAQ,GAAG;aAEX,eAAe,GAAG,IAAIA;QAM9B,IAAI,CAAC,MAAM,GAAG,IAAIC,KAAK,aAAa,CAAC,IAAI;QACzCH,QAAQ,GAAG,CAAC,0BAA0B,IAAI,CAAC,OAAO;IACpD;AAyEF"}
1
+ {"version":3,"file":"utils/data/base.mjs","sources":["../../../src/utils/data/base.ts"],"sourcesContent":["import { Common, Manifest, SDK } from '@rsdoctor/types';\nimport { Data } from '@rsdoctor/utils/common';\n\nexport abstract class BaseDataLoader implements Manifest.ManifestDataLoader {\n protected pool = new Map<string, Promise<unknown>>();\n\n protected loader: Data.APIDataLoader;\n\n protected disposed = false;\n\n protected shardingDataMap = new Map<\n keyof Manifest.RsdoctorManifestData | string,\n Promise<Manifest.RsdoctorManifestData[keyof Manifest.RsdoctorManifestData]>\n >();\n\n constructor(protected manifest: Manifest.RsdoctorManifestWithShardingFiles) {\n this.loader = new Data.APIDataLoader(this);\n console.log('[DataLoader] isLocal: ', this.isLocal());\n }\n\n protected get<T extends keyof Manifest.RsdoctorManifestWithShardingFiles>(\n key: T,\n ): void | Manifest.RsdoctorManifestWithShardingFiles[T] {\n if (!this.manifest) return;\n return this.manifest[key];\n }\n\n protected getData<T extends keyof Manifest.RsdoctorManifestData>(\n key: T,\n scope: 'data' | 'cloudData' = 'data',\n ): void | Manifest.RsdoctorManifestWithShardingFiles['data'][T] {\n const data = this.get(scope);\n if (!data) return;\n return data[key];\n }\n\n protected getKeys(key: string) {\n return key.split('.');\n }\n\n protected joinKeys(keys: string[]) {\n return keys.join('.');\n }\n\n public dispose() {\n this.disposed = true;\n }\n\n public limit<T>(\n key: string,\n fn: Common.Function<unknown[], Promise<T>>,\n ): Promise<T> {\n if (this.pool.has(key)) {\n return this.pool.get(key) as Promise<T>;\n }\n const res = fn().finally(() => this.pool.delete(key));\n this.pool.set(key, res);\n return res;\n }\n\n public log(...args: unknown[]) {\n console.log(`[${this.constructor.name}]`, ...args);\n }\n\n public async loadManifest() {\n return this.manifest;\n }\n\n abstract loadData<T extends string, P>(key: T): Promise<void | P>;\n\n abstract loadData<T extends Manifest.RsdoctorManifestMappingKeys>(\n key: T,\n ): Promise<void | Manifest.InferManifestDataValue<T>>;\n\n abstract isLocal(): boolean;\n\n abstract loadAPI<\n T extends SDK.ServerAPI.API,\n B extends SDK.ServerAPI.InferRequestBodyType<T> =\n SDK.ServerAPI.InferRequestBodyType<T>,\n R extends SDK.ServerAPI.InferResponseType<T> =\n SDK.ServerAPI.InferResponseType<T>,\n >(...args: B extends void ? [api: T] : [api: T, body: B]): Promise<R>;\n\n public abstract onDataUpdate<\n T extends SDK.ServerAPI.API | SDK.ServerAPI.APIExtends,\n >(\n api: T,\n body: SDK.ServerAPI.InferRequestBodyType<T, null> | null,\n fn: (response: SDK.ServerAPI.SocketResponseType<T>) => void,\n ): void;\n\n public abstract removeOnDataUpdate<\n T extends SDK.ServerAPI.API | SDK.ServerAPI.APIExtends,\n >(\n api: T,\n body: SDK.ServerAPI.InferRequestBodyType<T, null> | null,\n fn: (response: SDK.ServerAPI.SocketResponseType<T>) => void,\n ): void;\n}\n"],"names":["BaseDataLoader","key","scope","data","keys","fn","res","args","console","manifest","Map","Data"],"mappings":";;;;;;;;;;;AAGO,MAAeA;IAiBV,IACRC,GAAM,EACgD;QACtD,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE;QACpB,OAAO,IAAI,CAAC,QAAQ,CAACA,IAAI;IAC3B;IAEU,QACRA,GAAM,EACNC,QAA8B,MAAM,EAC0B;QAC9D,MAAMC,OAAO,IAAI,CAAC,GAAG,CAACD;QACtB,IAAI,CAACC,MAAM;QACX,OAAOA,IAAI,CAACF,IAAI;IAClB;IAEU,QAAQA,GAAW,EAAE;QAC7B,OAAOA,IAAI,KAAK,CAAC;IACnB;IAEU,SAASG,IAAc,EAAE;QACjC,OAAOA,KAAK,IAAI,CAAC;IACnB;IAEO,UAAU;QACf,IAAI,CAAC,QAAQ,GAAG;IAClB;IAEO,MACLH,GAAW,EACXI,EAA0C,EAC9B;QACZ,IAAI,IAAI,CAAC,IAAI,CAAC,GAAG,CAACJ,MAChB,OAAO,IAAI,CAAC,IAAI,CAAC,GAAG,CAACA;QAEvB,MAAMK,MAAMD,KAAK,OAAO,CAAC,IAAM,IAAI,CAAC,IAAI,CAAC,MAAM,CAACJ;QAChD,IAAI,CAAC,IAAI,CAAC,GAAG,CAACA,KAAKK;QACnB,OAAOA;IACT;IAEO,IAAI,GAAGC,IAAe,EAAE;QAC7BC,QAAQ,GAAG,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC,KAAKD;IAC/C;IAEA,MAAa,eAAe;QAC1B,OAAO,IAAI,CAAC,QAAQ;IACtB;IAnDA,YAAsBE,QAAoD,CAAE;;QAX5E,uBAAU,QAAV;QAEA,uBAAU,UAAV;QAEA,uBAAU,YAAV;QAEA,uBAAU,mBAAV;aAKsBA,QAAQ,GAARA;aAXZ,IAAI,GAAG,IAAIC;aAIX,QAAQ,GAAG;aAEX,eAAe,GAAG,IAAIA;QAM9B,IAAI,CAAC,MAAM,GAAG,IAAIC,KAAK,aAAa,CAAC,IAAI;QACzCH,QAAQ,GAAG,CAAC,0BAA0B,IAAI,CAAC,OAAO;IACpD;AAiFF"}
@@ -1,7 +1,13 @@
1
1
  import { Common, Manifest, SDK } from '@rsdoctor/types';
2
2
  import { BaseDataLoader } from './base.js';
3
+ type DataUpdateAPI = SDK.ServerAPI.API | SDK.ServerAPI.APIExtends;
4
+ type DataUpdateSubscription = {
5
+ api: DataUpdateAPI;
6
+ body: SDK.ServerAPI.InferRequestBodyType<DataUpdateAPI, null> | null;
7
+ listeners: Set<Common.Function>;
8
+ };
3
9
  export declare class LocalServerDataLoader extends BaseDataLoader {
4
- protected events: Map<SDK.ServerAPI.API | SDK.ServerAPI.APIExtends, Set<Common.Function>>;
10
+ protected events: Map<string, DataUpdateSubscription>;
5
11
  isLocal(): boolean;
6
12
  loadData<T extends keyof Manifest.RsdoctorManifestData>(key: T): Promise<void | Manifest.RsdoctorManifestData[T]>;
7
13
  loadAPI<T extends SDK.ServerAPI.API, B extends SDK.ServerAPI.InferRequestBodyType<T> = SDK.ServerAPI.InferRequestBodyType<T>, R extends SDK.ServerAPI.InferResponseType<T> = SDK.ServerAPI.InferResponseType<T>>(...args: B extends void ? [api: T] : [api: T, body: B]): Promise<R>;
@@ -9,6 +15,7 @@ export declare class LocalServerDataLoader extends BaseDataLoader {
9
15
  /**
10
16
  * add event listener when received data from server.
11
17
  */
12
- onDataUpdate<T extends SDK.ServerAPI.API | SDK.ServerAPI.APIExtends>(api: T, fn: (response: SDK.ServerAPI.SocketResponseType<T>) => void): void;
13
- removeOnDataUpdate<T extends SDK.ServerAPI.API | SDK.ServerAPI.APIExtends>(api: T, fn: (response: SDK.ServerAPI.SocketResponseType<T>) => void): void;
18
+ onDataUpdate<T extends SDK.ServerAPI.API | SDK.ServerAPI.APIExtends>(api: T, body: SDK.ServerAPI.InferRequestBodyType<T, null> | null, fn: (response: SDK.ServerAPI.SocketResponseType<T>) => void): void;
19
+ removeOnDataUpdate<T extends SDK.ServerAPI.API | SDK.ServerAPI.APIExtends>(api: T, body: SDK.ServerAPI.InferRequestBodyType<T, null> | null, fn: (response: SDK.ServerAPI.SocketResponseType<T>) => void): void;
14
20
  }
21
+ export {};
@@ -2,7 +2,8 @@ import { Manifest } from "@rsdoctor/utils/common";
2
2
  import { SDK } from "@rsdoctor/types";
3
3
  import { get } from "es-toolkit/compat";
4
4
  import { BaseDataLoader } from "./base.mjs";
5
- import { getSocket } from "../socket.mjs";
5
+ import { postServerAPI } from "../request.mjs";
6
+ import { requestServerAPI, subscribeServerAPI, unsubscribeServerAPI } from "../socket.mjs";
6
7
  function _define_property(obj, key, value) {
7
8
  if (key in obj) Object.defineProperty(obj, key, {
8
9
  value: value,
@@ -25,12 +26,11 @@ class LocalServerDataLoader extends BaseDataLoader {
25
26
  let res = data;
26
27
  if (Manifest.isShardingData(res)) {
27
28
  if (!this.shardingDataMap.has(key)) {
28
- const task = new Promise((resolve)=>{
29
- getSocket().emit(SDK.ServerAPI.API.LoadDataByKey, {
30
- key
31
- }, (res)=>{
32
- resolve(res.res);
33
- });
29
+ const task = postServerAPI(SDK.ServerAPI.API.LoadDataByKey, {
30
+ key
31
+ }).catch((err)=>{
32
+ this.log("loadData error: ", res, key);
33
+ throw err;
34
34
  });
35
35
  this.shardingDataMap.set(key, task);
36
36
  }
@@ -45,31 +45,44 @@ class LocalServerDataLoader extends BaseDataLoader {
45
45
  const [api, body] = args;
46
46
  const key = body ? `${api}_${JSON.stringify(body)}` : `${api}`;
47
47
  const socketPort = this.get('__SOCKET__PORT__') ?? '';
48
- return this.limit(key, async ()=>new Promise((resolve)=>{
49
- getSocket(socketPort).emit(api, body, (res)=>{
50
- resolve(res.res);
51
- });
52
- }));
48
+ return this.limit(key, async ()=>{
49
+ try {
50
+ return await requestServerAPI(api, body, socketPort);
51
+ } catch (err) {
52
+ this.log("loadAPI error: ", key);
53
+ throw err;
54
+ }
55
+ });
53
56
  }
54
57
  dispose() {
55
58
  super.dispose();
56
- this.events.forEach((evs, api)=>{
57
- evs.forEach((ev)=>{
58
- this.removeOnDataUpdate(api, ev);
59
+ this.events.forEach(({ api, body, listeners })=>{
60
+ listeners.forEach((listener)=>{
61
+ this.removeOnDataUpdate(api, body, listener);
59
62
  });
60
- evs.clear();
63
+ listeners.clear();
61
64
  });
62
65
  this.events.clear();
63
66
  }
64
- onDataUpdate(api, fn) {
65
- if (!this.events.has(api)) this.events.set(api, new Set());
66
- if (this.events.get(api).has(fn)) return;
67
- this.events.get(api).add(fn);
68
- getSocket().on(api, fn);
67
+ onDataUpdate(api, body, fn) {
68
+ const normalizedBody = body ?? null;
69
+ const key = `${api}::${JSON.stringify(normalizedBody)}`;
70
+ if (!this.events.has(key)) this.events.set(key, {
71
+ api,
72
+ body: normalizedBody,
73
+ listeners: new Set()
74
+ });
75
+ const subscription = this.events.get(key);
76
+ if (subscription.listeners.has(fn)) return;
77
+ subscription.listeners.add(fn);
78
+ const socketPort = this.get('__SOCKET__PORT__') ?? '';
79
+ subscribeServerAPI(api, normalizedBody, fn, socketPort);
69
80
  }
70
- removeOnDataUpdate(api, fn) {
71
- getSocket().off(api, fn);
72
- this.events.get(api).delete(fn);
81
+ removeOnDataUpdate(api, body, fn) {
82
+ const key = `${api}::${JSON.stringify(body ?? null)}`;
83
+ const socketPort = this.get('__SOCKET__PORT__') ?? '';
84
+ unsubscribeServerAPI(api, body, fn, socketPort);
85
+ this.events.get(key)?.listeners.delete(fn);
73
86
  }
74
87
  constructor(...args){
75
88
  super(...args), _define_property(this, "events", new Map());
@@ -1 +1 @@
1
- {"version":3,"file":"utils/data/local.mjs","sources":["../../../src/utils/data/local.ts"],"sourcesContent":["import { Manifest as ManifestShared } from '@rsdoctor/utils/common';\nimport { Common, Manifest, SDK } from '@rsdoctor/types';\nimport { get } from 'es-toolkit/compat';\nimport { BaseDataLoader } from './base';\nimport { getSocket } from '../socket';\n\nexport class LocalServerDataLoader extends BaseDataLoader {\n protected events: Map<\n SDK.ServerAPI.API | SDK.ServerAPI.APIExtends,\n Set<Common.Function>\n > = new Map();\n\n public isLocal() {\n return true;\n }\n\n public async loadData<T extends keyof Manifest.RsdoctorManifestData>(\n key: T,\n ): Promise<void | Manifest.RsdoctorManifestData[T]>;\n\n public async loadData(key: string): Promise<unknown> {\n return this.limit(key, async () => {\n const [scope, ...rest] = this.getKeys(key);\n const data = this.getData(scope as keyof Manifest.RsdoctorManifestData);\n\n if (!data) return;\n\n let res: unknown = data;\n\n // sharding files\n if (ManifestShared.isShardingData(res)) {\n if (!this.shardingDataMap.has(key)) {\n const task = new Promise((resolve) => {\n getSocket().emit(\n SDK.ServerAPI.API.LoadDataByKey,\n { key },\n (\n res: SDK.ServerAPI.SocketResponseType<SDK.ServerAPI.API.LoadDataByKey>,\n ) => {\n resolve(res.res);\n },\n );\n });\n // const task = postServerAPI(SDK.ServerAPI.API.LoadDataByKey, { key }).catch((err) => {\n // this.log(`loadData error: `, res, key);\n // throw err;\n // });\n // save with every key\n this.shardingDataMap.set(key, task);\n }\n\n res = await this.shardingDataMap.get(key);\n this.shardingDataMap.delete(key);\n return res;\n }\n\n return rest.length > 0 ? get(res, this.joinKeys(rest)) : res;\n });\n }\n\n public async loadAPI<\n T extends SDK.ServerAPI.API,\n B extends\n SDK.ServerAPI.InferRequestBodyType<T> = SDK.ServerAPI.InferRequestBodyType<T>,\n R extends\n SDK.ServerAPI.InferResponseType<T> = SDK.ServerAPI.InferResponseType<T>,\n >(...args: B extends void ? [api: T] : [api: T, body: B]): Promise<R> {\n const [api, body] = args;\n // request limitation key\n const key = body ? `${api}_${JSON.stringify(body)}` : `${api}`;\n const socketPort = this.get('__SOCKET__PORT__') ?? '';\n\n return this.limit(key, async () => {\n return new Promise((resolve) => {\n getSocket(socketPort).emit(\n api,\n body,\n (res: SDK.ServerAPI.SocketResponseType<T>) => {\n resolve(res.res as R);\n },\n );\n });\n // const res = await postServerAPI(...args).catch((err) => {\n // this.log(`loadAPI error: `, key);\n // throw err;\n // });\n\n // return res as R;\n });\n }\n\n public dispose() {\n super.dispose();\n this.events.forEach((evs, api) => {\n evs.forEach((ev) => {\n this.removeOnDataUpdate(api, ev);\n });\n evs.clear();\n });\n this.events.clear();\n }\n\n /**\n * add event listener when received data from server.\n */\n public onDataUpdate<T extends SDK.ServerAPI.API | SDK.ServerAPI.APIExtends>(\n api: T,\n fn: (response: SDK.ServerAPI.SocketResponseType<T>) => void,\n ) {\n if (!this.events.has(api)) {\n this.events.set(api, new Set());\n }\n\n if (this.events.get(api)!.has(fn)) {\n return;\n }\n\n this.events.get(api)!.add(fn);\n getSocket().on(api as string, fn);\n }\n\n public removeOnDataUpdate<\n T extends SDK.ServerAPI.API | SDK.ServerAPI.APIExtends,\n >(api: T, fn: (response: SDK.ServerAPI.SocketResponseType<T>) => void) {\n getSocket().off(api as string, fn);\n this.events.get(api)!.delete(fn);\n }\n}\n"],"names":["LocalServerDataLoader","BaseDataLoader","key","scope","rest","data","res","ManifestShared","task","Promise","resolve","getSocket","SDK","get","args","api","body","JSON","socketPort","evs","ev","fn","Set","Map"],"mappings":";;;;;;;;;;;;;;;AAMO,MAAMA,8BAA8BC;IAMlC,UAAU;QACf,OAAO;IACT;IAMA,MAAa,SAASC,GAAW,EAAoB;QACnD,OAAO,IAAI,CAAC,KAAK,CAACA,KAAK;YACrB,MAAM,CAACC,OAAO,GAAGC,KAAK,GAAG,IAAI,CAAC,OAAO,CAACF;YACtC,MAAMG,OAAO,IAAI,CAAC,OAAO,CAACF;YAE1B,IAAI,CAACE,MAAM;YAEX,IAAIC,MAAeD;YAGnB,IAAIE,SAAAA,cAA6B,CAACD,MAAM;gBACtC,IAAI,CAAC,IAAI,CAAC,eAAe,CAAC,GAAG,CAACJ,MAAM;oBAClC,MAAMM,OAAO,IAAIC,QAAQ,CAACC;wBACxBC,YAAY,IAAI,CACdC,IAAI,SAAS,CAAC,GAAG,CAAC,aAAa,EAC/B;4BAAEV;wBAAI,GACN,CACEI;4BAEAI,QAAQJ,IAAI,GAAG;wBACjB;oBAEJ;oBAMA,IAAI,CAAC,eAAe,CAAC,GAAG,CAACJ,KAAKM;gBAChC;gBAEAF,MAAM,MAAM,IAAI,CAAC,eAAe,CAAC,GAAG,CAACJ;gBACrC,IAAI,CAAC,eAAe,CAAC,MAAM,CAACA;gBAC5B,OAAOI;YACT;YAEA,OAAOF,KAAK,MAAM,GAAG,IAAIS,IAAIP,KAAK,IAAI,CAAC,QAAQ,CAACF,SAASE;QAC3D;IACF;IAEA,MAAa,QAMX,GAAGQ,IAAmD,EAAc;QACpE,MAAM,CAACC,KAAKC,KAAK,GAAGF;QAEpB,MAAMZ,MAAMc,OAAO,GAAGD,IAAI,CAAC,EAAEE,KAAK,SAAS,CAACD,OAAO,GAAG,GAAGD,KAAK;QAC9D,MAAMG,aAAa,IAAI,CAAC,GAAG,CAAC,uBAAuB;QAEnD,OAAO,IAAI,CAAC,KAAK,CAAChB,KAAK,UACd,IAAIO,QAAQ,CAACC;gBAClBC,UAAUO,YAAY,IAAI,CACxBH,KACAC,MACA,CAACV;oBACCI,QAAQJ,IAAI,GAAG;gBACjB;YAEJ;IAQJ;IAEO,UAAU;QACf,KAAK,CAAC;QACN,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,CAACa,KAAKJ;YACxBI,IAAI,OAAO,CAAC,CAACC;gBACX,IAAI,CAAC,kBAAkB,CAACL,KAAKK;YAC/B;YACAD,IAAI,KAAK;QACX;QACA,IAAI,CAAC,MAAM,CAAC,KAAK;IACnB;IAKO,aACLJ,GAAM,EACNM,EAA2D,EAC3D;QACA,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,CAACN,MACnB,IAAI,CAAC,MAAM,CAAC,GAAG,CAACA,KAAK,IAAIO;QAG3B,IAAI,IAAI,CAAC,MAAM,CAAC,GAAG,CAACP,KAAM,GAAG,CAACM,KAC5B;QAGF,IAAI,CAAC,MAAM,CAAC,GAAG,CAACN,KAAM,GAAG,CAACM;QAC1BV,YAAY,EAAE,CAACI,KAAeM;IAChC;IAEO,mBAELN,GAAM,EAAEM,EAA2D,EAAE;QACrEV,YAAY,GAAG,CAACI,KAAeM;QAC/B,IAAI,CAAC,MAAM,CAAC,GAAG,CAACN,KAAM,MAAM,CAACM;IAC/B;;QAxHK,gBACL,uBAAU,UAGN,IAAIE;;AAqHV"}
1
+ {"version":3,"file":"utils/data/local.mjs","sources":["../../../src/utils/data/local.ts"],"sourcesContent":["import { Manifest as ManifestShared } from '@rsdoctor/utils/common';\nimport { Common, Manifest, SDK } from '@rsdoctor/types';\nimport { get } from 'es-toolkit/compat';\nimport { BaseDataLoader } from './base';\nimport { postServerAPI } from '../request';\nimport {\n requestServerAPI,\n subscribeServerAPI,\n unsubscribeServerAPI,\n} from '../socket';\n\ntype DataUpdateAPI = SDK.ServerAPI.API | SDK.ServerAPI.APIExtends;\n\ntype DataUpdateSubscription = {\n api: DataUpdateAPI;\n body: SDK.ServerAPI.InferRequestBodyType<DataUpdateAPI, null> | null;\n listeners: Set<Common.Function>;\n};\n\nexport class LocalServerDataLoader extends BaseDataLoader {\n protected events: Map<string, DataUpdateSubscription> = new Map();\n\n public isLocal() {\n return true;\n }\n\n public async loadData<T extends keyof Manifest.RsdoctorManifestData>(\n key: T,\n ): Promise<void | Manifest.RsdoctorManifestData[T]>;\n\n public async loadData(key: string): Promise<unknown> {\n return this.limit(key, async () => {\n const [scope, ...rest] = this.getKeys(key);\n const data = this.getData(scope as keyof Manifest.RsdoctorManifestData);\n\n if (!data) return;\n\n let res: unknown = data;\n\n // sharding files\n if (ManifestShared.isShardingData(res)) {\n if (!this.shardingDataMap.has(key)) {\n const task = postServerAPI(SDK.ServerAPI.API.LoadDataByKey, {\n key,\n }).catch((err) => {\n this.log(`loadData error: `, res, key);\n throw err;\n });\n // save with every key\n this.shardingDataMap.set(key, task);\n }\n\n res = await this.shardingDataMap.get(key);\n this.shardingDataMap.delete(key);\n return res;\n }\n\n return rest.length > 0 ? get(res, this.joinKeys(rest)) : res;\n });\n }\n\n public async loadAPI<\n T extends SDK.ServerAPI.API,\n B extends SDK.ServerAPI.InferRequestBodyType<T> =\n SDK.ServerAPI.InferRequestBodyType<T>,\n R extends SDK.ServerAPI.InferResponseType<T> =\n SDK.ServerAPI.InferResponseType<T>,\n >(...args: B extends void ? [api: T] : [api: T, body: B]): Promise<R> {\n const [api, body] = args;\n // request limitation key\n const key = body ? `${api}_${JSON.stringify(body)}` : `${api}`;\n const socketPort = this.get('__SOCKET__PORT__') ?? '';\n\n return this.limit(key, async () => {\n try {\n return (await requestServerAPI(\n api,\n body as SDK.ServerAPI.InferRequestBodyType<T>,\n socketPort,\n )) as R;\n } catch (err) {\n this.log(`loadAPI error: `, key);\n throw err;\n }\n });\n }\n\n public dispose() {\n super.dispose();\n this.events.forEach(({ api, body, listeners }) => {\n listeners.forEach((listener) => {\n this.removeOnDataUpdate(api, body, listener);\n });\n listeners.clear();\n });\n this.events.clear();\n }\n\n /**\n * add event listener when received data from server.\n */\n public onDataUpdate<T extends SDK.ServerAPI.API | SDK.ServerAPI.APIExtends>(\n api: T,\n body: SDK.ServerAPI.InferRequestBodyType<T, null> | null,\n fn: (response: SDK.ServerAPI.SocketResponseType<T>) => void,\n ) {\n const normalizedBody = body ?? null;\n const key = `${api}::${JSON.stringify(normalizedBody)}`;\n if (!this.events.has(key)) {\n this.events.set(key, {\n api,\n body: normalizedBody,\n listeners: new Set(),\n });\n }\n\n const subscription = this.events.get(key)!;\n if (subscription.listeners.has(fn)) {\n return;\n }\n\n subscription.listeners.add(fn);\n const socketPort = this.get('__SOCKET__PORT__') ?? '';\n subscribeServerAPI(api, normalizedBody, fn, socketPort);\n }\n\n public removeOnDataUpdate<\n T extends SDK.ServerAPI.API | SDK.ServerAPI.APIExtends,\n >(\n api: T,\n body: SDK.ServerAPI.InferRequestBodyType<T, null> | null,\n fn: (response: SDK.ServerAPI.SocketResponseType<T>) => void,\n ) {\n const key = `${api}::${JSON.stringify(body ?? null)}`;\n const socketPort = this.get('__SOCKET__PORT__') ?? '';\n unsubscribeServerAPI(api, body, fn, socketPort);\n this.events.get(key)?.listeners.delete(fn);\n }\n}\n"],"names":["LocalServerDataLoader","BaseDataLoader","key","scope","rest","data","res","ManifestShared","task","postServerAPI","SDK","err","get","args","api","body","JSON","socketPort","requestServerAPI","listeners","listener","fn","normalizedBody","Set","subscription","subscribeServerAPI","unsubscribeServerAPI","Map"],"mappings":"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"}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,89 @@
1
+ import { afterEach, describe, expect, it, rs } from "@rstest/core";
2
+ import { SDK } from "@rsdoctor/types";
3
+ import { LocalServerDataLoader } from "./local.mjs";
4
+ function _define_property(obj, key, value) {
5
+ if (key in obj) Object.defineProperty(obj, key, {
6
+ value: value,
7
+ enumerable: true,
8
+ configurable: true,
9
+ writable: true
10
+ });
11
+ else obj[key] = value;
12
+ return obj;
13
+ }
14
+ class MockWebSocket {
15
+ addEventListener(event, listener) {
16
+ if (!this.listeners.has(event)) this.listeners.set(event, new Set());
17
+ this.listeners.get(event).add(listener);
18
+ }
19
+ send(message) {
20
+ this.sentMessages.push(message);
21
+ }
22
+ trigger(event, data) {
23
+ if ('open' === event) this.readyState = 1;
24
+ this.listeners.get(event)?.forEach((listener)=>listener(void 0 === data ? void 0 : {
25
+ data
26
+ }));
27
+ }
28
+ constructor(url){
29
+ _define_property(this, "url", void 0);
30
+ _define_property(this, "readyState", void 0);
31
+ _define_property(this, "sentMessages", void 0);
32
+ _define_property(this, "listeners", void 0);
33
+ this.url = url;
34
+ this.readyState = 0;
35
+ this.sentMessages = [];
36
+ this.listeners = new Map();
37
+ MockWebSocket.instances.push(this);
38
+ }
39
+ }
40
+ _define_property(MockWebSocket, "instances", []);
41
+ describe('LocalServerDataLoader', ()=>{
42
+ const originalFetch = globalThis.fetch;
43
+ const originalWebSocket = globalThis.WebSocket;
44
+ afterEach(()=>{
45
+ globalThis.fetch = originalFetch;
46
+ globalThis.WebSocket = originalWebSocket;
47
+ MockWebSocket.instances = [];
48
+ rs.restoreAllMocks();
49
+ });
50
+ it("disposes subscriptions when request body strings contain delimiters", ()=>{
51
+ const loader = new LocalServerDataLoader({
52
+ data: {}
53
+ });
54
+ loader.onDataUpdate(SDK.ServerAPI.API.GetModuleByName, {
55
+ name: 'foo::bar'
56
+ }, rs.fn());
57
+ expect(()=>loader.dispose()).not.toThrow();
58
+ });
59
+ it('loads APIs through websocket requests', async ()=>{
60
+ globalThis.WebSocket = MockWebSocket;
61
+ const fetchMock = rs.fn();
62
+ globalThis.fetch = fetchMock;
63
+ const loader = new LocalServerDataLoader({
64
+ data: {},
65
+ __SOCKET__PORT__: '3083'
66
+ });
67
+ const task = loader.loadAPI(SDK.ServerAPI.API.GetAllModuleGraph, {});
68
+ const socket = MockWebSocket.instances[0];
69
+ socket.trigger('open');
70
+ const request = JSON.parse(socket.sentMessages[0]);
71
+ socket.trigger('message', JSON.stringify({
72
+ type: 'response',
73
+ id: request.id,
74
+ payload: [
75
+ {
76
+ id: 1
77
+ }
78
+ ]
79
+ }));
80
+ await expect(task).resolves.toStrictEqual([
81
+ {
82
+ id: 1
83
+ }
84
+ ]);
85
+ expect(fetchMock).not.toHaveBeenCalled();
86
+ });
87
+ });
88
+
89
+ //# sourceMappingURL=local.test.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils/data/local.test.mjs","sources":["../../../src/utils/data/local.test.ts"],"sourcesContent":["import { afterEach, describe, expect, it, rs } from '@rstest/core';\nimport { SDK } from '@rsdoctor/types';\nimport { LocalServerDataLoader } from './local';\n\nclass MockWebSocket {\n static instances: MockWebSocket[] = [];\n\n public readyState = 0;\n\n public sentMessages: string[] = [];\n\n private listeners = new Map<\n string,\n Set<(event?: { data: string }) => void>\n >();\n\n constructor(public url: string) {\n MockWebSocket.instances.push(this);\n }\n\n addEventListener(\n event: string,\n listener: (event?: { data: string }) => void,\n ) {\n if (!this.listeners.has(event)) {\n this.listeners.set(event, new Set());\n }\n this.listeners.get(event)!.add(listener);\n }\n\n send(message: string) {\n this.sentMessages.push(message);\n }\n\n trigger(event: string, data?: string) {\n if (event === 'open') {\n this.readyState = 1;\n }\n this.listeners\n .get(event)\n ?.forEach((listener) =>\n listener(data === undefined ? undefined : { data }),\n );\n }\n}\n\ndescribe('LocalServerDataLoader', () => {\n const originalFetch = globalThis.fetch;\n const originalWebSocket = globalThis.WebSocket;\n\n afterEach(() => {\n globalThis.fetch = originalFetch;\n globalThis.WebSocket = originalWebSocket;\n MockWebSocket.instances = [];\n rs.restoreAllMocks();\n });\n\n it('disposes subscriptions when request body strings contain delimiters', () => {\n const loader = new LocalServerDataLoader({\n data: {},\n } as any);\n\n loader.onDataUpdate(\n SDK.ServerAPI.API.GetModuleByName,\n { name: 'foo::bar' } as any,\n rs.fn(),\n );\n\n expect(() => loader.dispose()).not.toThrow();\n });\n\n it('loads APIs through websocket requests', async () => {\n globalThis.WebSocket = MockWebSocket as any;\n const fetchMock = rs.fn();\n globalThis.fetch = fetchMock as typeof fetch;\n const loader = new LocalServerDataLoader({\n data: {},\n __SOCKET__PORT__: '3083',\n } as any);\n\n const task = loader.loadAPI(SDK.ServerAPI.API.GetAllModuleGraph, {} as any);\n const socket = MockWebSocket.instances[0];\n socket.trigger('open');\n const request = JSON.parse(socket.sentMessages[0]);\n\n socket.trigger(\n 'message',\n JSON.stringify({\n type: 'response',\n id: request.id,\n payload: [{ id: 1 }],\n }),\n );\n\n await expect(task).resolves.toStrictEqual([{ id: 1 }]);\n expect(fetchMock).not.toHaveBeenCalled();\n });\n});\n"],"names":["MockWebSocket","event","listener","Set","message","data","undefined","url","Map","describe","originalFetch","globalThis","originalWebSocket","afterEach","rs","it","loader","LocalServerDataLoader","SDK","expect","fetchMock","task","socket","request","JSON"],"mappings":";;;;;;;;;;;;;AAIA,MAAMA;IAgBJ,iBACEC,KAAa,EACbC,QAA4C,EAC5C;QACA,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,CAACD,QACtB,IAAI,CAAC,SAAS,CAAC,GAAG,CAACA,OAAO,IAAIE;QAEhC,IAAI,CAAC,SAAS,CAAC,GAAG,CAACF,OAAQ,GAAG,CAACC;IACjC;IAEA,KAAKE,OAAe,EAAE;QACpB,IAAI,CAAC,YAAY,CAAC,IAAI,CAACA;IACzB;IAEA,QAAQH,KAAa,EAAEI,IAAa,EAAE;QACpC,IAAIJ,AAAU,WAAVA,OACF,IAAI,CAAC,UAAU,GAAG;QAEpB,IAAI,CAAC,SAAS,CACX,GAAG,CAACA,QACH,QAAQ,CAACC,WACTA,SAASG,AAASC,WAATD,OAAqBC,SAAY;gBAAED;YAAK;IAEvD;IA3BA,YAAmBE,GAAW,CAAE;;QAThC,uBAAO,cAAP;QAEA,uBAAO,gBAAP;QAEA,uBAAQ,aAAR;aAKmBA,GAAG,GAAHA;aATZ,UAAU,GAAG;aAEb,YAAY,GAAa,EAAE;aAE1B,SAAS,GAAG,IAAIC;QAMtBR,cAAc,SAAS,CAAC,IAAI,CAAC,IAAI;IACnC;AA0BF;AAvCE,iBADIA,eACG,aAA6B,EAAE;AAyCxCS,SAAS,yBAAyB;IAChC,MAAMC,gBAAgBC,WAAW,KAAK;IACtC,MAAMC,oBAAoBD,WAAW,SAAS;IAE9CE,UAAU;QACRF,WAAW,KAAK,GAAGD;QACnBC,WAAW,SAAS,GAAGC;QACvBZ,cAAc,SAAS,GAAG,EAAE;QAC5Bc,GAAG,eAAe;IACpB;IAEAC,GAAG,uEAAuE;QACxE,MAAMC,SAAS,IAAIC,sBAAsB;YACvC,MAAM,CAAC;QACT;QAEAD,OAAO,YAAY,CACjBE,IAAI,SAAS,CAAC,GAAG,CAAC,eAAe,EACjC;YAAE,MAAM;QAAW,GACnBJ,GAAG,EAAE;QAGPK,OAAO,IAAMH,OAAO,OAAO,IAAI,GAAG,CAAC,OAAO;IAC5C;IAEAD,GAAG,yCAAyC;QAC1CJ,WAAW,SAAS,GAAGX;QACvB,MAAMoB,YAAYN,GAAG,EAAE;QACvBH,WAAW,KAAK,GAAGS;QACnB,MAAMJ,SAAS,IAAIC,sBAAsB;YACvC,MAAM,CAAC;YACP,kBAAkB;QACpB;QAEA,MAAMI,OAAOL,OAAO,OAAO,CAACE,IAAI,SAAS,CAAC,GAAG,CAAC,iBAAiB,EAAE,CAAC;QAClE,MAAMI,SAAStB,cAAc,SAAS,CAAC,EAAE;QACzCsB,OAAO,OAAO,CAAC;QACf,MAAMC,UAAUC,KAAK,KAAK,CAACF,OAAO,YAAY,CAAC,EAAE;QAEjDA,OAAO,OAAO,CACZ,WACAE,KAAK,SAAS,CAAC;YACb,MAAM;YACN,IAAID,QAAQ,EAAE;YACd,SAAS;gBAAC;oBAAE,IAAI;gBAAE;aAAE;QACtB;QAGF,MAAMJ,OAAOE,MAAM,QAAQ,CAAC,aAAa,CAAC;YAAC;gBAAE,IAAI;YAAE;SAAE;QACrDF,OAAOC,WAAW,GAAG,CAAC,gBAAgB;IACxC;AACF"}
@@ -25,6 +25,6 @@ export declare function useDuplicatePackagesByManifest(manifest: Manifest.Rsdoct
25
25
  export declare function useCompileAlertsByErrors(errors: Manifest.RsdoctorManifestData['errors']): Rule.RuleStoreDataItem[];
26
26
  export declare function useBundleAlertsByErrors(errors: Manifest.RsdoctorManifestData['errors']): Rule.RuleStoreDataItem[];
27
27
  export declare function useDuplicatePackagesByErrors(errors: Manifest.RsdoctorManifestData['errors']): Rule.PackageRelationDiffRuleStoreData[];
28
- export declare function useWebpackConfigurationByConfigs(configs?: SDK.ConfigData): SDK.WebpackConfigData | null | undefined;
28
+ export declare function useWebpackConfigurationByConfigs(configs?: SDK.ConfigData): SDK.BundlerConfigData | null | undefined;
29
29
  export declare function useDetectIfCloudIdeEnv(): boolean;
30
30
  export declare function useWindowWidth(): number;
@@ -77,14 +77,15 @@ async function fetchManifest(url = getManifestUrl()) {
77
77
  async function postServerAPI(...args) {
78
78
  const [api, body] = args;
79
79
  const timeout = 'development' === process.env.NODE_ENV ? 10000 : 60000;
80
- const res = await Fetch.fetchWithTimeout(resolveRequestUrl(`${api}?_t=${random()}`), {
80
+ const requestInit = {
81
81
  method: 'POST',
82
82
  headers: {
83
83
  'Content-Type': 'application/json'
84
84
  },
85
- body: void 0 === body ? void 0 : JSON.stringify(body),
86
85
  timeout
87
- });
86
+ };
87
+ if (null != body) requestInit.body = JSON.stringify(body);
88
+ const res = await Fetch.fetchWithTimeout(resolveRequestUrl(`${api}?_t=${random()}`), requestInit);
88
89
  return await res.json();
89
90
  }
90
91
  export { fetchJSONByUrl, fetchJSONByUrls, fetchManifest, fetchShardingFile, getManifestUrl, loadManifestByUrl, parseManifest, postServerAPI };
@@ -1 +1 @@
1
- {"version":3,"file":"utils/request.mjs","sources":["../../src/utils/request.ts"],"sourcesContent":["import { Manifest, SDK } from '@rsdoctor/types';\nimport { Fetch, Manifest as ManifestMethod, Url } from '@rsdoctor/utils/common';\nimport { APILoaderMode4Dev } from '../constants';\nimport { getManifestUrlFromUrlQuery } from './url';\nimport { getAPILoaderModeFromStorage } from './storage';\n\nfunction random() {\n return `${Date.now()}${Math.floor(Math.random() * 10000)}`;\n}\n\nfunction resolveRequestUrl(url: string): string {\n if (\n process.env.NODE_ENV === 'development' &&\n getAPILoaderModeFromStorage() === APILoaderMode4Dev.Local &&\n url.startsWith('/')\n ) {\n const nextUrl =\n url === manifestUrlForDev ? SDK.ServerAPI.API.Manifest : url;\n const currentUrl = new URL(location.href);\n currentUrl.port = String(process.env.LOCAL_CLI_PORT!);\n return `${currentUrl.origin}${nextUrl}`;\n }\n\n return url;\n}\n\nasync function requestText(url: string, timeout: number) {\n const res = await Fetch.fetchWithTimeout(resolveRequestUrl(url), { timeout });\n return res.text();\n}\n\nexport async function fetchShardingFile(url: string): Promise<string> {\n if (Url.isUrl(url)) {\n return requestText(url, 999999);\n }\n // json string\n return url;\n}\n\nexport async function loadManifestByUrl(url: string) {\n const json = await fetchJSONByUrl(url);\n\n const res = await parseManifest(json);\n return res;\n}\n\nexport async function fetchJSONByUrl(url: string) {\n let json: unknown = await requestText(url, 30000);\n\n if (typeof json === 'string') {\n const trimmed = json.trim();\n // If we got an HTML document (usually error page / SPA fallback), skip JSON.parse\n if (/^<!doctype html\\b/i.test(trimmed) || /^<html\\b/i.test(trimmed)) {\n json = {} as Manifest.RsdoctorManifestWithShardingFiles;\n } else {\n json = JSON.parse(json);\n }\n }\n\n return json as Manifest.RsdoctorManifestWithShardingFiles;\n}\n\nexport function fetchJSONByUrls(urls: string[]) {\n return Promise.all(urls.map((url) => fetchJSONByUrl(url)));\n}\n\nexport async function parseManifest(\n json: Manifest.RsdoctorManifestWithShardingFiles,\n) {\n let transformedData: Manifest.RsdoctorManifestData;\n\n try {\n // try to load cloud data first\n if (json.cloudData) {\n try {\n transformedData = await ManifestMethod.fetchShardingFiles(\n json.cloudData,\n fetchShardingFile,\n );\n } catch (error) {\n console.log('cloudData load error: ', error);\n }\n } else {\n transformedData = await ManifestMethod.fetchShardingFiles(\n json.data,\n fetchShardingFile,\n );\n }\n } catch {\n transformedData = await ManifestMethod.fetchShardingFiles(\n json.data,\n fetchShardingFile,\n );\n }\n\n return {\n ...json,\n data: transformedData!,\n };\n}\n\nconst manifestUrlForDev = '/manifest.json';\n\nexport function getManifestUrl(): string {\n let file: string | void;\n\n if (\n (window as { [key: string]: any })[\n Manifest.RsdoctorManifestClientConstant.WindowPropertyForManifestUrl\n ]\n ) {\n // load from window property\n file = (window as { [key: string]: any })[\n Manifest.RsdoctorManifestClientConstant.WindowPropertyForManifestUrl\n ];\n } else {\n // load from url query\n file = getManifestUrlFromUrlQuery();\n }\n\n if (!file) {\n file = SDK.ServerAPI.API.Manifest;\n }\n\n return file;\n}\n\nconst pool = new Map<\n string,\n Promise<Manifest.RsdoctorManifestWithShardingFiles>\n>();\n\nexport async function fetchManifest(url = getManifestUrl()) {\n if (!pool.has(url)) {\n pool.set(\n url,\n fetchJSONByUrl(url).catch((err) => {\n pool.delete(url);\n throw err;\n }),\n );\n }\n\n const res = await pool.get(url)!;\n\n return res;\n}\n\nexport async function postServerAPI<\n T extends SDK.ServerAPI.API,\n B extends SDK.ServerAPI.InferRequestBodyType<T> =\n SDK.ServerAPI.InferRequestBodyType<T>,\n R extends SDK.ServerAPI.InferResponseType<T> =\n SDK.ServerAPI.InferResponseType<T>,\n>(...args: B extends void ? [api: T] : [api: T, body: B]): Promise<R> {\n const [api, body] = args;\n const timeout = process.env.NODE_ENV === 'development' ? 10000 : 60000;\n const res = await Fetch.fetchWithTimeout(\n resolveRequestUrl(`${api}?_t=${random()}`),\n {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: body === undefined ? undefined : JSON.stringify(body),\n timeout,\n },\n );\n return (await res.json()) as R;\n}\n"],"names":["random","Date","Math","resolveRequestUrl","url","process","getAPILoaderModeFromStorage","APILoaderMode4Dev","nextUrl","manifestUrlForDev","SDK","currentUrl","URL","location","String","requestText","timeout","res","Fetch","fetchShardingFile","Url","loadManifestByUrl","json","fetchJSONByUrl","parseManifest","trimmed","JSON","fetchJSONByUrls","urls","Promise","transformedData","ManifestMethod","error","console","getManifestUrl","file","window","Manifest","getManifestUrlFromUrlQuery","pool","Map","fetchManifest","err","postServerAPI","args","api","body","undefined"],"mappings":"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"}
1
+ {"version":3,"file":"utils/request.mjs","sources":["../../src/utils/request.ts"],"sourcesContent":["import { Manifest, SDK } from '@rsdoctor/types';\nimport { Fetch, Manifest as ManifestMethod, Url } from '@rsdoctor/utils/common';\nimport { APILoaderMode4Dev } from '../constants';\nimport { getManifestUrlFromUrlQuery } from './url';\nimport { getAPILoaderModeFromStorage } from './storage';\n\nfunction random() {\n return `${Date.now()}${Math.floor(Math.random() * 10000)}`;\n}\n\nfunction resolveRequestUrl(url: string): string {\n if (\n process.env.NODE_ENV === 'development' &&\n getAPILoaderModeFromStorage() === APILoaderMode4Dev.Local &&\n url.startsWith('/')\n ) {\n const nextUrl =\n url === manifestUrlForDev ? SDK.ServerAPI.API.Manifest : url;\n const currentUrl = new URL(location.href);\n currentUrl.port = String(process.env.LOCAL_CLI_PORT!);\n return `${currentUrl.origin}${nextUrl}`;\n }\n\n return url;\n}\n\nasync function requestText(url: string, timeout: number) {\n const res = await Fetch.fetchWithTimeout(resolveRequestUrl(url), { timeout });\n return res.text();\n}\n\nexport async function fetchShardingFile(url: string): Promise<string> {\n if (Url.isUrl(url)) {\n return requestText(url, 999999);\n }\n // json string\n return url;\n}\n\nexport async function loadManifestByUrl(url: string) {\n const json = await fetchJSONByUrl(url);\n\n const res = await parseManifest(json);\n return res;\n}\n\nexport async function fetchJSONByUrl(url: string) {\n let json: unknown = await requestText(url, 30000);\n\n if (typeof json === 'string') {\n const trimmed = json.trim();\n // If we got an HTML document (usually error page / SPA fallback), skip JSON.parse\n if (/^<!doctype html\\b/i.test(trimmed) || /^<html\\b/i.test(trimmed)) {\n json = {} as Manifest.RsdoctorManifestWithShardingFiles;\n } else {\n json = JSON.parse(json);\n }\n }\n\n return json as Manifest.RsdoctorManifestWithShardingFiles;\n}\n\nexport function fetchJSONByUrls(urls: string[]) {\n return Promise.all(urls.map((url) => fetchJSONByUrl(url)));\n}\n\nexport async function parseManifest(\n json: Manifest.RsdoctorManifestWithShardingFiles,\n) {\n let transformedData: Manifest.RsdoctorManifestData;\n\n try {\n // try to load cloud data first\n if (json.cloudData) {\n try {\n transformedData = await ManifestMethod.fetchShardingFiles(\n json.cloudData,\n fetchShardingFile,\n );\n } catch (error) {\n console.log('cloudData load error: ', error);\n }\n } else {\n transformedData = await ManifestMethod.fetchShardingFiles(\n json.data,\n fetchShardingFile,\n );\n }\n } catch {\n transformedData = await ManifestMethod.fetchShardingFiles(\n json.data,\n fetchShardingFile,\n );\n }\n\n return {\n ...json,\n data: transformedData!,\n };\n}\n\nconst manifestUrlForDev = '/manifest.json';\n\nexport function getManifestUrl(): string {\n let file: string | void;\n\n if (\n (window as { [key: string]: any })[\n Manifest.RsdoctorManifestClientConstant.WindowPropertyForManifestUrl\n ]\n ) {\n // load from window property\n file = (window as { [key: string]: any })[\n Manifest.RsdoctorManifestClientConstant.WindowPropertyForManifestUrl\n ];\n } else {\n // load from url query\n file = getManifestUrlFromUrlQuery();\n }\n\n if (!file) {\n file = SDK.ServerAPI.API.Manifest;\n }\n\n return file;\n}\n\nconst pool = new Map<\n string,\n Promise<Manifest.RsdoctorManifestWithShardingFiles>\n>();\n\nexport async function fetchManifest(url = getManifestUrl()) {\n if (!pool.has(url)) {\n pool.set(\n url,\n fetchJSONByUrl(url).catch((err) => {\n pool.delete(url);\n throw err;\n }),\n );\n }\n\n const res = await pool.get(url)!;\n\n return res;\n}\n\nexport async function postServerAPI<\n T extends SDK.ServerAPI.API,\n B extends SDK.ServerAPI.InferRequestBodyType<T> =\n SDK.ServerAPI.InferRequestBodyType<T>,\n R extends SDK.ServerAPI.InferResponseType<T> =\n SDK.ServerAPI.InferResponseType<T>,\n>(...args: B extends void ? [api: T] : [api: T, body: B]): Promise<R> {\n const [api, body] = args;\n const timeout = process.env.NODE_ENV === 'development' ? 10000 : 60000;\n const requestInit: Fetch.FetchOptions = {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n timeout,\n };\n\n if (body != null) {\n requestInit.body = JSON.stringify(body);\n }\n\n const res = await Fetch.fetchWithTimeout(\n resolveRequestUrl(`${api}?_t=${random()}`),\n requestInit,\n );\n return (await res.json()) as R;\n}\n"],"names":["random","Date","Math","resolveRequestUrl","url","process","getAPILoaderModeFromStorage","APILoaderMode4Dev","nextUrl","manifestUrlForDev","SDK","currentUrl","URL","location","String","requestText","timeout","res","Fetch","fetchShardingFile","Url","loadManifestByUrl","json","fetchJSONByUrl","parseManifest","trimmed","JSON","fetchJSONByUrls","urls","Promise","transformedData","ManifestMethod","error","console","getManifestUrl","file","window","Manifest","getManifestUrlFromUrlQuery","pool","Map","fetchManifest","err","postServerAPI","args","api","body","requestInit"],"mappings":"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"}
@@ -56,6 +56,29 @@ describe('request utils', ()=>{
56
56
  ok: true
57
57
  });
58
58
  });
59
+ it('postServerAPI() omits request body when body is null', async ()=>{
60
+ const fetchMock = rs.fn().mockResolvedValue({
61
+ ok: true,
62
+ json: async ()=>({
63
+ ok: true
64
+ })
65
+ });
66
+ globalThis.fetch = fetchMock;
67
+ process.env.NODE_ENV = 'production';
68
+ const result = await postServerAPI('/api/demo', null);
69
+ const [url, init] = fetchMock.mock.calls[0];
70
+ expect(url).toContain('/api/demo?_t=');
71
+ expect(init).toMatchObject({
72
+ method: 'POST',
73
+ headers: {
74
+ 'Content-Type': 'application/json'
75
+ }
76
+ });
77
+ expect(init).not.toHaveProperty('body');
78
+ expect(result).toStrictEqual({
79
+ ok: true
80
+ });
81
+ });
59
82
  });
60
83
 
61
84
  //# sourceMappingURL=request.test.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"utils/request.test.mjs","sources":["../../src/utils/request.test.ts"],"sourcesContent":["import { afterEach, describe, expect, it, rs } from '@rstest/core';\nimport { fetchJSONByUrl, postServerAPI } from './request';\n\ndescribe('request utils', () => {\n const originalFetch = globalThis.fetch;\n const originalNodeEnv = process.env.NODE_ENV;\n\n afterEach(() => {\n globalThis.fetch = originalFetch;\n process.env.NODE_ENV = originalNodeEnv;\n });\n\n it('fetchJSONByUrl() parses json text payload', async () => {\n const fetchMock = rs.fn().mockResolvedValue({\n ok: true,\n text: async () => '{\"name\":\"rsdoctor\"}',\n });\n globalThis.fetch = fetchMock as typeof fetch;\n process.env.NODE_ENV = 'production';\n\n const data = await fetchJSONByUrl('https://example.com/manifest.json');\n\n expect(data).toStrictEqual({ name: 'rsdoctor' });\n expect(fetchMock).toBeCalledTimes(1);\n });\n\n it('fetchJSONByUrl() throws for non-2xx response', async () => {\n const fetchMock = rs.fn().mockResolvedValue({\n ok: false,\n status: 500,\n });\n globalThis.fetch = fetchMock as typeof fetch;\n process.env.NODE_ENV = 'production';\n\n await expect(\n fetchJSONByUrl('https://example.com/manifest.json'),\n ).rejects.toThrow('Request failed with status 500');\n });\n\n it('postServerAPI() sends json body and parses response json', async () => {\n const fetchMock = rs.fn().mockResolvedValue({\n ok: true,\n json: async () => ({ ok: true }),\n });\n globalThis.fetch = fetchMock as typeof fetch;\n process.env.NODE_ENV = 'production';\n\n const result = await (postServerAPI as any)('/api/demo', { id: 1 });\n const [url, init] = fetchMock.mock.calls[0];\n\n expect(url).toContain('/api/demo?_t=');\n expect(init).toMatchObject({\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({ id: 1 }),\n });\n expect(result).toStrictEqual({ ok: true });\n });\n});\n"],"names":["describe","originalFetch","globalThis","originalNodeEnv","process","afterEach","it","fetchMock","rs","data","fetchJSONByUrl","expect","result","postServerAPI","url","init","JSON"],"mappings":";;AAGAA,SAAS,iBAAiB;IACxB,MAAMC,gBAAgBC,WAAW,KAAK;IACtC,MAAMC,kBAAkBC,QAAQ,GAAG,CAAC,QAAQ;IAE5CC,UAAU;QACRH,WAAW,KAAK,GAAGD;QACnBG,QAAQ,GAAG,CAAC,QAAQ,GAAGD;IACzB;IAEAG,GAAG,6CAA6C;QAC9C,MAAMC,YAAYC,GAAG,EAAE,GAAG,iBAAiB,CAAC;YAC1C,IAAI;YACJ,MAAM,UAAY;QACpB;QACAN,WAAW,KAAK,GAAGK;QACnBH,QAAQ,GAAG,CAAC,QAAQ,GAAG;QAEvB,MAAMK,OAAO,MAAMC,eAAe;QAElCC,OAAOF,MAAM,aAAa,CAAC;YAAE,MAAM;QAAW;QAC9CE,OAAOJ,WAAW,eAAe,CAAC;IACpC;IAEAD,GAAG,gDAAgD;QACjD,MAAMC,YAAYC,GAAG,EAAE,GAAG,iBAAiB,CAAC;YAC1C,IAAI;YACJ,QAAQ;QACV;QACAN,WAAW,KAAK,GAAGK;QACnBH,QAAQ,GAAG,CAAC,QAAQ,GAAG;QAEvB,MAAMO,OACJD,eAAe,sCACf,OAAO,CAAC,OAAO,CAAC;IACpB;IAEAJ,GAAG,4DAA4D;QAC7D,MAAMC,YAAYC,GAAG,EAAE,GAAG,iBAAiB,CAAC;YAC1C,IAAI;YACJ,MAAM,UAAa;oBAAE,IAAI;gBAAK;QAChC;QACAN,WAAW,KAAK,GAAGK;QACnBH,QAAQ,GAAG,CAAC,QAAQ,GAAG;QAEvB,MAAMQ,SAAS,MAAOC,cAAsB,aAAa;YAAE,IAAI;QAAE;QACjE,MAAM,CAACC,KAAKC,KAAK,GAAGR,UAAU,IAAI,CAAC,KAAK,CAAC,EAAE;QAE3CI,OAAOG,KAAK,SAAS,CAAC;QACtBH,OAAOI,MAAM,aAAa,CAAC;YACzB,QAAQ;YACR,SAAS;gBACP,gBAAgB;YAClB;YACA,MAAMC,KAAK,SAAS,CAAC;gBAAE,IAAI;YAAE;QAC/B;QACAL,OAAOC,QAAQ,aAAa,CAAC;YAAE,IAAI;QAAK;IAC1C;AACF"}
1
+ {"version":3,"file":"utils/request.test.mjs","sources":["../../src/utils/request.test.ts"],"sourcesContent":["import { afterEach, describe, expect, it, rs } from '@rstest/core';\nimport { fetchJSONByUrl, postServerAPI } from './request';\n\ndescribe('request utils', () => {\n const originalFetch = globalThis.fetch;\n const originalNodeEnv = process.env.NODE_ENV;\n\n afterEach(() => {\n globalThis.fetch = originalFetch;\n process.env.NODE_ENV = originalNodeEnv;\n });\n\n it('fetchJSONByUrl() parses json text payload', async () => {\n const fetchMock = rs.fn().mockResolvedValue({\n ok: true,\n text: async () => '{\"name\":\"rsdoctor\"}',\n });\n globalThis.fetch = fetchMock as typeof fetch;\n process.env.NODE_ENV = 'production';\n\n const data = await fetchJSONByUrl('https://example.com/manifest.json');\n\n expect(data).toStrictEqual({ name: 'rsdoctor' });\n expect(fetchMock).toBeCalledTimes(1);\n });\n\n it('fetchJSONByUrl() throws for non-2xx response', async () => {\n const fetchMock = rs.fn().mockResolvedValue({\n ok: false,\n status: 500,\n });\n globalThis.fetch = fetchMock as typeof fetch;\n process.env.NODE_ENV = 'production';\n\n await expect(\n fetchJSONByUrl('https://example.com/manifest.json'),\n ).rejects.toThrow('Request failed with status 500');\n });\n\n it('postServerAPI() sends json body and parses response json', async () => {\n const fetchMock = rs.fn().mockResolvedValue({\n ok: true,\n json: async () => ({ ok: true }),\n });\n globalThis.fetch = fetchMock as typeof fetch;\n process.env.NODE_ENV = 'production';\n\n const result = await (postServerAPI as any)('/api/demo', { id: 1 });\n const [url, init] = fetchMock.mock.calls[0];\n\n expect(url).toContain('/api/demo?_t=');\n expect(init).toMatchObject({\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({ id: 1 }),\n });\n expect(result).toStrictEqual({ ok: true });\n });\n\n it('postServerAPI() omits request body when body is null', async () => {\n const fetchMock = rs.fn().mockResolvedValue({\n ok: true,\n json: async () => ({ ok: true }),\n });\n globalThis.fetch = fetchMock as typeof fetch;\n process.env.NODE_ENV = 'production';\n\n const result = await (postServerAPI as any)('/api/demo', null);\n const [url, init] = fetchMock.mock.calls[0];\n\n expect(url).toContain('/api/demo?_t=');\n expect(init).toMatchObject({\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n },\n });\n expect(init).not.toHaveProperty('body');\n expect(result).toStrictEqual({ ok: true });\n });\n});\n"],"names":["describe","originalFetch","globalThis","originalNodeEnv","process","afterEach","it","fetchMock","rs","data","fetchJSONByUrl","expect","result","postServerAPI","url","init","JSON"],"mappings":";;AAGAA,SAAS,iBAAiB;IACxB,MAAMC,gBAAgBC,WAAW,KAAK;IACtC,MAAMC,kBAAkBC,QAAQ,GAAG,CAAC,QAAQ;IAE5CC,UAAU;QACRH,WAAW,KAAK,GAAGD;QACnBG,QAAQ,GAAG,CAAC,QAAQ,GAAGD;IACzB;IAEAG,GAAG,6CAA6C;QAC9C,MAAMC,YAAYC,GAAG,EAAE,GAAG,iBAAiB,CAAC;YAC1C,IAAI;YACJ,MAAM,UAAY;QACpB;QACAN,WAAW,KAAK,GAAGK;QACnBH,QAAQ,GAAG,CAAC,QAAQ,GAAG;QAEvB,MAAMK,OAAO,MAAMC,eAAe;QAElCC,OAAOF,MAAM,aAAa,CAAC;YAAE,MAAM;QAAW;QAC9CE,OAAOJ,WAAW,eAAe,CAAC;IACpC;IAEAD,GAAG,gDAAgD;QACjD,MAAMC,YAAYC,GAAG,EAAE,GAAG,iBAAiB,CAAC;YAC1C,IAAI;YACJ,QAAQ;QACV;QACAN,WAAW,KAAK,GAAGK;QACnBH,QAAQ,GAAG,CAAC,QAAQ,GAAG;QAEvB,MAAMO,OACJD,eAAe,sCACf,OAAO,CAAC,OAAO,CAAC;IACpB;IAEAJ,GAAG,4DAA4D;QAC7D,MAAMC,YAAYC,GAAG,EAAE,GAAG,iBAAiB,CAAC;YAC1C,IAAI;YACJ,MAAM,UAAa;oBAAE,IAAI;gBAAK;QAChC;QACAN,WAAW,KAAK,GAAGK;QACnBH,QAAQ,GAAG,CAAC,QAAQ,GAAG;QAEvB,MAAMQ,SAAS,MAAOC,cAAsB,aAAa;YAAE,IAAI;QAAE;QACjE,MAAM,CAACC,KAAKC,KAAK,GAAGR,UAAU,IAAI,CAAC,KAAK,CAAC,EAAE;QAE3CI,OAAOG,KAAK,SAAS,CAAC;QACtBH,OAAOI,MAAM,aAAa,CAAC;YACzB,QAAQ;YACR,SAAS;gBACP,gBAAgB;YAClB;YACA,MAAMC,KAAK,SAAS,CAAC;gBAAE,IAAI;YAAE;QAC/B;QACAL,OAAOC,QAAQ,aAAa,CAAC;YAAE,IAAI;QAAK;IAC1C;IAEAN,GAAG,wDAAwD;QACzD,MAAMC,YAAYC,GAAG,EAAE,GAAG,iBAAiB,CAAC;YAC1C,IAAI;YACJ,MAAM,UAAa;oBAAE,IAAI;gBAAK;QAChC;QACAN,WAAW,KAAK,GAAGK;QACnBH,QAAQ,GAAG,CAAC,QAAQ,GAAG;QAEvB,MAAMQ,SAAS,MAAOC,cAAsB,aAAa;QACzD,MAAM,CAACC,KAAKC,KAAK,GAAGR,UAAU,IAAI,CAAC,KAAK,CAAC,EAAE;QAE3CI,OAAOG,KAAK,SAAS,CAAC;QACtBH,OAAOI,MAAM,aAAa,CAAC;YACzB,QAAQ;YACR,SAAS;gBACP,gBAAgB;YAClB;QACF;QACAJ,OAAOI,MAAM,GAAG,CAAC,cAAc,CAAC;QAChCJ,OAAOC,QAAQ,aAAa,CAAC;YAAE,IAAI;QAAK;IAC1C;AACF"}
@@ -1,6 +1,6 @@
1
1
  import { Manifest } from "@rsdoctor/types";
2
2
  function routes_hasCompile(routes) {
3
- const hasCompile = routes.includes(Manifest.RsdoctorManifestClientRoutes.WebpackLoaders) || routes.includes(Manifest.RsdoctorManifestClientRoutes.ModuleResolve) || routes.includes(Manifest.RsdoctorManifestClientRoutes.WebpackPlugins);
3
+ const hasCompile = routes.includes(Manifest.RsdoctorManifestClientRoutes.Loaders) || routes.includes(Manifest.RsdoctorManifestClientRoutes.ModuleResolve) || routes.includes(Manifest.RsdoctorManifestClientRoutes.Plugins);
4
4
  return hasCompile;
5
5
  }
6
6
  function routes_hasBundle(routes) {
@@ -1 +1 @@
1
- {"version":3,"file":"utils/routes.mjs","sources":["../../src/utils/routes.ts"],"sourcesContent":["import { Manifest } from '@rsdoctor/types';\n\nexport function hasCompile(routes: Manifest.RsdoctorManifestClientRoutes[]) {\n const hasCompile =\n routes.includes(Manifest.RsdoctorManifestClientRoutes.WebpackLoaders) ||\n routes.includes(Manifest.RsdoctorManifestClientRoutes.ModuleResolve) ||\n routes.includes(Manifest.RsdoctorManifestClientRoutes.WebpackPlugins);\n return hasCompile;\n}\n\nexport function hasBundle(routes: Manifest.RsdoctorManifestClientRoutes[]) {\n const hasBundle =\n routes.includes(Manifest.RsdoctorManifestClientRoutes.BundleSize) ||\n routes.includes(Manifest.RsdoctorManifestClientRoutes.ModuleGraph) ||\n routes.includes(Manifest.RsdoctorManifestClientRoutes.TreeShaking);\n return hasBundle;\n}\n"],"names":["hasCompile","routes","Manifest","hasBundle"],"mappings":";AAEO,SAASA,kBAAWC,MAA+C;IACxE,MAAMD,aACJC,OAAO,QAAQ,CAACC,SAAS,4BAA4B,CAAC,cAAc,KACpED,OAAO,QAAQ,CAACC,SAAS,4BAA4B,CAAC,aAAa,KACnED,OAAO,QAAQ,CAACC,SAAS,4BAA4B,CAAC,cAAc;IACtE,OAAOF;AACT;AAEO,SAASG,iBAAUF,MAA+C;IACvE,MAAME,YACJF,OAAO,QAAQ,CAACC,SAAS,4BAA4B,CAAC,UAAU,KAChED,OAAO,QAAQ,CAACC,SAAS,4BAA4B,CAAC,WAAW,KACjED,OAAO,QAAQ,CAACC,SAAS,4BAA4B,CAAC,WAAW;IACnE,OAAOC;AACT"}
1
+ {"version":3,"file":"utils/routes.mjs","sources":["../../src/utils/routes.ts"],"sourcesContent":["import { Manifest } from '@rsdoctor/types';\n\nexport function hasCompile(routes: Manifest.RsdoctorManifestClientRoutes[]) {\n const hasCompile =\n routes.includes(Manifest.RsdoctorManifestClientRoutes.Loaders) ||\n routes.includes(Manifest.RsdoctorManifestClientRoutes.ModuleResolve) ||\n routes.includes(Manifest.RsdoctorManifestClientRoutes.Plugins);\n return hasCompile;\n}\n\nexport function hasBundle(routes: Manifest.RsdoctorManifestClientRoutes[]) {\n const hasBundle =\n routes.includes(Manifest.RsdoctorManifestClientRoutes.BundleSize) ||\n routes.includes(Manifest.RsdoctorManifestClientRoutes.ModuleGraph) ||\n routes.includes(Manifest.RsdoctorManifestClientRoutes.TreeShaking);\n return hasBundle;\n}\n"],"names":["hasCompile","routes","Manifest","hasBundle"],"mappings":";AAEO,SAASA,kBAAWC,MAA+C;IACxE,MAAMD,aACJC,OAAO,QAAQ,CAACC,SAAS,4BAA4B,CAAC,OAAO,KAC7DD,OAAO,QAAQ,CAACC,SAAS,4BAA4B,CAAC,aAAa,KACnED,OAAO,QAAQ,CAACC,SAAS,4BAA4B,CAAC,OAAO;IAC/D,OAAOF;AACT;AAEO,SAASG,iBAAUF,MAA+C;IACvE,MAAME,YACJF,OAAO,QAAQ,CAACC,SAAS,4BAA4B,CAAC,UAAU,KAChED,OAAO,QAAQ,CAACC,SAAS,4BAA4B,CAAC,WAAW,KACjED,OAAO,QAAQ,CAACC,SAAS,4BAA4B,CAAC,WAAW;IACnE,OAAOC;AACT"}