@atlaspack/inspector 0.0.19-canary.3998
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.
- package/LICENSE +201 -0
- package/README.md +126 -0
- package/bin/atlaspack-inspector.js +2 -0
- package/lib/backend/cli.js +4 -0
- package/lib/backend/config/logger.js +16 -0
- package/lib/backend/config/middleware/cacheDataMiddleware.js +60 -0
- package/lib/backend/config/middleware/errorHandlingMiddleware.js +17 -0
- package/lib/backend/config/middleware/errorHandlingMiddleware.test.js +44 -0
- package/lib/backend/config/middleware/loggingMiddleware.js +22 -0
- package/lib/backend/controllers/BundleGraphController.js +42 -0
- package/lib/backend/controllers/CacheDataController.js +143 -0
- package/lib/backend/controllers/FrontendAssetsController.js +61 -0
- package/lib/backend/controllers/TreeMapController.js +108 -0
- package/lib/backend/controllers/mcp/InspectorMCP.js +231 -0
- package/lib/backend/controllers/mcp/InspectorMCPController.js +16 -0
- package/lib/backend/errors/HTTPError.js +16 -0
- package/lib/backend/errors/HTTPError.test.js +21 -0
- package/lib/backend/index.js +177 -0
- package/lib/backend/services/AnalyticsService.js +86 -0
- package/lib/backend/services/LazyValue.js +33 -0
- package/lib/backend/services/LazyValue.test.js +12 -0
- package/lib/backend/services/buildJsonGraph.js +86 -0
- package/lib/backend/services/buildTreemap.js +140 -0
- package/lib/backend/services/buildTreemapBundle.test.js +298 -0
- package/lib/backend/services/findSourceCodeUrl.js +107 -0
- package/lib/backend/services/findSourceCodeUrl.test.js +216 -0
- package/lib/backend/services/getCacheStats.js +36 -0
- package/lib/backend/services/getCacheStats.test.js +162 -0
- package/lib/backend/services/getDisplayName.js +18 -0
- package/lib/backend/services/getDisplayName.test.js +71 -0
- package/lib/backend/services/loadCacheData.js +209 -0
- package/lib/backend/services/loadCacheData.test.js +79 -0
- package/lib/backend/testing/TemporaryDirectory.js +46 -0
- package/lib/frontend/node_modules/@atlaspack/packager-js/lib/dev-prelude.js +145 -0
- package/lib/frontend/node_modules/@atlaspack/packager-js/src/dev-prelude.js +145 -0
- package/package.json +75 -0
- package/screenshots/bottom-up.png +0 -0
- package/screenshots/cache-inspector.png +0 -0
- package/screenshots/treemap.png +0 -0
- package/src/backend/README.md +14 -0
- package/src/backend/cli.ts +3 -0
- package/src/backend/config/logger.ts +14 -0
- package/src/backend/config/middleware/cacheDataMiddleware.ts +94 -0
- package/src/backend/config/middleware/errorHandlingMiddleware.test.ts +52 -0
- package/src/backend/config/middleware/errorHandlingMiddleware.ts +20 -0
- package/src/backend/config/middleware/loggingMiddleware.ts +24 -0
- package/src/backend/controllers/BundleGraphController.ts +73 -0
- package/src/backend/controllers/CacheDataController.ts +187 -0
- package/src/backend/controllers/FrontendAssetsController.ts +28 -0
- package/src/backend/controllers/TreeMapController.ts +143 -0
- package/src/backend/controllers/mcp/InspectorMCP.ts +311 -0
- package/src/backend/controllers/mcp/InspectorMCPController.ts +17 -0
- package/src/backend/errors/HTTPError.test.ts +19 -0
- package/src/backend/errors/HTTPError.ts +14 -0
- package/src/backend/globals.d.ts +9 -0
- package/src/backend/index.ts +271 -0
- package/src/backend/services/AnalyticsService.ts +118 -0
- package/src/backend/services/LazyValue.test.ts +13 -0
- package/src/backend/services/LazyValue.ts +29 -0
- package/src/backend/services/buildJsonGraph.ts +124 -0
- package/src/backend/services/buildTreemap.ts +273 -0
- package/src/backend/services/buildTreemapBundle.test.ts +348 -0
- package/src/backend/services/findSourceCodeUrl.test.ts +228 -0
- package/src/backend/services/findSourceCodeUrl.ts +146 -0
- package/src/backend/services/getCacheStats.test.ts +169 -0
- package/src/backend/services/getCacheStats.ts +46 -0
- package/src/backend/services/getDisplayName.test.ts +84 -0
- package/src/backend/services/getDisplayName.ts +20 -0
- package/src/backend/services/loadCacheData.test.ts +101 -0
- package/src/backend/services/loadCacheData.ts +294 -0
- package/src/backend/testing/TemporaryDirectory.ts +50 -0
- package/src/frontend/.atlaspackrc +4 -0
- package/src/frontend/.eslintrc.json +19 -0
- package/src/frontend/dist/atlassian-dark-brand-refresh.91b786da.js +2 -0
- package/src/frontend/dist/atlassian-dark-brand-refresh.91b786da.js.map +1 -0
- package/src/frontend/dist/atlassian-dark-future.59ebadca.js +2 -0
- package/src/frontend/dist/atlassian-dark-future.59ebadca.js.map +1 -0
- package/src/frontend/dist/atlassian-dark-increased-contrast.ff6775f2.js +2 -0
- package/src/frontend/dist/atlassian-dark-increased-contrast.ff6775f2.js.map +1 -0
- package/src/frontend/dist/atlassian-dark.ad679134.js +2 -0
- package/src/frontend/dist/atlassian-dark.ad679134.js.map +1 -0
- package/src/frontend/dist/atlassian-legacy-dark.8aa27f7f.js +2 -0
- package/src/frontend/dist/atlassian-legacy-dark.8aa27f7f.js.map +1 -0
- package/src/frontend/dist/atlassian-legacy-light.2eb372ce.js +2 -0
- package/src/frontend/dist/atlassian-legacy-light.2eb372ce.js.map +1 -0
- package/src/frontend/dist/atlassian-light-brand-refresh.fadcab0a.js +2 -0
- package/src/frontend/dist/atlassian-light-brand-refresh.fadcab0a.js.map +1 -0
- package/src/frontend/dist/atlassian-light-future.612afe8a.js +2 -0
- package/src/frontend/dist/atlassian-light-future.612afe8a.js.map +1 -0
- package/src/frontend/dist/atlassian-light-increased-contrast.7161cd79.js +2 -0
- package/src/frontend/dist/atlassian-light-increased-contrast.7161cd79.js.map +1 -0
- package/src/frontend/dist/atlassian-light.bc343d4c.js +2 -0
- package/src/frontend/dist/atlassian-light.bc343d4c.js.map +1 -0
- package/src/frontend/dist/atlassian-shape.b92d69c0.js +2 -0
- package/src/frontend/dist/atlassian-shape.b92d69c0.js.map +1 -0
- package/src/frontend/dist/atlassian-spacing.60ddd8e7.js +2 -0
- package/src/frontend/dist/atlassian-spacing.60ddd8e7.js.map +1 -0
- package/src/frontend/dist/atlassian-typography-adg3.f88947f6.js +2 -0
- package/src/frontend/dist/atlassian-typography-adg3.f88947f6.js.map +1 -0
- package/src/frontend/dist/atlassian-typography-modernized.42016c51.js +2 -0
- package/src/frontend/dist/atlassian-typography-modernized.42016c51.js.map +1 -0
- package/src/frontend/dist/atlassian-typography-refreshed.ec0d111b.js +2 -0
- package/src/frontend/dist/atlassian-typography-refreshed.ec0d111b.js.map +1 -0
- package/src/frontend/dist/atlassian-typography.66d7e8f4.js +2 -0
- package/src/frontend/dist/atlassian-typography.66d7e8f4.js.map +1 -0
- package/src/frontend/dist/badge-light.7e55986a.png +0 -0
- package/src/frontend/dist/custom-theme.4680282a.js +2 -0
- package/src/frontend/dist/custom-theme.4680282a.js.map +1 -0
- package/src/frontend/dist/drag-handle.136830d3.js +2 -0
- package/src/frontend/dist/drag-handle.136830d3.js.map +1 -0
- package/src/frontend/dist/drag-handle.63bdb345.css +2 -0
- package/src/frontend/dist/drag-handle.63bdb345.css.map +1 -0
- package/src/frontend/dist/index.a41fafce.css +2 -0
- package/src/frontend/dist/index.a41fafce.css.map +1 -0
- package/src/frontend/dist/index.a4ce2b12.js +28 -0
- package/src/frontend/dist/index.a4ce2b12.js.map +1 -0
- package/src/frontend/dist/index.html +1 -0
- package/src/frontend/dist/index.runtime.a729d997.js +2 -0
- package/src/frontend/dist/index.runtime.a729d997.js.map +1 -0
- package/src/frontend/dist/refractor.2c1fd9a1.js +2 -0
- package/src/frontend/dist/refractor.2c1fd9a1.js.map +1 -0
- package/src/frontend/index.html +11 -0
- package/src/frontend/jest.config.js +16 -0
- package/src/frontend/package.json +64 -0
- package/src/frontend/src/APIError.test.ts +72 -0
- package/src/frontend/src/APIError.tsx +29 -0
- package/src/frontend/src/AppRoutes.tsx +56 -0
- package/src/frontend/src/hack-feature-flags.ts +6 -0
- package/src/frontend/src/main.tsx +50 -0
- package/src/frontend/src/test/stubCssModule.js +1 -0
- package/src/frontend/src/ui/App.module.css +122 -0
- package/src/frontend/src/ui/App.module.css.d.ts +8 -0
- package/src/frontend/src/ui/AppLayout/AppLayout.tsx +26 -0
- package/src/frontend/src/ui/AppLayout/SidebarNavigation/LinkItem.tsx +26 -0
- package/src/frontend/src/ui/AppLayout/SidebarNavigation/SidebarNavigation.tsx +45 -0
- package/src/frontend/src/ui/AppLayout/TopNavigation/Logo.module.css +12 -0
- package/src/frontend/src/ui/AppLayout/TopNavigation/Logo.module.css.d.ts +4 -0
- package/src/frontend/src/ui/AppLayout/TopNavigation/Logo.tsx +11 -0
- package/src/frontend/src/ui/AppLayout/TopNavigation/TopNavigation.module.css +14 -0
- package/src/frontend/src/ui/AppLayout/TopNavigation/TopNavigation.module.css.d.ts +3 -0
- package/src/frontend/src/ui/AppLayout/TopNavigation/TopNavigation.tsx +45 -0
- package/src/frontend/src/ui/AppLayout/TopNavigation/badge-light.png +0 -0
- package/src/frontend/src/ui/AppLayout/TopNavigation/logo-light.png +0 -0
- package/src/frontend/src/ui/DefaultLoadingIndicator/DefaultLoadingIndicator.module.css +9 -0
- package/src/frontend/src/ui/DefaultLoadingIndicator/DefaultLoadingIndicator.module.css.d.ts +3 -0
- package/src/frontend/src/ui/DefaultLoadingIndicator/DefaultLoadingIndicator.test.tsx +15 -0
- package/src/frontend/src/ui/DefaultLoadingIndicator/DefaultLoadingIndicator.tsx +14 -0
- package/src/frontend/src/ui/app/StatsPage.tsx +77 -0
- package/src/frontend/src/ui/app/cache/CacheKeysIndexPage.tsx +13 -0
- package/src/frontend/src/ui/app/cache/CacheKeysPage.module.css +11 -0
- package/src/frontend/src/ui/app/cache/CacheKeysPage.module.css.d.ts +4 -0
- package/src/frontend/src/ui/app/cache/CacheKeysPage.tsx +23 -0
- package/src/frontend/src/ui/app/cache/[key]/CacheValuePage.tsx +40 -0
- package/src/frontend/src/ui/app/cache/ui/CacheKeyList.module.css +40 -0
- package/src/frontend/src/ui/app/cache/ui/CacheKeyList.module.css.d.ts +7 -0
- package/src/frontend/src/ui/app/cache/ui/CacheKeyList.tsx +187 -0
- package/src/frontend/src/ui/app/cache-invalidation/CacheInvalidationPage.tsx +22 -0
- package/src/frontend/src/ui/app/cache-invalidation/[fileId]/CacheInvalidationFilePage.tsx +22 -0
- package/src/frontend/src/ui/app/cache-invalidation/ui/CacheFileList.module.css +40 -0
- package/src/frontend/src/ui/app/cache-invalidation/ui/CacheFileList.module.css.d.ts +7 -0
- package/src/frontend/src/ui/app/cache-invalidation/ui/CacheFileList.tsx +185 -0
- package/src/frontend/src/ui/app/treemap/BottomPanelResizeState.test.ts +25 -0
- package/src/frontend/src/ui/app/treemap/BottomPanelResizeState.tsx +48 -0
- package/src/frontend/src/ui/app/treemap/FoamTreemapPage.module.css +24 -0
- package/src/frontend/src/ui/app/treemap/FoamTreemapPage.module.css.d.ts +6 -0
- package/src/frontend/src/ui/app/treemap/FoamTreemapPage.tsx +47 -0
- package/src/frontend/src/ui/app/treemap/controllers/RelatedBundlesController.tsx +41 -0
- package/src/frontend/src/ui/app/treemap/controllers/UrlFocusController.tsx +33 -0
- package/src/frontend/src/ui/app/treemap/ui/BottomPanel/BottomPanel.module.css +24 -0
- package/src/frontend/src/ui/app/treemap/ui/BottomPanel/BottomPanel.module.css.d.ts +5 -0
- package/src/frontend/src/ui/app/treemap/ui/BottomPanel/BottomPanel.tsx +24 -0
- package/src/frontend/src/ui/app/treemap/ui/BottomPanel/FocusedGroupInfo/AdvancedSettings.module.css +13 -0
- package/src/frontend/src/ui/app/treemap/ui/BottomPanel/FocusedGroupInfo/AdvancedSettings.module.css.d.ts +5 -0
- package/src/frontend/src/ui/app/treemap/ui/BottomPanel/FocusedGroupInfo/AdvancedSettings.tsx +53 -0
- package/src/frontend/src/ui/app/treemap/ui/BottomPanel/FocusedGroupInfo/AssetTable/AssetTable.tsx +135 -0
- package/src/frontend/src/ui/app/treemap/ui/BottomPanel/FocusedGroupInfo/AssetTable/CollapsibleTable/CollapsibleTable.module.css +7 -0
- package/src/frontend/src/ui/app/treemap/ui/BottomPanel/FocusedGroupInfo/AssetTable/CollapsibleTable/CollapsibleTable.module.css.d.ts +3 -0
- package/src/frontend/src/ui/app/treemap/ui/BottomPanel/FocusedGroupInfo/AssetTable/CollapsibleTable/CollapsibleTable.tsx +123 -0
- package/src/frontend/src/ui/app/treemap/ui/BottomPanel/FocusedGroupInfo/AssetTable/CollapsibleTable/CollapsibleTableModel.tsx +18 -0
- package/src/frontend/src/ui/app/treemap/ui/BottomPanel/FocusedGroupInfo/AssetTable/CollapsibleTable/CollapsibleTableRow.module.css +20 -0
- package/src/frontend/src/ui/app/treemap/ui/BottomPanel/FocusedGroupInfo/AssetTable/CollapsibleTable/CollapsibleTableRow.module.css.d.ts +6 -0
- package/src/frontend/src/ui/app/treemap/ui/BottomPanel/FocusedGroupInfo/AssetTable/CollapsibleTable/CollapsibleTableRow.tsx +79 -0
- package/src/frontend/src/ui/app/treemap/ui/BottomPanel/FocusedGroupInfo/AssetTable/getFileURL.test.ts +19 -0
- package/src/frontend/src/ui/app/treemap/ui/BottomPanel/FocusedGroupInfo/AssetTable/getFileURL.ts +24 -0
- package/src/frontend/src/ui/app/treemap/ui/BottomPanel/FocusedGroupInfo/FocusedGroupInfo.module.css +20 -0
- package/src/frontend/src/ui/app/treemap/ui/BottomPanel/FocusedGroupInfo/FocusedGroupInfo.module.css.d.ts +5 -0
- package/src/frontend/src/ui/app/treemap/ui/BottomPanel/FocusedGroupInfo/FocusedGroupInfo.tsx +42 -0
- package/src/frontend/src/ui/app/treemap/ui/BottomPanel/FocusedGroupInfo/FocusedGroupInfoInner.module.css +29 -0
- package/src/frontend/src/ui/app/treemap/ui/BottomPanel/FocusedGroupInfo/FocusedGroupInfoInner.module.css.d.ts +6 -0
- package/src/frontend/src/ui/app/treemap/ui/BottomPanel/FocusedGroupInfo/FocusedGroupInfoInner.tsx +107 -0
- package/src/frontend/src/ui/app/treemap/ui/BottomPanel/FocusedGroupInfo/GraphContainer.module.css +7 -0
- package/src/frontend/src/ui/app/treemap/ui/BottomPanel/FocusedGroupInfo/GraphContainer.module.css.d.ts +3 -0
- package/src/frontend/src/ui/app/treemap/ui/BottomPanel/FocusedGroupInfo/GraphContainer.tsx +20 -0
- package/src/frontend/src/ui/app/treemap/ui/BottomPanel/FocusedGroupInfo/SourceCodeURL.tsx +5 -0
- package/src/frontend/src/ui/app/treemap/ui/BundleGraphRenderer.module.css +13 -0
- package/src/frontend/src/ui/app/treemap/ui/BundleGraphRenderer.module.css.d.ts +4 -0
- package/src/frontend/src/ui/app/treemap/ui/BundleGraphRenderer.tsx +95 -0
- package/src/frontend/src/ui/app/treemap/ui/FocusBreadcrumbs/FocusBreadcrumbs.module.css +6 -0
- package/src/frontend/src/ui/app/treemap/ui/FocusBreadcrumbs/FocusBreadcrumbs.module.css.d.ts +3 -0
- package/src/frontend/src/ui/app/treemap/ui/FocusBreadcrumbs/FocusBreadcrumbs.tsx +49 -0
- package/src/frontend/src/ui/app/treemap/ui/SigmaGraph.module.css +5 -0
- package/src/frontend/src/ui/app/treemap/ui/SigmaGraph.module.css.d.ts +3 -0
- package/src/frontend/src/ui/app/treemap/ui/SigmaGraph.tsx +80 -0
- package/src/frontend/src/ui/app/treemap/ui/Treemap.tsx +14 -0
- package/src/frontend/src/ui/app/treemap/ui/TreemapRenderer/ImpactScore.module.css +32 -0
- package/src/frontend/src/ui/app/treemap/ui/TreemapRenderer/ImpactScore.module.css.d.ts +5 -0
- package/src/frontend/src/ui/app/treemap/ui/TreemapRenderer/ImpactScore.tsx +24 -0
- package/src/frontend/src/ui/app/treemap/ui/TreemapRenderer/TreemapRenderer.module.css +14 -0
- package/src/frontend/src/ui/app/treemap/ui/TreemapRenderer/TreemapRenderer.module.css.d.ts +4 -0
- package/src/frontend/src/ui/app/treemap/ui/TreemapRenderer/TreemapRenderer.tsx +271 -0
- package/src/frontend/src/ui/app/treemap/ui/TreemapRenderer/TreemapTooltip.module.css +15 -0
- package/src/frontend/src/ui/app/treemap/ui/TreemapRenderer/TreemapTooltip.module.css.d.ts +4 -0
- package/src/frontend/src/ui/app/treemap/ui/TreemapRenderer/TreemapTooltip.tsx +111 -0
- package/src/frontend/src/ui/app/treemap/ui/TreemapRenderer/controllers/useStableCallback.test.ts +27 -0
- package/src/frontend/src/ui/app/treemap/ui/TreemapRenderer/controllers/useStableCallback.ts +21 -0
- package/src/frontend/src/ui/app/treemap/ui/TreemapRenderer/useMouseMoveController.ts +20 -0
- package/src/frontend/src/ui/globals.css +26 -0
- package/src/frontend/src/ui/globals.css.d.ts +1 -0
- package/src/frontend/src/ui/globals.d.ts +9 -0
- package/src/frontend/src/ui/model/ViewModel.test.ts +31 -0
- package/src/frontend/src/ui/model/ViewModel.ts +62 -0
- package/src/frontend/src/ui/not-found/NotFoundPage.module.css +7 -0
- package/src/frontend/src/ui/not-found/NotFoundPage.module.css.d.ts +3 -0
- package/src/frontend/src/ui/not-found/NotFoundPage.tsx +9 -0
- package/src/frontend/src/ui/types/Graph.tsx +12 -0
- package/src/frontend/src/ui/util/ErrorBoundary.module.css +3 -0
- package/src/frontend/src/ui/util/ErrorBoundary.module.css.d.ts +3 -0
- package/src/frontend/src/ui/util/ErrorBoundary.test.tsx +65 -0
- package/src/frontend/src/ui/util/ErrorBoundary.tsx +75 -0
- package/src/frontend/src/ui/util/colorPalette.tsx +122 -0
- package/src/frontend/src/ui/util/formatBytes.test.ts +13 -0
- package/src/frontend/src/ui/util/formatBytes.tsx +9 -0
- package/src/frontend/src/ui/util/getRandomDarkerColor.tsx +31 -0
- package/src/frontend/tsconfig.json +12 -0
- package/src/frontend/yarn.lock +0 -0
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.configureInspectorApp = configureInspectorApp;
|
|
7
|
+
exports.buildInspectorApp = buildInspectorApp;
|
|
8
|
+
exports.main = main;
|
|
9
|
+
/* eslint-disable import/first */
|
|
10
|
+
// Stateful import to ensure serializers are loaded
|
|
11
|
+
require('@atlaspack/core');
|
|
12
|
+
const commander_1 = require("commander");
|
|
13
|
+
const express_1 = __importDefault(require("express"));
|
|
14
|
+
const cors_1 = __importDefault(require("cors"));
|
|
15
|
+
const path_1 = __importDefault(require("path"));
|
|
16
|
+
const feature_flags_1 = require("@atlaspack/feature-flags");
|
|
17
|
+
const loadCacheData_1 = require("./services/loadCacheData");
|
|
18
|
+
const logger_1 = require("./config/logger");
|
|
19
|
+
const errorHandlingMiddleware_1 = require("./config/middleware/errorHandlingMiddleware");
|
|
20
|
+
const loggingMiddleware_1 = require("./config/middleware/loggingMiddleware");
|
|
21
|
+
const FrontendAssetsController_1 = require("./controllers/FrontendAssetsController");
|
|
22
|
+
const cacheDataMiddleware_1 = require("./config/middleware/cacheDataMiddleware");
|
|
23
|
+
const BundleGraphController_1 = require("./controllers/BundleGraphController");
|
|
24
|
+
const TreeMapController_1 = require("./controllers/TreeMapController");
|
|
25
|
+
const CacheDataController_1 = require("./controllers/CacheDataController");
|
|
26
|
+
const findSourceCodeUrl_1 = require("./services/findSourceCodeUrl");
|
|
27
|
+
const InspectorMCPController_1 = require("./controllers/mcp/InspectorMCPController");
|
|
28
|
+
const child_process_1 = require("child_process");
|
|
29
|
+
const AnalyticsService_1 = require("./services/AnalyticsService");
|
|
30
|
+
/**
|
|
31
|
+
* Configures the inspector app.
|
|
32
|
+
*
|
|
33
|
+
* - Find paths for the source repository, project and cache.
|
|
34
|
+
* - Open the cache and deserialize bundler data out of it.
|
|
35
|
+
* - Build the tree-map model.
|
|
36
|
+
*/
|
|
37
|
+
function configureInspectorApp({ projectRoot: projectRootFromFlags, target, }) {
|
|
38
|
+
const flags = {
|
|
39
|
+
...feature_flags_1.DEFAULT_FEATURE_FLAGS,
|
|
40
|
+
cachePerformanceImprovements: true,
|
|
41
|
+
};
|
|
42
|
+
(0, feature_flags_1.setFeatureFlags)(flags);
|
|
43
|
+
const projectRoot = projectRootFromFlags ?? (0, findSourceCodeUrl_1.findProjectRoot)(target) ?? path_1.default.dirname(target);
|
|
44
|
+
const repositoryRoot = (0, findSourceCodeUrl_1.findRepositoryRoot)(target) ?? path_1.default.dirname(target);
|
|
45
|
+
const sourceCodeURL = (0, findSourceCodeUrl_1.findSourceCodeURL)(target);
|
|
46
|
+
logger_1.logger.debug({ target, projectRoot, repositoryRoot, sourceCodeURL }, 'Found paths');
|
|
47
|
+
const cacheData = (0, loadCacheData_1.loadCacheData)({ target, projectRoot, repositoryRoot });
|
|
48
|
+
return {
|
|
49
|
+
cacheData,
|
|
50
|
+
projectRoot,
|
|
51
|
+
repositoryRoot,
|
|
52
|
+
sourceCodeURL,
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Wire-up the express server app.
|
|
57
|
+
*/
|
|
58
|
+
function buildInspectorApp({ cacheData, projectRoot, repositoryRoot, sourceCodeURL, }) {
|
|
59
|
+
const app = (0, express_1.default)();
|
|
60
|
+
app.use((0, loggingMiddleware_1.loggingMiddleware)());
|
|
61
|
+
app.use((0, cors_1.default)({
|
|
62
|
+
origin: /http:\/\/localhost:(\d+)/,
|
|
63
|
+
credentials: true,
|
|
64
|
+
}));
|
|
65
|
+
app.use(express_1.default.json());
|
|
66
|
+
app.use((0, cacheDataMiddleware_1.cacheDataMiddleware)(cacheData));
|
|
67
|
+
app.use((0, FrontendAssetsController_1.makeFrontendAssetsController)());
|
|
68
|
+
app.use((0, BundleGraphController_1.makeBundleGraphController)({ projectRoot, repositoryRoot }));
|
|
69
|
+
app.use((0, TreeMapController_1.makeTreemapController)({
|
|
70
|
+
projectRoot,
|
|
71
|
+
repositoryRoot,
|
|
72
|
+
sourceCodeURL,
|
|
73
|
+
}));
|
|
74
|
+
app.use((0, InspectorMCPController_1.makeInspectorMCPController)());
|
|
75
|
+
app.use((0, CacheDataController_1.makeCacheDataController)());
|
|
76
|
+
app.use(errorHandlingMiddleware_1.errorHandlingMiddleware);
|
|
77
|
+
return app;
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Executes `atlaspack build` to build the client application for the inspector.
|
|
81
|
+
*
|
|
82
|
+
* The inspector requires `cachePerformanceImprovements` to be enabled.
|
|
83
|
+
*
|
|
84
|
+
* @param targets - The targets/entry-points to build.
|
|
85
|
+
*/
|
|
86
|
+
async function buildClientApplicationForInspector(targets) {
|
|
87
|
+
logger_1.logger.info({ targets }, 'Building app...');
|
|
88
|
+
const child = (0, child_process_1.spawn)('yarn', [
|
|
89
|
+
'atlaspack',
|
|
90
|
+
'build',
|
|
91
|
+
'--feature-flag',
|
|
92
|
+
'cachePerformanceImprovements=true',
|
|
93
|
+
...targets,
|
|
94
|
+
], {
|
|
95
|
+
shell: true,
|
|
96
|
+
stdio: 'inherit',
|
|
97
|
+
});
|
|
98
|
+
await new Promise((resolve, reject) => {
|
|
99
|
+
child.on('error', (error) => {
|
|
100
|
+
logger_1.logger.error(error, 'Build error');
|
|
101
|
+
process.exitCode = 1;
|
|
102
|
+
reject(error);
|
|
103
|
+
});
|
|
104
|
+
child.on('exit', (code) => {
|
|
105
|
+
logger_1.logger.info(`Build process exited with code ${code}`);
|
|
106
|
+
if (code !== 0) {
|
|
107
|
+
process.exitCode = code ?? 1;
|
|
108
|
+
reject(new Error(`Build failed with code ${code}`));
|
|
109
|
+
}
|
|
110
|
+
else {
|
|
111
|
+
resolve(null);
|
|
112
|
+
}
|
|
113
|
+
});
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* CLI entry point for `@atlaspack/inspector`.
|
|
118
|
+
*
|
|
119
|
+
* Usage:
|
|
120
|
+
*
|
|
121
|
+
* ```bash
|
|
122
|
+
* yarn @atlaspack/inspector --target ./path/to/cache --project-root ./path/to/project
|
|
123
|
+
* ```
|
|
124
|
+
*/
|
|
125
|
+
function main() {
|
|
126
|
+
const version = require('../../package.json').version;
|
|
127
|
+
let isStartCommand = false;
|
|
128
|
+
commander_1.program.name('atlaspack-inspector').version(version);
|
|
129
|
+
AnalyticsService_1.analyticsService.sendEvent({
|
|
130
|
+
data: {
|
|
131
|
+
name: 'atlaspack-inspector-start',
|
|
132
|
+
action: 'atlaspack-inspector-start',
|
|
133
|
+
},
|
|
134
|
+
});
|
|
135
|
+
const command = commander_1.program
|
|
136
|
+
.command('start [options]', { isDefault: true })
|
|
137
|
+
.description('Start the inspector server')
|
|
138
|
+
.option('-t, --target <path>', 'Path to the target cache', process.cwd())
|
|
139
|
+
.option('-p, --port <port>', 'Port to run the server on', '3000')
|
|
140
|
+
.option('--project-root <path>', 'Path to the project root', undefined)
|
|
141
|
+
.action(() => {
|
|
142
|
+
isStartCommand = true;
|
|
143
|
+
});
|
|
144
|
+
commander_1.program
|
|
145
|
+
.command('build <target...>')
|
|
146
|
+
.description('Build an app with atlaspack-inspector required feature-flags')
|
|
147
|
+
.action(async (targets) => {
|
|
148
|
+
await buildClientApplicationForInspector(targets);
|
|
149
|
+
});
|
|
150
|
+
commander_1.program.parse(process.argv);
|
|
151
|
+
if (!isStartCommand) {
|
|
152
|
+
return;
|
|
153
|
+
}
|
|
154
|
+
const options = command.opts();
|
|
155
|
+
const inspectorAppParams = configureInspectorApp({
|
|
156
|
+
target: options.target,
|
|
157
|
+
projectRoot: options.projectRoot,
|
|
158
|
+
});
|
|
159
|
+
const app = buildInspectorApp(inspectorAppParams);
|
|
160
|
+
const port = Number(options.port ?? process.env.PORT ?? 3000);
|
|
161
|
+
const server = app.listen(port, () => {
|
|
162
|
+
const address = server.address();
|
|
163
|
+
if (address == null) {
|
|
164
|
+
logger_1.logger.error('Server did not start correctly');
|
|
165
|
+
}
|
|
166
|
+
else {
|
|
167
|
+
const addressString = typeof address === 'string'
|
|
168
|
+
? address
|
|
169
|
+
: `http://localhost:${address.port}`;
|
|
170
|
+
logger_1.logger.info(`Server is running on ${addressString}`);
|
|
171
|
+
}
|
|
172
|
+
});
|
|
173
|
+
server.on('error', (error) => {
|
|
174
|
+
logger_1.logger.error(error, 'HTTP Server error');
|
|
175
|
+
});
|
|
176
|
+
return server;
|
|
177
|
+
}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.analyticsService = exports.AnalyticsService = void 0;
|
|
4
|
+
const crypto_1 = require("crypto");
|
|
5
|
+
const logger_1 = require("../config/logger");
|
|
6
|
+
/**
|
|
7
|
+
* Reports analytics events to a daemon server running at port 16621.
|
|
8
|
+
*
|
|
9
|
+
* The application will automatically check if the service is available and will not report
|
|
10
|
+
* anything if it is not.
|
|
11
|
+
*/
|
|
12
|
+
class AnalyticsService {
|
|
13
|
+
constructor() {
|
|
14
|
+
this.daemonUrl = 'http://localhost:16621';
|
|
15
|
+
this.isAvailable = null;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Return the analytics service status.
|
|
19
|
+
*/
|
|
20
|
+
async checkAvailable() {
|
|
21
|
+
const response = await fetch(`${this.daemonUrl}/version`);
|
|
22
|
+
if (!response.ok) {
|
|
23
|
+
const status = response.status;
|
|
24
|
+
const body = await response.json();
|
|
25
|
+
logger_1.logger.warn({ body, status }, 'Failed to check analytics service availability');
|
|
26
|
+
this.isAvailable = false;
|
|
27
|
+
return { available: false };
|
|
28
|
+
}
|
|
29
|
+
const data = await response.json();
|
|
30
|
+
this.isAvailable = true;
|
|
31
|
+
return {
|
|
32
|
+
available: data.version !== 'unknown',
|
|
33
|
+
name: data.name,
|
|
34
|
+
version: data.version,
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Record an analytics event.
|
|
39
|
+
*/
|
|
40
|
+
async sendEvent(event) {
|
|
41
|
+
try {
|
|
42
|
+
if (this.isAvailable == null) {
|
|
43
|
+
const available = await this.checkAvailable();
|
|
44
|
+
logger_1.logger.debug(available, `Analytics service is ${available.available ? 'available' : 'not available'}`);
|
|
45
|
+
}
|
|
46
|
+
if (!this.isAvailable) {
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
const body = {
|
|
50
|
+
id: `atlaspack-inspector-${(0, crypto_1.randomUUID)()}`,
|
|
51
|
+
cwd: process.cwd(),
|
|
52
|
+
type: 'DISCRETE_EVENT',
|
|
53
|
+
...event,
|
|
54
|
+
data: {
|
|
55
|
+
startTimestamp: new Date().toISOString(),
|
|
56
|
+
status: 'success',
|
|
57
|
+
product: 'atlaspack-inspector',
|
|
58
|
+
category: 'atlaspack-internal',
|
|
59
|
+
name: 'atlaspack-inspector',
|
|
60
|
+
...event.data,
|
|
61
|
+
},
|
|
62
|
+
};
|
|
63
|
+
logger_1.logger.debug({ event: body }, 'Tracking analytics event');
|
|
64
|
+
const response = await fetch(`${this.daemonUrl}/events`, {
|
|
65
|
+
method: 'POST',
|
|
66
|
+
headers: {
|
|
67
|
+
'Content-Type': 'application/json',
|
|
68
|
+
},
|
|
69
|
+
body: JSON.stringify(body),
|
|
70
|
+
});
|
|
71
|
+
if (!response.ok) {
|
|
72
|
+
const status = response.status;
|
|
73
|
+
const body = await response.json();
|
|
74
|
+
logger_1.logger.warn({ body, status }, 'Failed to send analytics event, skipping');
|
|
75
|
+
return;
|
|
76
|
+
}
|
|
77
|
+
const json = await response.json();
|
|
78
|
+
logger_1.logger.debug({ json }, 'Analytics event sent');
|
|
79
|
+
}
|
|
80
|
+
catch (err) {
|
|
81
|
+
logger_1.logger.warn({ err }, 'Failed to send analytics event');
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
exports.AnalyticsService = AnalyticsService;
|
|
86
|
+
exports.analyticsService = new AnalyticsService();
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.LazyValue = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* A value that is computed once on read, then cached.
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
*
|
|
9
|
+
* ```ts
|
|
10
|
+
* const lazyComputation = new LazyValue(() => doExpensiveComputation());
|
|
11
|
+
*
|
|
12
|
+
* const result1 = lazyComputation.get();
|
|
13
|
+
* const result2 = lazyComputation.get();
|
|
14
|
+
*
|
|
15
|
+
* assert(result1 === result2);
|
|
16
|
+
* ```
|
|
17
|
+
*/
|
|
18
|
+
class LazyValue {
|
|
19
|
+
constructor(factory) {
|
|
20
|
+
this.factory = factory;
|
|
21
|
+
this.value = null;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Builds the value if it hasn't been built and returns it.
|
|
25
|
+
*/
|
|
26
|
+
get() {
|
|
27
|
+
if (this.value == null) {
|
|
28
|
+
this.value = this.factory();
|
|
29
|
+
}
|
|
30
|
+
return this.value;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
exports.LazyValue = LazyValue;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const LazyValue_1 = require("./LazyValue");
|
|
4
|
+
describe('LazyValue', () => {
|
|
5
|
+
it('should return the value by calling the factory function once', () => {
|
|
6
|
+
const mock = jest.fn().mockImplementation(() => 'test');
|
|
7
|
+
const lazyValue = new LazyValue_1.LazyValue(mock);
|
|
8
|
+
expect(lazyValue.get()).toBe('test');
|
|
9
|
+
expect(lazyValue.get()).toBe('test');
|
|
10
|
+
expect(mock).toHaveBeenCalledTimes(1);
|
|
11
|
+
});
|
|
12
|
+
});
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.buildJsonGraph = buildJsonGraph;
|
|
4
|
+
const graph_1 = require("@atlaspack/graph");
|
|
5
|
+
const getDisplayName_1 = require("./getDisplayName");
|
|
6
|
+
/**
|
|
7
|
+
* Build a simplified representation of a graph for a front-end to render.
|
|
8
|
+
*
|
|
9
|
+
* The graph is simplified by:
|
|
10
|
+
* - being a JSON serialisable object
|
|
11
|
+
* - filtering out unnecessary nodes
|
|
12
|
+
* - limiting the depth of nodes returned from the root
|
|
13
|
+
*/
|
|
14
|
+
function buildJsonGraph(graph, rootNodeId, filter = () => true, extra) {
|
|
15
|
+
const depths = new Map();
|
|
16
|
+
const rootNodeIndex = rootNodeId
|
|
17
|
+
? graph.getNodeIdByContentKey(rootNodeId)
|
|
18
|
+
: graph.rootNodeId;
|
|
19
|
+
// build path from `graph.rootNodeId` node to `rootNodeId`
|
|
20
|
+
let path = null;
|
|
21
|
+
{
|
|
22
|
+
const stack = [];
|
|
23
|
+
const visited = new Set();
|
|
24
|
+
graph.dfs({
|
|
25
|
+
visit: {
|
|
26
|
+
enter(nodeId, context, actions) {
|
|
27
|
+
stack.push(nodeId);
|
|
28
|
+
visited.add(nodeId);
|
|
29
|
+
if (nodeId === rootNodeIndex) {
|
|
30
|
+
actions.stop();
|
|
31
|
+
path = stack.slice();
|
|
32
|
+
}
|
|
33
|
+
},
|
|
34
|
+
exit() {
|
|
35
|
+
stack.pop();
|
|
36
|
+
},
|
|
37
|
+
},
|
|
38
|
+
getChildren: (nodeId) => {
|
|
39
|
+
return graph.getNodeIdsConnectedFrom(nodeId, graph_1.ALL_EDGE_TYPES);
|
|
40
|
+
},
|
|
41
|
+
startNodeId: graph.rootNodeId,
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
// Build depths of all nodes in the graph
|
|
45
|
+
{
|
|
46
|
+
const topologicalOrder = [];
|
|
47
|
+
graph.traverse({
|
|
48
|
+
exit(nodeId) {
|
|
49
|
+
topologicalOrder.push(nodeId);
|
|
50
|
+
},
|
|
51
|
+
}, rootNodeIndex, graph_1.ALL_EDGE_TYPES);
|
|
52
|
+
topologicalOrder.reverse();
|
|
53
|
+
for (let i = 0; i < topologicalOrder.length; i++) {
|
|
54
|
+
const nodeId = topologicalOrder[i];
|
|
55
|
+
const currentDepth = depths.get(nodeId) ?? 0;
|
|
56
|
+
const neighbors = graph.getNodeIdsConnectedFrom(nodeId, graph_1.ALL_EDGE_TYPES);
|
|
57
|
+
for (const other of neighbors) {
|
|
58
|
+
const increment = filter(graph.getNode(other)) ? 1 : 0;
|
|
59
|
+
depths.set(other, Math.max(currentDepth + increment, depths.get(other) ?? 0));
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
const allNodes = [];
|
|
64
|
+
graph.traverse((nodeId) => {
|
|
65
|
+
allNodes.push(nodeId);
|
|
66
|
+
}, rootNodeIndex, graph_1.ALL_EDGE_TYPES);
|
|
67
|
+
const maxDepth = 100;
|
|
68
|
+
return {
|
|
69
|
+
nodes: allNodes
|
|
70
|
+
.filter((nodeId) => (depths.get(nodeId) ?? 0) < maxDepth)
|
|
71
|
+
.filter((nodeId) => filter(graph.getNode(nodeId)))
|
|
72
|
+
.map((nodeId) => ({
|
|
73
|
+
id: graph.getNode(nodeId).id,
|
|
74
|
+
nodeId,
|
|
75
|
+
path: nodeId === rootNodeIndex
|
|
76
|
+
? (path?.map((id) => graph.getNode(id).id) ?? null)
|
|
77
|
+
: null,
|
|
78
|
+
displayName: (0, getDisplayName_1.getDisplayName)(graph.getNode(nodeId)),
|
|
79
|
+
level: depths.get(nodeId) ?? 0,
|
|
80
|
+
edges: graph
|
|
81
|
+
.getNodeIdsConnectedFrom(nodeId, graph_1.ALL_EDGE_TYPES)
|
|
82
|
+
.map((nodeId) => graph.getNode(nodeId).id),
|
|
83
|
+
extra: extra ? extra(graph.getNode(nodeId)) : null,
|
|
84
|
+
})),
|
|
85
|
+
};
|
|
86
|
+
}
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.getWriteBundleRequestsByBundleId = getWriteBundleRequestsByBundleId;
|
|
7
|
+
exports.buildTreemapBundle = buildTreemapBundle;
|
|
8
|
+
exports.findBundleInfo = findBundleInfo;
|
|
9
|
+
exports.buildTreemap = buildTreemap;
|
|
10
|
+
// @ts-expect-error TS2749
|
|
11
|
+
const RequestTracker_js_1 = require("@atlaspack/core/lib/RequestTracker.js");
|
|
12
|
+
const fs_1 = __importDefault(require("fs"));
|
|
13
|
+
const path_1 = __importDefault(require("path"));
|
|
14
|
+
const logger_1 = require("../config/logger");
|
|
15
|
+
/**
|
|
16
|
+
* In order to find the sizes of bundles, we look-up write bundle requests for each bundle
|
|
17
|
+
* in this build, then read the sizes of each file from disk.
|
|
18
|
+
*/
|
|
19
|
+
function getWriteBundleRequestsByBundleId(requestTracker) {
|
|
20
|
+
const writeBundleRequests = requestTracker.graph.nodes.filter((requestNode) => requestNode &&
|
|
21
|
+
requestNode.type === 1 &&
|
|
22
|
+
requestNode.requestType === RequestTracker_js_1.requestTypes.write_bundle_request);
|
|
23
|
+
return new Map(writeBundleRequests.map((request) => [
|
|
24
|
+
request.result?.bundleId ?? '',
|
|
25
|
+
request,
|
|
26
|
+
]));
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Builds a tree-map model for a bundle graph.
|
|
30
|
+
*
|
|
31
|
+
* The tree-map is a tree structure starting at the bundle and having layers for
|
|
32
|
+
* each asset sub-directory in its asset tree.
|
|
33
|
+
*
|
|
34
|
+
* Asset sizes are calculated from the asset size stats, which should represent
|
|
35
|
+
* sizes post-transformation, but before minification.
|
|
36
|
+
*
|
|
37
|
+
* Bundle sizes are read from the bundle files on disk.
|
|
38
|
+
*
|
|
39
|
+
* The sub-directories are sized to the size of their children.
|
|
40
|
+
*/
|
|
41
|
+
function buildTreemapBundle({ writeBundleRequestsByBundleId, node, projectRoot, repositoryRoot, bundleGraph, }) {
|
|
42
|
+
const writeBundleRequest = writeBundleRequestsByBundleId.get(node.id);
|
|
43
|
+
const { size, filePath } = findBundleInfo({
|
|
44
|
+
writeBundleRequest,
|
|
45
|
+
projectRoot,
|
|
46
|
+
repositoryRoot,
|
|
47
|
+
node,
|
|
48
|
+
});
|
|
49
|
+
// this is the directory structure
|
|
50
|
+
const assetTree = {
|
|
51
|
+
id: `${node.id}::/`,
|
|
52
|
+
path: '',
|
|
53
|
+
children: {},
|
|
54
|
+
size: 0,
|
|
55
|
+
};
|
|
56
|
+
const assets = [];
|
|
57
|
+
bundleGraph.traverseAssets(node.value, (asset) => {
|
|
58
|
+
assets.push(asset);
|
|
59
|
+
});
|
|
60
|
+
for (const asset of assets) {
|
|
61
|
+
const filePath = path_1.default.isAbsolute(asset.filePath)
|
|
62
|
+
? path_1.default.relative(repositoryRoot, asset.filePath)
|
|
63
|
+
: asset.filePath;
|
|
64
|
+
const parts = filePath.split('/');
|
|
65
|
+
const assetSize = asset.stats.size;
|
|
66
|
+
let current = assetTree;
|
|
67
|
+
let currentSubpath = '';
|
|
68
|
+
for (let part of parts) {
|
|
69
|
+
currentSubpath += '/' + part;
|
|
70
|
+
current.size += assetSize;
|
|
71
|
+
current.children[part] = current.children[part] ?? {
|
|
72
|
+
id: `${node.id}::${currentSubpath}`,
|
|
73
|
+
path: currentSubpath,
|
|
74
|
+
children: {},
|
|
75
|
+
size: 0,
|
|
76
|
+
};
|
|
77
|
+
current = current.children[part];
|
|
78
|
+
}
|
|
79
|
+
current.size += assetSize;
|
|
80
|
+
}
|
|
81
|
+
const treemapBundle = {
|
|
82
|
+
id: node.id,
|
|
83
|
+
displayName: node.value.displayName,
|
|
84
|
+
bundle: node,
|
|
85
|
+
size,
|
|
86
|
+
filePath: filePath ?? '',
|
|
87
|
+
assetTree,
|
|
88
|
+
};
|
|
89
|
+
return treemapBundle;
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Finds the size and file path of a bundle.
|
|
93
|
+
*
|
|
94
|
+
* If the file path is not absolute, it is made absolute by joining it with the project root.
|
|
95
|
+
*
|
|
96
|
+
* If the file path is not found, the size is 0.
|
|
97
|
+
*
|
|
98
|
+
* If the file path is found but the file cannot be read, an error is logged and the size is 0.
|
|
99
|
+
*/
|
|
100
|
+
function findBundleInfo({ writeBundleRequest, projectRoot, repositoryRoot, node, }) {
|
|
101
|
+
let filePath = writeBundleRequest?.result?.filePath
|
|
102
|
+
? path_1.default.isAbsolute(writeBundleRequest?.result?.filePath)
|
|
103
|
+
? writeBundleRequest.result.filePath
|
|
104
|
+
: path_1.default.join(projectRoot, writeBundleRequest.result.filePath)
|
|
105
|
+
: null;
|
|
106
|
+
let size = 0;
|
|
107
|
+
try {
|
|
108
|
+
size = filePath ? fs_1.default.statSync(filePath).size : 0;
|
|
109
|
+
}
|
|
110
|
+
catch (e) {
|
|
111
|
+
logger_1.logger.error({ filePath, nodeId: node.id, error: e }, `Error getting size of bundle at ${filePath}`);
|
|
112
|
+
}
|
|
113
|
+
filePath = filePath
|
|
114
|
+
? path_1.default.isAbsolute(filePath)
|
|
115
|
+
? path_1.default.relative(repositoryRoot, filePath)
|
|
116
|
+
: filePath
|
|
117
|
+
: null;
|
|
118
|
+
return { size, filePath };
|
|
119
|
+
}
|
|
120
|
+
function buildTreemap({ projectRoot, repositoryRoot, bundleGraph, requestTracker, }) {
|
|
121
|
+
const treemap = {
|
|
122
|
+
bundles: [],
|
|
123
|
+
totalSize: 0,
|
|
124
|
+
};
|
|
125
|
+
const writeBundleRequestsByBundleId = getWriteBundleRequestsByBundleId(requestTracker);
|
|
126
|
+
bundleGraph._graph.nodes.forEach((node) => {
|
|
127
|
+
if (node.type === 'bundle') {
|
|
128
|
+
const treemapBundle = buildTreemapBundle({
|
|
129
|
+
writeBundleRequestsByBundleId,
|
|
130
|
+
node,
|
|
131
|
+
projectRoot,
|
|
132
|
+
repositoryRoot,
|
|
133
|
+
bundleGraph,
|
|
134
|
+
});
|
|
135
|
+
treemap.bundles.push(treemapBundle);
|
|
136
|
+
treemap.totalSize += treemapBundle.size;
|
|
137
|
+
}
|
|
138
|
+
});
|
|
139
|
+
return treemap;
|
|
140
|
+
}
|