diff --git a/IT/programming/visual_programming_js/a_bpmn_js_1.md b/IT/programming/visual_programming_js/a_bpmn_js_1.md index e089a7f7..a509afdb 100644 --- a/IT/programming/visual_programming_js/a_bpmn_js_1.md +++ b/IT/programming/visual_programming_js/a_bpmn_js_1.md @@ -258,5 +258,351 @@ const result = await fetch('/api/execute', { - [Apache KIE Tools](https://github.com/apache/incubator-kie-tools) - [bpmn.io — экосистема инструментов](https://bpmn.io) - Share: https://chat.deepseek.com/a/chat/s/e841c3c8-0070-4a6b-ac9b-6ec56ee56fc9 + +## 2 +## 📐 Подробные примеры реализации калькулятора для каждого инструмента трансляции BPMN в JavaScript + +Ниже приведены детальные примеры использования каждого из четырёх инструментов для реализации калькулятора: два поля ввода чисел, выбор операции (+, -, *, /) и поле результата. + +--- + +## 1. **bpmn-engine** (полноценный движок выполнения, Node.js) + +### Описание +`bpmn-engine` — JavaScript-движок для выполнения BPMN-процессов в Node.js. Позволяет загружать BPMN XML, задавать переменные и обрабатывать задачи через кастомные сервисы. + +### BPMN XML (calculator.bpmn) +```xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +``` + +### Код Node.js (calculator-engine.js) +```javascript +const Engine = require('bpmn-engine'); +const fs = require('fs'); + +// Читаем BPMN XML (или используем строку) +const bpmnXml = fs.readFileSync('./calculator.bpmn', 'utf8'); + +// Создаём движок с кастомным сервисом для задачи CalculateTask +const engine = new Engine({ + source: bpmnXml, + services: { + // Имя задачи должно совпадать с id в BPMN + CalculateTask: async (context) => { + // Получаем переменные из контекста процесса + const { num1, num2, operation } = context.environment.variables; + + // Выполняем вычисление + let result; + switch (operation) { + case '+': result = num1 + num2; break; + case '-': result = num1 - num2; break; + case '*': result = num1 * num2; break; + case '/': result = num2 === 0 ? 'Ошибка: деление на ноль' : num1 / num2; break; + default: result = 'Ошибка: неизвестная операция'; + } + + // Сохраняем результат в переменные процесса + context.environment.variables.result = result; + return result; + } + } +}); + +// Запускаем процесс с входными переменными +engine.execute((err, instance) => { + if (err) { + console.error('Ошибка выполнения:', err); + return; + } + + // Устанавливаем переменные перед началом + instance.environment.setVariable('num1', 10); + instance.environment.setVariable('num2', 5); + instance.environment.setVariable('operation', '+'); + + // Слушаем окончание процесса + instance.on('end', () => { + const result = instance.environment.getVariable('result'); + console.log(`Результат: ${result}`); + }); +}); +``` + +### Пояснение +- **Движок** загружает BPMN XML и регистрирует обработчик для `CalculateTask`. +- Входные данные передаются как переменные окружения. +- После выполнения задачи результат сохраняется в переменную `result`. +- В конце процесса мы получаем результат. + +--- + +## 2. **@process-engine/process_engine_core** (модульный движок, Node.js) + +### Описание +Более модульный движок, разделяющий парсинг и выполнение. Позволяет гибко настраивать обработчики для разных типов узлов. + +### Установка +```bash +npm install @process-engine/process_engine_core +``` + +### Код Node.js (calculator-process-engine.js) +```javascript +const { BpmnModelParser } = require('@process-engine/process_engine_core').Model; +const { ExecuteProcessService } = require('@process-engine/process_engine_core').Runtime; +const fs = require('fs'); + +// 1. Парсим BPMN XML в модель +const bpmnXml = fs.readFileSync('./calculator.bpmn', 'utf8'); +const parser = new BpmnModelParser(); +const model = parser.parse(bpmnXml); // модель процесса + +// 2. Создаём экземпляр сервиса выполнения +const executionService = new ExecuteProcessService(); + +// 3. Регистрируем кастомный обработчик для ServiceTask +const flowNodeHandlers = { + serviceTask: { + async onEnter(flowNode, context) { + if (flowNode.id === 'CalculateTask') { + // Получаем переменные процесса + const variables = context.executionContext.getVariables(); + const num1 = variables.num1; + const num2 = variables.num2; + const operation = variables.operation; + + // Вычисляем + let result; + switch (operation) { + case '+': result = num1 + num2; break; + case '-': result = num1 - num2; break; + case '*': result = num1 * num2; break; + case '/': result = num2 === 0 ? 'Ошибка: деление на ноль' : num1 / num2; break; + default: result = 'Ошибка: неизвестная операция'; + } + + // Сохраняем результат + context.executionContext.setVariable('result', result); + return; // завершаем задачу + } + } + } +}; + +// 4. Запускаем процесс с входными переменными +const variables = { + num1: 10, + num2: 5, + operation: '+' +}; + +executionService.start(model, variables, flowNodeHandlers) + .then((executionContext) => { + // Процесс завершён + const result = executionContext.getVariable('result'); + console.log(`Результат: ${result}`); + }) + .catch((err) => console.error('Ошибка выполнения:', err)); +``` + +### Пояснение +- **Парсер** превращает XML в объектную модель. +- **Сервис выполнения** запускает процесс, передавая ему переменные и хендлеры. +- Для узла `CalculateTask` мы определяем `onEnter`, который выполняет вычисление и сохраняет результат. +- Процесс завершается автоматически после выполнения всех узлов. + +--- + +## 3. **bpmn-moddle** (парсинг XML ↔ JSON, браузер / Node.js) + +### Описание +`bpmn-moddle` не выполняет процессы, а только парсит BPMN XML в JavaScript-объекты и обратно. Мы можем использовать его для чтения BPMN и последующей ручной интерпретации. + +### Код (браузерный пример) +```html + + + + + BPMN Moddle Calculator + + + + + + +
Результат:
+ + + + +``` + +### Пояснение +- `BpmnModdle` парсит XML в объектную модель. +- В примере мы парсим диаграмму, а затем используем отдельную JavaScript-функцию для вычислений. +- **bpmn-moddle** не выполняет процесс; мы сами должны интерпретировать модель и вызывать нужные обработчики. + +--- + +## 4. **bpmn-marshaller** (от Apache KIE Tools, TypeScript, браузер) + +### Описание +`bpmn-marshaller` — современный TypeScript-инструмент для парсинга BPMN XML в строго типизированные JavaScript-объекты. Он также не выполняет процессы, но даёт удобный доступ к данным модели. + +### Установка +```bash +npm install @kie-tools/bpmn-marshaller +``` + +### Код (TypeScript / браузер) +```typescript +import { Bpmn2Marshaller } from '@kie-tools/bpmn-marshaller'; +import { XmlParser } from '@kie-tools/xml-parser-ts'; + +// BPMN XML +const bpmnXml = ` + + + + + + + + +`; + +// Создаём парсер XML +const xmlParser = new XmlParser(); + +// Используем маршаллер +const marshaller = new Bpmn2Marshaller(); +const model = marshaller.unmarshal(xmlParser.parse(bpmnXml)); +// model — строго типизированный объект, описывающий BPMN-диаграмму + +// Находим задачу +const definitions = model.definitions; +const process = definitions.rootElements?.find(el => el.$type === 'bpmn:Process'); +const serviceTasks = process?.flowElements?.filter(el => el.$type === 'bpmn:ServiceTask'); +console.log('Задачи:', serviceTasks?.map(t => t.id)); + +// Логика калькулятора (отдельно) +// ... +``` + +### Пояснение +- `bpmn-marshaller` даёт **строго типизированное** представление BPMN. +- Можно легко навигировать по модели, получать информацию о задачах, шлюзах и т.д. +- Выполнение процесса нужно реализовывать самостоятельно, используя полученную модель. + +--- + +## 📊 Сравнение подходов в контексте калькулятора + +| Инструмент | Где выполняется | Сложность реализации | Особенности | +|------------|----------------|----------------------|-------------| +| **bpmn-engine** | Node.js | Низкая | Готовый движок, кастомные сервисы. Не работает в браузере. | +| **ProcessEngine Core** | Node.js | Средняя | Модульный, гибкие обработчики. Требует больше кода. | +| **bpmn-moddle** | Браузер/Node.js | Низкая (парсинг) | Только парсинг. Выполнение нужно писать самому. | +| **bpmn-marshaller** | Браузер/Node.js | Низкая (парсинг) | TypeScript, строгая типизация. Выполнение ручное. | + +### Рекомендация для вашего приложения +Если вы создаёте веб-приложение (как в вашем предыдущем коде с bpmn-js) и хотите выполнять BPMN-процессы прямо в браузере: +- **bpmn-moddle** или **bpmn-marshaller** позволят разобрать XML, а логику вычислений реализовать вручную (как вы уже сделали). +- Если вам нужен полноценный исполняемый движок в браузере, можно рассмотреть портирование `bpmn-engine` в Web Worker, но это сложнее. + +Для серверной части (Node.js) лучше использовать **bpmn-engine** или **ProcessEngine Core**, так как они предоставляют готовое выполнение процессов. + +Если нужен пример интеграции **bpmn-engine** с вашим веб-интерфейсом (через API), дайте знать – подготовлю дополнительный пример.