@openworkers/croner-wasm
v0.3.1
Published
WebAssembly bindings for the croner cron expression parser
Downloads
483
Readme
croner-wasm
WebAssembly bindings for the croner cron expression parser.
Features
- ✅ Parse and validate cron expressions
- ✅ Get human-readable descriptions
- ✅ Calculate next occurrences
- ✅ Support for seconds (6-field format)
- ✅ Quartz scheduler extensions (L, W, #)
- ✅ Zero dependencies (pure WASM)
- ✅ Works in Node.js, browsers, and bundlers
Installation
npm install @openworkers/croner-wasm
# or
bun add @openworkers/croner-wasmUsage
Node.js
import { WasmCron } from '@openworkers/croner-wasm';
// Parse a cron expression
const cron = new WasmCron('0 * * * *');
// Get human-readable description
console.log(cron.describe());
// => "At minute 0 past every hour."
// Get next run time
const next = cron.nextRun();
console.log(next);
// => Date object
// Get multiple next runs
const nextRuns = cron.nextRuns(5);
console.log(nextRuns);
// => Array of 5 Date objectsBrowser (ES Modules)
import init, { WasmCron } from '@openworkers/croner-wasm';
// Initialize WASM module (required in browser)
await init();
// Parse a cron expression
const cron = new WasmCron('0 * * * *');
console.log(cron.describe());Validation
import { WasmCron } from '@openworkers/croner-wasm';
// Validate without creating an instance
if (WasmCron.validate('0 * * * *')) {
console.log('Valid cron pattern!');
}
// Validate with seconds option
if (WasmCron.validate('0 * * * *', { seconds: 'disallowed' })) {
console.log('Valid 5-field pattern!');
}
if (!WasmCron.validate('0 * * * * *', { seconds: 'disallowed' })) {
console.log('6-field pattern rejected with disallowed seconds');
}
// Try-catch for parsing
try {
const cron = new WasmCron('invalid pattern');
} catch (error) {
console.error('Invalid cron:', error);
}Parse and Describe
import { parseAndDescribe } from '@openworkers/croner-wasm';
const result = parseAndDescribe('0 0 * * FRI');
console.log(result);
// => { pattern: "0 0 * * FRI", description: "At 00:00 on Friday" }Seconds Configuration
You can control whether seconds are allowed, required, or disallowed:
// Optional seconds (default) - accepts both 5 and 6 fields
const cron1 = new WasmCron('0 * * * *');
const cron2 = new WasmCron('0 * * * * *');
// Disallow seconds - only 5-field patterns allowed
const cron3 = new WasmCron('0 * * * *', { seconds: 'disallowed' });
// new WasmCron('0 * * * * *', { seconds: 'disallowed' }); // ❌ Throws error
// Require seconds - only 6-field patterns allowed
const cron4 = new WasmCron('0 * * * * *', { seconds: 'required' });
// new WasmCron('0 * * * *', { seconds: 'required' }); // ❌ Throws errorAdvanced Usage
const cron = new WasmCron('*/5 * * * *', { timezone: 'UTC' });
// Get pattern
console.log(cron.pattern());
// => "*/5 * * * *"
// Check if pattern has seconds
console.log(cron.hasSeconds());
// => false
const cronWithSeconds = new WasmCron('0/30 * * * * *');
console.log(cronWithSeconds.hasSeconds());
// => true
// Get next run from now
const next = cron.nextRun();
// Get next run from specific date
const from = new Date('2024-01-01T00:00:00Z');
const nextFromDate = cron.nextRun(from);
// Get multiple next runs
const nextRuns = cron.nextRuns(10); // From now
const nextRunsFrom = cron.nextRuns(10, from); // From specific date
// Check if a date matches the pattern
const matches = cron.isMatch(new Date());Supported Cron Formats
5-field format (minute hour day month weekday):
0 * * * * # Every hour
*/5 * * * * # Every 5 minutes
0 0 * * FRI # Every Friday at midnight
0 9-17 * * MON-FRI # Every hour from 9-5, Mon-Fri6-field format (second minute hour day month weekday):
0/30 * * * * * # Every 30 seconds
*/5 * * * * * # Every 5 seconds
0 0 * * * * # Every hour (at 0 seconds)Quartz extensions:
0 0 L * * # Last day of the month
0 0 15W * * # Nearest weekday to the 15th
0 0 * * 5L # Last Friday of the month
0 0 * * 5#3 # Third Friday of the monthAPI Reference
WasmCron Class
Constructor
new WasmCron(pattern: string, options?: { timezone?: string, seconds?: 'optional' | 'required' | 'disallowed' })- Parse a cron expression (throws on invalid)seconds: 'optional'(default) - Accept both 5 and 6-field patternsseconds: 'required'- Only accept 6-field patterns (with seconds)seconds: 'disallowed'- Only accept 5-field patterns (no seconds)
Static Methods
WasmCron.validate(pattern: string, options?: { seconds?: 'optional' | 'required' | 'disallowed' }): boolean- Validate a pattern
Instance Methods
describe(): string- Get human-readable descriptionpattern(): string- Get the original patternhasSeconds(): boolean- Check if pattern uses seconds (6-field format)nextRun(from?: Date): Date | null- Get next occurrence (from now or specified date)nextRuns(count: number, from?: Date): Date[]- Get N next occurrences (from now or specified date)isMatch(date: Date): boolean- Check if date matches pattern
Functions
parseAndDescribe(pattern: string): { pattern: string, description: string }- Parse and describe in one call
Package Exports
This package supports multiple environments:
{
"exports": {
".": {
"node": "./dist/node/croner_wasm.js",
"browser": "./dist/croner_wasm.js",
"default": "./dist/bundler/croner_wasm.js"
}
}
}- Node.js: Uses CommonJS build automatically
- Browser: Uses ES modules with WASM
- Bundlers (webpack, rollup, vite): Uses optimized build
Building from Source
Prerequisites
- Rust (install via rustup)
- wasm-pack:
cargo install wasm-pack
Build Commands
# Build all targets (Node.js, browser, bundlers)
bun run build:all
# Or build individually
bun run build # Web only
bun run build:node # Node.js only
bun run build:bundler # Bundlers only
# Run tests
bun run test # Rust tests
bun run test:wasm # WASM tests in browserFile Size
- WASM binary: ~119 KB (optimized)
- JS glue code: ~12 KB
- Total: ~131 KB
License
MIT
Credits
Built on top of croner by Hexagon.
