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

Sponsor this project

 

Packages

No packages published