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.

script & readme section for bundle sizes

+325 -127
+1
.gitignore
··· 1 1 node_modules 2 2 dist 3 3 coverage 4 + .bundle-analysis 4 5 .DS_Store 5 6 *.log 6 7 .env
+19 -5
README.md
··· 159 159 160 160 **Note:** All returned Date objects are in UTC (ending with `Z` in `.toISOString()`). Use `.toLocaleString()` to display in any timezone. 161 161 162 - ## Tree-Shaking 162 + ## Bundle Size 163 163 164 - cron-fast is fully tree-shakeable. Import only what you need: 164 + cron-fast is extremely lightweight and fully tree-shakeable. Here are the actual bundle sizes for different import scenarios: 165 + 166 + | Import | Raw | Minified | Gzipped | 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** | 177 + 178 + Import only what you need: 165 179 166 180 ```typescript 167 - // Small bundle - only validation 181 + // Small bundle - only validation (~900 B gzipped) 168 182 import { isValid } from "cron-fast"; 169 183 170 - // Medium bundle - one function + dependencies 184 + // Medium bundle - one function + dependencies (~2 KB gzipped) 171 185 import { nextRun } from "cron-fast"; 172 186 173 - // Full bundle - everything 187 + // Full bundle - everything (~2.3 KB gzipped) 174 188 import * as cron from "cron-fast"; 175 189 ``` 176 190
+3
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 69 "prepublishOnly": "pnpm run build" 69 70 }, 70 71 "devDependencies": { ··· 72 73 "@types/node": "^25.2.2", 73 74 "@vitest/coverage-v8": "^3.2.4", 74 75 "@vitest/ui": "^3.2.4", 76 + "esbuild": "^0.27.3", 75 77 "oxfmt": "^0.28.0", 76 78 "oxlint": "^1.43.0", 77 79 "tsdown": "^0.20.3", 80 + "tsx": "^4.21.0", 78 81 "typescript": "^5.9.3", 79 82 "vite": "^7.3.1", 80 83 "vitest": "3.2.4"
+141 -122
pnpm-lock.yaml
··· 20 20 '@vitest/ui': 21 21 specifier: ^3.2.4 22 22 version: 3.2.4(vitest@3.2.4) 23 + esbuild: 24 + specifier: ^0.27.3 25 + version: 0.27.3 23 26 oxfmt: 24 27 specifier: ^0.28.0 25 28 version: 0.28.0 ··· 29 32 tsdown: 30 33 specifier: ^0.20.3 31 34 version: 0.20.3(typescript@5.9.3) 35 + tsx: 36 + specifier: ^4.21.0 37 + version: 4.21.0 32 38 typescript: 33 39 specifier: ^5.9.3 34 40 version: 5.9.3 35 41 vite: 36 42 specifier: ^7.3.1 37 - version: 7.3.1(@types/node@25.2.2) 43 + version: 7.3.1(@types/node@25.2.2)(tsx@4.21.0) 38 44 vitest: 39 45 specifier: 3.2.4 40 - version: 3.2.4(@types/node@25.2.2)(@vitest/ui@3.2.4) 46 + version: 3.2.4(@types/node@25.2.2)(@vitest/ui@3.2.4)(tsx@4.21.0) 41 47 42 48 packages: 43 49 ··· 156 162 cpu: [ppc64] 157 163 os: [aix] 158 164 159 - '@esbuild/aix-ppc64@0.27.2': 160 - resolution: {integrity: sha512-GZMB+a0mOMZs4MpDbj8RJp4cw+w1WV5NYD6xzgvzUJ5Ek2jerwfO2eADyI6ExDSUED+1X8aMbegahsJi+8mgpw==} 165 + '@esbuild/aix-ppc64@0.27.3': 166 + resolution: {integrity: sha512-9fJMTNFTWZMh5qwrBItuziu834eOCUcEqymSH7pY+zoMVEZg3gcPuBNxH1EvfVYe9h0x/Ptw8KBzv7qxb7l8dg==} 161 167 engines: {node: '>=18'} 162 168 cpu: [ppc64] 163 169 os: [aix] ··· 168 174 cpu: [arm64] 169 175 os: [android] 170 176 171 - '@esbuild/android-arm64@0.27.2': 172 - resolution: {integrity: sha512-pvz8ZZ7ot/RBphf8fv60ljmaoydPU12VuXHImtAs0XhLLw+EXBi2BLe3OYSBslR4rryHvweW5gmkKFwTiFy6KA==} 177 + '@esbuild/android-arm64@0.27.3': 178 + resolution: {integrity: sha512-YdghPYUmj/FX2SYKJ0OZxf+iaKgMsKHVPF1MAq/P8WirnSpCStzKJFjOjzsW0QQ7oIAiccHdcqjbHmJxRb/dmg==} 173 179 engines: {node: '>=18'} 174 180 cpu: [arm64] 175 181 os: [android] ··· 180 186 cpu: [arm] 181 187 os: [android] 182 188 183 - '@esbuild/android-arm@0.27.2': 184 - resolution: {integrity: sha512-DVNI8jlPa7Ujbr1yjU2PfUSRtAUZPG9I1RwW4F4xFB1Imiu2on0ADiI/c3td+KmDtVKNbi+nffGDQMfcIMkwIA==} 189 + '@esbuild/android-arm@0.27.3': 190 + resolution: {integrity: sha512-i5D1hPY7GIQmXlXhs2w8AWHhenb00+GxjxRncS2ZM7YNVGNfaMxgzSGuO8o8SJzRc/oZwU2bcScvVERk03QhzA==} 185 191 engines: {node: '>=18'} 186 192 cpu: [arm] 187 193 os: [android] ··· 192 198 cpu: [x64] 193 199 os: [android] 194 200 195 - '@esbuild/android-x64@0.27.2': 196 - resolution: {integrity: sha512-z8Ank4Byh4TJJOh4wpz8g2vDy75zFL0TlZlkUkEwYXuPSgX8yzep596n6mT7905kA9uHZsf/o2OJZubl2l3M7A==} 201 + '@esbuild/android-x64@0.27.3': 202 + resolution: {integrity: sha512-IN/0BNTkHtk8lkOM8JWAYFg4ORxBkZQf9zXiEOfERX/CzxW3Vg1ewAhU7QSWQpVIzTW+b8Xy+lGzdYXV6UZObQ==} 197 203 engines: {node: '>=18'} 198 204 cpu: [x64] 199 205 os: [android] ··· 204 210 cpu: [arm64] 205 211 os: [darwin] 206 212 207 - '@esbuild/darwin-arm64@0.27.2': 208 - resolution: {integrity: sha512-davCD2Zc80nzDVRwXTcQP/28fiJbcOwvdolL0sOiOsbwBa72kegmVU0Wrh1MYrbuCL98Omp5dVhQFWRKR2ZAlg==} 213 + '@esbuild/darwin-arm64@0.27.3': 214 + resolution: {integrity: sha512-Re491k7ByTVRy0t3EKWajdLIr0gz2kKKfzafkth4Q8A5n1xTHrkqZgLLjFEHVD+AXdUGgQMq+Godfq45mGpCKg==} 209 215 engines: {node: '>=18'} 210 216 cpu: [arm64] 211 217 os: [darwin] ··· 216 222 cpu: [x64] 217 223 os: [darwin] 218 224 219 - '@esbuild/darwin-x64@0.27.2': 220 - resolution: {integrity: sha512-ZxtijOmlQCBWGwbVmwOF/UCzuGIbUkqB1faQRf5akQmxRJ1ujusWsb3CVfk/9iZKr2L5SMU5wPBi1UWbvL+VQA==} 225 + '@esbuild/darwin-x64@0.27.3': 226 + resolution: {integrity: sha512-vHk/hA7/1AckjGzRqi6wbo+jaShzRowYip6rt6q7VYEDX4LEy1pZfDpdxCBnGtl+A5zq8iXDcyuxwtv3hNtHFg==} 221 227 engines: {node: '>=18'} 222 228 cpu: [x64] 223 229 os: [darwin] ··· 228 234 cpu: [arm64] 229 235 os: [freebsd] 230 236 231 - '@esbuild/freebsd-arm64@0.27.2': 232 - resolution: {integrity: sha512-lS/9CN+rgqQ9czogxlMcBMGd+l8Q3Nj1MFQwBZJyoEKI50XGxwuzznYdwcav6lpOGv5BqaZXqvBSiB/kJ5op+g==} 237 + '@esbuild/freebsd-arm64@0.27.3': 238 + resolution: {integrity: sha512-ipTYM2fjt3kQAYOvo6vcxJx3nBYAzPjgTCk7QEgZG8AUO3ydUhvelmhrbOheMnGOlaSFUoHXB6un+A7q4ygY9w==} 233 239 engines: {node: '>=18'} 234 240 cpu: [arm64] 235 241 os: [freebsd] ··· 240 246 cpu: [x64] 241 247 os: [freebsd] 242 248 243 - '@esbuild/freebsd-x64@0.27.2': 244 - resolution: {integrity: sha512-tAfqtNYb4YgPnJlEFu4c212HYjQWSO/w/h/lQaBK7RbwGIkBOuNKQI9tqWzx7Wtp7bTPaGC6MJvWI608P3wXYA==} 249 + '@esbuild/freebsd-x64@0.27.3': 250 + resolution: {integrity: sha512-dDk0X87T7mI6U3K9VjWtHOXqwAMJBNN2r7bejDsc+j03SEjtD9HrOl8gVFByeM0aJksoUuUVU9TBaZa2rgj0oA==} 245 251 engines: {node: '>=18'} 246 252 cpu: [x64] 247 253 os: [freebsd] ··· 252 258 cpu: [arm64] 253 259 os: [linux] 254 260 255 - '@esbuild/linux-arm64@0.27.2': 256 - resolution: {integrity: sha512-hYxN8pr66NsCCiRFkHUAsxylNOcAQaxSSkHMMjcpx0si13t1LHFphxJZUiGwojB1a/Hd5OiPIqDdXONia6bhTw==} 261 + '@esbuild/linux-arm64@0.27.3': 262 + resolution: {integrity: sha512-sZOuFz/xWnZ4KH3YfFrKCf1WyPZHakVzTiqji3WDc0BCl2kBwiJLCXpzLzUBLgmp4veFZdvN5ChW4Eq/8Fc2Fg==} 257 263 engines: {node: '>=18'} 258 264 cpu: [arm64] 259 265 os: [linux] ··· 264 270 cpu: [arm] 265 271 os: [linux] 266 272 267 - '@esbuild/linux-arm@0.27.2': 268 - resolution: {integrity: sha512-vWfq4GaIMP9AIe4yj1ZUW18RDhx6EPQKjwe7n8BbIecFtCQG4CfHGaHuh7fdfq+y3LIA2vGS/o9ZBGVxIDi9hw==} 273 + '@esbuild/linux-arm@0.27.3': 274 + resolution: {integrity: sha512-s6nPv2QkSupJwLYyfS+gwdirm0ukyTFNl3KTgZEAiJDd+iHZcbTPPcWCcRYH+WlNbwChgH2QkE9NSlNrMT8Gfw==} 269 275 engines: {node: '>=18'} 270 276 cpu: [arm] 271 277 os: [linux] ··· 276 282 cpu: [ia32] 277 283 os: [linux] 278 284 279 - '@esbuild/linux-ia32@0.27.2': 280 - resolution: {integrity: sha512-MJt5BRRSScPDwG2hLelYhAAKh9imjHK5+NE/tvnRLbIqUWa+0E9N4WNMjmp/kXXPHZGqPLxggwVhz7QP8CTR8w==} 285 + '@esbuild/linux-ia32@0.27.3': 286 + resolution: {integrity: sha512-yGlQYjdxtLdh0a3jHjuwOrxQjOZYD/C9PfdbgJJF3TIZWnm/tMd/RcNiLngiu4iwcBAOezdnSLAwQDPqTmtTYg==} 281 287 engines: {node: '>=18'} 282 288 cpu: [ia32] 283 289 os: [linux] ··· 288 294 cpu: [loong64] 289 295 os: [linux] 290 296 291 - '@esbuild/linux-loong64@0.27.2': 292 - resolution: {integrity: sha512-lugyF1atnAT463aO6KPshVCJK5NgRnU4yb3FUumyVz+cGvZbontBgzeGFO1nF+dPueHD367a2ZXe1NtUkAjOtg==} 297 + '@esbuild/linux-loong64@0.27.3': 298 + resolution: {integrity: sha512-WO60Sn8ly3gtzhyjATDgieJNet/KqsDlX5nRC5Y3oTFcS1l0KWba+SEa9Ja1GfDqSF1z6hif/SkpQJbL63cgOA==} 293 299 engines: {node: '>=18'} 294 300 cpu: [loong64] 295 301 os: [linux] ··· 300 306 cpu: [mips64el] 301 307 os: [linux] 302 308 303 - '@esbuild/linux-mips64el@0.27.2': 304 - resolution: {integrity: sha512-nlP2I6ArEBewvJ2gjrrkESEZkB5mIoaTswuqNFRv/WYd+ATtUpe9Y09RnJvgvdag7he0OWgEZWhviS1OTOKixw==} 309 + '@esbuild/linux-mips64el@0.27.3': 310 + resolution: {integrity: sha512-APsymYA6sGcZ4pD6k+UxbDjOFSvPWyZhjaiPyl/f79xKxwTnrn5QUnXR5prvetuaSMsb4jgeHewIDCIWljrSxw==} 305 311 engines: {node: '>=18'} 306 312 cpu: [mips64el] 307 313 os: [linux] ··· 312 318 cpu: [ppc64] 313 319 os: [linux] 314 320 315 - '@esbuild/linux-ppc64@0.27.2': 316 - resolution: {integrity: sha512-C92gnpey7tUQONqg1n6dKVbx3vphKtTHJaNG2Ok9lGwbZil6DrfyecMsp9CrmXGQJmZ7iiVXvvZH6Ml5hL6XdQ==} 321 + '@esbuild/linux-ppc64@0.27.3': 322 + resolution: {integrity: sha512-eizBnTeBefojtDb9nSh4vvVQ3V9Qf9Df01PfawPcRzJH4gFSgrObw+LveUyDoKU3kxi5+9RJTCWlj4FjYXVPEA==} 317 323 engines: {node: '>=18'} 318 324 cpu: [ppc64] 319 325 os: [linux] ··· 324 330 cpu: [riscv64] 325 331 os: [linux] 326 332 327 - '@esbuild/linux-riscv64@0.27.2': 328 - resolution: {integrity: sha512-B5BOmojNtUyN8AXlK0QJyvjEZkWwy/FKvakkTDCziX95AowLZKR6aCDhG7LeF7uMCXEJqwa8Bejz5LTPYm8AvA==} 333 + '@esbuild/linux-riscv64@0.27.3': 334 + resolution: {integrity: sha512-3Emwh0r5wmfm3ssTWRQSyVhbOHvqegUDRd0WhmXKX2mkHJe1SFCMJhagUleMq+Uci34wLSipf8Lagt4LlpRFWQ==} 329 335 engines: {node: '>=18'} 330 336 cpu: [riscv64] 331 337 os: [linux] ··· 336 342 cpu: [s390x] 337 343 os: [linux] 338 344 339 - '@esbuild/linux-s390x@0.27.2': 340 - resolution: {integrity: sha512-p4bm9+wsPwup5Z8f4EpfN63qNagQ47Ua2znaqGH6bqLlmJ4bx97Y9JdqxgGZ6Y8xVTixUnEkoKSHcpRlDnNr5w==} 345 + '@esbuild/linux-s390x@0.27.3': 346 + resolution: {integrity: sha512-pBHUx9LzXWBc7MFIEEL0yD/ZVtNgLytvx60gES28GcWMqil8ElCYR4kvbV2BDqsHOvVDRrOxGySBM9Fcv744hw==} 341 347 engines: {node: '>=18'} 342 348 cpu: [s390x] 343 349 os: [linux] ··· 348 354 cpu: [x64] 349 355 os: [linux] 350 356 351 - '@esbuild/linux-x64@0.27.2': 352 - resolution: {integrity: sha512-uwp2Tip5aPmH+NRUwTcfLb+W32WXjpFejTIOWZFw/v7/KnpCDKG66u4DLcurQpiYTiYwQ9B7KOeMJvLCu/OvbA==} 357 + '@esbuild/linux-x64@0.27.3': 358 + resolution: {integrity: sha512-Czi8yzXUWIQYAtL/2y6vogER8pvcsOsk5cpwL4Gk5nJqH5UZiVByIY8Eorm5R13gq+DQKYg0+JyQoytLQas4dA==} 353 359 engines: {node: '>=18'} 354 360 cpu: [x64] 355 361 os: [linux] ··· 360 366 cpu: [arm64] 361 367 os: [netbsd] 362 368 363 - '@esbuild/netbsd-arm64@0.27.2': 364 - resolution: {integrity: sha512-Kj6DiBlwXrPsCRDeRvGAUb/LNrBASrfqAIok+xB0LxK8CHqxZ037viF13ugfsIpePH93mX7xfJp97cyDuTZ3cw==} 369 + '@esbuild/netbsd-arm64@0.27.3': 370 + resolution: {integrity: sha512-sDpk0RgmTCR/5HguIZa9n9u+HVKf40fbEUt+iTzSnCaGvY9kFP0YKBWZtJaraonFnqef5SlJ8/TiPAxzyS+UoA==} 365 371 engines: {node: '>=18'} 366 372 cpu: [arm64] 367 373 os: [netbsd] ··· 372 378 cpu: [x64] 373 379 os: [netbsd] 374 380 375 - '@esbuild/netbsd-x64@0.27.2': 376 - resolution: {integrity: sha512-HwGDZ0VLVBY3Y+Nw0JexZy9o/nUAWq9MlV7cahpaXKW6TOzfVno3y3/M8Ga8u8Yr7GldLOov27xiCnqRZf0tCA==} 381 + '@esbuild/netbsd-x64@0.27.3': 382 + resolution: {integrity: sha512-P14lFKJl/DdaE00LItAukUdZO5iqNH7+PjoBm+fLQjtxfcfFE20Xf5CrLsmZdq5LFFZzb5JMZ9grUwvtVYzjiA==} 377 383 engines: {node: '>=18'} 378 384 cpu: [x64] 379 385 os: [netbsd] ··· 384 390 cpu: [arm64] 385 391 os: [openbsd] 386 392 387 - '@esbuild/openbsd-arm64@0.27.2': 388 - resolution: {integrity: sha512-DNIHH2BPQ5551A7oSHD0CKbwIA/Ox7+78/AWkbS5QoRzaqlev2uFayfSxq68EkonB+IKjiuxBFoV8ESJy8bOHA==} 393 + '@esbuild/openbsd-arm64@0.27.3': 394 + resolution: {integrity: sha512-AIcMP77AvirGbRl/UZFTq5hjXK+2wC7qFRGoHSDrZ5v5b8DK/GYpXW3CPRL53NkvDqb9D+alBiC/dV0Fb7eJcw==} 389 395 engines: {node: '>=18'} 390 396 cpu: [arm64] 391 397 os: [openbsd] ··· 396 402 cpu: [x64] 397 403 os: [openbsd] 398 404 399 - '@esbuild/openbsd-x64@0.27.2': 400 - resolution: {integrity: sha512-/it7w9Nb7+0KFIzjalNJVR5bOzA9Vay+yIPLVHfIQYG/j+j9VTH84aNB8ExGKPU4AzfaEvN9/V4HV+F+vo8OEg==} 405 + '@esbuild/openbsd-x64@0.27.3': 406 + resolution: {integrity: sha512-DnW2sRrBzA+YnE70LKqnM3P+z8vehfJWHXECbwBmH/CU51z6FiqTQTHFenPlHmo3a8UgpLyH3PT+87OViOh1AQ==} 401 407 engines: {node: '>=18'} 402 408 cpu: [x64] 403 409 os: [openbsd] ··· 408 414 cpu: [arm64] 409 415 os: [openharmony] 410 416 411 - '@esbuild/openharmony-arm64@0.27.2': 412 - resolution: {integrity: sha512-LRBbCmiU51IXfeXk59csuX/aSaToeG7w48nMwA6049Y4J4+VbWALAuXcs+qcD04rHDuSCSRKdmY63sruDS5qag==} 417 + '@esbuild/openharmony-arm64@0.27.3': 418 + resolution: {integrity: sha512-NinAEgr/etERPTsZJ7aEZQvvg/A6IsZG/LgZy+81wON2huV7SrK3e63dU0XhyZP4RKGyTm7aOgmQk0bGp0fy2g==} 413 419 engines: {node: '>=18'} 414 420 cpu: [arm64] 415 421 os: [openharmony] ··· 420 426 cpu: [x64] 421 427 os: [sunos] 422 428 423 - '@esbuild/sunos-x64@0.27.2': 424 - resolution: {integrity: sha512-kMtx1yqJHTmqaqHPAzKCAkDaKsffmXkPHThSfRwZGyuqyIeBvf08KSsYXl+abf5HDAPMJIPnbBfXvP2ZC2TfHg==} 429 + '@esbuild/sunos-x64@0.27.3': 430 + resolution: {integrity: sha512-PanZ+nEz+eWoBJ8/f8HKxTTD172SKwdXebZ0ndd953gt1HRBbhMsaNqjTyYLGLPdoWHy4zLU7bDVJztF5f3BHA==} 425 431 engines: {node: '>=18'} 426 432 cpu: [x64] 427 433 os: [sunos] ··· 432 438 cpu: [arm64] 433 439 os: [win32] 434 440 435 - '@esbuild/win32-arm64@0.27.2': 436 - resolution: {integrity: sha512-Yaf78O/B3Kkh+nKABUF++bvJv5Ijoy9AN1ww904rOXZFLWVc5OLOfL56W+C8F9xn5JQZa3UX6m+IktJnIb1Jjg==} 441 + '@esbuild/win32-arm64@0.27.3': 442 + resolution: {integrity: sha512-B2t59lWWYrbRDw/tjiWOuzSsFh1Y/E95ofKz7rIVYSQkUYBjfSgf6oeYPNWHToFRr2zx52JKApIcAS/D5TUBnA==} 437 443 engines: {node: '>=18'} 438 444 cpu: [arm64] 439 445 os: [win32] ··· 444 450 cpu: [ia32] 445 451 os: [win32] 446 452 447 - '@esbuild/win32-ia32@0.27.2': 448 - resolution: {integrity: sha512-Iuws0kxo4yusk7sw70Xa2E2imZU5HoixzxfGCdxwBdhiDgt9vX9VUCBhqcwY7/uh//78A1hMkkROMJq9l27oLQ==} 453 + '@esbuild/win32-ia32@0.27.3': 454 + resolution: {integrity: sha512-QLKSFeXNS8+tHW7tZpMtjlNb7HKau0QDpwm49u0vUp9y1WOF+PEzkU84y9GqYaAVW8aH8f3GcBck26jh54cX4Q==} 449 455 engines: {node: '>=18'} 450 456 cpu: [ia32] 451 457 os: [win32] ··· 456 462 cpu: [x64] 457 463 os: [win32] 458 464 459 - '@esbuild/win32-x64@0.27.2': 460 - resolution: {integrity: sha512-sRdU18mcKf7F+YgheI/zGf5alZatMUTKj/jNS6l744f9u3WFu4v7twcUI9vu4mknF4Y9aDlblIie0IM+5xxaqQ==} 465 + '@esbuild/win32-x64@0.27.3': 466 + resolution: {integrity: sha512-4uJGhsxuptu3OcpVAzli+/gWusVGwZZHTlS63hh++ehExkVT8SgiEf7/uC/PclrPPkLhZqGgCTjd0VWLo6xMqA==} 461 467 engines: {node: '>=18'} 462 468 cpu: [x64] 463 469 os: [win32] ··· 1180 1186 engines: {node: '>=18'} 1181 1187 hasBin: true 1182 1188 1183 - esbuild@0.27.2: 1184 - resolution: {integrity: sha512-HyNQImnsOC7X9PMNaCIeAm4ISCQXs5a5YasTXVliKv4uuBo1dKrG0A+uQS8M5eXjVMnLg3WgXaKvprHlFJQffw==} 1189 + esbuild@0.27.3: 1190 + resolution: {integrity: sha512-8VwMnyGCONIs6cWue2IdpHxHnAjzxnw2Zr7MkVxB2vjmQ2ivqGFb4LEG3SMnv0Gb2F/G/2yA8zUaiL1gywDCCg==} 1185 1191 engines: {node: '>=18'} 1186 1192 hasBin: true 1187 1193 ··· 1544 1550 tslib@2.8.1: 1545 1551 resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} 1546 1552 1553 + tsx@4.21.0: 1554 + resolution: {integrity: sha512-5C1sg4USs1lfG0GFb2RLXsdpXqBSEhAaA/0kPL01wxzpMqLILNxIxIOKiILz+cdg/pLnOUxFYOR5yhHU666wbw==} 1555 + engines: {node: '>=18.0.0'} 1556 + hasBin: true 1557 + 1547 1558 typescript@5.9.3: 1548 1559 resolution: {integrity: sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==} 1549 1560 engines: {node: '>=14.17'} ··· 1755 1766 cjs-module-lexer: 1.4.3 1756 1767 esbuild: 0.27.0 1757 1768 miniflare: 4.20260205.0 1758 - vitest: 3.2.4(@types/node@25.2.2)(@vitest/ui@3.2.4) 1769 + vitest: 3.2.4(@types/node@25.2.2)(@vitest/ui@3.2.4)(tsx@4.21.0) 1759 1770 wrangler: 4.63.0 1760 1771 transitivePeerDependencies: 1761 1772 - '@cloudflare/workers-types' ··· 1800 1811 '@esbuild/aix-ppc64@0.27.0': 1801 1812 optional: true 1802 1813 1803 - '@esbuild/aix-ppc64@0.27.2': 1814 + '@esbuild/aix-ppc64@0.27.3': 1804 1815 optional: true 1805 1816 1806 1817 '@esbuild/android-arm64@0.27.0': 1807 1818 optional: true 1808 1819 1809 - '@esbuild/android-arm64@0.27.2': 1820 + '@esbuild/android-arm64@0.27.3': 1810 1821 optional: true 1811 1822 1812 1823 '@esbuild/android-arm@0.27.0': 1813 1824 optional: true 1814 1825 1815 - '@esbuild/android-arm@0.27.2': 1826 + '@esbuild/android-arm@0.27.3': 1816 1827 optional: true 1817 1828 1818 1829 '@esbuild/android-x64@0.27.0': 1819 1830 optional: true 1820 1831 1821 - '@esbuild/android-x64@0.27.2': 1832 + '@esbuild/android-x64@0.27.3': 1822 1833 optional: true 1823 1834 1824 1835 '@esbuild/darwin-arm64@0.27.0': 1825 1836 optional: true 1826 1837 1827 - '@esbuild/darwin-arm64@0.27.2': 1838 + '@esbuild/darwin-arm64@0.27.3': 1828 1839 optional: true 1829 1840 1830 1841 '@esbuild/darwin-x64@0.27.0': 1831 1842 optional: true 1832 1843 1833 - '@esbuild/darwin-x64@0.27.2': 1844 + '@esbuild/darwin-x64@0.27.3': 1834 1845 optional: true 1835 1846 1836 1847 '@esbuild/freebsd-arm64@0.27.0': 1837 1848 optional: true 1838 1849 1839 - '@esbuild/freebsd-arm64@0.27.2': 1850 + '@esbuild/freebsd-arm64@0.27.3': 1840 1851 optional: true 1841 1852 1842 1853 '@esbuild/freebsd-x64@0.27.0': 1843 1854 optional: true 1844 1855 1845 - '@esbuild/freebsd-x64@0.27.2': 1856 + '@esbuild/freebsd-x64@0.27.3': 1846 1857 optional: true 1847 1858 1848 1859 '@esbuild/linux-arm64@0.27.0': 1849 1860 optional: true 1850 1861 1851 - '@esbuild/linux-arm64@0.27.2': 1862 + '@esbuild/linux-arm64@0.27.3': 1852 1863 optional: true 1853 1864 1854 1865 '@esbuild/linux-arm@0.27.0': 1855 1866 optional: true 1856 1867 1857 - '@esbuild/linux-arm@0.27.2': 1868 + '@esbuild/linux-arm@0.27.3': 1858 1869 optional: true 1859 1870 1860 1871 '@esbuild/linux-ia32@0.27.0': 1861 1872 optional: true 1862 1873 1863 - '@esbuild/linux-ia32@0.27.2': 1874 + '@esbuild/linux-ia32@0.27.3': 1864 1875 optional: true 1865 1876 1866 1877 '@esbuild/linux-loong64@0.27.0': 1867 1878 optional: true 1868 1879 1869 - '@esbuild/linux-loong64@0.27.2': 1880 + '@esbuild/linux-loong64@0.27.3': 1870 1881 optional: true 1871 1882 1872 1883 '@esbuild/linux-mips64el@0.27.0': 1873 1884 optional: true 1874 1885 1875 - '@esbuild/linux-mips64el@0.27.2': 1886 + '@esbuild/linux-mips64el@0.27.3': 1876 1887 optional: true 1877 1888 1878 1889 '@esbuild/linux-ppc64@0.27.0': 1879 1890 optional: true 1880 1891 1881 - '@esbuild/linux-ppc64@0.27.2': 1892 + '@esbuild/linux-ppc64@0.27.3': 1882 1893 optional: true 1883 1894 1884 1895 '@esbuild/linux-riscv64@0.27.0': 1885 1896 optional: true 1886 1897 1887 - '@esbuild/linux-riscv64@0.27.2': 1898 + '@esbuild/linux-riscv64@0.27.3': 1888 1899 optional: true 1889 1900 1890 1901 '@esbuild/linux-s390x@0.27.0': 1891 1902 optional: true 1892 1903 1893 - '@esbuild/linux-s390x@0.27.2': 1904 + '@esbuild/linux-s390x@0.27.3': 1894 1905 optional: true 1895 1906 1896 1907 '@esbuild/linux-x64@0.27.0': 1897 1908 optional: true 1898 1909 1899 - '@esbuild/linux-x64@0.27.2': 1910 + '@esbuild/linux-x64@0.27.3': 1900 1911 optional: true 1901 1912 1902 1913 '@esbuild/netbsd-arm64@0.27.0': 1903 1914 optional: true 1904 1915 1905 - '@esbuild/netbsd-arm64@0.27.2': 1916 + '@esbuild/netbsd-arm64@0.27.3': 1906 1917 optional: true 1907 1918 1908 1919 '@esbuild/netbsd-x64@0.27.0': 1909 1920 optional: true 1910 1921 1911 - '@esbuild/netbsd-x64@0.27.2': 1922 + '@esbuild/netbsd-x64@0.27.3': 1912 1923 optional: true 1913 1924 1914 1925 '@esbuild/openbsd-arm64@0.27.0': 1915 1926 optional: true 1916 1927 1917 - '@esbuild/openbsd-arm64@0.27.2': 1928 + '@esbuild/openbsd-arm64@0.27.3': 1918 1929 optional: true 1919 1930 1920 1931 '@esbuild/openbsd-x64@0.27.0': 1921 1932 optional: true 1922 1933 1923 - '@esbuild/openbsd-x64@0.27.2': 1934 + '@esbuild/openbsd-x64@0.27.3': 1924 1935 optional: true 1925 1936 1926 1937 '@esbuild/openharmony-arm64@0.27.0': 1927 1938 optional: true 1928 1939 1929 - '@esbuild/openharmony-arm64@0.27.2': 1940 + '@esbuild/openharmony-arm64@0.27.3': 1930 1941 optional: true 1931 1942 1932 1943 '@esbuild/sunos-x64@0.27.0': 1933 1944 optional: true 1934 1945 1935 - '@esbuild/sunos-x64@0.27.2': 1946 + '@esbuild/sunos-x64@0.27.3': 1936 1947 optional: true 1937 1948 1938 1949 '@esbuild/win32-arm64@0.27.0': 1939 1950 optional: true 1940 1951 1941 - '@esbuild/win32-arm64@0.27.2': 1952 + '@esbuild/win32-arm64@0.27.3': 1942 1953 optional: true 1943 1954 1944 1955 '@esbuild/win32-ia32@0.27.0': 1945 1956 optional: true 1946 1957 1947 - '@esbuild/win32-ia32@0.27.2': 1958 + '@esbuild/win32-ia32@0.27.3': 1948 1959 optional: true 1949 1960 1950 1961 '@esbuild/win32-x64@0.27.0': 1951 1962 optional: true 1952 1963 1953 - '@esbuild/win32-x64@0.27.2': 1964 + '@esbuild/win32-x64@0.27.3': 1954 1965 optional: true 1955 1966 1956 1967 '@img/colour@1.0.0': {} ··· 2314 2325 std-env: 3.10.0 2315 2326 test-exclude: 7.0.1 2316 2327 tinyrainbow: 2.0.0 2317 - vitest: 3.2.4(@types/node@25.2.2)(@vitest/ui@3.2.4) 2328 + vitest: 3.2.4(@types/node@25.2.2)(@vitest/ui@3.2.4)(tsx@4.21.0) 2318 2329 transitivePeerDependencies: 2319 2330 - supports-color 2320 2331 ··· 2326 2337 chai: 5.3.3 2327 2338 tinyrainbow: 2.0.0 2328 2339 2329 - '@vitest/mocker@3.2.4(vite@7.3.1(@types/node@25.2.2))': 2340 + '@vitest/mocker@3.2.4(vite@7.3.1(@types/node@25.2.2)(tsx@4.21.0))': 2330 2341 dependencies: 2331 2342 '@vitest/spy': 3.2.4 2332 2343 estree-walker: 3.0.3 2333 2344 magic-string: 0.30.21 2334 2345 optionalDependencies: 2335 - vite: 7.3.1(@types/node@25.2.2) 2346 + vite: 7.3.1(@types/node@25.2.2)(tsx@4.21.0) 2336 2347 2337 2348 '@vitest/pretty-format@3.2.4': 2338 2349 dependencies: ··· 2378 2389 sirv: 3.0.2 2379 2390 tinyglobby: 0.2.15 2380 2391 tinyrainbow: 2.0.0 2381 - vitest: 3.2.4(@types/node@25.2.2)(@vitest/ui@3.2.4) 2392 + vitest: 3.2.4(@types/node@25.2.2)(@vitest/ui@3.2.4)(tsx@4.21.0) 2382 2393 2383 2394 '@vitest/utils@3.2.4': 2384 2395 dependencies: ··· 2508 2519 '@esbuild/win32-ia32': 0.27.0 2509 2520 '@esbuild/win32-x64': 0.27.0 2510 2521 2511 - esbuild@0.27.2: 2522 + esbuild@0.27.3: 2512 2523 optionalDependencies: 2513 - '@esbuild/aix-ppc64': 0.27.2 2514 - '@esbuild/android-arm': 0.27.2 2515 - '@esbuild/android-arm64': 0.27.2 2516 - '@esbuild/android-x64': 0.27.2 2517 - '@esbuild/darwin-arm64': 0.27.2 2518 - '@esbuild/darwin-x64': 0.27.2 2519 - '@esbuild/freebsd-arm64': 0.27.2 2520 - '@esbuild/freebsd-x64': 0.27.2 2521 - '@esbuild/linux-arm': 0.27.2 2522 - '@esbuild/linux-arm64': 0.27.2 2523 - '@esbuild/linux-ia32': 0.27.2 2524 - '@esbuild/linux-loong64': 0.27.2 2525 - '@esbuild/linux-mips64el': 0.27.2 2526 - '@esbuild/linux-ppc64': 0.27.2 2527 - '@esbuild/linux-riscv64': 0.27.2 2528 - '@esbuild/linux-s390x': 0.27.2 2529 - '@esbuild/linux-x64': 0.27.2 2530 - '@esbuild/netbsd-arm64': 0.27.2 2531 - '@esbuild/netbsd-x64': 0.27.2 2532 - '@esbuild/openbsd-arm64': 0.27.2 2533 - '@esbuild/openbsd-x64': 0.27.2 2534 - '@esbuild/openharmony-arm64': 0.27.2 2535 - '@esbuild/sunos-x64': 0.27.2 2536 - '@esbuild/win32-arm64': 0.27.2 2537 - '@esbuild/win32-ia32': 0.27.2 2538 - '@esbuild/win32-x64': 0.27.2 2524 + '@esbuild/aix-ppc64': 0.27.3 2525 + '@esbuild/android-arm': 0.27.3 2526 + '@esbuild/android-arm64': 0.27.3 2527 + '@esbuild/android-x64': 0.27.3 2528 + '@esbuild/darwin-arm64': 0.27.3 2529 + '@esbuild/darwin-x64': 0.27.3 2530 + '@esbuild/freebsd-arm64': 0.27.3 2531 + '@esbuild/freebsd-x64': 0.27.3 2532 + '@esbuild/linux-arm': 0.27.3 2533 + '@esbuild/linux-arm64': 0.27.3 2534 + '@esbuild/linux-ia32': 0.27.3 2535 + '@esbuild/linux-loong64': 0.27.3 2536 + '@esbuild/linux-mips64el': 0.27.3 2537 + '@esbuild/linux-ppc64': 0.27.3 2538 + '@esbuild/linux-riscv64': 0.27.3 2539 + '@esbuild/linux-s390x': 0.27.3 2540 + '@esbuild/linux-x64': 0.27.3 2541 + '@esbuild/netbsd-arm64': 0.27.3 2542 + '@esbuild/netbsd-x64': 0.27.3 2543 + '@esbuild/openbsd-arm64': 0.27.3 2544 + '@esbuild/openbsd-x64': 0.27.3 2545 + '@esbuild/openharmony-arm64': 0.27.3 2546 + '@esbuild/sunos-x64': 0.27.3 2547 + '@esbuild/win32-arm64': 0.27.3 2548 + '@esbuild/win32-ia32': 0.27.3 2549 + '@esbuild/win32-x64': 0.27.3 2539 2550 2540 2551 estree-walker@3.0.3: 2541 2552 dependencies: ··· 2929 2940 tslib@2.8.1: 2930 2941 optional: true 2931 2942 2943 + tsx@4.21.0: 2944 + dependencies: 2945 + esbuild: 0.27.3 2946 + get-tsconfig: 4.13.1 2947 + optionalDependencies: 2948 + fsevents: 2.3.3 2949 + 2932 2950 typescript@5.9.3: {} 2933 2951 2934 2952 unconfig-core@7.4.2: ··· 2948 2966 dependencies: 2949 2967 rolldown: 1.0.0-rc.3 2950 2968 2951 - vite-node@3.2.4(@types/node@25.2.2): 2969 + vite-node@3.2.4(@types/node@25.2.2)(tsx@4.21.0): 2952 2970 dependencies: 2953 2971 cac: 6.7.14 2954 2972 debug: 4.4.3 2955 2973 es-module-lexer: 1.7.0 2956 2974 pathe: 2.0.3 2957 - vite: 7.3.1(@types/node@25.2.2) 2975 + vite: 7.3.1(@types/node@25.2.2)(tsx@4.21.0) 2958 2976 transitivePeerDependencies: 2959 2977 - '@types/node' 2960 2978 - jiti ··· 2969 2987 - tsx 2970 2988 - yaml 2971 2989 2972 - vite@7.3.1(@types/node@25.2.2): 2990 + vite@7.3.1(@types/node@25.2.2)(tsx@4.21.0): 2973 2991 dependencies: 2974 - esbuild: 0.27.2 2992 + esbuild: 0.27.3 2975 2993 fdir: 6.5.0(picomatch@4.0.3) 2976 2994 picomatch: 4.0.3 2977 2995 postcss: 8.5.6 ··· 2980 2998 optionalDependencies: 2981 2999 '@types/node': 25.2.2 2982 3000 fsevents: 2.3.3 3001 + tsx: 4.21.0 2983 3002 2984 - vitest@3.2.4(@types/node@25.2.2)(@vitest/ui@3.2.4): 3003 + vitest@3.2.4(@types/node@25.2.2)(@vitest/ui@3.2.4)(tsx@4.21.0): 2985 3004 dependencies: 2986 3005 '@types/chai': 5.2.3 2987 3006 '@vitest/expect': 3.2.4 2988 - '@vitest/mocker': 3.2.4(vite@7.3.1(@types/node@25.2.2)) 3007 + '@vitest/mocker': 3.2.4(vite@7.3.1(@types/node@25.2.2)(tsx@4.21.0)) 2989 3008 '@vitest/pretty-format': 3.2.4 2990 3009 '@vitest/runner': 3.2.4 2991 3010 '@vitest/snapshot': 3.2.4 ··· 3003 3022 tinyglobby: 0.2.15 3004 3023 tinypool: 1.1.1 3005 3024 tinyrainbow: 2.0.0 3006 - vite: 7.3.1(@types/node@25.2.2) 3007 - vite-node: 3.2.4(@types/node@25.2.2) 3025 + vite: 7.3.1(@types/node@25.2.2)(tsx@4.21.0) 3026 + vite-node: 3.2.4(@types/node@25.2.2)(tsx@4.21.0) 3008 3027 why-is-node-running: 2.3.0 3009 3028 optionalDependencies: 3010 3029 '@types/node': 25.2.2
+161
scripts/bundle-size.ts
··· 1 + #!/usr/bin/env node 2 + /** 3 + * Analyze bundle sizes for different import scenarios 4 + */ 5 + import { build } from "esbuild"; 6 + import { gzipSync } from "node:zlib"; 7 + import { writeFileSync, mkdirSync } from "node:fs"; 8 + import { join } from "node:path"; 9 + 10 + const rootDir = process.cwd(); 11 + const indexPath = join(rootDir, "src/index.ts"); 12 + 13 + const scenarios = [ 14 + { 15 + name: "Full bundle (all exports)", 16 + code: `import * as cron from "${indexPath}"; 17 + console.log(cron);`, 18 + }, 19 + { 20 + name: "nextRun only", 21 + code: `import { nextRun } from "${indexPath}"; 22 + console.log(nextRun);`, 23 + }, 24 + { 25 + name: "previousRun only", 26 + code: `import { previousRun } from "${indexPath}"; 27 + console.log(previousRun);`, 28 + }, 29 + { 30 + name: "nextRuns only", 31 + code: `import { nextRuns } from "${indexPath}"; 32 + console.log(nextRuns);`, 33 + }, 34 + { 35 + name: "isValid only", 36 + code: `import { isValid } from "${indexPath}"; 37 + console.log(isValid);`, 38 + }, 39 + { 40 + name: "parse only", 41 + code: `import { parse } from "${indexPath}"; 42 + console.log(parse);`, 43 + }, 44 + { 45 + name: "isMatch only", 46 + code: `import { isMatch } from "${indexPath}"; 47 + console.log(isMatch);`, 48 + }, 49 + { 50 + name: "Validation only (isValid + parse)", 51 + code: `import { isValid, parse } from "${indexPath}"; 52 + console.log(isValid, parse);`, 53 + }, 54 + { 55 + name: "Scheduling only (nextRun + previousRun + nextRuns)", 56 + code: `import { nextRun, previousRun, nextRuns } from "${indexPath}"; 57 + console.log(nextRun, previousRun, nextRuns);`, 58 + }, 59 + ]; 60 + 61 + interface BundleResult { 62 + name: string; 63 + raw: number; 64 + minified: number; 65 + gzipped: number; 66 + } 67 + 68 + async function analyzeBundle(name: string, code: string): Promise<BundleResult> { 69 + const tempDir = join(process.cwd(), ".bundle-analysis"); 70 + mkdirSync(tempDir, { recursive: true }); 71 + 72 + const entryFile = join(tempDir, "entry.ts"); 73 + writeFileSync(entryFile, code); 74 + 75 + // Build with esbuild 76 + const result = await build({ 77 + entryPoints: [entryFile], 78 + bundle: true, 79 + minify: true, 80 + format: "esm", 81 + target: "es2020", 82 + write: false, 83 + treeShaking: true, 84 + }); 85 + 86 + const minified = result.outputFiles[0].contents; 87 + const minifiedSize = minified.length; 88 + 89 + // Build without minification for raw size 90 + const rawResult = await build({ 91 + entryPoints: [entryFile], 92 + bundle: true, 93 + minify: false, 94 + format: "esm", 95 + target: "es2020", 96 + write: false, 97 + treeShaking: true, 98 + }); 99 + 100 + const raw = rawResult.outputFiles[0].contents; 101 + const rawSize = raw.length; 102 + 103 + // Gzip the minified bundle 104 + const gzipped = gzipSync(minified); 105 + const gzippedSize = gzipped.length; 106 + 107 + return { 108 + name, 109 + raw: rawSize, 110 + minified: minifiedSize, 111 + gzipped: gzippedSize, 112 + }; 113 + } 114 + 115 + function formatBytes(bytes: number): string { 116 + if (bytes < 1024) return `${bytes} B`; 117 + if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(2)} KB`; 118 + return `${(bytes / (1024 * 1024)).toFixed(2)} MB`; 119 + } 120 + 121 + async function main() { 122 + console.log("📦 Analyzing bundle sizes...\n"); 123 + 124 + const results: BundleResult[] = []; 125 + 126 + for (const scenario of scenarios) { 127 + const result = await analyzeBundle(scenario.name, scenario.code); 128 + results.push(result); 129 + } 130 + 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)); 138 + 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 + ); 156 + } 157 + 158 + console.log("\n✅ Done!"); 159 + } 160 + 161 + main().catch(console.error);