npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@bernierllc/content-workflow-schedule-step

v1.2.2

Published

Scheduling workflow step for content publishing with immediate and scheduled execution support

Readme

@bernierllc/content-workflow-schedule-step

Scheduling workflow step for content publishing with immediate and scheduled execution support.

Features

  • Immediate Publishing: Execute content publishing immediately
  • Scheduled Publishing: Schedule content for future publishing
  • Constraint Validation: Enforce minimum and maximum scheduling delays
  • Multi-Platform Support: Schedule across multiple platforms
  • Timezone Support: Handle timezone conversions
  • Job Management: Cancel and reschedule jobs

Installation

npm install @bernierllc/content-workflow-schedule-step

Usage

Basic Setup

import { ScheduleStep } from '@bernierllc/content-workflow-schedule-step';
import { SchedulerService } from '@bernierllc/scheduler-service';
import { Logger } from '@bernierllc/logger';

// Initialize dependencies
const scheduler = new SchedulerService({
  maxConcurrentJobs: 10,
  defaultTimezone: 'UTC',
  // ... other config
});

const logger = new Logger({ serviceName: 'workflow' });

// Create schedule step
const scheduleStep = new ScheduleStep(scheduler, logger);

Immediate Publishing

import type { WorkflowStepConfig, WorkflowContext } from '@bernierllc/content-workflow-schedule-step';

const config: WorkflowStepConfig = {
  id: 'schedule',
  name: 'Schedule Step',
  type: 'schedule',
  scheduleConfig: {
    allowImmediate: true
  }
};

const context: WorkflowContext = {
  content: {
    id: 'article-123',
    type: 'article',
    title: 'My Article',
    data: { body: 'Content here' }
  },
  variables: new Map(),
  userId: 'user-123'
};

const result = await scheduleStep.execute(config, context);

if (result.success) {
  console.log('Scheduled:', result.data);
  // {
  //   scheduledFor: Date,
  //   jobId: 'job-123',
  //   immediate: true
  // }
}

Scheduled Publishing

const futureTime = new Date(Date.now() + 2 * 60 * 60 * 1000); // 2 hours from now

const config: WorkflowStepConfig = {
  id: 'schedule',
  name: 'Schedule Step',
  type: 'schedule',
  scheduleConfig: {
    allowImmediate: false,
    minDelayMinutes: 5,
    maxDelayDays: 30,
    timezone: 'America/New_York'
  }
};

const context: WorkflowContext = {
  content: {
    id: 'article-123',
    type: 'article',
    data: { body: 'Content' }
  },
  variables: new Map([
    ['scheduledTime', futureTime],
    ['platforms', ['twitter', 'facebook']]
  ]),
  userId: 'user-123'
};

const result = await scheduleStep.execute(config, context);

if (result.success) {
  console.log('Scheduled for:', result.data?.scheduledFor);
  console.log('Job ID:', result.data?.jobId);
  console.log('Platforms:', result.data?.platforms);
}

Multi-Platform Scheduling

const context: WorkflowContext = {
  content: {
    id: 'article-123',
    type: 'article',
    data: {}
  },
  variables: new Map([
    ['scheduledTime', new Date('2025-12-25T10:00:00Z')],
    ['platforms', ['twitter', 'facebook', 'linkedin']]
  ]),
  userId: 'user-123'
};

const result = await scheduleStep.execute(config, context);
// Job will be created for all three platforms

Configuration Validation

const config: WorkflowStepConfig = {
  id: 'schedule',
  name: 'Schedule Step',
  type: 'schedule',
  scheduleConfig: {
    minDelayMinutes: 30,
    maxDelayDays: 7,
    timezone: 'Europe/London'
  }
};

const validation = scheduleStep.validate(config);

if (!validation.valid) {
  console.error('Configuration errors:', validation.errors);
}

Job Management

Cancel a Scheduled Job

const cancelled = await scheduleStep.cancelScheduledJob('job-123');

if (cancelled) {
  console.log('Job cancelled successfully');
} else {
  console.error('Failed to cancel job');
}

Reschedule a Job

const newTime = new Date(Date.now() + 4 * 60 * 60 * 1000); // 4 hours from now

const result = await scheduleStep.rescheduleJob('job-123', newTime, {
  minDelayMinutes: 5,
  timezone: 'America/New_York'
});

if (result.success) {
  console.log('New job ID:', result.data?.jobId);
  console.log('New scheduled time:', result.data?.scheduledFor);
}

API Reference

ScheduleStep

Main workflow step class for scheduling content.

Properties

  • id: string - Step identifier ('schedule-step')
  • type: string - Step type ('schedule')

Methods

execute(config, context)

Execute the schedule step.

Parameters:

  • config: WorkflowStepConfig - Step configuration
  • context: WorkflowContext - Workflow execution context

Returns: Promise<WorkflowStepExecutionResult>

validate(config)

Validate step configuration.

Parameters:

  • config: WorkflowStepConfig - Configuration to validate

Returns: ValidationResult

cancelScheduledJob(jobId)

Cancel a scheduled job.

Parameters:

  • jobId: string - Job identifier

Returns: Promise<boolean>

rescheduleJob(jobId, newScheduledTime, scheduleConfig)

Reschedule an existing job.

Parameters:

  • jobId: string - Job identifier
  • newScheduledTime: Date - New scheduled time
  • scheduleConfig: ScheduleConfig - Schedule constraints

Returns: Promise<WorkflowStepExecutionResult>

Types

ScheduleConfig

interface ScheduleConfig {
  allowImmediate?: boolean;
  minDelayMinutes?: number;
  maxDelayDays?: number;
  timezone?: string;
}

ScheduleResult

interface ScheduleResult {
  scheduledFor: Date;
  jobId: string;
  immediate: boolean;
  platforms?: string[];
}

WorkflowContext

interface WorkflowContext {
  content: WorkflowContentItem;
  variables: Map<string, any>;
  userId?: string;
  metadata?: Record<string, any>;
}

Validation Functions

validateScheduleConfig(config)

Validate schedule configuration.

import { validateScheduleConfig } from '@bernierllc/content-workflow-schedule-step';

const result = validateScheduleConfig({
  id: 'schedule',
  name: 'Schedule',
  type: 'schedule',
  scheduleConfig: {
    minDelayMinutes: 5,
    maxDelayDays: 30
  }
});

validateScheduledTime(scheduledTime, config)

Validate scheduled time against constraints.

import { validateScheduledTime } from '@bernierllc/content-workflow-schedule-step';

const futureTime = new Date(Date.now() + 60 * 60 * 1000);

const result = validateScheduledTime(futureTime, {
  minDelayMinutes: 5,
  maxDelayDays: 7
});

convertToTimezone(date, timezone)

Convert date to specific timezone.

import { convertToTimezone } from '@bernierllc/content-workflow-schedule-step';

const date = new Date('2025-12-25T10:00:00Z');
const converted = convertToTimezone(date, 'America/New_York');

Error Handling

The schedule step returns errors in a structured format:

const result = await scheduleStep.execute(config, context);

if (!result.success) {
  console.error('Error:', result.error);
  // Possible errors:
  // - "Scheduled time is required when immediate publishing is not allowed"
  // - "Scheduled time cannot be in the past"
  // - "Scheduled time must be at least X minutes in the future"
  // - "Scheduled time cannot be more than X days in the future"
}

Integration with Scheduler Service

The schedule step integrates with @bernierllc/scheduler-service to create jobs:

  • Job type: CONTENT_PUBLISH
  • Schedule type: ONCE
  • Retry policy: 3 attempts with 5 second delay
  • Tags: ['content-publish', 'workflow']

Best Practices

  1. Always validate configuration before using in production
  2. Set reasonable constraints (min/max delays) based on your use case
  3. Handle timezone conversions explicitly for international audiences
  4. Monitor scheduled jobs using the scheduler service
  5. Cancel jobs when content is deleted or workflows are cancelled

Testing

npm test                 # Run all tests
npm run test:coverage    # Run with coverage
npm run test:watch       # Watch mode

License

Copyright (c) 2025 Bernier LLC. See LICENSE for details.