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

@quanticjs/workflow-quanticflow

v8.0.0

Published

QuanticFlow workflow engine adapter for @quanticjs/workflow — supports callback and event-driven service task execution

Readme

@quanticjs/workflow-quanticflow

QuanticFlow workflow engine adapter for @quanticjs/workflow. Connects any QuanticJS application to a standalone QuanticFlow instance via REST API.

Supports two modes for service task execution:

| Mode | Transport | How it works | |---|---|---| | Callback | HTTP webhook | QuanticFlow POSTs to your app's /workflow-callback/service-task endpoint | | Event | Redis Streams | Your app consumes ServiceTaskStartedEvent from Redis and signals back via REST |

Both modes can run simultaneously (mode: 'both').

Install

npm install @quanticjs/workflow-quanticflow

Quick Start

import { Module } from '@nestjs/common';
import { QuanticFlowWorkflowModule } from '@quanticjs/workflow-quanticflow';
import { QuanticWorkflowModule } from '@quanticjs/workflow';

@Module({
  imports: [
    // 1. Register the QuanticFlow engine adapter
    QuanticFlowWorkflowModule.forRoot({
      url: 'http://quanticflow:3000',
      serviceTaskHandling: {
        mode: 'both',                          // 'callback' | 'event' | 'both'
        callbackSecret: process.env.CALLBACK_SECRET,
      },
    }),

    // 2. Wire the @Workflow decorator into the CQRS pipeline
    QuanticWorkflowModule.forRoot(),
  ],
})
export class AppModule {}

Now any command decorated with @Workflow will be routed to QuanticFlow:

import { Workflow } from '@quanticjs/core';

@Workflow('expense-approval')
@Validate(CreateExpenseValidator)
export class CreateExpenseCommand {
  constructor(
    readonly amount: number,
    readonly category: string,
  ) {}
}

Service Task Handlers

Register handlers that execute when QuanticFlow reaches a service task node:

import { Injectable } from '@nestjs/common';
import { ServiceTaskHandler, ServiceTaskContext, ServiceTaskResult } from '@quanticjs/workflow-quanticflow';

@Injectable()
export class SendEmailHandler implements ServiceTaskHandler {
  constructor(private readonly mailer: MailerService) {}

  async execute(context: ServiceTaskContext): Promise<ServiceTaskResult> {
    await this.mailer.send({
      to: context.variables.recipientEmail,
      subject: `Process ${context.correlationId} update`,
    });
    return { signal: 'email-sent', data: { sentAt: new Date() } };
  }
}

Register handlers in your module — the registry resolves them by name from the DI container:

@Module({
  providers: [SendEmailHandler],
})
export class NotificationsModule {}

The handler name in the BPMN definition must match the class name (e.g., SendEmailHandler).

Configuration

QuanticFlowWorkflowModule.forRoot({
  // Required
  url: 'http://quanticflow:3000',

  // Optional
  requestTimeout: 10000,                     // HTTP timeout in ms (default: 10000)

  serviceTaskHandling: {
    mode: 'callback',                        // 'callback' | 'event' | 'both'

    // Callback mode options
    callbackSecret: 'hmac-secret',           // HMAC-SHA256 signature verification

    // Event mode options (requires ioredis + @quanticjs/redis)
    streamKey: 'quantic:events:services',       // Redis stream (default)
    consumerGroup: 'my-app-tasks',           // Consumer group name
    consumerName: 'worker-1',                // Consumer name (default: consumer-{pid})
  },
})

Using the Client Directly

The QuanticFlowClient is exported for direct REST API access beyond the WorkflowEngine interface:

import { QuanticFlowClient } from '@quanticjs/workflow-quanticflow';

@Injectable()
export class WorkflowDashboardService {
  constructor(private readonly qf: QuanticFlowClient) {}

  async getMyTasks(userId: string) {
    return this.qf.listTasks({ userId, status: 'pending' });
  }

  async approveTask(taskId: string) {
    return this.qf.executeTaskAction(taskId, 'approve', { comment: 'Looks good' });
  }
}

Client Methods

| Method | Endpoint | Description | |---|---|---| | startInstance(definitionId, variables?, correlationId?) | POST /workflow/instances | Start a workflow | | signalInstance(instanceId, signal, data?) | POST /workflow/instances/:id/signal | Send signal | | abortInstance(instanceId) | POST /workflow/instances/:id/abort | Abort workflow | | getInstance(instanceId) | GET /workflow/instances/:id | Get instance detail | | updateVariables(instanceId, variables) | PUT /workflow/instances/:id/variables | Update variables | | listTasks(filters?) | GET /workflow/tasks | List tasks | | getTask(taskId) | GET /workflow/tasks/:id | Get task detail | | claimTask(taskId) | POST /workflow/tasks/:id/claim | Claim task | | executeTaskAction(taskId, action, data?) | POST /workflow/tasks/:id/action | Execute action |

Architecture

┌──────────────────────────────────────────────┐
│  Your NestJS App                             │
│                                              │
│  @Workflow('expense')                        │
│  CreateExpenseCommand ──▶ WorkflowBehavior   │
│                              │               │
│                    ┌─────────▼──────────┐    │
│                    │ QuanticFlowWorkflow │    │
│                    │ Engine (HTTP)       │    │
│                    └─────────┬──────────┘    │
│                              │               │
│  ┌───────────────────────────┼────────────┐  │
│  │ Service Task Handling     │            │  │
│  │                           │            │  │
│  │  ┌─────────────┐  ┌──────▼─────────┐  │  │
│  │  │  Callback   │  │  Event         │  │  │
│  │  │  Controller │  │  Consumer      │  │  │
│  │  │  (webhook)  │  │  (Redis Stream)│  │  │
│  │  └──────┬──────┘  └──────┬─────────┘  │  │
│  │         │                │             │  │
│  │         ▼                ▼             │  │
│  │  ServiceTaskHandlerRegistry            │  │
│  │         │                              │  │
│  │         ▼                              │  │
│  │  SendEmailHandler (your code)          │  │
│  └────────────────────────────────────────┘  │
└──────────────────────────────────────────────┘
                    │
                    │ HTTP / Redis
                    ▼
         ┌──────────────────┐
         │   QuanticFlow    │
         │   (standalone)   │
         └──────────────────┘

License

MIT