bpmn-elements 9.2.0 → 10.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +13 -0
- package/README.md +4 -0
- package/dist/Context.js +21 -4
- package/dist/Environment.js +1 -1
- package/dist/Timers.js +63 -43
- package/dist/activity/Activity.js +17 -1
- package/dist/definition/DefinitionExecution.js +14 -10
- package/dist/eventDefinitions/TimerEventDefinition.js +51 -41
- package/dist/index.js +19 -0
- package/dist/iso-duration.js +88 -0
- package/dist/process/Lane.js +38 -0
- package/dist/process/Process.js +16 -0
- package/dist/tasks/SubProcess.js +2 -2
- package/package.json +13 -13
- package/src/Context.js +27 -4
- package/src/Environment.js +1 -1
- package/src/Timers.js +71 -40
- package/src/activity/Activity.js +18 -0
- package/src/definition/DefinitionExecution.js +11 -15
- package/src/eventDefinitions/TimerEventDefinition.js +49 -40
- package/src/index.js +6 -0
- package/src/iso-duration.js +91 -0
- package/src/process/Lane.js +27 -0
- package/src/process/Process.js +18 -0
- package/src/tasks/SubProcess.js +2 -2
- package/types/index.d.ts +117 -8
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
// License MIT @ https://tolu.mit-license.org/
|
|
2
|
+
|
|
3
|
+
const numbers = '\\d+';
|
|
4
|
+
const fractionalNumbers = ''.concat(numbers, '(?:[\\.,]').concat(numbers, ')?');
|
|
5
|
+
const datePattern = '('.concat(numbers, 'Y)?(').concat(numbers, 'M)?(').concat(numbers, 'W)?(').concat(fractionalNumbers, 'D)?');
|
|
6
|
+
const timePattern = 'T('.concat(fractionalNumbers, 'H)?(').concat(fractionalNumbers, 'M)?(').concat(fractionalNumbers, 'S)?');
|
|
7
|
+
|
|
8
|
+
const rPattern = '(?:R('.concat(numbers).concat(')/)?');
|
|
9
|
+
const iso8601 = rPattern.concat('P(?:').concat(datePattern, '(?:').concat(timePattern, ')?)');
|
|
10
|
+
const objMap = [
|
|
11
|
+
'years',
|
|
12
|
+
'months',
|
|
13
|
+
'weeks',
|
|
14
|
+
'days',
|
|
15
|
+
'hours',
|
|
16
|
+
'minutes',
|
|
17
|
+
'seconds',
|
|
18
|
+
];
|
|
19
|
+
const defaultDuration = Object.freeze({
|
|
20
|
+
years: 0,
|
|
21
|
+
months: 0,
|
|
22
|
+
weeks: 0,
|
|
23
|
+
days: 0,
|
|
24
|
+
hours: 0,
|
|
25
|
+
minutes: 0,
|
|
26
|
+
seconds: 0,
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* The ISO8601 regex for matching / testing durations
|
|
31
|
+
*/
|
|
32
|
+
const pattern = new RegExp(iso8601);
|
|
33
|
+
|
|
34
|
+
/** Parse PnYnMnDTnHnMnS format to object */
|
|
35
|
+
export function parse(durationString) {
|
|
36
|
+
const matches = durationString.replace(/,/g, '.').match(pattern);
|
|
37
|
+
if (!matches) {
|
|
38
|
+
throw new RangeError('invalid duration: ' + durationString);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
// Slice away repeat and first entry in match-array (the input string)
|
|
42
|
+
const slicedMatches = matches.slice(2);
|
|
43
|
+
if (slicedMatches.filter(Boolean).length === 0) {
|
|
44
|
+
throw new RangeError('invalid duration: ' + durationString);
|
|
45
|
+
}
|
|
46
|
+
// Check only one fraction is used
|
|
47
|
+
if (slicedMatches.filter((v) => {
|
|
48
|
+
return /\./.test(v || '');
|
|
49
|
+
}).length > 1) {
|
|
50
|
+
throw new RangeError('Fractions are allowed on the smallest unit in the string, e.g. P0.5D or PT1.0001S but not PT0.5M0.1S: ' + durationString);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
const result = {};
|
|
54
|
+
if (matches[1]) result.repeat = Number(matches[1]);
|
|
55
|
+
|
|
56
|
+
return slicedMatches.reduce((prev, next, idx) => {
|
|
57
|
+
prev[objMap[idx]] = parseFloat(next || '0') || 0;
|
|
58
|
+
return prev;
|
|
59
|
+
}, result);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/** Convert ISO8601 duration object to an end Date. */
|
|
63
|
+
export function end(durationInput, startDate) {
|
|
64
|
+
const duration = Object.assign({}, defaultDuration, durationInput);
|
|
65
|
+
// Create two equal timestamps, add duration to 'then' and return time difference
|
|
66
|
+
const timestamp = startDate.getTime();
|
|
67
|
+
const then = new Date(timestamp);
|
|
68
|
+
then.setFullYear(then.getFullYear() + duration.years);
|
|
69
|
+
then.setMonth(then.getMonth() + duration.months);
|
|
70
|
+
then.setDate(then.getDate() + duration.days);
|
|
71
|
+
// set time as milliseconds to get fractions working for minutes/hours
|
|
72
|
+
const hoursInMs = duration.hours * 3600 * 1000;
|
|
73
|
+
const minutesInMs = duration.minutes * 60 * 1000;
|
|
74
|
+
then.setMilliseconds(then.getMilliseconds() + duration.seconds * 1000 + hoursInMs + minutesInMs);
|
|
75
|
+
// Special case weeks
|
|
76
|
+
then.setDate(then.getDate() + duration.weeks * 7);
|
|
77
|
+
return then;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/** Convert ISO8601 duration object to seconds */
|
|
81
|
+
export function toSeconds(durationInput, startDate) {
|
|
82
|
+
if (startDate === void 0) {
|
|
83
|
+
startDate = new Date();
|
|
84
|
+
}
|
|
85
|
+
const duration = Object.assign({}, defaultDuration, durationInput);
|
|
86
|
+
const timestamp = startDate.getTime();
|
|
87
|
+
const now = new Date(timestamp);
|
|
88
|
+
const then = end(duration, now);
|
|
89
|
+
const seconds = (then.getTime() - now.getTime()) / 1000;
|
|
90
|
+
return seconds;
|
|
91
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
const kProcess = Symbol.for('process');
|
|
2
|
+
|
|
3
|
+
export default function Lane(process, laneDefinition) {
|
|
4
|
+
const {broker, environment} = process;
|
|
5
|
+
const {id, type, behaviour} = laneDefinition;
|
|
6
|
+
|
|
7
|
+
this[kProcess] = process;
|
|
8
|
+
|
|
9
|
+
this.id = id;
|
|
10
|
+
this.type = type;
|
|
11
|
+
this.name = behaviour.name;
|
|
12
|
+
this.parent = {
|
|
13
|
+
id: process.id,
|
|
14
|
+
type: process.type,
|
|
15
|
+
};
|
|
16
|
+
this.behaviour = {...behaviour};
|
|
17
|
+
this.environment = environment;
|
|
18
|
+
this.broker = broker;
|
|
19
|
+
this.context = process.context;
|
|
20
|
+
this.logger = environment.Logger(type.toLowerCase());
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
Object.defineProperty(Lane.prototype, 'process', {
|
|
24
|
+
get() {
|
|
25
|
+
return this[kProcess];
|
|
26
|
+
},
|
|
27
|
+
});
|
package/src/process/Process.js
CHANGED
|
@@ -10,6 +10,7 @@ const kCounters = Symbol.for('counters');
|
|
|
10
10
|
const kExec = Symbol.for('execution');
|
|
11
11
|
const kExecuteMessage = Symbol.for('executeMessage');
|
|
12
12
|
const kExtensions = Symbol.for('extensions');
|
|
13
|
+
const kLanes = Symbol.for('lanes');
|
|
13
14
|
const kMessageHandlers = Symbol.for('messageHandlers');
|
|
14
15
|
const kStateMessage = Symbol.for('stateMessage');
|
|
15
16
|
const kStatus = Symbol.for('status');
|
|
@@ -53,6 +54,9 @@ export function Process(processDef, context) {
|
|
|
53
54
|
|
|
54
55
|
this.logger = environment.Logger(type.toLowerCase());
|
|
55
56
|
|
|
57
|
+
if (behaviour.lanes) {
|
|
58
|
+
this[kLanes] = behaviour.lanes.map((lane) => new lane.Behaviour(this, lane));
|
|
59
|
+
}
|
|
56
60
|
this[kExtensions] = context.loadExtensions(this);
|
|
57
61
|
}
|
|
58
62
|
|
|
@@ -63,6 +67,14 @@ Object.defineProperty(Process.prototype, 'counters', {
|
|
|
63
67
|
},
|
|
64
68
|
});
|
|
65
69
|
|
|
70
|
+
Object.defineProperty(Process.prototype, 'lanes', {
|
|
71
|
+
enumerable: true,
|
|
72
|
+
get() {
|
|
73
|
+
const lanes = this[kLanes];
|
|
74
|
+
return lanes && lanes.slice();
|
|
75
|
+
},
|
|
76
|
+
});
|
|
77
|
+
|
|
66
78
|
Object.defineProperty(Process.prototype, 'extensions', {
|
|
67
79
|
enumerable: true,
|
|
68
80
|
get() {
|
|
@@ -399,6 +411,12 @@ Process.prototype.getSequenceFlows = function getSequenceFlows() {
|
|
|
399
411
|
return this.context.getSequenceFlows();
|
|
400
412
|
};
|
|
401
413
|
|
|
414
|
+
Process.prototype.getLaneById = function getLaneById(laneId) {
|
|
415
|
+
const lanes = this[kLanes];
|
|
416
|
+
if (!lanes) return;
|
|
417
|
+
return lanes.find((lane) => lane.id === laneId);
|
|
418
|
+
};
|
|
419
|
+
|
|
402
420
|
Process.prototype.getPostponed = function getPostponed(...args) {
|
|
403
421
|
const execution = this.execution;
|
|
404
422
|
if (!execution) return [];
|
package/src/tasks/SubProcess.js
CHANGED
|
@@ -135,7 +135,7 @@ SubProcessBehaviour.prototype.recover = function recover(state) {
|
|
|
135
135
|
}
|
|
136
136
|
|
|
137
137
|
const subEnvironment = this.environment.clone().recover(state.environment);
|
|
138
|
-
const subContext = this.context.clone(subEnvironment);
|
|
138
|
+
const subContext = this.context.clone(subEnvironment, this.activity);
|
|
139
139
|
|
|
140
140
|
const execution = new ProcessExecution(this.activity, subContext).recover(state);
|
|
141
141
|
|
|
@@ -176,7 +176,7 @@ SubProcessBehaviour.prototype._upsertExecution = function upsertExecution(execut
|
|
|
176
176
|
}
|
|
177
177
|
|
|
178
178
|
const subEnvironment = this.environment.clone();
|
|
179
|
-
const subContext = this.context.clone(subEnvironment);
|
|
179
|
+
const subContext = this.context.clone(subEnvironment, this.activity);
|
|
180
180
|
|
|
181
181
|
execution = new ProcessExecution(this.activity, subContext);
|
|
182
182
|
this[kExecutions].push(execution);
|
package/types/index.d.ts
CHANGED
|
@@ -37,7 +37,8 @@ declare module 'bpmn-elements' {
|
|
|
37
37
|
content: ElementMessageContent,
|
|
38
38
|
}
|
|
39
39
|
|
|
40
|
-
|
|
40
|
+
class EventDefinition {
|
|
41
|
+
constructor(activity: Activity, eventDefinitionElement: SerializableElement)
|
|
41
42
|
get id(): string;
|
|
42
43
|
get type(): string;
|
|
43
44
|
get executionId(): string;
|
|
@@ -287,6 +288,8 @@ declare module 'bpmn-elements' {
|
|
|
287
288
|
get sid(): string;
|
|
288
289
|
get definitionContext(): SerializableContext;
|
|
289
290
|
get environment(): Environment;
|
|
291
|
+
/** Context owner, Process or SubProcess activity */
|
|
292
|
+
get owner(): Process | Activity | undefined;
|
|
290
293
|
getActivityById<T>(activityId: string): T;
|
|
291
294
|
getSequenceFlowById(sequenceFlowId: string): SequenceFlow;
|
|
292
295
|
getInboundSequenceFlows(activityId: string): SequenceFlow[];
|
|
@@ -428,6 +431,7 @@ declare module 'bpmn-elements' {
|
|
|
428
431
|
constructor(processDef: SerializableElement, context: Context);
|
|
429
432
|
get isExecutable(): boolean;
|
|
430
433
|
get counters(): completedCounters;
|
|
434
|
+
get lanes(): Lane[] | undefined;
|
|
431
435
|
get extensions(): IExtension;
|
|
432
436
|
get stopped(): boolean;
|
|
433
437
|
get isRunning(): boolean;
|
|
@@ -447,6 +451,7 @@ declare module 'bpmn-elements' {
|
|
|
447
451
|
getActivities(): Activity[];
|
|
448
452
|
getStartActivities(filterOptions?: startActivityFilterOptions): Activity[];
|
|
449
453
|
getSequenceFlows(): SequenceFlow[];
|
|
454
|
+
getLaneById(laneId: string): Lane | undefined;
|
|
450
455
|
getPostponed(filterFn: filterPostponed): Api<ElementBase>[];
|
|
451
456
|
}
|
|
452
457
|
|
|
@@ -470,6 +475,24 @@ declare module 'bpmn-elements' {
|
|
|
470
475
|
getApi(message?: ElementBrokerMessage): Api<ElementBase>;
|
|
471
476
|
}
|
|
472
477
|
|
|
478
|
+
class Lane extends ElementBase {
|
|
479
|
+
constructor(process: Process, laneDefinition: SerializableElement);
|
|
480
|
+
/** Process broker */
|
|
481
|
+
get broker(): Broker;
|
|
482
|
+
get process(): Process;
|
|
483
|
+
}
|
|
484
|
+
|
|
485
|
+
interface ISequenceFlowCondition {
|
|
486
|
+
/** Condition type, e.g. script or expression */
|
|
487
|
+
get type(): string;
|
|
488
|
+
/**
|
|
489
|
+
* Execute sequence flow condition
|
|
490
|
+
* @param message Source element execution message
|
|
491
|
+
* @param callback Callback with truthy result if flow should be taken
|
|
492
|
+
*/
|
|
493
|
+
execute(message: ElementBrokerMessage, callback: (err: Error, result: any) => void): void;
|
|
494
|
+
}
|
|
495
|
+
|
|
473
496
|
class SequenceFlow extends Element<SequenceFlow> {
|
|
474
497
|
get sourceId(): string;
|
|
475
498
|
get targetId(): string;
|
|
@@ -479,7 +502,7 @@ declare module 'bpmn-elements' {
|
|
|
479
502
|
take(content?: any): boolean;
|
|
480
503
|
discard(content?: any): void;
|
|
481
504
|
shake(message: any): number;
|
|
482
|
-
getCondition():
|
|
505
|
+
getCondition(): ISequenceFlowCondition | null;
|
|
483
506
|
createMessage(override?: any): object;
|
|
484
507
|
/**
|
|
485
508
|
* Evaluate flow
|
|
@@ -495,6 +518,7 @@ declare module 'bpmn-elements' {
|
|
|
495
518
|
get id(): string;
|
|
496
519
|
get processId(): string;
|
|
497
520
|
}
|
|
521
|
+
|
|
498
522
|
class MessageFlow extends Element<MessageFlow> {
|
|
499
523
|
get source(): MessageFlowReference;
|
|
500
524
|
get target(): MessageFlowReference;
|
|
@@ -521,15 +545,53 @@ declare module 'bpmn-elements' {
|
|
|
521
545
|
[x: string]: any,
|
|
522
546
|
}
|
|
523
547
|
|
|
524
|
-
type wrappedSetTimeout = (handler:
|
|
525
|
-
type wrappedClearTimeout = (
|
|
548
|
+
type wrappedSetTimeout = (handler: TimerHandler, delay: number, ...args: any[]) => Timer;
|
|
549
|
+
type wrappedClearTimeout = (ref: any) => void;
|
|
550
|
+
|
|
551
|
+
interface Timer {
|
|
552
|
+
/** The function to call when the timer elapses */
|
|
553
|
+
readonly callback: TimerHandler;
|
|
554
|
+
/** The number of milliseconds to wait before calling the callback */
|
|
555
|
+
readonly delay: number;
|
|
556
|
+
/** Optional arguments to pass when the callback is called */
|
|
557
|
+
readonly args?: any[];
|
|
558
|
+
/** Timer owner if any */
|
|
559
|
+
readonly owner?: any;
|
|
560
|
+
/** Timer Id */
|
|
561
|
+
readonly timerId: string;
|
|
562
|
+
/** Timeout, return from setTimeout */
|
|
563
|
+
readonly timerRef: any;
|
|
564
|
+
[x: string]: any;
|
|
565
|
+
}
|
|
566
|
+
|
|
567
|
+
interface RegisteredTimer {
|
|
568
|
+
owner?: any;
|
|
569
|
+
get setTimeout(): wrappedSetTimeout;
|
|
570
|
+
get clearTimeout(): wrappedClearTimeout;
|
|
571
|
+
}
|
|
526
572
|
|
|
527
573
|
interface ITimers {
|
|
528
|
-
get executing(): any[];
|
|
529
574
|
get setTimeout(): wrappedSetTimeout;
|
|
530
575
|
get clearTimeout(): wrappedClearTimeout;
|
|
531
|
-
register(owner?: any):
|
|
532
|
-
[x: string]: any
|
|
576
|
+
register(owner?: any): RegisteredTimer;
|
|
577
|
+
[x: string]: any;
|
|
578
|
+
}
|
|
579
|
+
|
|
580
|
+
interface TimersOptions {
|
|
581
|
+
/** Defaults to builtin setTimeout */
|
|
582
|
+
setTimeout?: typeof setTimeout;
|
|
583
|
+
/** Defaults to builtin clearTimeout */
|
|
584
|
+
clearTimeout?: typeof clearTimeout;
|
|
585
|
+
[x: string]: any;
|
|
586
|
+
}
|
|
587
|
+
|
|
588
|
+
class Timers implements ITimers {
|
|
589
|
+
options: TimersOptions;
|
|
590
|
+
constructor(options?: TimersOptions);
|
|
591
|
+
get executing(): Timer[];
|
|
592
|
+
get setTimeout(): wrappedSetTimeout;
|
|
593
|
+
get clearTimeout(): wrappedClearTimeout;
|
|
594
|
+
register(owner?: any): RegisteredTimer;
|
|
533
595
|
}
|
|
534
596
|
|
|
535
597
|
interface IScripts {
|
|
@@ -557,6 +619,8 @@ declare module 'bpmn-elements' {
|
|
|
557
619
|
get triggeredByEvent(): boolean;
|
|
558
620
|
get attachedTo(): Activity;
|
|
559
621
|
get eventDefinitions(): EventDefinition[];
|
|
622
|
+
/** Parent element process or sub process reference */
|
|
623
|
+
get parentElement(): Process | Activity;
|
|
560
624
|
activate(): void;
|
|
561
625
|
deactivate(): void;
|
|
562
626
|
init(initContent?: any): void;
|
|
@@ -602,7 +666,30 @@ declare module 'bpmn-elements' {
|
|
|
602
666
|
var MessageEventDefinition: EventDefinition;
|
|
603
667
|
var SignalEventDefinition: EventDefinition;
|
|
604
668
|
var TerminateEventDefinition: EventDefinition;
|
|
605
|
-
|
|
669
|
+
|
|
670
|
+
const enum TimerType {
|
|
671
|
+
TimeCycle = 'timeCycle',
|
|
672
|
+
TimeDuration = 'timeDuration',
|
|
673
|
+
TimeDate = 'timeDate',
|
|
674
|
+
}
|
|
675
|
+
|
|
676
|
+
type parsedTimer = {
|
|
677
|
+
/** Expires at date time */
|
|
678
|
+
expireAt?: Date,
|
|
679
|
+
/** Repeat number of times */
|
|
680
|
+
repeat?: number,
|
|
681
|
+
/** Delay in milliseconds */
|
|
682
|
+
delay?: number,
|
|
683
|
+
};
|
|
684
|
+
|
|
685
|
+
class TimerEventDefinition extends EventDefinition {
|
|
686
|
+
/**
|
|
687
|
+
* Parse timer type
|
|
688
|
+
* @param timerType type of timer
|
|
689
|
+
* @param timerValue resolved expression timer string
|
|
690
|
+
*/
|
|
691
|
+
parse(timerType: TimerType, timerValue: string): parsedTimer;
|
|
692
|
+
}
|
|
606
693
|
|
|
607
694
|
class BpmnError {
|
|
608
695
|
get id(): string;
|
|
@@ -641,6 +728,28 @@ declare module 'bpmn-elements' {
|
|
|
641
728
|
code?: string;
|
|
642
729
|
constructor(description: string, sourceMessage: MessageMessage, inner?: Error);
|
|
643
730
|
}
|
|
731
|
+
|
|
732
|
+
interface Duration {
|
|
733
|
+
years?: number;
|
|
734
|
+
months?: number;
|
|
735
|
+
weeks?: number;
|
|
736
|
+
days?: number;
|
|
737
|
+
hours?: number;
|
|
738
|
+
minutes?: number;
|
|
739
|
+
seconds?: number;
|
|
740
|
+
repeat?: number;
|
|
741
|
+
}
|
|
742
|
+
|
|
743
|
+
type ISODurationApi = {
|
|
744
|
+
/** Parse PnYnMnDTnHnMnS format to object */
|
|
745
|
+
parse: (durationString: string) => Duration,
|
|
746
|
+
/** Convert ISO8601 duration object to an end Date. */
|
|
747
|
+
end: (durationInput: Duration, startDate?: Date) => Date,
|
|
748
|
+
/** Convert ISO8601 duration object to seconds */
|
|
749
|
+
toSeconds: (durationInput: Duration, startDate?: Date) => number,
|
|
750
|
+
}
|
|
751
|
+
|
|
752
|
+
const ISODuration: ISODurationApi;
|
|
644
753
|
}
|
|
645
754
|
|
|
646
755
|
/**
|