diff --git a/package.json b/package.json index 31f05079..ea28a2bc 100644 --- a/package.json +++ b/package.json @@ -88,6 +88,7 @@ "typescript": "^5.8.3" }, "dependencies": { + "@lit/task": "^1.0.3", "@nodesecure/documentation-ui": "^1.3.0", "@nodesecure/flags": "^3.0.3", "@nodesecure/i18n": "^4.0.1", diff --git a/public/components/bundlephobia/bundlephobia.js b/public/components/bundlephobia/bundlephobia.js index 7523d79a..78086ef5 100644 --- a/public/components/bundlephobia/bundlephobia.js +++ b/public/components/bundlephobia/bundlephobia.js @@ -1,48 +1,150 @@ // Import Third-party Dependencies import prettyBytes from "pretty-bytes"; import { getJSON } from "@nodesecure/vis-network"; +import { LitElement, html, css } from "lit"; +import { Task } from "@lit/task"; -export class Bundlephobia { - /** - * @param {!string} name - * @param {!string} version - */ - constructor(name, version) { - this.name = name; - this.version = version; +class Bundlephobia extends LitElement { + /* + TODO: the css has been duplicated for now but once we migrated the code that use bundlephobia.css to lit + we should reuse this css in each lit component + * */ + static styles = css` + div.bundlephobia { + height: 50px; + display: flex; + margin-top: 10px; +} + + div.bundlephobia>div { + height: inherit; + box-sizing: border-box; + border-radius: 4px; + border: 2px dashed var(--secondary); + flex-grow: 1; + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; + box-shadow: 1px 1px 10px rgb(41 103 122 / 30%) inset; +} + + div.bundlephobia>div+div { + margin-left: 10px; +} + + div.bundlephobia>div>b { + font-weight: 800; + color: var(--secondary); + margin-bottom: 5px; + font-size: 18px; +} + + div.bundlephobia>div>b i { + font-family: mononoki; + font-size: 14px; + color: #fce12b; +} + + div.bundlephobia>div>span { + font-size: 12px; + font-family: mononoki; + text-transform: uppercase; +} + +.head-title { + background: var(--primary-darker); + height: 28px; + flex-shrink: 0; + display: flex; + align-items: center; + border-bottom: 2px solid var(--primary-lighter); + border-radius: 2px 2px 0 0; +} + +.head-title>p { + text-shadow: 1px 1px 5px rgb(20 20 20 / 50%); + font-size: 18px; + font-variant: small-caps; + + /* lowercase is needed with small-caps font variant */ + text-transform: lowercase; + font-family: mononoki; + font-weight: bold; + letter-spacing: 1px; + padding: 0 10px; +} +`; + + static get DEFAULT_SIZE() { + return "N/A"; + } + static properties = { + name: { type: String }, + version: { type: String } + }; + + #bunldeTask = new Task(this, { + task: async([name, version]) => { + try { + const { + gzip, size, dependencySizes + } = await getJSON(`/bundle/${this.#httpName(name)}/${version}`); + const fullSize = dependencySizes.reduce((prev, curr) => prev + curr.approximateSize, 0); + + return { + gzip: prettyBytes(gzip), + min: prettyBytes(size), + full: prettyBytes(fullSize) + }; + } + catch { + return null; + } + }, + args: () => [this.name, this.version] + }); + + #httpName(name) { + return name.replaceAll("/", "%2F"); } - get httpName() { - return this.name.replaceAll("/", "%2F"); + render() { + return this.#bunldeTask.render({ + pending: () => this.#bundlephobiaTemplate(), + complete: (bundle) => this.#bundlephobiaTemplate(bundle), + error: () => this.#bundlephobiaTemplate() + }); } - async fetchDataOnHttpServer() { - const [sizeGzip, sizeMin, sizeFull] = [ - document.querySelector(".size-gzip"), - document.querySelector(".size-min"), - document.querySelector(".size-full") - ]; - - try { - const { - gzip, size, dependencySizes - } = await getJSON(`/bundle/${this.httpName}/${this.version}`); - const fullSize = dependencySizes.reduce((prev, curr) => prev + curr.approximateSize, 0); - - const result = { - gzip: prettyBytes(gzip), - min: prettyBytes(size), - full: prettyBytes(fullSize) - }; - - sizeGzip.textContent = result.gzip; - sizeMin.textContent = result.min; - sizeFull.textContent = result.full; - - return result; - } - catch { - return null; - } + #bundlephobiaTemplate(bundle = { + gzip: Bundlephobia.DEFAULT_SIZE, + min: Bundlephobia.DEFAULT_SIZE, + full: Bundlephobia.DEFAULT_SIZE + }) { + const { gzip, min, full } = bundle; + + return html` +
+

bundlephobia

+
+
+
+ ${min} + MIN +
+
+ ${gzip} + GZIP +
+
+ ${full} + FULL +
+
+`; } } + +customElements.define("bundle-phobia", Bundlephobia); + diff --git a/public/components/package/package.html b/public/components/package/package.html index 5e866e77..d2366b20 100644 --- a/public/components/package/package.html +++ b/public/components/package/package.html @@ -134,24 +134,6 @@

[[=z.token('package_info.title.minified_files')]]

- - -
-

bundlephobia

-
-
-
- N/A - MIN -
-
- N/A - GZIP -
-
- N/A - FULL -
diff --git a/public/components/package/package.js b/public/components/package/package.js index e8232d33..499dfb29 100644 --- a/public/components/package/package.js +++ b/public/components/package/package.js @@ -1,7 +1,8 @@ // Import Internal Dependencies -import { Bundlephobia } from "../bundlephobia/bundlephobia.js"; +import "../bundlephobia/bundlephobia.js"; import { PackageHeader } from "./header/header.js"; import * as Pannels from "./pannels/index.js"; +import * as utils from "../../common/utils.js"; export class PackageInfo { static DOMElementName = "package-info"; @@ -83,17 +84,19 @@ export class PackageInfo { packageHTMLElement.setAttribute("class", "slide-in"); if (window.settings.config.disableExternalRequests) { - const bundlephobiaElement = packageHTMLElement.querySelector("#bundlephobia-sizes"); - const bundlephobiaTitleElement = bundlephobiaElement.previousElementSibling; - bundlephobiaElement.classList.add("hidden"); - bundlephobiaTitleElement.classList.add("hidden"); - return; } - new Bundlephobia(this.dependencyVersion.name, this.dependencyVersion.version) - .fetchDataOnHttpServer() - .catch(console.error); + const panFiles = packageHTMLElement.querySelector("#pan-files"); + + const bundlephobia = utils.createDOMElement("bundle-phobia", { + attributes: { + name: this.dependencyVersion.name, + version: this.dependencyVersion.version + } + }); + + panFiles.appendChild(bundlephobia); } /**