rollup-plugin-webpack-stats 3.1.0 → 3.1.1-beta.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.
@@ -8,7 +8,14 @@ path = require_runtime.__toESM(path);
8
8
  /**
9
9
  * Recursivily check if a chunk is async based on the chunks issuers
10
10
  */
11
- const lookupChunkAsync = (chunksIssuers, chunk, processedChunks = []) => {
11
+ const lookupChunkAsync = (chunksIssuers, chunk, processedChunks = [], cache = /* @__PURE__ */ new Map()) => {
12
+ const cached = cache.get(chunk.fileName);
13
+ if (cached !== void 0) return cached;
14
+ const result = lookupChunkAsyncUncached(chunksIssuers, chunk, processedChunks, cache);
15
+ cache.set(chunk.fileName, result);
16
+ return result;
17
+ };
18
+ const lookupChunkAsyncUncached = (chunksIssuers, chunk, processedChunks, cache) => {
12
19
  if (processedChunks.includes(chunk.fileName)) return true;
13
20
  if (chunk.isEntry) return false;
14
21
  if (chunk.isDynamicEntry) return true;
@@ -29,9 +36,8 @@ const lookupChunkAsync = (chunksIssuers, chunk, processedChunks = []) => {
29
36
  * - if at least one issuer is sync, the chunk is sync
30
37
  * - if none of the issuers are sync, the chunk is async
31
38
  */
32
- let isAsync = true;
33
- for (let i = 0; i < syncChunksIssuers.length && isAsync; i++) isAsync = lookupChunkAsync(chunksIssuers, syncChunksIssuers[i], [...processedChunks, chunk.fileName]);
34
- return isAsync;
39
+ const nextProcessed = [...processedChunks, chunk.fileName];
40
+ return syncChunksIssuers.every((issuer) => lookupChunkAsync(chunksIssuers, issuer, nextProcessed, cache));
35
41
  };
36
42
  /**
37
43
  * Store transformed sources
@@ -1 +1 @@
1
- {"version":3,"file":"transform.cjs","names":["getByteSize","getChunkId"],"sources":["../src/transform.ts"],"sourcesContent":["import path from 'path';\nimport type {\n Stats,\n AssetStats,\n ChunkStats,\n ModuleStats,\n} from 'rollup-plugin-stats/extract';\n\nimport { getByteSize, getChunkId } from './utils';\n\n// https://github.com/relative-ci/bundle-stats/blob/master/packages/plugin-webpack-filter/src/index.ts\nexport type WebpackStatsFilteredAsset = {\n name: string;\n size?: number;\n};\n\nexport interface WebpackStatsFilteredChunk {\n id: number | string;\n entry: boolean;\n initial: boolean;\n files?: Array<string>;\n names?: Array<string>;\n}\n\nexport interface WebpackStatsFilteredModule {\n name: string;\n size?: number;\n chunks: Array<string | number>;\n}\n\nexport interface WebpackStatsFilteredConcatenatedModule {\n name: string;\n size?: number;\n}\n\nexport interface WebpackStatsFilteredRootModule extends WebpackStatsFilteredModule {\n modules?: Array<WebpackStatsFilteredConcatenatedModule>;\n}\n\nexport interface WebpackStatsFiltered {\n builtAt: number;\n hash?: string;\n assets: Array<WebpackStatsFilteredAsset>;\n chunks: Array<WebpackStatsFilteredChunk>;\n modules: Array<WebpackStatsFilteredRootModule>;\n}\n\nexport type ChunksIssuers = Record<string, Array<ChunkStats>>;\n\n/**\n * Recursivily check if a chunk is async based on the chunks issuers\n */\nexport const lookupChunkAsync = (\n chunksIssuers: ChunksIssuers,\n chunk: ChunkStats,\n processedChunks: Array<string> = []\n): boolean => {\n // When the chunks are having a circular dependency, return true to continue the recursive check\n if (processedChunks.includes(chunk.fileName)) {\n return true;\n }\n\n if (chunk.isEntry) {\n return false;\n }\n\n if (chunk.isDynamicEntry) {\n return true;\n }\n\n const chunkIssuers = chunksIssuers[chunk.fileName];\n\n /**\n * A sync chunk without issuer chunks, is sync\n */\n if (!chunkIssuers) {\n return false;\n }\n\n const syncChunksIssuers = chunkIssuers.filter((chunkIssuer) => {\n return chunkIssuer.isDynamicEntry === false;\n });\n\n /**\n * A sync chunk with all the chunk issuer async, is async\n */\n if (syncChunksIssuers.length === 0) {\n return true;\n }\n\n /**\n * Recursively lookup for sync loads on the 2nd level issuers\n * - if at least one issuer is sync, the chunk is sync\n * - if none of the issuers are sync, the chunk is async\n */\n let isAsync = true;\n\n for (let i = 0; i < syncChunksIssuers.length && isAsync; i++) {\n isAsync = lookupChunkAsync(chunksIssuers, syncChunksIssuers[i], [\n ...processedChunks,\n chunk.fileName,\n ]);\n }\n\n return isAsync;\n};\n\ntype AssetSource = ChunkStats | AssetStats;\ntype ChunkSource = ChunkStats;\ntype ModuleSource = { fileName: string } & ModuleStats;\n\n/**\n * Store transformed sources\n */\nclass TransformSources {\n constructor() {\n this.entries = {};\n }\n\n entries: Record<string, unknown> = {};\n\n push(id: string, source: AssetSource | ChunkSource | ModuleSource) {\n this.entries[id] = source;\n }\n\n /**\n * Get asset source\n */\n getByAsset = (asset: WebpackStatsFilteredAsset): AssetSource => {\n return this.entries[asset.name] as AssetSource;\n };\n\n /**\n * Get chunk source\n */\n getByChunk = (chunk: WebpackStatsFilteredChunk): ChunkSource => {\n return this.entries[chunk.id] as ChunkSource;\n };\n\n /**\n * Get module source\n */\n getByModule = (module: WebpackStatsFilteredModule): ModuleSource => {\n return this.entries[module.name] as ModuleSource;\n };\n}\n\nexport type TransformCallback = (\n stats: WebpackStatsFiltered,\n sources: TransformSources,\n bundle: Stats\n) => WebpackStatsFiltered;\n\nconst defaultTransform: TransformCallback = (stats) => stats;\n\nexport type BundleTransformOptions = {\n /**\n * Extract module original size or rendered size\n * default: false\n */\n moduleOriginalSize?: boolean;\n /**\n * Callback function to access and mutate the resulting stats after the transformation\n */\n transform?: TransformCallback;\n};\n\nexport const bundleToWebpackStats = (\n bundle: Stats,\n pluginOptions?: BundleTransformOptions\n): WebpackStatsFiltered => {\n const options = {\n moduleOriginalSize: false,\n ...pluginOptions,\n } satisfies BundleTransformOptions;\n const { moduleOriginalSize, transform = defaultTransform } = options;\n\n const assets: Array<WebpackStatsFilteredAsset> = [];\n const chunks: Array<WebpackStatsFilteredChunk> = [];\n const moduleByFileName: Record<string, WebpackStatsFilteredModule> = {};\n const sources = new TransformSources();\n const chunksIssuers: ChunksIssuers = {};\n\n const entries = Object.values(bundle);\n\n // Collect metadata\n entries.forEach((entry) => {\n if (entry.type === 'chunk') {\n entry.imports?.forEach((chunkImportFileName) => {\n // Skip circular references\n if (\n chunksIssuers[entry.fileName]?.find(\n (chunkIssuer) => chunkIssuer.fileName === chunkImportFileName\n )\n ) {\n return;\n }\n\n if (!chunksIssuers[chunkImportFileName]) {\n chunksIssuers[chunkImportFileName] = [];\n }\n\n chunksIssuers[chunkImportFileName].push(entry);\n });\n }\n });\n\n // Process data\n entries.forEach((entry) => {\n if (entry.type === 'chunk') {\n assets.push({\n name: entry.fileName,\n size: getByteSize(entry.code),\n });\n sources.push(entry.fileName, entry);\n\n const chunkId = getChunkId(entry);\n const chunkAsync = lookupChunkAsync(chunksIssuers, entry);\n\n chunks.push({\n id: chunkId,\n entry: entry.isEntry,\n initial: !chunkAsync,\n files: [entry.fileName],\n names: [entry.name],\n });\n sources.push(chunkId, entry);\n\n Object.entries(entry.modules).forEach(([modulePath, moduleInfo]) => {\n // Remove unexpected rollup null prefix\n const normalizedModulePath = modulePath.replace('\\u0000', '');\n\n const relativeModulePath = path.relative(\n process.cwd(),\n normalizedModulePath\n );\n\n // Match webpack output - add current directory prefix for child modules\n const relativeModulePathWithPrefix = relativeModulePath.match(/^\\.\\./)\n ? relativeModulePath\n : `.${path.sep}${relativeModulePath}`;\n\n const moduleEntry = moduleByFileName[relativeModulePathWithPrefix];\n\n if (moduleEntry) {\n moduleEntry.chunks.push(chunkId);\n } else {\n moduleByFileName[relativeModulePathWithPrefix] = {\n name: relativeModulePathWithPrefix,\n size: moduleOriginalSize\n ? moduleInfo.originalLength\n : moduleInfo.renderedLength,\n chunks: [chunkId],\n };\n sources.push(relativeModulePathWithPrefix, {\n fileName: modulePath,\n ...moduleInfo,\n });\n }\n });\n } else if (entry.type === 'asset') {\n assets.push({\n name: entry.fileName,\n size: getByteSize(entry.source),\n });\n sources.push(entry.fileName, entry);\n } else {\n // noop for unknown types\n }\n });\n\n const stats: WebpackStatsFiltered = {\n builtAt: Date.now(),\n assets,\n chunks,\n modules: Object.values(moduleByFileName),\n };\n\n let result: WebpackStatsFiltered;\n\n try {\n result = transform(stats, sources, bundle);\n } catch (error) {\n console.error(\n 'Custom transform failed! Returning stats without any transforms.',\n error\n );\n result = stats;\n }\n\n return result;\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"transform.cjs","names":["getByteSize","getChunkId"],"sources":["../src/transform.ts"],"sourcesContent":["import path from 'path';\nimport type {\n Stats,\n AssetStats,\n ChunkStats,\n ModuleStats,\n} from 'rollup-plugin-stats/extract';\n\nimport { getByteSize, getChunkId } from './utils';\n\n// https://github.com/relative-ci/bundle-stats/blob/master/packages/plugin-webpack-filter/src/index.ts\nexport type WebpackStatsFilteredAsset = {\n name: string;\n size?: number;\n};\n\nexport interface WebpackStatsFilteredChunk {\n id: number | string;\n entry: boolean;\n initial: boolean;\n files?: Array<string>;\n names?: Array<string>;\n}\n\nexport interface WebpackStatsFilteredModule {\n name: string;\n size?: number;\n chunks: Array<string | number>;\n}\n\nexport interface WebpackStatsFilteredConcatenatedModule {\n name: string;\n size?: number;\n}\n\nexport interface WebpackStatsFilteredRootModule extends WebpackStatsFilteredModule {\n modules?: Array<WebpackStatsFilteredConcatenatedModule>;\n}\n\nexport interface WebpackStatsFiltered {\n builtAt: number;\n hash?: string;\n assets: Array<WebpackStatsFilteredAsset>;\n chunks: Array<WebpackStatsFilteredChunk>;\n modules: Array<WebpackStatsFilteredRootModule>;\n}\n\nexport type ChunksIssuers = Record<string, Array<ChunkStats>>;\n\n/**\n * Recursivily check if a chunk is async based on the chunks issuers\n */\nexport const lookupChunkAsync = (\n chunksIssuers: ChunksIssuers,\n chunk: ChunkStats,\n processedChunks: Array<string> = [],\n cache: Map<string, boolean> = new Map()\n): boolean => {\n const cached = cache.get(chunk.fileName);\n if (cached !== undefined) {\n return cached;\n }\n\n const result = lookupChunkAsyncUncached(\n chunksIssuers,\n chunk,\n processedChunks,\n cache\n );\n\n cache.set(chunk.fileName, result);\n return result;\n};\n\nconst lookupChunkAsyncUncached = (\n chunksIssuers: ChunksIssuers,\n chunk: ChunkStats,\n processedChunks: Array<string>,\n cache: Map<string, boolean>\n): boolean => {\n // When the chunks are having a circular dependency, return true to continue the recursive check\n if (processedChunks.includes(chunk.fileName)) {\n return true;\n }\n\n if (chunk.isEntry) {\n return false;\n }\n\n if (chunk.isDynamicEntry) {\n return true;\n }\n\n const chunkIssuers = chunksIssuers[chunk.fileName];\n\n /**\n * A sync chunk without issuer chunks, is sync\n */\n if (!chunkIssuers) {\n return false;\n }\n\n const syncChunksIssuers = chunkIssuers.filter((chunkIssuer) => {\n return chunkIssuer.isDynamicEntry === false;\n });\n\n /**\n * A sync chunk with all the chunk issuer async, is async\n */\n if (syncChunksIssuers.length === 0) {\n return true;\n }\n\n /**\n * Recursively lookup for sync loads on the 2nd level issuers\n * - if at least one issuer is sync, the chunk is sync\n * - if none of the issuers are sync, the chunk is async\n */\n const nextProcessed = [...processedChunks, chunk.fileName];\n\n return syncChunksIssuers.every((issuer) =>\n lookupChunkAsync(chunksIssuers, issuer, nextProcessed, cache)\n );\n};\n\ntype AssetSource = ChunkStats | AssetStats;\ntype ChunkSource = ChunkStats;\ntype ModuleSource = { fileName: string } & ModuleStats;\n\n/**\n * Store transformed sources\n */\nclass TransformSources {\n constructor() {\n this.entries = {};\n }\n\n entries: Record<string, unknown> = {};\n\n push(id: string, source: AssetSource | ChunkSource | ModuleSource) {\n this.entries[id] = source;\n }\n\n /**\n * Get asset source\n */\n getByAsset = (asset: WebpackStatsFilteredAsset): AssetSource => {\n return this.entries[asset.name] as AssetSource;\n };\n\n /**\n * Get chunk source\n */\n getByChunk = (chunk: WebpackStatsFilteredChunk): ChunkSource => {\n return this.entries[chunk.id] as ChunkSource;\n };\n\n /**\n * Get module source\n */\n getByModule = (module: WebpackStatsFilteredModule): ModuleSource => {\n return this.entries[module.name] as ModuleSource;\n };\n}\n\nexport type TransformCallback = (\n stats: WebpackStatsFiltered,\n sources: TransformSources,\n bundle: Stats\n) => WebpackStatsFiltered;\n\nconst defaultTransform: TransformCallback = (stats) => stats;\n\nexport type BundleTransformOptions = {\n /**\n * Extract module original size or rendered size\n * default: false\n */\n moduleOriginalSize?: boolean;\n /**\n * Callback function to access and mutate the resulting stats after the transformation\n */\n transform?: TransformCallback;\n};\n\nexport const bundleToWebpackStats = (\n bundle: Stats,\n pluginOptions?: BundleTransformOptions\n): WebpackStatsFiltered => {\n const options = {\n moduleOriginalSize: false,\n ...pluginOptions,\n } satisfies BundleTransformOptions;\n const { moduleOriginalSize, transform = defaultTransform } = options;\n\n const assets: Array<WebpackStatsFilteredAsset> = [];\n const chunks: Array<WebpackStatsFilteredChunk> = [];\n const moduleByFileName: Record<string, WebpackStatsFilteredModule> = {};\n const sources = new TransformSources();\n const chunksIssuers: ChunksIssuers = {};\n\n const entries = Object.values(bundle);\n\n // Collect metadata\n entries.forEach((entry) => {\n if (entry.type === 'chunk') {\n entry.imports?.forEach((chunkImportFileName) => {\n // Skip circular references\n if (\n chunksIssuers[entry.fileName]?.find(\n (chunkIssuer) => chunkIssuer.fileName === chunkImportFileName\n )\n ) {\n return;\n }\n\n if (!chunksIssuers[chunkImportFileName]) {\n chunksIssuers[chunkImportFileName] = [];\n }\n\n chunksIssuers[chunkImportFileName].push(entry);\n });\n }\n });\n\n // Process data\n entries.forEach((entry) => {\n if (entry.type === 'chunk') {\n assets.push({\n name: entry.fileName,\n size: getByteSize(entry.code),\n });\n sources.push(entry.fileName, entry);\n\n const chunkId = getChunkId(entry);\n const chunkAsync = lookupChunkAsync(chunksIssuers, entry);\n\n chunks.push({\n id: chunkId,\n entry: entry.isEntry,\n initial: !chunkAsync,\n files: [entry.fileName],\n names: [entry.name],\n });\n sources.push(chunkId, entry);\n\n Object.entries(entry.modules).forEach(([modulePath, moduleInfo]) => {\n // Remove unexpected rollup null prefix\n const normalizedModulePath = modulePath.replace('\\u0000', '');\n\n const relativeModulePath = path.relative(\n process.cwd(),\n normalizedModulePath\n );\n\n // Match webpack output - add current directory prefix for child modules\n const relativeModulePathWithPrefix = relativeModulePath.match(/^\\.\\./)\n ? relativeModulePath\n : `.${path.sep}${relativeModulePath}`;\n\n const moduleEntry = moduleByFileName[relativeModulePathWithPrefix];\n\n if (moduleEntry) {\n moduleEntry.chunks.push(chunkId);\n } else {\n moduleByFileName[relativeModulePathWithPrefix] = {\n name: relativeModulePathWithPrefix,\n size: moduleOriginalSize\n ? moduleInfo.originalLength\n : moduleInfo.renderedLength,\n chunks: [chunkId],\n };\n sources.push(relativeModulePathWithPrefix, {\n fileName: modulePath,\n ...moduleInfo,\n });\n }\n });\n } else if (entry.type === 'asset') {\n assets.push({\n name: entry.fileName,\n size: getByteSize(entry.source),\n });\n sources.push(entry.fileName, entry);\n } else {\n // noop for unknown types\n }\n });\n\n const stats: WebpackStatsFiltered = {\n builtAt: Date.now(),\n assets,\n chunks,\n modules: Object.values(moduleByFileName),\n };\n\n let result: WebpackStatsFiltered;\n\n try {\n result = transform(stats, sources, bundle);\n } catch (error) {\n console.error(\n 'Custom transform failed! Returning stats without any transforms.',\n error\n );\n result = stats;\n }\n\n return result;\n};\n"],"mappings":"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"}
@@ -35,7 +35,7 @@ type ChunksIssuers = Record<string, Array<ChunkStats>>;
35
35
  /**
36
36
  * Recursivily check if a chunk is async based on the chunks issuers
37
37
  */
38
- declare const lookupChunkAsync: (chunksIssuers: ChunksIssuers, chunk: ChunkStats, processedChunks?: Array<string>) => boolean;
38
+ declare const lookupChunkAsync: (chunksIssuers: ChunksIssuers, chunk: ChunkStats, processedChunks?: Array<string>, cache?: Map<string, boolean>) => boolean;
39
39
  type AssetSource = ChunkStats | AssetStats;
40
40
  type ChunkSource = ChunkStats;
41
41
  type ModuleSource = {
@@ -1 +1 @@
1
- {"version":3,"file":"transform.d.cts","names":[],"sources":["../src/transform.ts"],"mappings":";;;KAWY,yBAAA;EACV,IAAA;EACA,IAAA;AAAA;AAAA,UAGe,yBAAA;EACf,EAAA;EACA,KAAA;EACA,OAAA;EACA,KAAA,GAAQ,KAAA;EACR,KAAA,GAAQ,KAAA;AAAA;AAAA,UAGO,0BAAA;EACf,IAAA;EACA,IAAA;EACA,MAAA,EAAQ,KAAA;AAAA;AAAA,UAGO,sCAAA;EACf,IAAA;EACA,IAAA;AAAA;AAAA,UAGe,8BAAA,SAAuC,0BAAA;EACtD,OAAA,GAAU,KAAA,CAAM,sCAAA;AAAA;AAAA,UAGD,oBAAA;EACf,OAAA;EACA,IAAA;EACA,MAAA,EAAQ,KAAA,CAAM,yBAAA;EACd,MAAA,EAAQ,KAAA,CAAM,yBAAA;EACd,OAAA,EAAS,KAAA,CAAM,8BAAA;AAAA;AAAA,KAGL,aAAA,GAAgB,MAAA,SAAe,KAAA,CAAM,UAAA;;;;cAKpC,gBAAA,GACX,aAAA,EAAe,aAAA,EACf,KAAA,EAAO,UAAA,EACP,eAAA,GAAiB,KAAA;AAAA,KAoDd,WAAA,GAAc,UAAA,GAAa,UAAA;AAAA,KAC3B,WAAA,GAAc,UAAA;AAAA,KACd,YAAA;EAAiB,QAAA;AAAA,IAAqB,WAAA;;;;cAKrC,gBAAA;;EAKJ,OAAA,EAAS,MAAA;EAET,IAAA,CAAK,EAAA,UAAY,MAAA,EAAQ,WAAA,GAAc,WAAA,GAAc,YAAA;EArFC;;AAGxD;EAyFE,UAAA,GAAc,KAAA,EAAO,yBAAA,KAA4B,WAAA;;;;EAOjD,UAAA,GAAc,KAAA,EAAO,yBAAA,KAA4B,WAAA;EA5FzC;;;EAmGR,WAAA,GAAe,MAAA,EAAQ,0BAAA,KAA6B,YAAA;AAAA;AAAA,KAK1C,iBAAA,IACV,KAAA,EAAO,oBAAA,EACP,OAAA,EAAS,gBAAA,EACT,MAAA,EAAQ,KAAA,KACL,oBAAA;AAAA,KAIO,sBAAA;EAjHV;;;;EAsHA,kBAAA;EArHc;;;EAyHd,SAAA,GAAY,iBAAA;AAAA;AAAA,cAGD,oBAAA,GACX,MAAA,EAAQ,KAAA,EACR,aAAA,GAAgB,sBAAA,KACf,oBAAA"}
1
+ {"version":3,"file":"transform.d.cts","names":[],"sources":["../src/transform.ts"],"mappings":";;;KAWY,yBAAA;EACV,IAAA;EACA,IAAA;AAAA;AAAA,UAGe,yBAAA;EACf,EAAA;EACA,KAAA;EACA,OAAA;EACA,KAAA,GAAQ,KAAA;EACR,KAAA,GAAQ,KAAA;AAAA;AAAA,UAGO,0BAAA;EACf,IAAA;EACA,IAAA;EACA,MAAA,EAAQ,KAAA;AAAA;AAAA,UAGO,sCAAA;EACf,IAAA;EACA,IAAA;AAAA;AAAA,UAGe,8BAAA,SAAuC,0BAAA;EACtD,OAAA,GAAU,KAAA,CAAM,sCAAA;AAAA;AAAA,UAGD,oBAAA;EACf,OAAA;EACA,IAAA;EACA,MAAA,EAAQ,KAAA,CAAM,yBAAA;EACd,MAAA,EAAQ,KAAA,CAAM,yBAAA;EACd,OAAA,EAAS,KAAA,CAAM,8BAAA;AAAA;AAAA,KAGL,aAAA,GAAgB,MAAA,SAAe,KAAA,CAAM,UAAA;;;;cAKpC,gBAAA,GACX,aAAA,EAAe,aAAA,EACf,KAAA,EAAO,UAAA,EACP,eAAA,GAAiB,KAAA,UACjB,KAAA,GAAO,GAAA;AAAA,KAqEJ,WAAA,GAAc,UAAA,GAAa,UAAA;AAAA,KAC3B,WAAA,GAAc,UAAA;AAAA,KACd,YAAA;EAAiB,QAAA;AAAA,IAAqB,WAAA;;;;cAKrC,gBAAA;;EAKJ,OAAA,EAAS,MAAA;EAET,IAAA,CAAK,EAAA,UAAY,MAAA,EAAQ,WAAA,GAAc,WAAA,GAAc,YAAA;EAvGC;;AAGxD;EA2GE,UAAA,GAAc,KAAA,EAAO,yBAAA,KAA4B,WAAA;;;;EAOjD,UAAA,GAAc,KAAA,EAAO,yBAAA,KAA4B,WAAA;EA9GzC;;;EAqHR,WAAA,GAAe,MAAA,EAAQ,0BAAA,KAA6B,YAAA;AAAA;AAAA,KAK1C,iBAAA,IACV,KAAA,EAAO,oBAAA,EACP,OAAA,EAAS,gBAAA,EACT,MAAA,EAAQ,KAAA,KACL,oBAAA;AAAA,KAIO,sBAAA;EAnIV;;;;EAwIA,kBAAA;EAvIc;;;EA2Id,SAAA,GAAY,iBAAA;AAAA;AAAA,cAGD,oBAAA,GACX,MAAA,EAAQ,KAAA,EACR,aAAA,GAAgB,sBAAA,KACf,oBAAA"}
@@ -35,7 +35,7 @@ type ChunksIssuers = Record<string, Array<ChunkStats>>;
35
35
  /**
36
36
  * Recursivily check if a chunk is async based on the chunks issuers
37
37
  */
38
- declare const lookupChunkAsync: (chunksIssuers: ChunksIssuers, chunk: ChunkStats, processedChunks?: Array<string>) => boolean;
38
+ declare const lookupChunkAsync: (chunksIssuers: ChunksIssuers, chunk: ChunkStats, processedChunks?: Array<string>, cache?: Map<string, boolean>) => boolean;
39
39
  type AssetSource = ChunkStats | AssetStats;
40
40
  type ChunkSource = ChunkStats;
41
41
  type ModuleSource = {
@@ -1 +1 @@
1
- {"version":3,"file":"transform.d.mts","names":[],"sources":["../src/transform.ts"],"mappings":";;;KAWY,yBAAA;EACV,IAAA;EACA,IAAA;AAAA;AAAA,UAGe,yBAAA;EACf,EAAA;EACA,KAAA;EACA,OAAA;EACA,KAAA,GAAQ,KAAA;EACR,KAAA,GAAQ,KAAA;AAAA;AAAA,UAGO,0BAAA;EACf,IAAA;EACA,IAAA;EACA,MAAA,EAAQ,KAAA;AAAA;AAAA,UAGO,sCAAA;EACf,IAAA;EACA,IAAA;AAAA;AAAA,UAGe,8BAAA,SAAuC,0BAAA;EACtD,OAAA,GAAU,KAAA,CAAM,sCAAA;AAAA;AAAA,UAGD,oBAAA;EACf,OAAA;EACA,IAAA;EACA,MAAA,EAAQ,KAAA,CAAM,yBAAA;EACd,MAAA,EAAQ,KAAA,CAAM,yBAAA;EACd,OAAA,EAAS,KAAA,CAAM,8BAAA;AAAA;AAAA,KAGL,aAAA,GAAgB,MAAA,SAAe,KAAA,CAAM,UAAA;;;;cAKpC,gBAAA,GACX,aAAA,EAAe,aAAA,EACf,KAAA,EAAO,UAAA,EACP,eAAA,GAAiB,KAAA;AAAA,KAoDd,WAAA,GAAc,UAAA,GAAa,UAAA;AAAA,KAC3B,WAAA,GAAc,UAAA;AAAA,KACd,YAAA;EAAiB,QAAA;AAAA,IAAqB,WAAA;;;;cAKrC,gBAAA;;EAKJ,OAAA,EAAS,MAAA;EAET,IAAA,CAAK,EAAA,UAAY,MAAA,EAAQ,WAAA,GAAc,WAAA,GAAc,YAAA;EArFC;;AAGxD;EAyFE,UAAA,GAAc,KAAA,EAAO,yBAAA,KAA4B,WAAA;;;;EAOjD,UAAA,GAAc,KAAA,EAAO,yBAAA,KAA4B,WAAA;EA5FzC;;;EAmGR,WAAA,GAAe,MAAA,EAAQ,0BAAA,KAA6B,YAAA;AAAA;AAAA,KAK1C,iBAAA,IACV,KAAA,EAAO,oBAAA,EACP,OAAA,EAAS,gBAAA,EACT,MAAA,EAAQ,KAAA,KACL,oBAAA;AAAA,KAIO,sBAAA;EAjHV;;;;EAsHA,kBAAA;EArHc;;;EAyHd,SAAA,GAAY,iBAAA;AAAA;AAAA,cAGD,oBAAA,GACX,MAAA,EAAQ,KAAA,EACR,aAAA,GAAgB,sBAAA,KACf,oBAAA"}
1
+ {"version":3,"file":"transform.d.mts","names":[],"sources":["../src/transform.ts"],"mappings":";;;KAWY,yBAAA;EACV,IAAA;EACA,IAAA;AAAA;AAAA,UAGe,yBAAA;EACf,EAAA;EACA,KAAA;EACA,OAAA;EACA,KAAA,GAAQ,KAAA;EACR,KAAA,GAAQ,KAAA;AAAA;AAAA,UAGO,0BAAA;EACf,IAAA;EACA,IAAA;EACA,MAAA,EAAQ,KAAA;AAAA;AAAA,UAGO,sCAAA;EACf,IAAA;EACA,IAAA;AAAA;AAAA,UAGe,8BAAA,SAAuC,0BAAA;EACtD,OAAA,GAAU,KAAA,CAAM,sCAAA;AAAA;AAAA,UAGD,oBAAA;EACf,OAAA;EACA,IAAA;EACA,MAAA,EAAQ,KAAA,CAAM,yBAAA;EACd,MAAA,EAAQ,KAAA,CAAM,yBAAA;EACd,OAAA,EAAS,KAAA,CAAM,8BAAA;AAAA;AAAA,KAGL,aAAA,GAAgB,MAAA,SAAe,KAAA,CAAM,UAAA;;;;cAKpC,gBAAA,GACX,aAAA,EAAe,aAAA,EACf,KAAA,EAAO,UAAA,EACP,eAAA,GAAiB,KAAA,UACjB,KAAA,GAAO,GAAA;AAAA,KAqEJ,WAAA,GAAc,UAAA,GAAa,UAAA;AAAA,KAC3B,WAAA,GAAc,UAAA;AAAA,KACd,YAAA;EAAiB,QAAA;AAAA,IAAqB,WAAA;;;;cAKrC,gBAAA;;EAKJ,OAAA,EAAS,MAAA;EAET,IAAA,CAAK,EAAA,UAAY,MAAA,EAAQ,WAAA,GAAc,WAAA,GAAc,YAAA;EAvGC;;AAGxD;EA2GE,UAAA,GAAc,KAAA,EAAO,yBAAA,KAA4B,WAAA;;;;EAOjD,UAAA,GAAc,KAAA,EAAO,yBAAA,KAA4B,WAAA;EA9GzC;;;EAqHR,WAAA,GAAe,MAAA,EAAQ,0BAAA,KAA6B,YAAA;AAAA;AAAA,KAK1C,iBAAA,IACV,KAAA,EAAO,oBAAA,EACP,OAAA,EAAS,gBAAA,EACT,MAAA,EAAQ,KAAA,KACL,oBAAA;AAAA,KAIO,sBAAA;EAnIV;;;;EAwIA,kBAAA;EAvIc;;;EA2Id,SAAA,GAAY,iBAAA;AAAA;AAAA,cAGD,oBAAA,GACX,MAAA,EAAQ,KAAA,EACR,aAAA,GAAgB,sBAAA,KACf,oBAAA"}
@@ -5,7 +5,14 @@ import path from "path";
5
5
  /**
6
6
  * Recursivily check if a chunk is async based on the chunks issuers
7
7
  */
8
- const lookupChunkAsync = (chunksIssuers, chunk, processedChunks = []) => {
8
+ const lookupChunkAsync = (chunksIssuers, chunk, processedChunks = [], cache = /* @__PURE__ */ new Map()) => {
9
+ const cached = cache.get(chunk.fileName);
10
+ if (cached !== void 0) return cached;
11
+ const result = lookupChunkAsyncUncached(chunksIssuers, chunk, processedChunks, cache);
12
+ cache.set(chunk.fileName, result);
13
+ return result;
14
+ };
15
+ const lookupChunkAsyncUncached = (chunksIssuers, chunk, processedChunks, cache) => {
9
16
  if (processedChunks.includes(chunk.fileName)) return true;
10
17
  if (chunk.isEntry) return false;
11
18
  if (chunk.isDynamicEntry) return true;
@@ -26,9 +33,8 @@ const lookupChunkAsync = (chunksIssuers, chunk, processedChunks = []) => {
26
33
  * - if at least one issuer is sync, the chunk is sync
27
34
  * - if none of the issuers are sync, the chunk is async
28
35
  */
29
- let isAsync = true;
30
- for (let i = 0; i < syncChunksIssuers.length && isAsync; i++) isAsync = lookupChunkAsync(chunksIssuers, syncChunksIssuers[i], [...processedChunks, chunk.fileName]);
31
- return isAsync;
36
+ const nextProcessed = [...processedChunks, chunk.fileName];
37
+ return syncChunksIssuers.every((issuer) => lookupChunkAsync(chunksIssuers, issuer, nextProcessed, cache));
32
38
  };
33
39
  /**
34
40
  * Store transformed sources
@@ -1 +1 @@
1
- {"version":3,"file":"transform.mjs","names":[],"sources":["../src/transform.ts"],"sourcesContent":["import path from 'path';\nimport type {\n Stats,\n AssetStats,\n ChunkStats,\n ModuleStats,\n} from 'rollup-plugin-stats/extract';\n\nimport { getByteSize, getChunkId } from './utils';\n\n// https://github.com/relative-ci/bundle-stats/blob/master/packages/plugin-webpack-filter/src/index.ts\nexport type WebpackStatsFilteredAsset = {\n name: string;\n size?: number;\n};\n\nexport interface WebpackStatsFilteredChunk {\n id: number | string;\n entry: boolean;\n initial: boolean;\n files?: Array<string>;\n names?: Array<string>;\n}\n\nexport interface WebpackStatsFilteredModule {\n name: string;\n size?: number;\n chunks: Array<string | number>;\n}\n\nexport interface WebpackStatsFilteredConcatenatedModule {\n name: string;\n size?: number;\n}\n\nexport interface WebpackStatsFilteredRootModule extends WebpackStatsFilteredModule {\n modules?: Array<WebpackStatsFilteredConcatenatedModule>;\n}\n\nexport interface WebpackStatsFiltered {\n builtAt: number;\n hash?: string;\n assets: Array<WebpackStatsFilteredAsset>;\n chunks: Array<WebpackStatsFilteredChunk>;\n modules: Array<WebpackStatsFilteredRootModule>;\n}\n\nexport type ChunksIssuers = Record<string, Array<ChunkStats>>;\n\n/**\n * Recursivily check if a chunk is async based on the chunks issuers\n */\nexport const lookupChunkAsync = (\n chunksIssuers: ChunksIssuers,\n chunk: ChunkStats,\n processedChunks: Array<string> = []\n): boolean => {\n // When the chunks are having a circular dependency, return true to continue the recursive check\n if (processedChunks.includes(chunk.fileName)) {\n return true;\n }\n\n if (chunk.isEntry) {\n return false;\n }\n\n if (chunk.isDynamicEntry) {\n return true;\n }\n\n const chunkIssuers = chunksIssuers[chunk.fileName];\n\n /**\n * A sync chunk without issuer chunks, is sync\n */\n if (!chunkIssuers) {\n return false;\n }\n\n const syncChunksIssuers = chunkIssuers.filter((chunkIssuer) => {\n return chunkIssuer.isDynamicEntry === false;\n });\n\n /**\n * A sync chunk with all the chunk issuer async, is async\n */\n if (syncChunksIssuers.length === 0) {\n return true;\n }\n\n /**\n * Recursively lookup for sync loads on the 2nd level issuers\n * - if at least one issuer is sync, the chunk is sync\n * - if none of the issuers are sync, the chunk is async\n */\n let isAsync = true;\n\n for (let i = 0; i < syncChunksIssuers.length && isAsync; i++) {\n isAsync = lookupChunkAsync(chunksIssuers, syncChunksIssuers[i], [\n ...processedChunks,\n chunk.fileName,\n ]);\n }\n\n return isAsync;\n};\n\ntype AssetSource = ChunkStats | AssetStats;\ntype ChunkSource = ChunkStats;\ntype ModuleSource = { fileName: string } & ModuleStats;\n\n/**\n * Store transformed sources\n */\nclass TransformSources {\n constructor() {\n this.entries = {};\n }\n\n entries: Record<string, unknown> = {};\n\n push(id: string, source: AssetSource | ChunkSource | ModuleSource) {\n this.entries[id] = source;\n }\n\n /**\n * Get asset source\n */\n getByAsset = (asset: WebpackStatsFilteredAsset): AssetSource => {\n return this.entries[asset.name] as AssetSource;\n };\n\n /**\n * Get chunk source\n */\n getByChunk = (chunk: WebpackStatsFilteredChunk): ChunkSource => {\n return this.entries[chunk.id] as ChunkSource;\n };\n\n /**\n * Get module source\n */\n getByModule = (module: WebpackStatsFilteredModule): ModuleSource => {\n return this.entries[module.name] as ModuleSource;\n };\n}\n\nexport type TransformCallback = (\n stats: WebpackStatsFiltered,\n sources: TransformSources,\n bundle: Stats\n) => WebpackStatsFiltered;\n\nconst defaultTransform: TransformCallback = (stats) => stats;\n\nexport type BundleTransformOptions = {\n /**\n * Extract module original size or rendered size\n * default: false\n */\n moduleOriginalSize?: boolean;\n /**\n * Callback function to access and mutate the resulting stats after the transformation\n */\n transform?: TransformCallback;\n};\n\nexport const bundleToWebpackStats = (\n bundle: Stats,\n pluginOptions?: BundleTransformOptions\n): WebpackStatsFiltered => {\n const options = {\n moduleOriginalSize: false,\n ...pluginOptions,\n } satisfies BundleTransformOptions;\n const { moduleOriginalSize, transform = defaultTransform } = options;\n\n const assets: Array<WebpackStatsFilteredAsset> = [];\n const chunks: Array<WebpackStatsFilteredChunk> = [];\n const moduleByFileName: Record<string, WebpackStatsFilteredModule> = {};\n const sources = new TransformSources();\n const chunksIssuers: ChunksIssuers = {};\n\n const entries = Object.values(bundle);\n\n // Collect metadata\n entries.forEach((entry) => {\n if (entry.type === 'chunk') {\n entry.imports?.forEach((chunkImportFileName) => {\n // Skip circular references\n if (\n chunksIssuers[entry.fileName]?.find(\n (chunkIssuer) => chunkIssuer.fileName === chunkImportFileName\n )\n ) {\n return;\n }\n\n if (!chunksIssuers[chunkImportFileName]) {\n chunksIssuers[chunkImportFileName] = [];\n }\n\n chunksIssuers[chunkImportFileName].push(entry);\n });\n }\n });\n\n // Process data\n entries.forEach((entry) => {\n if (entry.type === 'chunk') {\n assets.push({\n name: entry.fileName,\n size: getByteSize(entry.code),\n });\n sources.push(entry.fileName, entry);\n\n const chunkId = getChunkId(entry);\n const chunkAsync = lookupChunkAsync(chunksIssuers, entry);\n\n chunks.push({\n id: chunkId,\n entry: entry.isEntry,\n initial: !chunkAsync,\n files: [entry.fileName],\n names: [entry.name],\n });\n sources.push(chunkId, entry);\n\n Object.entries(entry.modules).forEach(([modulePath, moduleInfo]) => {\n // Remove unexpected rollup null prefix\n const normalizedModulePath = modulePath.replace('\\u0000', '');\n\n const relativeModulePath = path.relative(\n process.cwd(),\n normalizedModulePath\n );\n\n // Match webpack output - add current directory prefix for child modules\n const relativeModulePathWithPrefix = relativeModulePath.match(/^\\.\\./)\n ? relativeModulePath\n : `.${path.sep}${relativeModulePath}`;\n\n const moduleEntry = moduleByFileName[relativeModulePathWithPrefix];\n\n if (moduleEntry) {\n moduleEntry.chunks.push(chunkId);\n } else {\n moduleByFileName[relativeModulePathWithPrefix] = {\n name: relativeModulePathWithPrefix,\n size: moduleOriginalSize\n ? moduleInfo.originalLength\n : moduleInfo.renderedLength,\n chunks: [chunkId],\n };\n sources.push(relativeModulePathWithPrefix, {\n fileName: modulePath,\n ...moduleInfo,\n });\n }\n });\n } else if (entry.type === 'asset') {\n assets.push({\n name: entry.fileName,\n size: getByteSize(entry.source),\n });\n sources.push(entry.fileName, entry);\n } else {\n // noop for unknown types\n }\n });\n\n const stats: WebpackStatsFiltered = {\n builtAt: Date.now(),\n assets,\n chunks,\n modules: Object.values(moduleByFileName),\n };\n\n let result: WebpackStatsFiltered;\n\n try {\n result = transform(stats, sources, bundle);\n } catch (error) {\n console.error(\n 'Custom transform failed! Returning stats without any transforms.',\n error\n );\n result = stats;\n }\n\n return result;\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"transform.mjs","names":[],"sources":["../src/transform.ts"],"sourcesContent":["import path from 'path';\nimport type {\n Stats,\n AssetStats,\n ChunkStats,\n ModuleStats,\n} from 'rollup-plugin-stats/extract';\n\nimport { getByteSize, getChunkId } from './utils';\n\n// https://github.com/relative-ci/bundle-stats/blob/master/packages/plugin-webpack-filter/src/index.ts\nexport type WebpackStatsFilteredAsset = {\n name: string;\n size?: number;\n};\n\nexport interface WebpackStatsFilteredChunk {\n id: number | string;\n entry: boolean;\n initial: boolean;\n files?: Array<string>;\n names?: Array<string>;\n}\n\nexport interface WebpackStatsFilteredModule {\n name: string;\n size?: number;\n chunks: Array<string | number>;\n}\n\nexport interface WebpackStatsFilteredConcatenatedModule {\n name: string;\n size?: number;\n}\n\nexport interface WebpackStatsFilteredRootModule extends WebpackStatsFilteredModule {\n modules?: Array<WebpackStatsFilteredConcatenatedModule>;\n}\n\nexport interface WebpackStatsFiltered {\n builtAt: number;\n hash?: string;\n assets: Array<WebpackStatsFilteredAsset>;\n chunks: Array<WebpackStatsFilteredChunk>;\n modules: Array<WebpackStatsFilteredRootModule>;\n}\n\nexport type ChunksIssuers = Record<string, Array<ChunkStats>>;\n\n/**\n * Recursivily check if a chunk is async based on the chunks issuers\n */\nexport const lookupChunkAsync = (\n chunksIssuers: ChunksIssuers,\n chunk: ChunkStats,\n processedChunks: Array<string> = [],\n cache: Map<string, boolean> = new Map()\n): boolean => {\n const cached = cache.get(chunk.fileName);\n if (cached !== undefined) {\n return cached;\n }\n\n const result = lookupChunkAsyncUncached(\n chunksIssuers,\n chunk,\n processedChunks,\n cache\n );\n\n cache.set(chunk.fileName, result);\n return result;\n};\n\nconst lookupChunkAsyncUncached = (\n chunksIssuers: ChunksIssuers,\n chunk: ChunkStats,\n processedChunks: Array<string>,\n cache: Map<string, boolean>\n): boolean => {\n // When the chunks are having a circular dependency, return true to continue the recursive check\n if (processedChunks.includes(chunk.fileName)) {\n return true;\n }\n\n if (chunk.isEntry) {\n return false;\n }\n\n if (chunk.isDynamicEntry) {\n return true;\n }\n\n const chunkIssuers = chunksIssuers[chunk.fileName];\n\n /**\n * A sync chunk without issuer chunks, is sync\n */\n if (!chunkIssuers) {\n return false;\n }\n\n const syncChunksIssuers = chunkIssuers.filter((chunkIssuer) => {\n return chunkIssuer.isDynamicEntry === false;\n });\n\n /**\n * A sync chunk with all the chunk issuer async, is async\n */\n if (syncChunksIssuers.length === 0) {\n return true;\n }\n\n /**\n * Recursively lookup for sync loads on the 2nd level issuers\n * - if at least one issuer is sync, the chunk is sync\n * - if none of the issuers are sync, the chunk is async\n */\n const nextProcessed = [...processedChunks, chunk.fileName];\n\n return syncChunksIssuers.every((issuer) =>\n lookupChunkAsync(chunksIssuers, issuer, nextProcessed, cache)\n );\n};\n\ntype AssetSource = ChunkStats | AssetStats;\ntype ChunkSource = ChunkStats;\ntype ModuleSource = { fileName: string } & ModuleStats;\n\n/**\n * Store transformed sources\n */\nclass TransformSources {\n constructor() {\n this.entries = {};\n }\n\n entries: Record<string, unknown> = {};\n\n push(id: string, source: AssetSource | ChunkSource | ModuleSource) {\n this.entries[id] = source;\n }\n\n /**\n * Get asset source\n */\n getByAsset = (asset: WebpackStatsFilteredAsset): AssetSource => {\n return this.entries[asset.name] as AssetSource;\n };\n\n /**\n * Get chunk source\n */\n getByChunk = (chunk: WebpackStatsFilteredChunk): ChunkSource => {\n return this.entries[chunk.id] as ChunkSource;\n };\n\n /**\n * Get module source\n */\n getByModule = (module: WebpackStatsFilteredModule): ModuleSource => {\n return this.entries[module.name] as ModuleSource;\n };\n}\n\nexport type TransformCallback = (\n stats: WebpackStatsFiltered,\n sources: TransformSources,\n bundle: Stats\n) => WebpackStatsFiltered;\n\nconst defaultTransform: TransformCallback = (stats) => stats;\n\nexport type BundleTransformOptions = {\n /**\n * Extract module original size or rendered size\n * default: false\n */\n moduleOriginalSize?: boolean;\n /**\n * Callback function to access and mutate the resulting stats after the transformation\n */\n transform?: TransformCallback;\n};\n\nexport const bundleToWebpackStats = (\n bundle: Stats,\n pluginOptions?: BundleTransformOptions\n): WebpackStatsFiltered => {\n const options = {\n moduleOriginalSize: false,\n ...pluginOptions,\n } satisfies BundleTransformOptions;\n const { moduleOriginalSize, transform = defaultTransform } = options;\n\n const assets: Array<WebpackStatsFilteredAsset> = [];\n const chunks: Array<WebpackStatsFilteredChunk> = [];\n const moduleByFileName: Record<string, WebpackStatsFilteredModule> = {};\n const sources = new TransformSources();\n const chunksIssuers: ChunksIssuers = {};\n\n const entries = Object.values(bundle);\n\n // Collect metadata\n entries.forEach((entry) => {\n if (entry.type === 'chunk') {\n entry.imports?.forEach((chunkImportFileName) => {\n // Skip circular references\n if (\n chunksIssuers[entry.fileName]?.find(\n (chunkIssuer) => chunkIssuer.fileName === chunkImportFileName\n )\n ) {\n return;\n }\n\n if (!chunksIssuers[chunkImportFileName]) {\n chunksIssuers[chunkImportFileName] = [];\n }\n\n chunksIssuers[chunkImportFileName].push(entry);\n });\n }\n });\n\n // Process data\n entries.forEach((entry) => {\n if (entry.type === 'chunk') {\n assets.push({\n name: entry.fileName,\n size: getByteSize(entry.code),\n });\n sources.push(entry.fileName, entry);\n\n const chunkId = getChunkId(entry);\n const chunkAsync = lookupChunkAsync(chunksIssuers, entry);\n\n chunks.push({\n id: chunkId,\n entry: entry.isEntry,\n initial: !chunkAsync,\n files: [entry.fileName],\n names: [entry.name],\n });\n sources.push(chunkId, entry);\n\n Object.entries(entry.modules).forEach(([modulePath, moduleInfo]) => {\n // Remove unexpected rollup null prefix\n const normalizedModulePath = modulePath.replace('\\u0000', '');\n\n const relativeModulePath = path.relative(\n process.cwd(),\n normalizedModulePath\n );\n\n // Match webpack output - add current directory prefix for child modules\n const relativeModulePathWithPrefix = relativeModulePath.match(/^\\.\\./)\n ? relativeModulePath\n : `.${path.sep}${relativeModulePath}`;\n\n const moduleEntry = moduleByFileName[relativeModulePathWithPrefix];\n\n if (moduleEntry) {\n moduleEntry.chunks.push(chunkId);\n } else {\n moduleByFileName[relativeModulePathWithPrefix] = {\n name: relativeModulePathWithPrefix,\n size: moduleOriginalSize\n ? moduleInfo.originalLength\n : moduleInfo.renderedLength,\n chunks: [chunkId],\n };\n sources.push(relativeModulePathWithPrefix, {\n fileName: modulePath,\n ...moduleInfo,\n });\n }\n });\n } else if (entry.type === 'asset') {\n assets.push({\n name: entry.fileName,\n size: getByteSize(entry.source),\n });\n sources.push(entry.fileName, entry);\n } else {\n // noop for unknown types\n }\n });\n\n const stats: WebpackStatsFiltered = {\n builtAt: Date.now(),\n assets,\n chunks,\n modules: Object.values(moduleByFileName),\n };\n\n let result: WebpackStatsFiltered;\n\n try {\n result = transform(stats, sources, bundle);\n } catch (error) {\n console.error(\n 'Custom transform failed! Returning stats without any transforms.',\n error\n );\n result = stats;\n }\n\n return result;\n};\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "rollup-plugin-webpack-stats",
3
3
  "description": "Rollup/Vite/Rolldown plugin to generate a stats JSON file with a bundle-stats webpack-compatible structure",
4
- "version": "3.1.0",
4
+ "version": "3.1.1-beta.0",
5
5
  "private": false,
6
6
  "license": "MIT",
7
7
  "keywords": [