From 112ac3838d64b910fb78a04edcfa641ac21f60e8 Mon Sep 17 00:00:00 2001 From: Denis Bardadym Date: Fri, 27 Dec 2024 11:04:21 +0100 Subject: [PATCH] Remove flamegraph, it does not bring any difference comparing to treemap or sunburst --- CHANGELOG.md | 2 + plugin/render-template.ts | 1 - plugin/template-types.ts | 3 +- rollup.config-dev.js | 2 +- rollup.config.js | 2 +- src/flamegraph/chart.tsx | 56 - src/flamegraph/color.ts | 81 - src/flamegraph/const.ts | 2 - src/flamegraph/flamegraph.tsx | 39 - src/flamegraph/index.tsx | 124 - src/flamegraph/main.tsx | 99 - src/flamegraph/node.tsx | 103 - src/flamegraph/tooltip.tsx | 165 - test/__snapshots__/e2e-rolldown.test.ts.snap | 27288 ++++++---------- test/__snapshots__/e2e.test.ts.snap | 27290 ++++++---------- test/__snapshots__/gh59.test.ts.snap | 27324 ++++++----------- test/__snapshots__/gh69.test.ts.snap | 27260 ++++++---------- test/__snapshots__/gh93.test.ts.snap | 27156 ++++++---------- test/util.ts | 2 +- 19 files changed, 44710 insertions(+), 92289 deletions(-) delete mode 100644 src/flamegraph/chart.tsx delete mode 100644 src/flamegraph/color.ts delete mode 100644 src/flamegraph/const.ts delete mode 100644 src/flamegraph/flamegraph.tsx delete mode 100644 src/flamegraph/index.tsx delete mode 100644 src/flamegraph/main.tsx delete mode 100644 src/flamegraph/node.tsx delete mode 100644 src/flamegraph/tooltip.tsx diff --git a/CHANGELOG.md b/CHANGELOG.md index cf4f3e8..e8d22d5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,8 @@ ## Next +* Remove `flamegraph` +* Merge #191. Thanks to @guillaumeduboc * Update deps * Switch jest -> vitest * Switch eslint -> oxlint diff --git a/plugin/render-template.ts b/plugin/render-template.ts index ec00450..38833dc 100644 --- a/plugin/render-template.ts +++ b/plugin/render-template.ts @@ -123,7 +123,6 @@ const TEMPLATE_TYPE_RENDERED: Record< treemap: buildHtml("treemap"), "raw-data": async ({ data }) => outputRawData(data), list: async ({ data }) => outputPlainTextList(data), - flamegraph: buildHtml("flamegraph"), }; export const renderTemplate = (templateType: TemplateType, options: RenderTemplateOptions) => { diff --git a/plugin/template-types.ts b/plugin/template-types.ts index 3a8fa5b..bd73977 100644 --- a/plugin/template-types.ts +++ b/plugin/template-types.ts @@ -1,6 +1,6 @@ "use strict"; -export type TemplateType = "sunburst" | "treemap" | "network" | "raw-data" | "list" | "flamegraph"; +export type TemplateType = "sunburst" | "treemap" | "network" | "raw-data" | "list" ; const templates: ReadonlyArray = [ "sunburst", @@ -8,7 +8,6 @@ const templates: ReadonlyArray = [ "network", "list", "raw-data", - "flamegraph", ]; export default templates; diff --git a/rollup.config-dev.js b/rollup.config-dev.js index b9effad..8abebb0 100644 --- a/rollup.config-dev.js +++ b/rollup.config-dev.js @@ -6,7 +6,7 @@ const postcssUrl = require("postcss-url"); const { visualizer } = require("."); -const HTML_TEMPLATE = ["treemap", "sunburst", "network", "flamegraph"]; +const HTML_TEMPLATE = ["treemap", "sunburst", "network"]; const PLAIN_TEMPLATE = ["raw-data", "list"]; const ALL_TEMPLATE = [...HTML_TEMPLATE, ...PLAIN_TEMPLATE]; diff --git a/rollup.config.js b/rollup.config.js index f37a15e..1deb19d 100644 --- a/rollup.config.js +++ b/rollup.config.js @@ -4,7 +4,7 @@ const typescript = require("@rollup/plugin-typescript"); const postcss = require("rollup-plugin-postcss"); const postcssUrl = require("postcss-url"); -const HTML_TEMPLATE = ["treemap", "sunburst", "network", "flamegraph"]; +const HTML_TEMPLATE = ["treemap", "sunburst", "network"]; /** @type {import('rollup').RollupOptions} */ module.exports = HTML_TEMPLATE.map((templateType) => ({ diff --git a/src/flamegraph/chart.tsx b/src/flamegraph/chart.tsx deleted file mode 100644 index c2047d9..0000000 --- a/src/flamegraph/chart.tsx +++ /dev/null @@ -1,56 +0,0 @@ -import { FunctionalComponent } from "preact"; -import { useState, useEffect } from "preact/hooks"; -import { HierarchyRectangularNode } from "d3-hierarchy"; - -import { ModuleTree, ModuleTreeLeaf, SizeKey } from "../../shared/types"; -import { FlameGraph } from "./flamegraph"; -import { Tooltip } from "./tooltip"; - -export interface ChartProps { - root: HierarchyRectangularNode; - sizeProperty: SizeKey; - selectedNode: HierarchyRectangularNode | undefined; - setSelectedNode: ( - node: HierarchyRectangularNode | undefined, - ) => void; -} - -export const Chart: FunctionalComponent = ({ - root, - sizeProperty, - selectedNode, - setSelectedNode, -}) => { - const [showTooltip, setShowTooltip] = useState(false); - const [tooltipNode, setTooltipNode] = useState< - HierarchyRectangularNode | undefined - >(undefined); - - useEffect(() => { - const handleMouseOut = () => { - setShowTooltip(false); - }; - - document.addEventListener("mouseover", handleMouseOut); - return () => { - document.removeEventListener("mouseover", handleMouseOut); - }; - }, []); - - return ( - <> - { - setTooltipNode(node); - setShowTooltip(true); - }} - selectedNode={selectedNode} - onNodeClick={(node) => { - setSelectedNode(selectedNode === node ? undefined : node); - }} - /> - - - ); -}; diff --git a/src/flamegraph/color.ts b/src/flamegraph/color.ts deleted file mode 100644 index 0c621a0..0000000 --- a/src/flamegraph/color.ts +++ /dev/null @@ -1,81 +0,0 @@ -import { scaleSequential, scaleLinear } from "d3-scale"; -import { hsl, RGBColor } from "d3-color"; - -import { HierarchyNode } from "d3-hierarchy"; -import { COLOR_BASE, CssColor } from "../color"; -import { ModuleTree, ModuleTreeLeaf } from "../../shared/types"; - -// https://www.w3.org/TR/WCAG20/#relativeluminancedef -const rc = 0.2126; -const gc = 0.7152; -const bc = 0.0722; -// low-gamma adjust coefficient -const lowc = 1 / 12.92; - -function adjustGamma(p: number) { - return Math.pow((p + 0.055) / 1.055, 2.4); -} - -function relativeLuminance(o: RGBColor) { - const rsrgb = o.r / 255; - const gsrgb = o.g / 255; - const bsrgb = o.b / 255; - - const r = rsrgb <= 0.03928 ? rsrgb * lowc : adjustGamma(rsrgb); - const g = gsrgb <= 0.03928 ? gsrgb * lowc : adjustGamma(gsrgb); - const b = bsrgb <= 0.03928 ? bsrgb * lowc : adjustGamma(bsrgb); - - return r * rc + g * gc + b * bc; -} - -export interface NodeColor { - backgroundColor: CssColor; - fontColor: CssColor; -} - -export type NodeColorGetter = (node: HierarchyNode) => NodeColor; - -const createRainbowColor = (root: HierarchyNode): NodeColorGetter => { - const colorParentMap = new Map, CssColor>(); - colorParentMap.set(root, COLOR_BASE); - - if (root.children != null) { - const colorScale = scaleSequential([0, root.children.length], (n) => hsl(360 * n, 0.3, 0.85)); - root.children.forEach((c, id) => { - colorParentMap.set(c, colorScale(id).toString()); - }); - } - - const colorMap = new Map, NodeColor>(); - - const lightScale = scaleLinear().domain([0, root.height]).range([0.9, 0.3]); - - const getBackgroundColor = (node: HierarchyNode) => { - const parents = node.ancestors(); - const colorStr = - parents.length === 1 - ? colorParentMap.get(parents[0]) - : colorParentMap.get(parents[parents.length - 2]); - - const hslColor = hsl(colorStr as string); - hslColor.l = lightScale(node.depth); - - return hslColor; - }; - - return (node: HierarchyNode): NodeColor => { - if (!colorMap.has(node)) { - const backgroundColor = getBackgroundColor(node); - const l = relativeLuminance(backgroundColor.rgb()); - const fontColor = l > 0.19 ? "#000" : "#fff"; - colorMap.set(node, { - backgroundColor: backgroundColor.toString(), - fontColor, - }); - } - - return colorMap.get(node) as NodeColor; - }; -}; - -export default createRainbowColor; diff --git a/src/flamegraph/const.ts b/src/flamegraph/const.ts deleted file mode 100644 index 07a12fc..0000000 --- a/src/flamegraph/const.ts +++ /dev/null @@ -1,2 +0,0 @@ -export const TOP_PADDING = 20; -export const PADDING = 2; diff --git a/src/flamegraph/flamegraph.tsx b/src/flamegraph/flamegraph.tsx deleted file mode 100644 index 494cc27..0000000 --- a/src/flamegraph/flamegraph.tsx +++ /dev/null @@ -1,39 +0,0 @@ -import { FunctionalComponent } from "preact"; -import { useContext } from "preact/hooks"; -import { HierarchyRectangularNode } from "d3-hierarchy"; - -import { ModuleTree, ModuleTreeLeaf } from "../../shared/types"; -import { Node } from "./node"; -import { StaticContext } from "./index"; - -export interface FlameGraphProps { - root: HierarchyRectangularNode; - onNodeHover: (event: HierarchyRectangularNode) => void; - selectedNode: HierarchyRectangularNode | undefined; - onNodeClick: (node: HierarchyRectangularNode) => void; -} - -export const FlameGraph: FunctionalComponent = ({ - root, - onNodeHover, - selectedNode, - onNodeClick, -}) => { - const { width, height, getModuleIds } = useContext(StaticContext); - - return ( - - {root.descendants().map((node) => { - return ( - - ); - })} - - ); -}; diff --git a/src/flamegraph/index.tsx b/src/flamegraph/index.tsx deleted file mode 100644 index f5c28c4..0000000 --- a/src/flamegraph/index.tsx +++ /dev/null @@ -1,124 +0,0 @@ -import { createContext, render } from "preact"; -import { hierarchy, HierarchyNode, partition, PartitionLayout } from "d3-hierarchy"; -import { - isModuleTree, - ModuleLengths, - ModuleTree, - ModuleTreeLeaf, - SizeKey, - VisualizerData, -} from "../../shared/types"; - -import { generateUniqueId, Id } from "../uid"; -import { getAvailableSizeOptions } from "../sizes"; -import { Main } from "./main"; -import createRainbowColor, { NodeColorGetter } from "./color"; - -import "../style/style-flamegraph.scss"; -import { PADDING } from "./const"; - -export interface StaticData { - data: VisualizerData; - availableSizeProperties: SizeKey[]; - width: number; - height: number; -} - -export interface ModuleIds { - nodeUid: Id; - clipUid: Id; -} - -export interface ChartData { - layout: PartitionLayout; - rawHierarchy: HierarchyNode; - getModuleSize: (node: ModuleTree | ModuleTreeLeaf, sizeKey: SizeKey) => number; - getModuleIds: (node: ModuleTree | ModuleTreeLeaf) => ModuleIds; - getModuleColor: NodeColorGetter; -} - -export type Context = StaticData & ChartData; - -export const StaticContext = createContext({} as unknown as Context); - -const drawChart = ( - parentNode: Element, - data: VisualizerData, - width: number, - height: number, -): void => { - const availableSizeProperties = getAvailableSizeOptions(data.options); - - console.time("layout create"); - - const layout = partition() - .size([width, height]) - .padding(PADDING) - .round(true); - - console.timeEnd("layout create"); - - console.time("rawHierarchy create"); - const rawHierarchy = hierarchy(data.tree); - console.timeEnd("rawHierarchy create"); - - const nodeSizesCache = new Map(); - - const nodeIdsCache = new Map(); - - const getModuleSize = (node: ModuleTree | ModuleTreeLeaf, sizeKey: SizeKey) => - nodeSizesCache.get(node)?.[sizeKey] ?? 0; - - console.time("rawHierarchy eachAfter cache"); - rawHierarchy.eachAfter((node) => { - const nodeData = node.data; - - nodeIdsCache.set(nodeData, { - nodeUid: generateUniqueId("node"), - clipUid: generateUniqueId("clip"), - }); - - const sizes: ModuleLengths = { renderedLength: 0, gzipLength: 0, brotliLength: 0 }; - if (isModuleTree(nodeData)) { - for (const sizeKey of availableSizeProperties) { - sizes[sizeKey] = nodeData.children.reduce( - (acc, child) => getModuleSize(child, sizeKey) + acc, - 0, - ); - } - } else { - for (const sizeKey of availableSizeProperties) { - sizes[sizeKey] = data.nodeParts[nodeData.uid][sizeKey] ?? 0; - } - } - nodeSizesCache.set(nodeData, sizes); - }); - console.timeEnd("rawHierarchy eachAfter cache"); - - const getModuleIds = (node: ModuleTree | ModuleTreeLeaf) => nodeIdsCache.get(node) as ModuleIds; - - console.time("color"); - const getModuleColor = createRainbowColor(rawHierarchy); - console.timeEnd("color"); - - render( - -
- , - parentNode, - ); -}; - -export default drawChart; diff --git a/src/flamegraph/main.tsx b/src/flamegraph/main.tsx deleted file mode 100644 index fc4e7ad..0000000 --- a/src/flamegraph/main.tsx +++ /dev/null @@ -1,99 +0,0 @@ -import { useContext, useMemo, useState } from "preact/hooks"; -import { HierarchyRectangularNode } from "d3-hierarchy"; - -import { FunctionalComponent } from "preact"; -import { SideBar } from "../sidebar"; -import { isModuleTree, ModuleTree, ModuleTreeLeaf, SizeKey } from "../../shared/types"; -import { useFilter } from "../use-filter"; -import { Chart } from "./chart"; - -import { StaticContext } from "./index"; - -export const Main: FunctionalComponent = () => { - const { availableSizeProperties, rawHierarchy, getModuleSize, layout, data } = - useContext(StaticContext); - - const [sizeProperty, setSizeProperty] = useState(availableSizeProperties[0]); - - const [selectedNode, setSelectedNode] = useState< - HierarchyRectangularNode | undefined - >(undefined); - - const { getModuleFilterMultiplier, setExcludeFilter, setIncludeFilter } = useFilter(); - - console.time("getNodeSizeMultiplier"); - const getNodeSizeMultiplier = useMemo(() => { - const selectedMultiplier = 1; // selectedSize < rootSize * increaseFactor ? (rootSize * increaseFactor) / selectedSize : rootSize / selectedSize; - const nonSelectedMultiplier = 0; // 1 / selectedMultiplier - - if (selectedNode === undefined) { - return (): number => 1; - } else if (isModuleTree(selectedNode.data)) { - const leaves = new Set(selectedNode.leaves().map((d) => d.data)); - return (node: ModuleTree | ModuleTreeLeaf): number => { - if (leaves.has(node)) { - return selectedMultiplier; - } - return nonSelectedMultiplier; - }; - } else { - return (node: ModuleTree | ModuleTreeLeaf): number => { - if (node === selectedNode.data) { - return selectedMultiplier; - } - return nonSelectedMultiplier; - }; - } - }, [getModuleSize, rawHierarchy.data, selectedNode, sizeProperty]); - console.timeEnd("getNodeSizeMultiplier"); - - console.time("root hierarchy compute"); - // root here always be the same as rawHierarchy even after layouting - const root = useMemo(() => { - const rootWithSizesAndSorted = rawHierarchy - .sum((node) => { - if (isModuleTree(node)) return 0; - - const meta = data.nodeMetas[data.nodeParts[node.uid].metaUid]; - /* eslint-disable typescript/no-non-null-asserted-optional-chain typescript/no-extra-non-null-assertion */ - const bundleId = Object.entries(meta.moduleParts).find(([, uid]) => uid == node.uid)?.[0]!!; - - const ownSize = getModuleSize(node, sizeProperty); - const zoomMultiplier = getNodeSizeMultiplier(node); - const filterMultiplier = getModuleFilterMultiplier(bundleId, meta); - - return ownSize * zoomMultiplier * filterMultiplier; - }) - .sort((a, b) => getModuleSize(a.data, sizeProperty) - getModuleSize(b.data, sizeProperty)); - - return layout(rootWithSizesAndSorted); - }, [ - data, - getModuleFilterMultiplier, - getModuleSize, - getNodeSizeMultiplier, - layout, - rawHierarchy, - sizeProperty, - ]); - - console.timeEnd("root hierarchy compute"); - - return ( - <> - - - - ); -}; diff --git a/src/flamegraph/node.tsx b/src/flamegraph/node.tsx deleted file mode 100644 index ca817a5..0000000 --- a/src/flamegraph/node.tsx +++ /dev/null @@ -1,103 +0,0 @@ -/* eslint-disable react/no-unknown-property */ -import { FunctionalComponent } from "preact"; -import { useContext, useLayoutEffect, useRef } from "preact/hooks"; -import { HierarchyRectangularNode } from "d3-hierarchy"; -import { ModuleTree, ModuleTreeLeaf } from "../../shared/types"; -import { PADDING, TOP_PADDING } from "./const"; -import { StaticContext } from "."; - -type NodeEventHandler = (event: HierarchyRectangularNode) => void; - -export interface NodeProps { - node: HierarchyRectangularNode; - onMouseOver: NodeEventHandler; - selected: boolean; - onClick: NodeEventHandler; -} - -export const Node: FunctionalComponent = ({ node, onMouseOver, onClick, selected }) => { - const { getModuleColor } = useContext(StaticContext); - const { backgroundColor, fontColor } = getModuleColor(node); - const { x0, x1, y1, y0, data, children = null } = node; - - const textRef = useRef(null); - const textRectRef = useRef(); - - const width = x1 - x0; - const height = y1 - y0; - - const textProps: Record = { - "font-size": "0.7em", - "dominant-baseline": "middle", - "text-anchor": "middle", - x: width / 2, - }; - if (children != null) { - textProps.y = (TOP_PADDING + PADDING) / 2; - } else { - textProps.y = height / 2; - } - - useLayoutEffect(() => { - if (width == 0 || height == 0 || !textRef.current) { - return; - } - - if (textRectRef.current == null) { - textRectRef.current = textRef.current.getBoundingClientRect(); - } - - let scale = 1; - - scale = Math.min( - (width * 0.9) / textRectRef.current.width, - (height * 0.9) / textRectRef.current.height, - ); - scale = Math.min(1, scale); - textRef.current.setAttribute("y", String(height / 2 / scale)); - textRef.current.setAttribute("x", String(width / 2 / scale)); - - textRef.current.setAttribute("transform", `scale(${scale.toFixed(2)})`); - }, [children, height, width]); - - if (width == 0 || height == 0) { - return null; - } - - return ( - { - event.stopPropagation(); - onClick(node); - }} - onMouseOver={(event: MouseEvent) => { - event.stopPropagation(); - onMouseOver(node); - }} - > - - { - if (window.getSelection()?.toString() !== "") { - event.stopPropagation(); - } - }} - {...textProps} - > - {data.name} - - - ); -}; diff --git a/src/flamegraph/tooltip.tsx b/src/flamegraph/tooltip.tsx deleted file mode 100644 index 953e62c..0000000 --- a/src/flamegraph/tooltip.tsx +++ /dev/null @@ -1,165 +0,0 @@ -import { useState, useRef, useEffect, useMemo, useContext } from "preact/hooks"; - -import { format as formatBytes } from "bytes"; - -import { FunctionalComponent } from "preact"; -import { HierarchyRectangularNode } from "d3-hierarchy"; -import { LABELS } from "../sizes"; -import { isModuleTree, ModuleTree, ModuleTreeLeaf, SizeKey } from "../../shared/types"; -import { StaticContext } from "."; - -export interface TooltipProps { - node?: HierarchyRectangularNode; - root: HierarchyRectangularNode; - sizeProperty: SizeKey; - visible: boolean; -} - -const Tooltip_marginX = 10; -const Tooltip_marginY = 30; - -const SOURCEMAP_RENDERED = ( - - {" "} - {LABELS.renderedLength} is a number of characters in the file after individual and
{" "} - whole bundle transformations according to sourcemap. -
-); - -const RENDRED = ( - - {LABELS.renderedLength} is a byte size of individual file after transformations and - treeshake. - -); - -const COMPRESSED = ( - - {LABELS.gzipLength} and {LABELS.brotliLength} is a byte size of individual file - after individual transformations, -
treeshake and compression. -
-); - -export const Tooltip: FunctionalComponent = ({ - node, - visible, - root, - sizeProperty, -}) => { - const { availableSizeProperties, getModuleSize, data } = useContext(StaticContext); - - const ref = useRef(null); - const [style, setStyle] = useState({}); - - const content = useMemo(() => { - if (!node) return null; - - const mainSize = getModuleSize(node.data, sizeProperty); - - const percentageNum = (100 * mainSize) / getModuleSize(root.data, sizeProperty); - const percentage = percentageNum.toFixed(2); - const percentageString = percentage + "%"; - - const path = node - .ancestors() - .reverse() - .map((d) => d.data.name) - .join("/"); - - let dataNode = null; - if (!isModuleTree(node.data)) { - const mainUid = data.nodeParts[node.data.uid].metaUid; - dataNode = data.nodeMetas[mainUid]; - } - - return ( - <> -
{path}
- {availableSizeProperties.map((sizeProp) => { - if (sizeProp === sizeProperty) { - return ( -
- - {LABELS[sizeProp]}: {formatBytes(mainSize)} - {" "} - ({percentageString}) -
- ); - } else { - return ( -
- {LABELS[sizeProp]}: {formatBytes(getModuleSize(node.data, sizeProp))} -
- ); - } - })} -
- {dataNode && dataNode.importedBy.length > 0 && ( -
-
- Imported By: -
- {dataNode.importedBy.map(({ uid }) => { - const id = data.nodeMetas[uid].id; - return
{id}
; - })} -
- )} -
- {data.options.sourcemap ? SOURCEMAP_RENDERED : RENDRED} - {(data.options.gzip || data.options.brotli) && ( - <> -
- {COMPRESSED} - - )} - - ); - }, [availableSizeProperties, data, getModuleSize, node, root.data, sizeProperty]); - - const updatePosition = (mouseCoords: { x: number; y: number }) => { - if (!ref.current) return; - - const pos = { - left: mouseCoords.x + Tooltip_marginX, - top: mouseCoords.y + Tooltip_marginY, - }; - - const boundingRect = ref.current.getBoundingClientRect(); - - if (pos.left + boundingRect.width > window.innerWidth) { - // Shifting horizontally - pos.left = window.innerWidth - boundingRect.width; - } - - if (pos.top + boundingRect.height > window.innerHeight) { - // Flipping vertically - pos.top = mouseCoords.y - Tooltip_marginY - boundingRect.height; - } - - setStyle(pos); - }; - - useEffect(() => { - const handleMouseMove = (event: MouseEvent) => { - updatePosition({ - x: event.pageX, - y: event.pageY, - }); - }; - - document.addEventListener("mousemove", handleMouseMove, true); - return () => { - document.removeEventListener("mousemove", handleMouseMove, true); - }; - }, []); - - return ( -
- {content} -
- ); -}; - -export default Tooltip; diff --git a/test/__snapshots__/e2e-rolldown.test.ts.snap b/test/__snapshots__/e2e-rolldown.test.ts.snap index 7f7c868..da6c84e 100644 --- a/test/__snapshots__/e2e-rolldown.test.ts.snap +++ b/test/__snapshots__/e2e-rolldown.test.ts.snap @@ -1,6 +1,25 @@ // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html -exports[`E2E > test - "flamegraph" 1`] = ` +exports[`E2E > test - "list" 1`] = ` +"file3-XCd8Ebz0.js: + /test/e2e/file3.js: + rendered: 60 + gzip: 76 + brotli: 52 +input.js: + /test/e2e/input.js: + rendered: 78 + gzip: 91 + brotli: 69 +input2.js: + /test/e2e/input2.js: + rendered: 124 + gzip: 126 + brotli: 105 +" +`; + +exports[`E2E > test - "network" 1`] = ` " @@ -150,15083 +169,5238 @@ main { - - - + /** + * Question marks + */ -" -`; + if (value === '?') { + const isGroup = prev && prev.value === '('; + if (!isGroup && opts.noextglob !== true && peek() === '(' && peek(2) !== '?') { + extglobOpen('qmark', value); + continue; + } -exports[`E2E > test - "list" 1`] = ` -"file3-XCd8Ebz0.js: - /test/e2e/file3.js: - rendered: 60 - gzip: 76 - brotli: 52 -input.js: - /test/e2e/input.js: - rendered: 78 - gzip: 91 - brotli: 69 -input2.js: - /test/e2e/input2.js: - rendered: 124 - gzip: 126 - brotli: 105 -" -`; + if (prev && prev.type === 'paren') { + const next = peek(); + let output = value; -exports[`E2E > test - "network" 1`] = ` -" - - - - - - - Rollup Visualizer - - - -
- - - - - -" -`; - -exports[`E2E > test - "raw-data" 1`] = ` -"{ - "version": 2, - "tree": { - "name": "root", - "children": [ - { - "name": "input.js", - "children": [ - { - "name": "test/e2e/input.js", - "uid": "7665939b-1" - } - ] - }, - { - "name": "input2.js", - "children": [ - { - "name": "test/e2e/input2.js", - "uid": "7665939b-3" - } - ] - }, - { - "name": "file3-XCd8Ebz0.js", - "children": [ - { - "name": "test/e2e/file3.js", - "uid": "7665939b-5" - } - ] - } - ], - "isRoot": true - }, - "nodeParts": { - "7665939b-1": { - "renderedLength": 78, - "gzipLength": 91, - "brotliLength": 69, - "metaUid": "7665939b-0" - }, - "7665939b-3": { - "renderedLength": 124, - "gzipLength": 126, - "brotliLength": 105, - "metaUid": "7665939b-2" - }, - "7665939b-5": { - "renderedLength": 60, - "gzipLength": 76, - "brotliLength": 52, - "metaUid": "7665939b-4" - } - }, - "nodeMetas": { - "7665939b-0": { - "id": "/test/e2e/input.js", - "moduleParts": { - "input.js": "7665939b-1" - }, - "imported": [ - { - "uid": "7665939b-6" - }, - { - "uid": "7665939b-7" - } - ], - "importedBy": [], - "isEntry": true - }, - "7665939b-2": { - "id": "/test/e2e/input2.js", - "moduleParts": { - "input2.js": "7665939b-3" - }, - "imported": [ - { - "uid": "7665939b-4", - "dynamic": true - } - ], - "importedBy": [], - "isEntry": true - }, - "7665939b-4": { - "id": "/test/e2e/file3.js", - "moduleParts": { - "file3-XCd8Ebz0.js": "7665939b-5" - }, - "imported": [], - "importedBy": [ - { - "uid": "7665939b-2" - } - ] - }, - "7665939b-6": { - "id": "/test/e2e/node_modules/module/test.js", - "moduleParts": {}, - "imported": [], - "importedBy": [ - { - "uid": "7665939b-0" - } - ] - }, - "7665939b-7": { - "id": "jquery", - "moduleParts": {}, - "imported": [], - "importedBy": [ - { - "uid": "7665939b-0" - } - ] - } - }, - "env": { - "rollup": "4.23.0" - }, - "options": { - "gzip": true, - "brotli": true, - "sourcemap": false - } -}" -`; - -exports[`E2E > test - "sunburst" 1`] = ` -" - - - - - - - Rollup Visualizer - - - -
- - - - + /** + * Question marks + */ -" -`; + if (value === '?') { + const isGroup = prev && prev.value === '('; + if (!isGroup && opts.noextglob !== true && peek() === '(' && peek(2) !== '?') { + extglobOpen('qmark', value); + continue; + } -exports[`E2E > test - "list" 1`] = ` -"file3-Bi_Qu0hn.js: - /test/e2e/file3.js: - rendered: 18 - gzip: 38 - brotli: 22 -input.js: - /test/e2e/input.js: - rendered: 66 - gzip: 80 - brotli: 67 -input2.js: - /test/e2e/input2.js: - rendered: 80 - gzip: 96 - brotli: 84 -" -`; + if (prev && prev.type === 'paren') { + const next = peek(); + let output = value; -exports[`E2E > test - "network" 1`] = ` -" - - - - - - - Rollup Visualizer - - - -
- - - - - -" -`; - -exports[`E2E > test - "raw-data" 1`] = ` -"{ - "version": 2, - "tree": { - "name": "root", - "children": [ - { - "name": "input.js", - "children": [ - { - "name": "test/e2e/input.js", - "uid": "04193cf6-1" - } - ] - }, - { - "name": "input2.js", - "children": [ - { - "name": "test/e2e/input2.js", - "uid": "04193cf6-3" - } - ] - }, - { - "name": "file3-Bi_Qu0hn.js", - "children": [ - { - "name": "test/e2e/file3.js", - "uid": "04193cf6-5" - } - ] - } - ], - "isRoot": true - }, - "nodeParts": { - "04193cf6-1": { - "renderedLength": 66, - "gzipLength": 80, - "brotliLength": 67, - "metaUid": "04193cf6-0" - }, - "04193cf6-3": { - "renderedLength": 80, - "gzipLength": 96, - "brotliLength": 84, - "metaUid": "04193cf6-2" - }, - "04193cf6-5": { - "renderedLength": 18, - "gzipLength": 38, - "brotliLength": 22, - "metaUid": "04193cf6-4" - } - }, - "nodeMetas": { - "04193cf6-0": { - "id": "/test/e2e/input.js", - "moduleParts": { - "input.js": "04193cf6-1" - }, - "imported": [ - { - "uid": "04193cf6-6" - }, - { - "uid": "04193cf6-7" - } - ], - "importedBy": [], - "isEntry": true - }, - "04193cf6-2": { - "id": "/test/e2e/input2.js", - "moduleParts": { - "input2.js": "04193cf6-3" - }, - "imported": [ - { - "uid": "04193cf6-4", - "dynamic": true - } - ], - "importedBy": [], - "isEntry": true - }, - "04193cf6-4": { - "id": "/test/e2e/file3.js", - "moduleParts": { - "file3-Bi_Qu0hn.js": "04193cf6-5" - }, - "imported": [], - "importedBy": [ - { - "uid": "04193cf6-2" - } - ] - }, - "04193cf6-6": { - "id": "/test/e2e/node_modules/module/test.js", - "moduleParts": {}, - "imported": [], - "importedBy": [ - { - "uid": "04193cf6-0" - } - ] - }, - "04193cf6-7": { - "id": "jquery", - "moduleParts": {}, - "imported": [], - "importedBy": [ - { - "uid": "04193cf6-0" - } - ], - "isExternal": true - } - }, - "env": { - "rollup": "4.29.1" - }, - "options": { - "gzip": true, - "brotli": true, - "sourcemap": false - } -}" -`; - -exports[`E2E > test - "sunburst" 1`] = ` -" - - - - - - - Rollup Visualizer - - - -
- - - - + push({ type: 'dot', value, output: DOT_LITERAL }); + continue; + } -" -`; + /** + * Question marks + */ -exports[`GH-59 > test - "list" 1`] = ` -"components/A.js: - /test/gh59/src/components/A.js: - rendered: 12 - gzip: 32 - brotli: 16 -components/B.js: - /test/gh59/src/components/B.js: - rendered: 12 - gzip: 32 - brotli: 16 -components/index.js: - /test/gh59/src/components/index.js: - rendered: 0 - gzip: 0 - brotli: 0 -index.js: - /test/gh59/src/index.js: - rendered: 18 - gzip: 38 - brotli: 22 -" -`; + if (value === '?') { + const isGroup = prev && prev.value === '('; + if (!isGroup && opts.noextglob !== true && peek() === '(' && peek(2) !== '?') { + extglobOpen('qmark', value); + continue; + } -exports[`GH-59 > test - "network" 1`] = ` -" - - - - - - - Rollup Visualizer - - - -
- - - - - -" -`; - -exports[`GH-59 > test - "raw-data" 1`] = ` -"{ - "version": 2, - "tree": { - "name": "root", - "children": [ - { - "name": "components/index.js", - "children": [ - { - "name": "test/gh59/src/components/index.js", - "uid": "dea430a7-1" - } - ] - }, - { - "name": "index.js", - "children": [ - { - "name": "test/gh59/src/index.js", - "uid": "dea430a7-3" - } - ] - }, - { - "name": "components/A.js", - "children": [ - { - "name": "test/gh59/src/components/A.js", - "uid": "dea430a7-5" - } - ] - }, - { - "name": "components/B.js", - "children": [ - { - "name": "test/gh59/src/components/B.js", - "uid": "dea430a7-7" - } - ] - } - ], - "isRoot": true - }, - "nodeParts": { - "dea430a7-1": { - "renderedLength": 0, - "gzipLength": 0, - "brotliLength": 0, - "metaUid": "dea430a7-0" - }, - "dea430a7-3": { - "renderedLength": 18, - "gzipLength": 38, - "brotliLength": 22, - "metaUid": "dea430a7-2" - }, - "dea430a7-5": { - "renderedLength": 12, - "gzipLength": 32, - "brotliLength": 16, - "metaUid": "dea430a7-4" - }, - "dea430a7-7": { - "renderedLength": 12, - "gzipLength": 32, - "brotliLength": 16, - "metaUid": "dea430a7-6" - } - }, - "nodeMetas": { - "dea430a7-0": { - "id": "/test/gh59/src/components/index.js", - "moduleParts": { - "components/index.js": "dea430a7-1" - }, - "imported": [ - { - "uid": "dea430a7-4" - }, - { - "uid": "dea430a7-6" - } - ], - "importedBy": [ - { - "uid": "dea430a7-2" - } - ], - "isEntry": true - }, - "dea430a7-2": { - "id": "/test/gh59/src/index.js", - "moduleParts": { - "index.js": "dea430a7-3" - }, - "imported": [ - { - "uid": "dea430a7-0" - } - ], - "importedBy": [], - "isEntry": true - }, - "dea430a7-4": { - "id": "/test/gh59/src/components/A.js", - "moduleParts": { - "components/A.js": "dea430a7-5" - }, - "imported": [], - "importedBy": [ - { - "uid": "dea430a7-0" - } - ], - "isEntry": true - }, - "dea430a7-6": { - "id": "/test/gh59/src/components/B.js", - "moduleParts": { - "components/B.js": "dea430a7-7" - }, - "imported": [], - "importedBy": [ - { - "uid": "dea430a7-0" - } - ], - "isEntry": true - } - }, - "env": { - "rollup": "4.29.1" - }, - "options": { - "gzip": true, - "brotli": true, - "sourcemap": false - } -}" -`; - -exports[`GH-59 > test - "sunburst" 1`] = ` -" - - - - - - - Rollup Visualizer - - - -
- - - - + push({ type: 'dot', value, output: DOT_LITERAL }); + continue; + } -" -`; + /** + * Question marks + */ -exports[`GH-69 > test - "list" 1`] = ` -"dynamic-AB-Kuj6Y.js: - /test/gh69/dynamic.js: - rendered: 6 - gzip: 26 - brotli: 10 -main.js: - /test/gh69/lib.js: - rendered: 86 - gzip: 73 - brotli: 67 - /test/gh69/main.js: - rendered: 84 - gzip: 98 - brotli: 88 -" -`; + if (value === '?') { + const isGroup = prev && prev.value === '('; + if (!isGroup && opts.noextglob !== true && peek() === '(' && peek(2) !== '?') { + extglobOpen('qmark', value); + continue; + } -exports[`GH-69 > test - "network" 1`] = ` -" - - - - - - - Rollup Visualizer - - - -
- - - - - -" -`; - -exports[`GH-69 > test - "raw-data" 1`] = ` -"{ - "version": 2, - "tree": { - "name": "root", - "children": [ - { - "name": "main.js", - "children": [ - { - "name": "test/gh69", - "children": [ - { - "uid": "9be6dbea-1", - "name": "lib.js" - }, - { - "uid": "9be6dbea-3", - "name": "main.js" - } - ] - } - ] - }, - { - "name": "dynamic-AB-Kuj6Y.js", - "children": [ - { - "name": "test/gh69/dynamic.js", - "uid": "9be6dbea-5" - } - ] - } - ], - "isRoot": true - }, - "nodeParts": { - "9be6dbea-1": { - "renderedLength": 86, - "gzipLength": 73, - "brotliLength": 67, - "metaUid": "9be6dbea-0" - }, - "9be6dbea-3": { - "renderedLength": 84, - "gzipLength": 98, - "brotliLength": 88, - "metaUid": "9be6dbea-2" - }, - "9be6dbea-5": { - "renderedLength": 6, - "gzipLength": 26, - "brotliLength": 10, - "metaUid": "9be6dbea-4" - } - }, - "nodeMetas": { - "9be6dbea-0": { - "id": "/test/gh69/lib.js", - "moduleParts": { - "main.js": "9be6dbea-1" - }, - "imported": [], - "importedBy": [ - { - "uid": "9be6dbea-2" - }, - { - "uid": "9be6dbea-4" - } - ] - }, - "9be6dbea-2": { - "id": "/test/gh69/main.js", - "moduleParts": { - "main.js": "9be6dbea-3" - }, - "imported": [ - { - "uid": "9be6dbea-0" - }, - { - "uid": "9be6dbea-4", - "dynamic": true - } - ], - "importedBy": [], - "isEntry": true - }, - "9be6dbea-4": { - "id": "/test/gh69/dynamic.js", - "moduleParts": { - "dynamic-AB-Kuj6Y.js": "9be6dbea-5" - }, - "imported": [ - { - "uid": "9be6dbea-0" - } - ], - "importedBy": [ - { - "uid": "9be6dbea-2" - } - ] - } - }, - "env": { - "rollup": "4.29.1" - }, - "options": { - "gzip": true, - "brotli": true, - "sourcemap": false - } -}" -`; - -exports[`GH-69 > test - "sunburst" 1`] = ` -" - - - - - - - Rollup Visualizer - - - -
- - - - + /** + * Pipes + */ -" -`; + if (value === '|') { + if (extglobs.length > 0) { + extglobs[extglobs.length - 1].conditions++; + } + push({ type: 'text', value }); + continue; + } -exports[`GH-93 > test - "list" 1`] = ` -"main.js: - /test/gh93/main.js: - rendered: 50 - gzip: 66 - brotli: 54 -virtual-id-a3e40_3s.js: - virtual-id: - rendered: 26 - gzip: 46 - brotli: 30 -" -`; + /** + * Commas + */ -exports[`GH-93 > test - "network" 1`] = ` -" - - - - - - - Rollup Visualizer - - - -
- - - - - -" -`; - -exports[`GH-93 > test - "raw-data" 1`] = ` -"{ - "version": 2, - "tree": { - "name": "root", - "children": [ - { - "name": "main.js", - "children": [ - { - "name": "test/gh93/main.js", - "uid": "3acc92b5-1" - } - ] - }, - { - "name": "virtual-id-a3e40_3s.js", - "children": [ - { - "uid": "3acc92b5-3", - "name": "virtual-id" - } - ] - } - ], - "isRoot": true - }, - "nodeParts": { - "3acc92b5-1": { - "renderedLength": 50, - "gzipLength": 66, - "brotliLength": 54, - "metaUid": "3acc92b5-0" - }, - "3acc92b5-3": { - "renderedLength": 26, - "gzipLength": 46, - "brotliLength": 30, - "metaUid": "3acc92b5-2" - } - }, - "nodeMetas": { - "3acc92b5-0": { - "id": "/test/gh93/main.js", - "moduleParts": { - "main.js": "3acc92b5-1" - }, - "imported": [], - "importedBy": [], - "isEntry": true - }, - "3acc92b5-2": { - "id": "virtual-id", - "moduleParts": { - "virtual-id-a3e40_3s.js": "3acc92b5-3" - }, - "imported": [], - "importedBy": [], - "isEntry": true - } - }, - "env": { - "rollup": "4.29.1" - }, - "options": { - "gzip": true, - "brotli": true, - "sourcemap": false - } -}" -`; - -exports[`GH-93 > test - "sunburst" 1`] = ` -" - - - - - - - Rollup Visualizer - - - -
-