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

@0dep/bpmn-extensions

v0.0.2

Published

Flow extensions for bpmn-elements: FEEL expressions and the zeebe-namespace BPMN extension elements

Readme

@0dep/bpmn-extensions

Built latestCoverage Statusnpm version

Flow extensions for bpmn-elements with FEEL expression support.

It teaches a bpmn-elements engine to run BPMN that uses the zeebe:* extension elements and FEEL expressions (= ...) — the counterpart to @onify/flow-extensions, which covers the older camunda:* extension elements.

Install

npm install @0dep/bpmn-extensions bpmn-elements

bpmn-elements (>= 18) is a peer dependency. Requires Node.js >= 22.

What it does

  • FEEL expressions — a FeelExpressions() adapter resolves FEEL (= order.total > 100) everywhere bpmn-elements resolves an expression, including sequence flow conditions.
  • zeebe:script — a FeelScripts() adapter runs a script task's FEEL expression and assigns the result to its resultVariable.
  • zeebe:taskDefinition — maps a service task's job type to an environment service (job worker).
  • zeebe:calledDecision — a business rule task resolves its decisionId via an environment service (you bring the decision; we don't evaluate DMN) and assigns the result to resultVariable.
  • zeebe:ioMapping — input mapping on entry (parent scope) and output mapping on completion (job-result scope), with dotted target paths. Propagates across boundaries: a call activity's input reaches the called process and its output maps the called process result back; a sub process's input becomes variables local to its children.
  • zeebe:taskHeaders / zeebe:properties — exposed on the element content.
  • zeebe:assignmentDefinition — assignee / candidate users / groups for user tasks.
  • zeebe:formDefinition — resolves a user task's form (formId / formKey / externalReference, bindingType) onto the element content for a task list to render.
  • zeebe:executionListeners — blocking start/end job workers around an element, called as (elementApi, { retries, headers }, callback) (retries and headers present only when the listener declares them).
  • zeebe:calledElement — call activity target process id.
  • zeebe:loopCharacteristics — collection-based multi-instance (inputCollection / inputElement), sequential or parallel, with outputElement aggregated into the outputCollection array in input order.

API

  • extensions(element, context) — the flow extensions factory; pass it as an environment extension.
  • extendFn(behaviour) — moddle-context-serializer behaviour extender (lifts the extension data bpmn-elements expects on the behaviour: call activity process id and multi-instance collection).
  • FeelExpressions() — a bpmn-elements IExpressions implementation backed by FEEL.
  • FeelScripts() — a bpmn-elements scripts implementation that runs zeebe:script FEEL expressions.
  • FEEL helpers: isFeelExpression, stripFeel, evaluateFeel, evaluateFeelUnaryTest, resolveValue.
  • JobService, ServiceError, FormatError.

Usage

Wire it into a bpmn-elements definition (see test/helpers/testHelpers.js for the full helper):

import { createRequire } from 'node:module';
import { strict as assert } from 'node:assert';
import BpmnModdle from 'bpmn-moddle';
import * as elements from 'bpmn-elements';
import { Serializer, TypeResolver } from 'moddle-context-serializer';
import { extensions, extendFn, FeelExpressions, FeelScripts } from '@0dep/bpmn-extensions';

const require = createRequire(import.meta.url);
const moddle = new BpmnModdle({ zeebe: require('zeebe-bpmn-moddle/resources/zeebe.json') });

const source = `<?xml version="1.0" encoding="UTF-8"?>
<definitions xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:zeebe="http://camunda.org/schema/zeebe/1.0" id="def">
  <process id="orders" isExecutable="true">
    <startEvent id="start" />
    <sequenceFlow id="to-charge" sourceRef="start" targetRef="charge" />
    <serviceTask id="charge">
      <extensionElements>
        <zeebe:taskDefinition type="charge-card" />
        <zeebe:ioMapping>
          <zeebe:input source="= order.total" target="amount" />
          <zeebe:output source="= transactionId" target="receipt.id" />
        </zeebe:ioMapping>
      </extensionElements>
    </serviceTask>
    <sequenceFlow id="to-end" sourceRef="charge" targetRef="end" />
    <endEvent id="end" />
  </process>
</definitions>`;

const moddleContext = await moddle.fromXML(source);
const serializer = Serializer(moddleContext, TypeResolver(elements), extendFn);

const definition = new elements.Definition(elements.Context(serializer), {
  expressions: FeelExpressions(),
  scripts: FeelScripts(),
  extensions: { flowExtensions: extensions },
  variables: { order: { total: 199 } },
  services: {
    'charge-card'(elementApi, callback) {
      // elementApi.content.input  — resolved zeebe:ioMapping input (here `{ amount: 199 }`)
      // elementApi.content.headers — resolved zeebe:taskHeaders
      callback(null, { transactionId: 'tx-1' }); // becomes the job variables for output mapping
    },
  },
});

definition.once('leave', () => {
  console.log(definition.environment.output); // { receipt: { id: 'tx-1' } }
  assert.deepEqual(definition.environment.output, { receipt: { id: 'tx-1' } });
});
definition.run();

A service task's zeebe:taskDefinition type="charge-card" is dispatched to the environment service named charge-card. Its callback result is the job's variables, which zeebe:ioMapping output parameters map back into the process.

Development

npm test           # mocha (BDD, mocha-cakes-2) + lint + run README examples (texample)
npm run test:md     # run the README javascript examples with texample
npm run dist        # bundle the CommonJS build with rollup
npm run types       # generate types/index.d.ts from JSDoc with dts-buddy
npm run format      # eslint --fix && prettier --write

Flows under test are authored programmatically with bpmn-moddle via the ProcessBuilder helper in test/helpers/factory.js, then run on a real bpmn-elements Definition. The test harness wires the engine's Logger to the debug package, so DEBUG=bpmn-extensions:* npm test traces the engine and extensions (:error:* for errors only).

See the camunda8-bpmn-schemas skill (.claude/skills/) for a reference of the zeebe:* extension elements and FEEL.

License

MIT