Skip to content

openworkers/croner-wasm

Repository files navigation

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-wasm

Usage

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 objects

Browser (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 error

Advanced 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-Fri

6-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 month

API 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 patterns
    • seconds: '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 description
  • pattern(): string - Get the original pattern
  • hasSeconds(): 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 browser

File Size

  • WASM binary: ~119 KB (optimized)
  • JS glue code: ~12 KB
  • Total: ~131 KB

License

MIT

Credits

Built on top of croner by Hexagon.

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Packages

No packages published