a collection of lightweight TypeScript packages for AT Protocol, the protocol powering Bluesky
atproto bluesky typescript npm
101
fork

Configure Feed

Select the types of activity you want to include in your feed.

chore: remove pkg-size-report

Mary da50d073 1eb0fe8c

+1 -397
-12
README.md
··· 106 106 pnpm run -r generate 107 107 ``` 108 108 109 - ### package size reporting 110 - 111 - check bundle sizes with the `pkg-size-report` tool: 112 - 113 - > [!WARNING] 114 - > run `pnpm run -r build` first, otherwise measurements may be inaccurate. 115 - 116 - ```sh 117 - pnpm pkg-size-report # show sizes (and diff if previously saved) 118 - pnpm pkg-size-report --save # save current sizes for comparison 119 - pnpm pkg-size-report --compare # show only changed packages 120 - ```
-1
package.json
··· 15 15 "oxfmt": "^0.28.0", 16 16 "oxlint": "^1.43.0", 17 17 "oxlint-tsgolint": "^0.11.4", 18 - "pkg-size-report": "workspace:^", 19 18 "prettier": "^3.8.1", 20 19 "typescript": "~5.9.3" 21 20 }
-7
packages/internal/pkg-size-report/CHANGELOG.md
··· 1 - # pkg-size-report 2 - 3 - ## 1.0.2 4 - 5 - ### Patch Changes 6 - 7 - - b30da0e: add `declarationMap` to tsconfig
-2
packages/internal/pkg-size-report/cli.mjs
··· 1 - #!/usr/bin/env node 2 - import './dist/index.js';
-25
packages/internal/pkg-size-report/package.json
··· 1 - { 2 - "name": "pkg-size-report", 3 - "version": "1.0.2", 4 - "private": true, 5 - "description": "cli tool to compute and analyze package sizes", 6 - "license": "0BSD", 7 - "repository": { 8 - "url": "https://github.com/mary-ext/atcute", 9 - "directory": "packages/internal/pkg-size-report" 10 - }, 11 - "bin": "./cli.mjs", 12 - "type": "module", 13 - "scripts": { 14 - "build": "tsgo" 15 - }, 16 - "dependencies": { 17 - "esbuild": "^0.25.12", 18 - "js-yaml": "^4.1.1", 19 - "picocolors": "^1.1.1" 20 - }, 21 - "devDependencies": { 22 - "@types/js-yaml": "^4.0.9", 23 - "@types/node": "^25.2.1" 24 - } 25 - }
-38
packages/internal/pkg-size-report/src/bundle.ts
··· 1 - import * as fs from 'node:fs'; 2 - import * as os from 'node:os'; 3 - import * as path from 'node:path'; 4 - import * as url from 'node:url'; 5 - 6 - import * as esbuild from 'esbuild'; 7 - 8 - import { computeFolderSize } from './fs.js'; 9 - 10 - export function computeBundleInformation(entry: URL, entryQualifier: string, keepBuild = false) { 11 - const tmpDirPrefix = path.join( 12 - os.tmpdir(), 13 - `atcute-pkg-size-build--${entryQualifier.replaceAll('/', '__')}--`, 14 - ); 15 - 16 - const tmpDir = fs.mkdtempSync(tmpDirPrefix); 17 - 18 - const { metafile } = esbuild.buildSync({ 19 - bundle: true, 20 - minify: true, 21 - target: 'esnext', 22 - format: 'esm', 23 - splitting: true, 24 - outdir: tmpDir, 25 - metafile: true, 26 - entryPoints: [url.fileURLToPath(entry)], 27 - }); 28 - 29 - const tmpDirUrl = url.pathToFileURL(tmpDir); 30 - const bundledSize = computeFolderSize(tmpDirUrl, true); 31 - 32 - if (!keepBuild) fs.rmSync(tmpDir, { recursive: true }); 33 - 34 - return { 35 - metafile, 36 - ...bundledSize, 37 - }; 38 - }
-3
packages/internal/pkg-size-report/src/consts.ts
··· 1 - export const WORKSPACE_ROOT = new URL('../../../../', import.meta.url); 2 - 3 - export const PKGSIZE_FOLDER = new URL('.pkgsize/', WORKSPACE_ROOT);
-44
packages/internal/pkg-size-report/src/data.ts
··· 1 - import * as fs from 'node:fs'; 2 - 3 - import type { Metafile } from 'esbuild'; 4 - 5 - import { PKGSIZE_FOLDER } from './consts.js'; 6 - 7 - const PKGSIZE_DATA = new URL(`data.json`, PKGSIZE_FOLDER); 8 - fs.mkdirSync(PKGSIZE_FOLDER, { recursive: true }); 9 - 10 - export interface EntrypointSizeInformation { 11 - name: string; 12 - size: number; 13 - gzip: number; 14 - brotli: number; 15 - metafile: Metafile; 16 - } 17 - 18 - export interface PackageSizeInformation { 19 - name: string; 20 - installSize: number; 21 - entries: EntrypointSizeInformation[]; 22 - } 23 - 24 - export function saveSizeData(data: PackageSizeInformation[]): void { 25 - const json = JSON.stringify(data, (k, v) => (k === 'metafile' ? void 0 : v), '\t'); 26 - fs.writeFileSync(PKGSIZE_DATA, json); 27 - } 28 - 29 - export function readSizeData(): PackageSizeInformation[] | null { 30 - if (!fs.existsSync(PKGSIZE_DATA)) return null; 31 - 32 - const json = fs.readFileSync(PKGSIZE_DATA, 'utf8'); 33 - return JSON.parse(json); 34 - } 35 - 36 - export function saveEsbuildMetafiles(data: PackageSizeInformation[]): void { 37 - for (const pkg of data) { 38 - for (const { name, metafile } of pkg.entries) { 39 - const path = new URL(`${name.replaceAll('/', '__')}-esbuild-metafile.json`, PKGSIZE_FOLDER); 40 - const json = JSON.stringify(metafile, null, '\t'); 41 - fs.writeFileSync(path, json); 42 - } 43 - } 44 - }
-35
packages/internal/pkg-size-report/src/diff.ts
··· 1 - import type { PackageSizeInformation } from './data.js'; 2 - 3 - export interface DiffInformation { 4 - [key: string]: { 5 - diff: number; 6 - entries: { 7 - [key: string]: { diff: number; gzip: number; brotli: number }; 8 - }; 9 - }; 10 - } 11 - 12 - export function computeSizeDiff( 13 - data: PackageSizeInformation[], 14 - old: PackageSizeInformation[], 15 - ): DiffInformation { 16 - const diff: DiffInformation = {}; 17 - for (const pkg of data) { 18 - const oldPkg = old.find((p) => p.name == pkg.name); 19 - if (!oldPkg) continue; 20 - 21 - diff[pkg.name] = { diff: pkg.installSize - oldPkg.installSize, entries: {} }; 22 - for (const entry of pkg.entries) { 23 - const oldEntry = oldPkg.entries.find((e) => e.name === entry.name); 24 - if (!oldEntry) continue; 25 - 26 - diff[pkg.name].entries[entry.name] = { 27 - diff: entry.size - oldEntry.size, 28 - gzip: entry.gzip - oldEntry.gzip, 29 - brotli: entry.brotli - oldEntry.brotli, 30 - }; 31 - } 32 - } 33 - 34 - return diff; 35 - }
-32
packages/internal/pkg-size-report/src/fs.ts
··· 1 - import * as fs from 'node:fs'; 2 - import * as zlib from 'node:zlib'; 3 - 4 - export function computeFolderSize(folder: URL, detailed = false) { 5 - folder.pathname += '/'; 6 - let res = { size: 0, gzip: 0, brotli: 0 }; 7 - 8 - for (const entry of fs.readdirSync(folder)) { 9 - const path = new URL(entry, folder); 10 - const stat = fs.statSync(path); 11 - 12 - if (stat.isDirectory()) { 13 - const nested = computeFolderSize(path); 14 - res.size += nested.size; 15 - res.gzip += nested.gzip; 16 - res.brotli += nested.brotli; 17 - } 18 - 19 - if (stat.isFile()) { 20 - res.size += stat.size; 21 - if (detailed) { 22 - const buf = fs.readFileSync(path); 23 - const gzipBuf = zlib.gzipSync(buf); 24 - const brotliBuf = zlib.brotliCompressSync(buf); 25 - res.gzip += gzipBuf.length; 26 - res.brotli += brotliBuf.length; 27 - } 28 - } 29 - } 30 - 31 - return res; 32 - }
-67
packages/internal/pkg-size-report/src/index.ts
··· 1 - import pc from 'picocolors'; 2 - 3 - import { readSizeData, saveEsbuildMetafiles, saveSizeData } from './data.js'; 4 - import { computeSizeDiff } from './diff.js'; 5 - import { computePackageSizeInformation, getAllWorkspacePackages } from './package.js'; 6 - 7 - const TREE_SYM_HAS_NEXT = '├'; 8 - const TREE_SYM_FINAL = '└'; 9 - 10 - const FLAG_SAVE = process.argv.includes('--save'); 11 - const FLAG_SAVE_META = process.argv.includes('--save-meta'); 12 - const FLAG_COMPARE = process.argv.includes('--compare'); 13 - const FLAG_KEEP_BUILDS = process.argv.includes('--keep-builds'); 14 - 15 - function formatSize(size: number) { 16 - return `${(size / 1000).toFixed(2)}kB`.padEnd(7, ' '); 17 - } 18 - 19 - function formatDiffSize(size: number) { 20 - const str = Math.abs(size) < 1000 ? `${size}B` : `${(size / 1000).toFixed(3)}kB`; 21 - return size < 0 ? pc.green(str) : pc.red(`+${str}`); 22 - } 23 - 24 - // Get package info 25 - const packages = getAllWorkspacePackages(); 26 - const sizeData = packages.map((pkg) => computePackageSizeInformation(pkg, FLAG_KEEP_BUILDS)); 27 - 28 - // Compute diff if applicable 29 - const prevData = readSizeData(); 30 - const diff = prevData && computeSizeDiff(sizeData, prevData); 31 - 32 - // Save files 33 - if (FLAG_SAVE) saveSizeData(sizeData); 34 - if (FLAG_SAVE || FLAG_SAVE_META) saveEsbuildMetafiles(sizeData); 35 - 36 - // Print to stdout. 37 - for (const pkg of sizeData) { 38 - const pkgDiff = diff?.[pkg.name]; 39 - if (FLAG_COMPARE && pkgDiff?.diff === 0) continue; 40 - 41 - let pkgInfo = `${pkg.name.padEnd(34, ' ')}\t${formatSize(pkg.installSize).padEnd(8, ' ')} ${pc.gray('install size')}`; 42 - if (pkgDiff?.diff) pkgInfo += ` ${formatDiffSize(pkgDiff.diff)}`; 43 - 44 - console.log(pkgInfo); 45 - 46 - for (let i = 0; i < pkg.entries.length; i++) { 47 - const entry = pkg.entries[i]; 48 - const entryDiff = pkgDiff?.entries[entry.name]; 49 - 50 - const size = formatSize(entry.size); 51 - const gzip = `${formatSize(entry.gzip)} ${pc.gray('gzip')}`; 52 - const brotli = `${formatSize(entry.brotli)} ${pc.gray('brotli')}`; 53 - 54 - const treeSym = i === pkg.entries.length - 1 ? TREE_SYM_FINAL : TREE_SYM_HAS_NEXT; 55 - let entryInfo = `${treeSym}── ${entry.name.padEnd(30, ' ')}\t${treeSym}── ${size}\t${gzip}\t${brotli}`; 56 - if (entryDiff?.diff) { 57 - const size = formatDiffSize(entryDiff.diff); 58 - const gzip = formatDiffSize(entryDiff.gzip); 59 - const brotli = formatDiffSize(entryDiff.brotli); 60 - entryInfo += ` ${size}/${gzip}/${brotli}`; 61 - } 62 - 63 - console.log(entryInfo); 64 - } 65 - 66 - console.log(); 67 - }
-80
packages/internal/pkg-size-report/src/package.ts
··· 1 - import * as fs from 'node:fs'; 2 - 3 - import { load as parseYaml } from 'js-yaml'; 4 - 5 - import { computeBundleInformation } from './bundle.js'; 6 - import { WORKSPACE_ROOT } from './consts.js'; 7 - import type { PackageSizeInformation } from './data.js'; 8 - import { computeFolderSize } from './fs.js'; 9 - 10 - interface PackageJsonData { 11 - folder: URL; 12 - relpath: string; 13 - name: string; 14 - private: boolean; 15 - exports: Record<string, string | { default: string }> | null; 16 - } 17 - 18 - const PNPM_LOCKFILE = new URL('pnpm-lock.yaml', WORKSPACE_ROOT); 19 - 20 - export function getAllWorkspacePackages(): PackageJsonData[] { 21 - const pnpmLockfileYaml = fs.readFileSync(PNPM_LOCKFILE, 'utf8'); 22 - const pnpmLockfile = parseYaml(pnpmLockfileYaml) as any; 23 - const packages = Object.keys(pnpmLockfile.importers); 24 - 25 - return packages 26 - .map((p) => { 27 - const packageFolder = new URL(`${p}/`, WORKSPACE_ROOT); 28 - const packageJsonFile = new URL('package.json', packageFolder); 29 - const packageJson = fs.readFileSync(packageJsonFile, 'utf8'); 30 - return Object.assign({}, JSON.parse(packageJson), { 31 - folder: packageFolder, 32 - relpath: p, 33 - }) as PackageJsonData; 34 - }) 35 - .filter((p) => !p.private); 36 - } 37 - 38 - export function computePackageSizeInformation( 39 - pkg: PackageJsonData, 40 - keepBuilds = false, 41 - ): PackageSizeInformation { 42 - const dist = new URL('dist/', pkg.folder); 43 - const { size: installSize } = computeFolderSize(dist); 44 - 45 - const pkgSizeInformation: PackageSizeInformation = { 46 - name: pkg.name, 47 - installSize, 48 - entries: [], 49 - }; 50 - 51 - // Those are just declaration packages with no useful payload. 52 - if (pkg.relpath.includes('definitions')) return pkgSizeInformation; 53 - 54 - // CLI & what not 55 - if (!pkg.exports) return pkgSizeInformation; 56 - 57 - // Non-web packages 58 - if (pkg.name.endsWith('-node') || pkg.name.endsWith('-bun') || pkg.name.endsWith('-deno')) 59 - return pkgSizeInformation; 60 - 61 - for (const entry in pkg.exports) { 62 - if (!Object.hasOwn(pkg.exports, entry)) continue; 63 - 64 - let res = pkg.exports[entry]; 65 - if (typeof res !== 'string') { 66 - res = res.default; 67 - } 68 - 69 - const entryQualifier = pkg.name + entry.slice(1); 70 - const entryFile = new URL(res, pkg.folder); 71 - 72 - const data = computeBundleInformation(entryFile, entryQualifier, keepBuilds); 73 - pkgSizeInformation.entries.push({ 74 - name: entryQualifier, 75 - ...data, 76 - }); 77 - } 78 - 79 - return pkgSizeInformation; 80 - }
-24
packages/internal/pkg-size-report/tsconfig.json
··· 1 - { 2 - "compilerOptions": { 3 - "rootDir": "src/", 4 - "outDir": "dist/", 5 - "esModuleInterop": true, 6 - "skipLibCheck": true, 7 - "target": "ESNext", 8 - "allowJs": true, 9 - "resolveJsonModule": true, 10 - "moduleDetection": "force", 11 - "isolatedModules": true, 12 - "verbatimModuleSyntax": true, 13 - "strict": true, 14 - "noImplicitOverride": true, 15 - "noUnusedLocals": true, 16 - "noUnusedParameters": true, 17 - "noFallthroughCasesInSwitch": true, 18 - "module": "NodeNext", 19 - "sourceMap": true, 20 - "declaration": true, 21 - "declarationMap": true 22 - }, 23 - "include": ["src"] 24 - }
+1 -27
pnpm-lock.yaml
··· 35 35 oxlint-tsgolint: 36 36 specifier: ^0.11.4 37 37 version: 0.11.4 38 - pkg-size-report: 39 - specifier: workspace:^ 40 - version: link:packages/internal/pkg-size-report 41 38 prettier: 42 39 specifier: ^3.8.1 43 40 version: 3.8.1 ··· 563 560 uint8arrays: 564 561 specifier: ^5.1.0 565 562 version: 5.1.0 566 - 567 - packages/internal/pkg-size-report: 568 - dependencies: 569 - esbuild: 570 - specifier: ^0.25.12 571 - version: 0.25.12 572 - js-yaml: 573 - specifier: ^4.1.1 574 - version: 4.1.1 575 - picocolors: 576 - specifier: ^1.1.1 577 - version: 1.1.1 578 - devDependencies: 579 - '@types/js-yaml': 580 - specifier: ^4.0.9 581 - version: 4.0.9 582 - '@types/node': 583 - specifier: ^25.2.1 584 - version: 25.2.1 585 563 586 564 packages/lexicons/lex-cli: 587 565 dependencies: ··· 2763 2741 2764 2742 '@types/estree@1.0.8': 2765 2743 resolution: {integrity: sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==} 2766 - 2767 - '@types/js-yaml@4.0.9': 2768 - resolution: {integrity: sha512-k4MGaQl5TGo/iipqb2UDG2UwjXziSWkh0uysQelTlJpX1qGlpUZYm8PnO4DxG1qBomtJUdYJ6qR6xdIah10JLg==} 2769 2744 2770 2745 '@types/node@12.20.55': 2771 2746 resolution: {integrity: sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ==} ··· 6590 6565 6591 6566 '@types/estree@1.0.8': {} 6592 6567 6593 - '@types/js-yaml@4.0.9': {} 6594 - 6595 6568 '@types/node@12.20.55': {} 6596 6569 6597 6570 '@types/node@25.2.1': ··· 7084 7057 '@esbuild/win32-arm64': 0.25.12 7085 7058 '@esbuild/win32-ia32': 0.25.12 7086 7059 '@esbuild/win32-x64': 0.25.12 7060 + optional: true 7087 7061 7088 7062 esbuild@0.27.3: 7089 7063 optionalDependencies: