Fast and tiny JavaScript/TypeScript cron parser with timezone support
1
fork

Configure Feed

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

update bundle-size script to autoupdate readme

+72 -57
+9 -9
README.md
··· 165 165 166 166 | Import | Raw | Minified | Gzipped | 167 167 | ---------------------------------------------------- | -------- | -------- | ----------- | 168 - | `Full bundle (all exports)` | 13.56 KB | 5.88 KB | **2.26 KB** | 169 - | `nextRun only` | 11.99 KB | 5.16 KB | **2.02 KB** | 170 - | `previousRun only` | 12.00 KB | 5.16 KB | **2.02 KB** | 171 - | `nextRuns only` | 12.38 KB | 5.31 KB | **2.08 KB** | 172 - | `isValid only` | 3.92 KB | 1.75 KB | **932 B** | 173 - | `parse only` | 3.80 KB | 1.70 KB | **907 B** | 174 - | `isMatch only` | 5.44 KB | 2.40 KB | **1.18 KB** | 175 - | `Validation only (isValid + parse)` | 3.92 KB | 1.75 KB | **934 B** | 176 - | `Scheduling only (nextRun + previousRun + nextRuns)` | 12.87 KB | 5.56 KB | **2.10 KB** | 168 + | `Full bundle (all exports) ` | 14.22 KB | 6.16 KB | **2.35 KB** | 169 + | `nextRun only ` | 12.64 KB | 5.43 KB | **2.12 KB** | 170 + | `previousRun only ` | 12.65 KB | 5.43 KB | **2.12 KB** | 171 + | `nextRuns only ` | 13.03 KB | 5.58 KB | **2.18 KB** | 172 + | `isValid only ` | 4.00 KB | 1.81 KB | **951 B** | 173 + | `parse only ` | 3.89 KB | 1.76 KB | **926 B** | 174 + | `isMatch only ` | 5.59 KB | 2.54 KB | **1.22 KB** | 175 + | `Validation only (isValid + parse) ` | 4.01 KB | 1.81 KB | **952 B** | 176 + | `Scheduling only (nextRun + previousRun + nextRuns) ` | 13.52 KB | 5.83 KB | **2.20 KB** | 177 177 178 178 Import only what you need: 179 179
+2 -1
package.json
··· 65 65 "fmt": "oxfmt", 66 66 "fmt:check": "oxfmt --check", 67 67 "typecheck": "tsc --noEmit", 68 - "bundle-size": "tsx scripts/bundle-size.ts" 68 + "bundle-size": "tsx scripts/bundle-size.ts", 69 + "update-bundle-size": "tsx scripts/bundle-size.ts --update" 69 70 }, 70 71 "devDependencies": { 71 72 "@cloudflare/vitest-pool-workers": "^0.12.10",
+60 -46
scripts/bundle-size.ts
··· 1 1 #!/usr/bin/env node 2 2 /** 3 - * Analyze bundle sizes for different import scenarios 3 + * Bundle size analysis script 4 + * 5 + * Usage: 6 + * pnpm bundle-size - Display bundle sizes only 7 + * pnpm update-bundle-size - Display and update README.md 4 8 */ 5 9 import { build } from "esbuild"; 6 10 import { gzipSync } from "node:zlib"; 7 - import { writeFileSync, mkdirSync } from "node:fs"; 11 + import { writeFileSync, readFileSync, mkdirSync } from "node:fs"; 8 12 import { join } from "node:path"; 9 13 10 14 const rootDir = process.cwd(); ··· 13 17 const scenarios = [ 14 18 { 15 19 name: "Full bundle (all exports)", 16 - code: `import * as cron from "${indexPath}"; 17 - console.log(cron);`, 20 + code: `import * as cron from "${indexPath}";\nconsole.log(cron);`, 18 21 }, 19 22 { 20 23 name: "nextRun only", 21 - code: `import { nextRun } from "${indexPath}"; 22 - console.log(nextRun);`, 24 + code: `import { nextRun } from "${indexPath}";\nconsole.log(nextRun);`, 23 25 }, 24 26 { 25 27 name: "previousRun only", 26 - code: `import { previousRun } from "${indexPath}"; 27 - console.log(previousRun);`, 28 + code: `import { previousRun } from "${indexPath}";\nconsole.log(previousRun);`, 28 29 }, 29 30 { 30 31 name: "nextRuns only", 31 - code: `import { nextRuns } from "${indexPath}"; 32 - console.log(nextRuns);`, 32 + code: `import { nextRuns } from "${indexPath}";\nconsole.log(nextRuns);`, 33 33 }, 34 34 { 35 35 name: "isValid only", 36 - code: `import { isValid } from "${indexPath}"; 37 - console.log(isValid);`, 36 + code: `import { isValid } from "${indexPath}";\nconsole.log(isValid);`, 38 37 }, 39 38 { 40 39 name: "parse only", 41 - code: `import { parse } from "${indexPath}"; 42 - console.log(parse);`, 40 + code: `import { parse } from "${indexPath}";\nconsole.log(parse);`, 43 41 }, 44 42 { 45 43 name: "isMatch only", 46 - code: `import { isMatch } from "${indexPath}"; 47 - console.log(isMatch);`, 44 + code: `import { isMatch } from "${indexPath}";\nconsole.log(isMatch);`, 48 45 }, 49 46 { 50 47 name: "Validation only (isValid + parse)", 51 - code: `import { isValid, parse } from "${indexPath}"; 52 - console.log(isValid, parse);`, 48 + code: `import { isValid, parse } from "${indexPath}";\nconsole.log(isValid, parse);`, 53 49 }, 54 50 { 55 51 name: "Scheduling only (nextRun + previousRun + nextRuns)", 56 - code: `import { nextRun, previousRun, nextRuns } from "${indexPath}"; 57 - console.log(nextRun, previousRun, nextRuns);`, 52 + code: `import { nextRun, previousRun, nextRuns } from "${indexPath}";\nconsole.log(nextRun, previousRun, nextRuns);`, 58 53 }, 59 54 ]; 60 55 ··· 118 113 return `${(bytes / (1024 * 1024)).toFixed(2)} MB`; 119 114 } 120 115 116 + function generateMarkdownTable(results: BundleResult[]): string { 117 + const rows = results.map((result) => { 118 + const name = result.name.padEnd(52); 119 + const raw = formatBytes(result.raw).padStart(8); 120 + const minified = formatBytes(result.minified).padStart(7); 121 + const gzipped = `**${formatBytes(result.gzipped)}**`.padStart(13); 122 + return `| \`${name}\` | ${raw} | ${minified} | ${gzipped} |`; 123 + }); 124 + 125 + return [ 126 + "| Import | Raw | Minified | Gzipped |", 127 + "| ---------------------------------------------------- | -------- | -------- | ----------- |", 128 + ...rows, 129 + ].join("\n"); 130 + } 131 + 132 + function updateReadme(table: string): void { 133 + const readmePath = join(rootDir, "README.md"); 134 + let readme = readFileSync(readmePath, "utf-8"); 135 + 136 + // Find the bundle size table and replace it 137 + const tableStart = readme.indexOf("| Import"); 138 + const tableEnd = readme.indexOf("\n\nImport only what you need:"); 139 + 140 + if (tableStart === -1 || tableEnd === -1) { 141 + throw new Error("Could not find bundle size table in README.md"); 142 + } 143 + 144 + readme = readme.slice(0, tableStart) + table + readme.slice(tableEnd); 145 + 146 + writeFileSync(readmePath, readme, "utf-8"); 147 + console.log("✅ README.md updated successfully!"); 148 + } 149 + 121 150 async function main() { 151 + const shouldUpdate = process.argv.includes("--update"); 152 + 122 153 console.log("📦 Analyzing bundle sizes...\n"); 123 154 124 155 const results: BundleResult[] = []; ··· 126 157 for (const scenario of scenarios) { 127 158 const result = await analyzeBundle(scenario.name, scenario.code); 128 159 results.push(result); 160 + console.log(`✓ ${scenario.name}: ${formatBytes(result.gzipped)} gzipped`); 129 161 } 130 162 131 - // Print results 132 - console.log("Bundle Size Analysis"); 133 - console.log("=".repeat(80)); 134 - console.log( 135 - `${"Scenario".padEnd(50)} ${"Raw".padStart(10)} ${"Minified".padStart(10)} ${"Gzipped".padStart(10)}`, 136 - ); 137 - console.log("-".repeat(80)); 163 + if (shouldUpdate) { 164 + console.log("\n📝 Generating markdown table..."); 165 + const table = generateMarkdownTable(results); 138 166 139 - for (const result of results) { 140 - console.log( 141 - `${result.name.padEnd(50)} ${formatBytes(result.raw).padStart(10)} ${formatBytes(result.minified).padStart(10)} ${formatBytes(result.gzipped).padStart(10)}`, 142 - ); 143 - } 144 - 145 - console.log("=".repeat(80)); 146 - 147 - // Generate markdown table 148 - console.log("\n📝 Markdown for README:\n"); 149 - console.log("| Import | Raw | Minified | Gzipped |"); 150 - console.log("|--------|-----|----------|---------|"); 151 - 152 - for (const result of results) { 153 - console.log( 154 - `| \`${result.name}\` | ${formatBytes(result.raw)} | ${formatBytes(result.minified)} | **${formatBytes(result.gzipped)}** |`, 155 - ); 167 + console.log("\n📄 Updating README.md..."); 168 + updateReadme(table); 169 + } else { 170 + console.log("\n✅ Bundle size analysis complete!"); 171 + console.log("💡 Run with --update flag to update README.md"); 156 172 } 157 - 158 - console.log("\n✅ Done!"); 159 173 } 160 174 161 175 main().catch(console.error);
+1 -1
src/matcher.ts
··· 30 30 /** 31 31 * Day-of-month and day-of-week use OR logic by default 32 32 * If both are restricted (not *), match either one 33 - * 33 + * 34 34 * @param daysInMonth - Optional validation that day is valid for the month (used by scheduler) 35 35 */ 36 36 export function matchesDayOrWeekday(