@miragon/pulse-engine-core 0.0.0-bootstrap.0 → 0.25.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/LICENSE +21 -0
- package/dist/activities.d.ts +31 -0
- package/dist/activities.d.ts.map +1 -0
- package/dist/activities.js +62 -0
- package/dist/activities.js.map +1 -0
- package/dist/advance-plan.d.ts +21 -0
- package/dist/advance-plan.d.ts.map +1 -0
- package/dist/advance-plan.js +192 -0
- package/dist/advance-plan.js.map +1 -0
- package/dist/conditions.d.ts +66 -0
- package/dist/conditions.d.ts.map +1 -0
- package/dist/conditions.js +119 -0
- package/dist/conditions.js.map +1 -0
- package/dist/dates.d.ts +59 -0
- package/dist/dates.d.ts.map +1 -0
- package/dist/dates.js +189 -0
- package/dist/dates.js.map +1 -0
- package/dist/durations.d.ts +4 -0
- package/dist/durations.d.ts.map +1 -0
- package/dist/durations.js +10 -0
- package/dist/durations.js.map +1 -0
- package/dist/engine-status.d.ts +57 -0
- package/dist/engine-status.d.ts.map +1 -0
- package/dist/engine-status.js +193 -0
- package/dist/engine-status.js.map +1 -0
- package/dist/errors.d.ts +101 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +18 -0
- package/dist/errors.js.map +1 -0
- package/dist/filters.d.ts +53 -0
- package/dist/filters.d.ts.map +1 -0
- package/dist/filters.js +74 -0
- package/dist/filters.js.map +1 -0
- package/dist/findings.d.ts +46 -0
- package/dist/findings.d.ts.map +1 -0
- package/dist/findings.js +105 -0
- package/dist/findings.js.map +1 -0
- package/dist/incident-recovery.d.ts +35 -0
- package/dist/incident-recovery.d.ts.map +1 -0
- package/dist/incident-recovery.js +24 -0
- package/dist/incident-recovery.js.map +1 -0
- package/dist/index.d.ts +36 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +33 -0
- package/dist/index.js.map +1 -0
- package/dist/inspect.d.ts +34 -0
- package/dist/inspect.d.ts.map +1 -0
- package/dist/inspect.js +247 -0
- package/dist/inspect.js.map +1 -0
- package/dist/next.d.ts +26 -0
- package/dist/next.d.ts.map +1 -0
- package/dist/next.js +83 -0
- package/dist/next.js.map +1 -0
- package/dist/operations.d.ts +9 -0
- package/dist/operations.d.ts.map +1 -0
- package/dist/operations.js +41 -0
- package/dist/operations.js.map +1 -0
- package/dist/poll.d.ts +24 -0
- package/dist/poll.d.ts.map +1 -0
- package/dist/poll.js +29 -0
- package/dist/poll.js.map +1 -0
- package/dist/port.d.ts +95 -0
- package/dist/port.d.ts.map +1 -0
- package/dist/port.js +113 -0
- package/dist/port.js.map +1 -0
- package/dist/records.d.ts +27 -0
- package/dist/records.d.ts.map +1 -0
- package/dist/records.js +58 -0
- package/dist/records.js.map +1 -0
- package/dist/requests.d.ts +24 -0
- package/dist/requests.d.ts.map +1 -0
- package/dist/requests.js +35 -0
- package/dist/requests.js.map +1 -0
- package/dist/retry-plan.d.ts +62 -0
- package/dist/retry-plan.d.ts.map +1 -0
- package/dist/retry-plan.js +140 -0
- package/dist/retry-plan.js.map +1 -0
- package/dist/root-cause.d.ts +17 -0
- package/dist/root-cause.d.ts.map +1 -0
- package/dist/root-cause.js +35 -0
- package/dist/root-cause.js.map +1 -0
- package/dist/select.d.ts +16 -0
- package/dist/select.d.ts.map +1 -0
- package/dist/select.js +133 -0
- package/dist/select.js.map +1 -0
- package/dist/snapshot.d.ts +12 -0
- package/dist/snapshot.d.ts.map +1 -0
- package/dist/snapshot.js +134 -0
- package/dist/snapshot.js.map +1 -0
- package/dist/sorting.d.ts +20 -0
- package/dist/sorting.d.ts.map +1 -0
- package/dist/sorting.js +17 -0
- package/dist/sorting.js.map +1 -0
- package/dist/status.d.ts +91 -0
- package/dist/status.d.ts.map +1 -0
- package/dist/status.js +222 -0
- package/dist/status.js.map +1 -0
- package/dist/testing/fake-port.d.ts +31 -0
- package/dist/testing/fake-port.d.ts.map +1 -0
- package/dist/testing/fake-port.js +50 -0
- package/dist/testing/fake-port.js.map +1 -0
- package/dist/testing/fixture.d.ts +39 -0
- package/dist/testing/fixture.d.ts.map +1 -0
- package/dist/testing/fixture.js +288 -0
- package/dist/testing/fixture.js.map +1 -0
- package/dist/testing/index.d.ts +23 -0
- package/dist/testing/index.d.ts.map +1 -0
- package/dist/testing/index.js +23 -0
- package/dist/testing/index.js.map +1 -0
- package/dist/testing/inspect-routes.d.ts +12 -0
- package/dist/testing/inspect-routes.d.ts.map +1 -0
- package/dist/testing/inspect-routes.js +63 -0
- package/dist/testing/inspect-routes.js.map +1 -0
- package/dist/testing/status.d.ts +18 -0
- package/dist/testing/status.d.ts.map +1 -0
- package/dist/testing/status.js +12 -0
- package/dist/testing/status.js.map +1 -0
- package/dist/testing/waits.d.ts +60 -0
- package/dist/testing/waits.d.ts.map +1 -0
- package/dist/testing/waits.js +53 -0
- package/dist/testing/waits.js.map +1 -0
- package/dist/timeline.d.ts +9 -0
- package/dist/timeline.d.ts.map +1 -0
- package/dist/timeline.js +63 -0
- package/dist/timeline.js.map +1 -0
- package/dist/tree.d.ts +19 -0
- package/dist/tree.d.ts.map +1 -0
- package/dist/tree.js +61 -0
- package/dist/tree.js.map +1 -0
- package/dist/types.d.ts +254 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +6 -0
- package/dist/types.js.map +1 -0
- package/dist/util.d.ts +26 -0
- package/dist/util.d.ts.map +1 -0
- package/dist/util.js +44 -0
- package/dist/util.js.map +1 -0
- package/dist/variable-writes.d.ts +32 -0
- package/dist/variable-writes.d.ts.map +1 -0
- package/dist/variable-writes.js +113 -0
- package/dist/variable-writes.js.map +1 -0
- package/dist/variables.d.ts +28 -0
- package/dist/variables.d.ts.map +1 -0
- package/dist/variables.js +64 -0
- package/dist/variables.js.map +1 -0
- package/dist/waits.d.ts +11 -0
- package/dist/waits.d.ts.map +1 -0
- package/dist/waits.js +253 -0
- package/dist/waits.js.map +1 -0
- package/package.json +47 -5
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Miragon GmbH
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The activity instance trees of the instances of a tree as one index: which activity instance an
|
|
3
|
+
* execution belongs to, which transition instance (async continuation) waits on it, and the leaf
|
|
4
|
+
* activity instances. Pure.
|
|
5
|
+
*/
|
|
6
|
+
import { type Rec } from "./records.js";
|
|
7
|
+
export interface ActivityNode {
|
|
8
|
+
readonly id: string;
|
|
9
|
+
readonly activityId: string;
|
|
10
|
+
readonly activityName?: string;
|
|
11
|
+
readonly activityType?: string;
|
|
12
|
+
readonly processInstanceId: string;
|
|
13
|
+
readonly depth: number;
|
|
14
|
+
/** The process instance itself (root of its activity instance tree). */
|
|
15
|
+
readonly root: boolean;
|
|
16
|
+
/** No child activity or transition instances. */
|
|
17
|
+
readonly leaf: boolean;
|
|
18
|
+
readonly transition: boolean;
|
|
19
|
+
readonly executionIds: readonly string[];
|
|
20
|
+
}
|
|
21
|
+
export interface ActivityIndex {
|
|
22
|
+
readonly nodes: readonly ActivityNode[];
|
|
23
|
+
byId(id: string | undefined): ActivityNode | undefined;
|
|
24
|
+
/** The activity instance of an execution: one of `activityId` if possible, else the deepest. */
|
|
25
|
+
forExecution(executionId: string | undefined, activityId?: string): ActivityNode | undefined;
|
|
26
|
+
/** The transition instance (async continuation) of an execution. */
|
|
27
|
+
transition(executionId: string | undefined, activityId?: string): ActivityNode | undefined;
|
|
28
|
+
}
|
|
29
|
+
/** Indexes the activity instance trees (ActivityInstanceDto) of the instances of a tree. */
|
|
30
|
+
export declare function indexActivities(trees: readonly Rec[]): ActivityIndex;
|
|
31
|
+
//# sourceMappingURL=activities.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"activities.d.ts","sourceRoot":"","sources":["../src/activities.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAsB,KAAK,GAAG,EAAgB,MAAM,cAAc,CAAA;AAEzE,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAA;IACnB,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAA;IAC3B,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAA;IAC9B,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAA;IAC9B,QAAQ,CAAC,iBAAiB,EAAE,MAAM,CAAA;IAClC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;IACtB,wEAAwE;IACxE,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAA;IACtB,iDAAiD;IACjD,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAA;IACtB,QAAQ,CAAC,UAAU,EAAE,OAAO,CAAA;IAC5B,QAAQ,CAAC,YAAY,EAAE,SAAS,MAAM,EAAE,CAAA;CACzC;AAED,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,KAAK,EAAE,SAAS,YAAY,EAAE,CAAA;IACvC,IAAI,CAAC,EAAE,EAAE,MAAM,GAAG,SAAS,GAAG,YAAY,GAAG,SAAS,CAAA;IACtD,gGAAgG;IAChG,YAAY,CAAC,WAAW,EAAE,MAAM,GAAG,SAAS,EAAE,UAAU,CAAC,EAAE,MAAM,GAAG,YAAY,GAAG,SAAS,CAAA;IAC5F,oEAAoE;IACpE,UAAU,CAAC,WAAW,EAAE,MAAM,GAAG,SAAS,EAAE,UAAU,CAAC,EAAE,MAAM,GAAG,YAAY,GAAG,SAAS,CAAA;CAC3F;AAyDD,4FAA4F;AAC5F,wBAAgB,eAAe,CAAC,KAAK,EAAE,SAAS,GAAG,EAAE,GAAG,aAAa,CAmBpE"}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The activity instance trees of the instances of a tree as one index: which activity instance an
|
|
3
|
+
* execution belongs to, which transition instance (async continuation) waits on it, and the leaf
|
|
4
|
+
* activity instances. Pure.
|
|
5
|
+
*/
|
|
6
|
+
import { compareText, field, records, str } from "./records.js";
|
|
7
|
+
function strings(value) {
|
|
8
|
+
return Array.isArray(value)
|
|
9
|
+
? value.filter((item) => typeof item === "string")
|
|
10
|
+
: [];
|
|
11
|
+
}
|
|
12
|
+
function node(instance, position, flags, executionIds) {
|
|
13
|
+
const name = str(instance, "activityName") ?? str(instance, "name");
|
|
14
|
+
const type = str(instance, "activityType");
|
|
15
|
+
return {
|
|
16
|
+
id: field(instance, "id"),
|
|
17
|
+
activityId: field(instance, "activityId"),
|
|
18
|
+
...(name === undefined ? {} : { activityName: name }),
|
|
19
|
+
...(type === undefined ? {} : { activityType: type }),
|
|
20
|
+
...position,
|
|
21
|
+
...flags,
|
|
22
|
+
executionIds,
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
function walk(instance, position, nodes) {
|
|
26
|
+
const children = records(instance.childActivityInstances);
|
|
27
|
+
const transitions = records(instance.childTransitionInstances);
|
|
28
|
+
const leaf = children.length === 0 && transitions.length === 0;
|
|
29
|
+
const flags = { root: position.depth === 0, leaf, transition: false };
|
|
30
|
+
nodes.push(node(instance, position, flags, strings(instance.executionIds)));
|
|
31
|
+
const below = { ...position, depth: position.depth + 1 };
|
|
32
|
+
for (const child of children)
|
|
33
|
+
walk(child, below, nodes);
|
|
34
|
+
for (const transition of transitions) {
|
|
35
|
+
const executionId = str(transition, "executionId");
|
|
36
|
+
const transitionFlags = { root: false, leaf: false, transition: true };
|
|
37
|
+
nodes.push(node(transition, below, transitionFlags, executionId === undefined ? [] : [executionId]));
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
/** Deepest first, then by id: a deterministic choice among candidates. */
|
|
41
|
+
function best(candidates, activityId) {
|
|
42
|
+
const matching = candidates.filter((candidate) => candidate.activityId === activityId);
|
|
43
|
+
return (matching.length > 0 ? matching : candidates).toSorted((left, right) => right.depth - left.depth || compareText(left.id, right.id))[0];
|
|
44
|
+
}
|
|
45
|
+
/** Indexes the activity instance trees (ActivityInstanceDto) of the instances of a tree. */
|
|
46
|
+
export function indexActivities(trees) {
|
|
47
|
+
const nodes = [];
|
|
48
|
+
for (const tree of trees) {
|
|
49
|
+
const processInstanceId = str(tree, "processInstanceId") ?? field(tree, "id");
|
|
50
|
+
walk(tree, { processInstanceId, depth: 0 }, nodes);
|
|
51
|
+
}
|
|
52
|
+
const containing = (executionId, transition) => executionId === undefined
|
|
53
|
+
? []
|
|
54
|
+
: nodes.filter((candidate) => candidate.transition === transition && candidate.executionIds.includes(executionId));
|
|
55
|
+
return {
|
|
56
|
+
nodes,
|
|
57
|
+
byId: (id) => (id === undefined ? undefined : nodes.find((candidate) => candidate.id === id)),
|
|
58
|
+
forExecution: (executionId, activityId) => best(containing(executionId, false), activityId),
|
|
59
|
+
transition: (executionId, activityId) => best(containing(executionId, true), activityId),
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
//# sourceMappingURL=activities.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"activities.js","sourceRoot":"","sources":["../src/activities.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Planning of advance: which wait state to move, which options apply to it, and the requests that
|
|
3
|
+
* move it. Pure.
|
|
4
|
+
*/
|
|
5
|
+
import type { PlannedWrite } from "./port.js";
|
|
6
|
+
import type { AdvanceInput, InstanceView, WaitState } from "./types.js";
|
|
7
|
+
/** Option combinations, checked before any request. */
|
|
8
|
+
export declare function checkAdvanceInput(input: AdvanceInput): void;
|
|
9
|
+
type ViewInput = Pick<InstanceView<unknown>, "id" | "state" | "waitingAt" | "children" | "truncated">;
|
|
10
|
+
/** The wait state to move: the only advanceable one (of `activityId`). */
|
|
11
|
+
export declare function chooseWait(view: ViewInput, activityId?: string): WaitState;
|
|
12
|
+
/** Options that do not apply to the chosen wait state are refused. */
|
|
13
|
+
export declare function checkOptions(wait: WaitState, input: AdvanceInput): void;
|
|
14
|
+
/** A suspended job is not executed behind the operator's back. */
|
|
15
|
+
export declare function checkSuspended(wait: WaitState): void;
|
|
16
|
+
/** A lock of another worker that has not expired is refused; `worker` is the caller's default. */
|
|
17
|
+
export declare function checkLock(wait: WaitState, input: AdvanceInput, now: number, worker: string): void;
|
|
18
|
+
/** The writes that move the wait state, in order; `worker` locks an external task by default. */
|
|
19
|
+
export declare function advanceSteps(wait: WaitState, input: AdvanceInput, worker: string): PlannedWrite[];
|
|
20
|
+
export {};
|
|
21
|
+
//# sourceMappingURL=advance-plan.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"advance-plan.d.ts","sourceRoot":"","sources":["../src/advance-plan.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,WAAW,CAAA;AAE7C,OAAO,KAAK,EAAE,YAAY,EAAiB,YAAY,EAAY,SAAS,EAAE,MAAM,YAAY,CAAA;AAmBhG,uDAAuD;AACvD,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,YAAY,GAAG,IAAI,CAU3D;AAED,KAAK,SAAS,GAAG,IAAI,CACnB,YAAY,CAAC,OAAO,CAAC,EACrB,IAAI,GAAG,OAAO,GAAG,WAAW,GAAG,UAAU,GAAG,WAAW,CACxD,CAAA;AAgBD,0EAA0E;AAC1E,wBAAgB,UAAU,CAAC,IAAI,EAAE,SAAS,EAAE,UAAU,CAAC,EAAE,MAAM,GAAG,SAAS,CAgB1E;AAED,sEAAsE;AACtE,wBAAgB,YAAY,CAAC,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,YAAY,GAAG,IAAI,CAYvE;AAED,kEAAkE;AAClE,wBAAgB,cAAc,CAAC,IAAI,EAAE,SAAS,GAAG,IAAI,CAOpD;AAED,kGAAkG;AAClG,wBAAgB,SAAS,CAAC,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,YAAY,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI,CAWjG;AAqGD,iGAAiG;AACjG,wBAAgB,YAAY,CAAC,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,YAAY,EAAE,MAAM,EAAE,MAAM,GAAG,YAAY,EAAE,CAYjG"}
|
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Planning of advance: which wait state to move, which options apply to it, and the requests that
|
|
3
|
+
* move it. Pure.
|
|
4
|
+
*/
|
|
5
|
+
import { WorkflowError } from "./errors.js";
|
|
6
|
+
import { isAdvanceable, isSuspendedJob } from "./next.js";
|
|
7
|
+
import { engineTime } from "./dates.js";
|
|
8
|
+
import { compact } from "./util.js";
|
|
9
|
+
import { waitId } from "./waits.js";
|
|
10
|
+
const LOCK_DURATION_MS = 60_000;
|
|
11
|
+
const TASKS = ["userTask", "externalTask"];
|
|
12
|
+
/** The kinds each option applies to, in the order the options are checked. */
|
|
13
|
+
const OPTION_KINDS = {
|
|
14
|
+
variables: ["userTask", "externalTask", "message", "signal", "other"],
|
|
15
|
+
localVariables: ["externalTask"],
|
|
16
|
+
bpmnError: TASKS,
|
|
17
|
+
errorMessage: TASKS,
|
|
18
|
+
fail: ["externalTask"],
|
|
19
|
+
retries: ["externalTask"],
|
|
20
|
+
workerId: ["externalTask"],
|
|
21
|
+
};
|
|
22
|
+
/** Option combinations, checked before any request. */
|
|
23
|
+
export function checkAdvanceInput(input) {
|
|
24
|
+
if (input.bpmnError !== undefined && input.fail !== undefined) {
|
|
25
|
+
throw new WorkflowError({ kind: "advance-input", rule: "bpmn-error-excludes-fail" });
|
|
26
|
+
}
|
|
27
|
+
if (input.errorMessage !== undefined && input.bpmnError === undefined) {
|
|
28
|
+
throw new WorkflowError({ kind: "advance-input", rule: "error-message-needs-bpmn-error" });
|
|
29
|
+
}
|
|
30
|
+
if (input.retries !== undefined && input.fail === undefined) {
|
|
31
|
+
throw new WorkflowError({ kind: "advance-input", rule: "retries-need-fail" });
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
function nothing(view, activityId) {
|
|
35
|
+
const firstChildId = view.truncated === true ? view.children[0]?.id : undefined;
|
|
36
|
+
return new WorkflowError({
|
|
37
|
+
kind: "advance-nothing",
|
|
38
|
+
id: view.id,
|
|
39
|
+
...compact({ activityId }),
|
|
40
|
+
waiting: view.waitingAt
|
|
41
|
+
.filter(isAdvanceable)
|
|
42
|
+
.map((wait) => ({ activityId: wait.activityId, kind: wait.kind })),
|
|
43
|
+
conditional: view.waitingAt.some((wait) => wait.kind === "conditional"),
|
|
44
|
+
...compact({ firstChildId }),
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
/** The wait state to move: the only advanceable one (of `activityId`). */
|
|
48
|
+
export function chooseWait(view, activityId) {
|
|
49
|
+
if (view.state !== "ACTIVE" && view.state !== "SUSPENDED") {
|
|
50
|
+
throw new WorkflowError({ kind: "advance-ended", id: view.id, state: view.state });
|
|
51
|
+
}
|
|
52
|
+
if (view.state === "SUSPENDED")
|
|
53
|
+
throw new WorkflowError({ kind: "advance-suspended", id: view.id });
|
|
54
|
+
const matching = view.waitingAt.filter((wait) => isAdvanceable(wait) && (activityId === undefined || wait.activityId === activityId));
|
|
55
|
+
// a suspended job does not count as a place while something else can move (like the next steps)
|
|
56
|
+
const movable = matching.filter((wait) => !isSuspendedJob(wait));
|
|
57
|
+
const waits = movable.length > 0 ? movable : matching;
|
|
58
|
+
const [only, ...others] = waits;
|
|
59
|
+
if (only === undefined)
|
|
60
|
+
throw nothing(view, activityId);
|
|
61
|
+
if (others.length > 0)
|
|
62
|
+
throw new WorkflowError({ kind: "advance-ambiguous", id: view.id, waits });
|
|
63
|
+
return only;
|
|
64
|
+
}
|
|
65
|
+
/** Options that do not apply to the chosen wait state are refused. */
|
|
66
|
+
export function checkOptions(wait, input) {
|
|
67
|
+
for (const [option, kinds] of Object.entries(OPTION_KINDS)) {
|
|
68
|
+
if (input[option] !== undefined && !kinds.includes(wait.kind)) {
|
|
69
|
+
throw new WorkflowError({
|
|
70
|
+
kind: "advance-option-kind",
|
|
71
|
+
option,
|
|
72
|
+
appliesTo: kinds,
|
|
73
|
+
activityId: wait.activityId,
|
|
74
|
+
waitKind: wait.kind,
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
/** A suspended job is not executed behind the operator's back. */
|
|
80
|
+
export function checkSuspended(wait) {
|
|
81
|
+
if (!isSuspendedJob(wait) || !("jobId" in wait))
|
|
82
|
+
return;
|
|
83
|
+
throw new WorkflowError({
|
|
84
|
+
kind: "advance-job-suspended",
|
|
85
|
+
jobId: wait.jobId,
|
|
86
|
+
activityId: wait.activityId,
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
/** A lock of another worker that has not expired is refused; `worker` is the caller's default. */
|
|
90
|
+
export function checkLock(wait, input, now, worker) {
|
|
91
|
+
if (wait.kind !== "externalTask" || wait.workerId === undefined)
|
|
92
|
+
return;
|
|
93
|
+
const own = input.workerId ?? worker;
|
|
94
|
+
const until = engineTime(wait.lockExpirationTime);
|
|
95
|
+
if (wait.workerId === own || until === undefined || until <= now)
|
|
96
|
+
return;
|
|
97
|
+
throw new WorkflowError({
|
|
98
|
+
kind: "advance-locked",
|
|
99
|
+
externalTaskId: wait.externalTaskId,
|
|
100
|
+
workerId: wait.workerId,
|
|
101
|
+
...compact({ lockExpirationTime: wait.lockExpirationTime }),
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
function write(label, operationId, pathArgs, body) {
|
|
105
|
+
return {
|
|
106
|
+
label,
|
|
107
|
+
operationId,
|
|
108
|
+
input: { pathArgs, query: {}, ...(body === undefined ? {} : { body }) },
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
function variablesOf(input) {
|
|
112
|
+
return compact({ variables: input.variables, localVariables: input.localVariables });
|
|
113
|
+
}
|
|
114
|
+
function userTaskSteps(taskId, input) {
|
|
115
|
+
if (input.bpmnError === undefined) {
|
|
116
|
+
return [
|
|
117
|
+
write(`complete user task ${taskId}`, "complete", [taskId], compact({ variables: input.variables })),
|
|
118
|
+
];
|
|
119
|
+
}
|
|
120
|
+
const body = {
|
|
121
|
+
errorCode: input.bpmnError,
|
|
122
|
+
...compact({ errorMessage: input.errorMessage, variables: input.variables }),
|
|
123
|
+
};
|
|
124
|
+
return [
|
|
125
|
+
write(`throw BPMN error ${input.bpmnError} on user task ${taskId}`, "handleBpmnError", [taskId], body),
|
|
126
|
+
];
|
|
127
|
+
}
|
|
128
|
+
function externalTaskSteps(id, input, workerId) {
|
|
129
|
+
const lock = write(`lock external task ${id} as ${workerId}`, "lock", [id], {
|
|
130
|
+
workerId,
|
|
131
|
+
lockDuration: LOCK_DURATION_MS,
|
|
132
|
+
});
|
|
133
|
+
if (input.bpmnError !== undefined) {
|
|
134
|
+
const body = {
|
|
135
|
+
workerId,
|
|
136
|
+
errorCode: input.bpmnError,
|
|
137
|
+
...compact({ errorMessage: input.errorMessage, variables: input.variables }),
|
|
138
|
+
};
|
|
139
|
+
return [
|
|
140
|
+
lock,
|
|
141
|
+
write(`throw BPMN error ${input.bpmnError} on external task ${id}`, "handleExternalTaskBpmnError", [id], body),
|
|
142
|
+
];
|
|
143
|
+
}
|
|
144
|
+
if (input.fail !== undefined) {
|
|
145
|
+
const body = {
|
|
146
|
+
workerId,
|
|
147
|
+
errorMessage: input.fail,
|
|
148
|
+
retries: input.retries ?? 0,
|
|
149
|
+
retryTimeout: 0,
|
|
150
|
+
...variablesOf(input),
|
|
151
|
+
};
|
|
152
|
+
return [lock, write(`report a failure of external task ${id}`, "handleFailure", [id], body)];
|
|
153
|
+
}
|
|
154
|
+
return [
|
|
155
|
+
lock,
|
|
156
|
+
write(`complete external task ${id}`, "completeExternalTaskResource", [id], {
|
|
157
|
+
workerId,
|
|
158
|
+
...variablesOf(input),
|
|
159
|
+
}),
|
|
160
|
+
];
|
|
161
|
+
}
|
|
162
|
+
/** The write of a message, a signal or a receive task (`other`). */
|
|
163
|
+
function eventStep(wait, input) {
|
|
164
|
+
const variables = compact({ variables: input.variables });
|
|
165
|
+
if (wait.kind === "message") {
|
|
166
|
+
const name = wait.eventName ?? "";
|
|
167
|
+
const label = `trigger message ${name} of execution ${wait.executionId}`;
|
|
168
|
+
return write(label, "triggerEvent", [wait.executionId, name], variables);
|
|
169
|
+
}
|
|
170
|
+
if (wait.kind === "signal") {
|
|
171
|
+
const name = wait.eventName ?? "";
|
|
172
|
+
const body = { name, executionId: wait.executionId, ...variables };
|
|
173
|
+
return write(`send signal ${name} to execution ${wait.executionId}`, "throwSignal", [], body);
|
|
174
|
+
}
|
|
175
|
+
const executionId = waitId(wait);
|
|
176
|
+
return write(`signal execution ${executionId}`, "signalExecution", [executionId], variables);
|
|
177
|
+
}
|
|
178
|
+
/** The writes that move the wait state, in order; `worker` locks an external task by default. */
|
|
179
|
+
export function advanceSteps(wait, input, worker) {
|
|
180
|
+
switch (wait.kind) {
|
|
181
|
+
case "userTask":
|
|
182
|
+
return userTaskSteps(wait.taskId, input);
|
|
183
|
+
case "externalTask":
|
|
184
|
+
return externalTaskSteps(wait.externalTaskId, input, input.workerId ?? worker);
|
|
185
|
+
case "timer":
|
|
186
|
+
case "asyncContinuation":
|
|
187
|
+
return [write(`execute job ${wait.jobId}`, "executeJob", [wait.jobId])];
|
|
188
|
+
default:
|
|
189
|
+
return [eventStep(wait, input)];
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
//# sourceMappingURL=advance-plan.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"advance-plan.js","sourceRoot":"","sources":["../src/advance-plan.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Wait conditions: parsing, the requests each condition needs per poll, and the order in which a
|
|
3
|
+
* poll decides.
|
|
4
|
+
*/
|
|
5
|
+
import type { EnginePort } from "./port.js";
|
|
6
|
+
export type Condition = {
|
|
7
|
+
readonly kind: "idle" | "ended" | "incident";
|
|
8
|
+
} | {
|
|
9
|
+
readonly kind: "task";
|
|
10
|
+
readonly key?: string;
|
|
11
|
+
} | {
|
|
12
|
+
readonly kind: "activity";
|
|
13
|
+
readonly id: string;
|
|
14
|
+
};
|
|
15
|
+
export declare function parseCondition(raw: string): Condition;
|
|
16
|
+
export declare function conditionLabel(condition: Condition): string;
|
|
17
|
+
/** The instance as one poll saw it. */
|
|
18
|
+
export interface Probe {
|
|
19
|
+
readonly id: string;
|
|
20
|
+
readonly ended: boolean;
|
|
21
|
+
/** The active tree (empty once the instance ended). */
|
|
22
|
+
readonly tree: readonly string[];
|
|
23
|
+
/** The tree was cut: instances beyond the cut are not counted. */
|
|
24
|
+
readonly truncated?: boolean;
|
|
25
|
+
}
|
|
26
|
+
export interface Measurement {
|
|
27
|
+
/** Instances of the tree with an incident. */
|
|
28
|
+
readonly incidents: number;
|
|
29
|
+
/** Labels of the conditions that hold, other than `incident`, in the given order. */
|
|
30
|
+
readonly held: readonly string[];
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* The jobs the job executor will run: retries left, due, and active. The engine's `executable`
|
|
34
|
+
* filter checks the suspension of the instance only, not of the job (a suspended job definition
|
|
35
|
+
* suspends its jobs), hence `active` (verified on all three engines).
|
|
36
|
+
*/
|
|
37
|
+
export declare const EXECUTABLE: {
|
|
38
|
+
readonly executable: "true";
|
|
39
|
+
readonly active: "true";
|
|
40
|
+
};
|
|
41
|
+
/**
|
|
42
|
+
* The counts of one poll: only what the conditions need, then the incident check. The incident
|
|
43
|
+
* count is read after the condition counts, never in parallel with them: a job that fails for good
|
|
44
|
+
* loses its last retry and gets its incident in one transaction, so a job count that no longer sees
|
|
45
|
+
* the job is followed by an incident count that sees the incident. Read in parallel, the incident
|
|
46
|
+
* count could come from before that transaction and the job count from after it, and the poll
|
|
47
|
+
* would see neither (a stuck instance reported as idle).
|
|
48
|
+
*/
|
|
49
|
+
export declare function measure(port: EnginePort, probe: Probe, conditions: readonly Condition[], checkIncidents: boolean): Promise<Measurement>;
|
|
50
|
+
export type Verdict = {
|
|
51
|
+
readonly kind: "held";
|
|
52
|
+
readonly until: string;
|
|
53
|
+
} | {
|
|
54
|
+
readonly kind: "incident";
|
|
55
|
+
} | {
|
|
56
|
+
readonly kind: "ended";
|
|
57
|
+
} | {
|
|
58
|
+
readonly kind: "pending";
|
|
59
|
+
};
|
|
60
|
+
/**
|
|
61
|
+
* The decision of a poll: the condition `incident` with an incident, then an incident with fail fast
|
|
62
|
+
* (a job that failed for good is not executable, so `idle` would otherwise report success for a
|
|
63
|
+
* stuck instance), then any other condition, then an ended instance.
|
|
64
|
+
*/
|
|
65
|
+
export declare function decide(conditions: readonly Condition[], failOnIncident: boolean, probe: Probe, measurement: Measurement): Verdict;
|
|
66
|
+
//# sourceMappingURL=conditions.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"conditions.d.ts","sourceRoot":"","sources":["../src/conditions.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,WAAW,CAAA;AAG3C,MAAM,MAAM,SAAS,GACjB;IAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,GAAG,UAAU,CAAA;CAAE,GAChD;IAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAA;CAAE,GAChD;IAAE,QAAQ,CAAC,IAAI,EAAE,UAAU,CAAC;IAAC,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAA;CAAE,CAAA;AAgBtD,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,CAQrD;AAED,wBAAgB,cAAc,CAAC,SAAS,EAAE,SAAS,GAAG,MAAM,CAS3D;AAED,uCAAuC;AACvC,MAAM,WAAW,KAAK;IACpB,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAA;IACnB,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAA;IACvB,uDAAuD;IACvD,QAAQ,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,CAAA;IAChC,kEAAkE;IAClE,QAAQ,CAAC,SAAS,CAAC,EAAE,OAAO,CAAA;CAC7B;AAED,MAAM,WAAW,WAAW;IAC1B,8CAA8C;IAC9C,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;IAC1B,qFAAqF;IACrF,QAAQ,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,CAAA;CACjC;AAsBD;;;;GAIG;AACH,eAAO,MAAM,UAAU;;;CAAkD,CAAA;AA6BzE;;;;;;;GAOG;AACH,wBAAsB,OAAO,CAC3B,IAAI,EAAE,UAAU,EAChB,KAAK,EAAE,KAAK,EACZ,UAAU,EAAE,SAAS,SAAS,EAAE,EAChC,cAAc,EAAE,OAAO,GACtB,OAAO,CAAC,WAAW,CAAC,CAOtB;AAED,MAAM,MAAM,OAAO,GACf;IAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GACjD;IAAE,QAAQ,CAAC,IAAI,EAAE,UAAU,CAAA;CAAE,GAC7B;IAAE,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAA;CAAE,GAC1B;IAAE,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAA;CAAE,CAAA;AAEhC;;;;GAIG;AACH,wBAAgB,MAAM,CACpB,UAAU,EAAE,SAAS,SAAS,EAAE,EAChC,cAAc,EAAE,OAAO,EACvB,KAAK,EAAE,KAAK,EACZ,WAAW,EAAE,WAAW,GACvB,OAAO,CAOT"}
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Wait conditions: parsing, the requests each condition needs per poll, and the order in which a
|
|
3
|
+
* poll decides.
|
|
4
|
+
*/
|
|
5
|
+
import { WorkflowError } from "./errors.js";
|
|
6
|
+
import { countByIds } from "./requests.js";
|
|
7
|
+
/** The accepted forms, for messages and help texts. */
|
|
8
|
+
const CONDITION_FORMS = [
|
|
9
|
+
"idle",
|
|
10
|
+
"ended",
|
|
11
|
+
"incident",
|
|
12
|
+
"task",
|
|
13
|
+
"task:<taskDefinitionKey>",
|
|
14
|
+
"activity:<activityId>",
|
|
15
|
+
];
|
|
16
|
+
function invalid(raw) {
|
|
17
|
+
return new WorkflowError({ kind: "condition-invalid", raw, forms: CONDITION_FORMS });
|
|
18
|
+
}
|
|
19
|
+
export function parseCondition(raw) {
|
|
20
|
+
if (raw === "idle" || raw === "ended" || raw === "incident" || raw === "task") {
|
|
21
|
+
return { kind: raw };
|
|
22
|
+
}
|
|
23
|
+
const [prefix, ...rest] = raw.split(":");
|
|
24
|
+
const id = rest.join(":");
|
|
25
|
+
if (id === "" || (prefix !== "task" && prefix !== "activity"))
|
|
26
|
+
throw invalid(raw);
|
|
27
|
+
return prefix === "task" ? { kind: "task", key: id } : { kind: "activity", id };
|
|
28
|
+
}
|
|
29
|
+
export function conditionLabel(condition) {
|
|
30
|
+
switch (condition.kind) {
|
|
31
|
+
case "activity":
|
|
32
|
+
return `activity:${condition.id}`;
|
|
33
|
+
case "task":
|
|
34
|
+
return condition.key === undefined ? "task" : `task:${condition.key}`;
|
|
35
|
+
default:
|
|
36
|
+
return condition.kind;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
/** Counts over the instances of the tree (`processInstanceIds` of process instances). */
|
|
40
|
+
function countInTree(port, tree, query) {
|
|
41
|
+
return countByIds(port, {
|
|
42
|
+
operationId: "getProcessInstancesCount",
|
|
43
|
+
key: "processInstanceIds",
|
|
44
|
+
ids: tree,
|
|
45
|
+
query,
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
async function activityReached(port, probe, activityId) {
|
|
49
|
+
const ids = [...new Set([probe.id, ...probe.tree])];
|
|
50
|
+
const history = { operationId: "getHistoricActivityInstancesCount", key: "processInstanceId" };
|
|
51
|
+
const [active, ...finished] = await Promise.all([
|
|
52
|
+
countInTree(port, probe.tree, { activityIdIn: activityId }),
|
|
53
|
+
...ids.map((pid) => countByIds(port, { ...history, ids: [pid], query: { activityId } })),
|
|
54
|
+
]);
|
|
55
|
+
return active > 0 || finished.some((count) => count > 0);
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* The jobs the job executor will run: retries left, due, and active. The engine's `executable`
|
|
59
|
+
* filter checks the suspension of the instance only, not of the job (a suspended job definition
|
|
60
|
+
* suspends its jobs), hence `active` (verified on all three engines).
|
|
61
|
+
*/
|
|
62
|
+
export const EXECUTABLE = { executable: "true", active: "true" };
|
|
63
|
+
/** No executable job in the tree; an ended instance has no tree and is idle. */
|
|
64
|
+
async function idle(port, probe) {
|
|
65
|
+
const request = { operationId: "getJobsCount", key: "processInstanceIds", ids: probe.tree };
|
|
66
|
+
return (await countByIds(port, { ...request, query: EXECUTABLE })) === 0;
|
|
67
|
+
}
|
|
68
|
+
async function taskOpen(port, probe, key) {
|
|
69
|
+
const query = key === undefined ? {} : { taskDefinitionKey: key };
|
|
70
|
+
const request = { operationId: "getTasksCount", key: "processInstanceIdIn", ids: probe.tree };
|
|
71
|
+
return (await countByIds(port, { ...request, query })) > 0;
|
|
72
|
+
}
|
|
73
|
+
async function holds(port, probe, condition) {
|
|
74
|
+
switch (condition.kind) {
|
|
75
|
+
case "ended":
|
|
76
|
+
return probe.ended;
|
|
77
|
+
case "incident":
|
|
78
|
+
return false;
|
|
79
|
+
case "idle":
|
|
80
|
+
return idle(port, probe);
|
|
81
|
+
case "task":
|
|
82
|
+
return taskOpen(port, probe, condition.key);
|
|
83
|
+
case "activity":
|
|
84
|
+
return activityReached(port, probe, condition.id);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* The counts of one poll: only what the conditions need, then the incident check. The incident
|
|
89
|
+
* count is read after the condition counts, never in parallel with them: a job that fails for good
|
|
90
|
+
* loses its last retry and gets its incident in one transaction, so a job count that no longer sees
|
|
91
|
+
* the job is followed by an incident count that sees the incident. Read in parallel, the incident
|
|
92
|
+
* count could come from before that transaction and the job count from after it, and the poll
|
|
93
|
+
* would see neither (a stuck instance reported as idle).
|
|
94
|
+
*/
|
|
95
|
+
export async function measure(port, probe, conditions, checkIncidents) {
|
|
96
|
+
const results = await Promise.all(conditions.map((condition) => holds(port, probe, condition)));
|
|
97
|
+
const incidents = checkIncidents
|
|
98
|
+
? await countInTree(port, probe.tree, { withIncident: "true" })
|
|
99
|
+
: 0;
|
|
100
|
+
const held = conditions.filter((_, index) => results[index] === true).map(conditionLabel);
|
|
101
|
+
return { incidents, held };
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* The decision of a poll: the condition `incident` with an incident, then an incident with fail fast
|
|
105
|
+
* (a job that failed for good is not executable, so `idle` would otherwise report success for a
|
|
106
|
+
* stuck instance), then any other condition, then an ended instance.
|
|
107
|
+
*/
|
|
108
|
+
export function decide(conditions, failOnIncident, probe, measurement) {
|
|
109
|
+
const wantsIncident = conditions.some((condition) => condition.kind === "incident");
|
|
110
|
+
if (wantsIncident && measurement.incidents > 0)
|
|
111
|
+
return { kind: "held", until: "incident" };
|
|
112
|
+
if (failOnIncident && measurement.incidents > 0)
|
|
113
|
+
return { kind: "incident" };
|
|
114
|
+
const [until] = measurement.held;
|
|
115
|
+
if (until !== undefined)
|
|
116
|
+
return { kind: "held", until };
|
|
117
|
+
return probe.ended ? { kind: "ended" } : { kind: "pending" };
|
|
118
|
+
}
|
|
119
|
+
//# sourceMappingURL=conditions.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"conditions.js","sourceRoot":"","sources":["../src/conditions.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AAE3C,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAA;AAO1C,uDAAuD;AACvD,MAAM,eAAe,GAAG;IACtB,MAAM;IACN,OAAO;IACP,UAAU;IACV,MAAM;IACN,0BAA0B;IAC1B,uBAAuB;CACxB,CAAA;AAED,SAAS,OAAO,CAAC,GAAW;IAC1B,OAAO,IAAI,aAAa,CAAC,EAAE,IAAI,EAAE,mBAAmB,EAAE,GAAG,EAAE,KAAK,EAAE,eAAe,EAAE,CAAC,CAAA;AACtF,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,GAAW;IACxC,IAAI,GAAG,KAAK,MAAM,IAAI,GAAG,KAAK,OAAO,IAAI,GAAG,KAAK,UAAU,IAAI,GAAG,KAAK,MAAM,EAAE,CAAC;QAC9E,OAAO,EAAE,IAAI,EAAE,GAAG,EAAE,CAAA;IACtB,CAAC;IACD,MAAM,CAAC,MAAM,EAAE,GAAG,IAAI,CAAC,GAAG,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAA;IACxC,MAAM,EAAE,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;IACzB,IAAI,EAAE,KAAK,EAAE,IAAI,CAAC,MAAM,KAAK,MAAM,IAAI,MAAM,KAAK,UAAU,CAAC;QAAE,MAAM,OAAO,CAAC,GAAG,CAAC,CAAA;IACjF,OAAO,MAAM,KAAK,MAAM,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,UAAU,EAAE,EAAE,EAAE,CAAA;AACjF,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,SAAoB;IACjD,QAAQ,SAAS,CAAC,IAAI,EAAE,CAAC;QACvB,KAAK,UAAU;YACb,OAAO,YAAY,SAAS,CAAC,EAAE,EAAE,CAAA;QACnC,KAAK,MAAM;YACT,OAAO,SAAS,CAAC,GAAG,KAAK,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,QAAQ,SAAS,CAAC,GAAG,EAAE,CAAA;QACvE;YACE,OAAO,SAAS,CAAC,IAAI,CAAA;IACzB,CAAC;AACH,CAAC;AAmBD,yFAAyF;AACzF,SAAS,WAAW,CAAC,IAAgB,EAAE,IAAuB,EAAE,KAA6B;IAC3F,OAAO,UAAU,CAAC,IAAI,EAAE;QACtB,WAAW,EAAE,0BAA0B;QACvC,GAAG,EAAE,oBAAoB;QACzB,GAAG,EAAE,IAAI;QACT,KAAK;KACN,CAAC,CAAA;AACJ,CAAC;AAED,KAAK,UAAU,eAAe,CAAC,IAAgB,EAAE,KAAY,EAAE,UAAkB;IAC/E,MAAM,GAAG,GAAG,CAAC,GAAG,IAAI,GAAG,CAAC,CAAC,KAAK,CAAC,EAAE,EAAE,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;IACnD,MAAM,OAAO,GAAG,EAAE,WAAW,EAAE,mCAAmC,EAAE,GAAG,EAAE,mBAAmB,EAAE,CAAA;IAC9F,MAAM,CAAC,MAAM,EAAE,GAAG,QAAQ,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;QAC9C,WAAW,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,EAAE,YAAY,EAAE,UAAU,EAAE,CAAC;QAC3D,GAAG,GAAG,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,UAAU,CAAC,IAAI,EAAE,EAAE,GAAG,OAAO,EAAE,GAAG,EAAE,CAAC,GAAG,CAAC,EAAE,KAAK,EAAE,EAAE,UAAU,EAAE,EAAE,CAAC,CAAC;KACzF,CAAC,CAAA;IACF,OAAO,MAAM,GAAG,CAAC,IAAI,QAAQ,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,GAAG,CAAC,CAAC,CAAA;AAC1D,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,MAAM,UAAU,GAAG,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAW,CAAA;AAEzE,gFAAgF;AAChF,KAAK,UAAU,IAAI,CAAC,IAAgB,EAAE,KAAY;IAChD,MAAM,OAAO,GAAG,EAAE,WAAW,EAAE,cAAc,EAAE,GAAG,EAAE,oBAAoB,EAAE,GAAG,EAAE,KAAK,CAAC,IAAI,EAAE,CAAA;IAC3F,OAAO,CAAC,MAAM,UAAU,CAAC,IAAI,EAAE,EAAE,GAAG,OAAO,EAAE,KAAK,EAAE,UAAU,EAAE,CAAC,CAAC,KAAK,CAAC,CAAA;AAC1E,CAAC;AAED,KAAK,UAAU,QAAQ,CAAC,IAAgB,EAAE,KAAY,EAAE,GAAuB;IAC7E,MAAM,KAAK,GAAG,GAAG,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,iBAAiB,EAAE,GAAG,EAAE,CAAA;IACjE,MAAM,OAAO,GAAG,EAAE,WAAW,EAAE,eAAe,EAAE,GAAG,EAAE,qBAAqB,EAAE,GAAG,EAAE,KAAK,CAAC,IAAI,EAAE,CAAA;IAC7F,OAAO,CAAC,MAAM,UAAU,CAAC,IAAI,EAAE,EAAE,GAAG,OAAO,EAAE,KAAK,EAAE,CAAC,CAAC,GAAG,CAAC,CAAA;AAC5D,CAAC;AAED,KAAK,UAAU,KAAK,CAAC,IAAgB,EAAE,KAAY,EAAE,SAAoB;IACvE,QAAQ,SAAS,CAAC,IAAI,EAAE,CAAC;QACvB,KAAK,OAAO;YACV,OAAO,KAAK,CAAC,KAAK,CAAA;QACpB,KAAK,UAAU;YACb,OAAO,KAAK,CAAA;QACd,KAAK,MAAM;YACT,OAAO,IAAI,CAAC,IAAI,EAAE,KAAK,CAAC,CAAA;QAC1B,KAAK,MAAM;YACT,OAAO,QAAQ,CAAC,IAAI,EAAE,KAAK,EAAE,SAAS,CAAC,GAAG,CAAC,CAAA;QAC7C,KAAK,UAAU;YACb,OAAO,eAAe,CAAC,IAAI,EAAE,KAAK,EAAE,SAAS,CAAC,EAAE,CAAC,CAAA;IACrD,CAAC;AACH,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,CAAC,KAAK,UAAU,OAAO,CAC3B,IAAgB,EAChB,KAAY,EACZ,UAAgC,EAChC,cAAuB;IAEvB,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,EAAE,KAAK,EAAE,SAAS,CAAC,CAAC,CAAC,CAAA;IAC/F,MAAM,SAAS,GAAG,cAAc;QAC9B,CAAC,CAAC,MAAM,WAAW,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,EAAE,YAAY,EAAE,MAAM,EAAE,CAAC;QAC/D,CAAC,CAAC,CAAC,CAAA;IACL,MAAM,IAAI,GAAG,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,KAAK,IAAI,CAAC,CAAC,GAAG,CAAC,cAAc,CAAC,CAAA;IACzF,OAAO,EAAE,SAAS,EAAE,IAAI,EAAE,CAAA;AAC5B,CAAC;AAQD;;;;GAIG;AACH,MAAM,UAAU,MAAM,CACpB,UAAgC,EAChC,cAAuB,EACvB,KAAY,EACZ,WAAwB;IAExB,MAAM,aAAa,GAAG,UAAU,CAAC,IAAI,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,SAAS,CAAC,IAAI,KAAK,UAAU,CAAC,CAAA;IACnF,IAAI,aAAa,IAAI,WAAW,CAAC,SAAS,GAAG,CAAC;QAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,UAAU,EAAE,CAAA;IAC1F,IAAI,cAAc,IAAI,WAAW,CAAC,SAAS,GAAG,CAAC;QAAE,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,CAAA;IAC5E,MAAM,CAAC,KAAK,CAAC,GAAG,WAAW,CAAC,IAAI,CAAA;IAChC,IAAI,KAAK,KAAK,SAAS;QAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,CAAA;IACvD,OAAO,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,CAAA;AAC9D,CAAC"}
|
package/dist/dates.d.ts
ADDED
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Engine dates. CIB seven / Camunda 7 / Operaton parse EVERY date (query
|
|
3
|
+
* filters, request bodies, `Date` variables) with one Java pattern,
|
|
4
|
+
* `yyyy-MM-dd'T'HH:mm:ss.SSSZ`, where `Z` is a `±HHMM` offset. A literal "Z",
|
|
5
|
+
* an offset with a colon, missing milliseconds or a bare date are all 400s.
|
|
6
|
+
* Callers therefore accept ordinary ISO 8601 at their boundary and convert it
|
|
7
|
+
* here, once: one parser, read in one of two {@link DateInputReading}s.
|
|
8
|
+
*
|
|
9
|
+
* The read direction has two readers as well: {@link engineDateMillis} (this
|
|
10
|
+
* parser, an offset required) and {@link engineTime} (`Date.parse`, which also
|
|
11
|
+
* reads an offset-less time, in the local zone). Both are kept as they are
|
|
12
|
+
* until the two readings are aligned (a behaviour change, not a move).
|
|
13
|
+
*/
|
|
14
|
+
/** The relaxed spellings; a time needs its offset. The default of every function here. */
|
|
15
|
+
export declare const OFFSET_REQUIRED = "offset-required";
|
|
16
|
+
/** The strict spellings; a time without an offset is UTC. */
|
|
17
|
+
export declare const UTC_WITHOUT_OFFSET = "utc-without-offset";
|
|
18
|
+
/**
|
|
19
|
+
* How an ISO 8601 date input is read: a closed set, one reading per interface today (the MCP
|
|
20
|
+
* tools {@link OFFSET_REQUIRED}, the CLI {@link UTC_WITHOUT_OFFSET}). Each keeps its reading until
|
|
21
|
+
* one is chosen for all of them (a behaviour change); its two rules stay internal.
|
|
22
|
+
*/
|
|
23
|
+
export type DateInputReading = typeof OFFSET_REQUIRED | typeof UTC_WITHOUT_OFFSET;
|
|
24
|
+
/** Example of the accepted input forms of {@link OFFSET_REQUIRED}, for error messages and descriptions. */
|
|
25
|
+
export declare const ENGINE_DATE_INPUT_FORMS = "ISO 8601: a date (2026-10-01, midnight UTC) or a date-time with offset (2026-10-01T08:30:00Z, 2026-10-01T08:30:00.000+02:00)";
|
|
26
|
+
/** Whether `input` is an ISO 8601 date the reading can convert. */
|
|
27
|
+
export declare function isEngineDateInput(input: string, reading?: DateInputReading): boolean;
|
|
28
|
+
/** The engine format of an ISO 8601 date input; undefined when the reading refuses it. */
|
|
29
|
+
export declare function engineDateInput(input: string, reading?: DateInputReading): string | undefined;
|
|
30
|
+
/**
|
|
31
|
+
* ISO 8601 (or a `Date`) → the engine's `yyyy-MM-dd'T'HH:mm:ss.SSS±HHMM`.
|
|
32
|
+
* A string keeps its own offset (`Z` becomes `+0000`), so the instant is
|
|
33
|
+
* unchanged; a bare date means midnight UTC; a `Date` is written in UTC.
|
|
34
|
+
* Throws a `RangeError` naming the accepted forms for anything else
|
|
35
|
+
* (read as {@link OFFSET_REQUIRED}).
|
|
36
|
+
*/
|
|
37
|
+
export declare function toEngineDate(input: string | Date): string;
|
|
38
|
+
/** {@link toEngineDate} for optional filters: `undefined` stays `undefined`. */
|
|
39
|
+
export declare function toOptionalEngineDate(input: string | undefined): string | undefined;
|
|
40
|
+
/**
|
|
41
|
+
* The read direction: a timestamp the engine EMITS (`…SSS±HHMM`, its local
|
|
42
|
+
* offset) → epoch millis; null when absent or unparseable. Engine timestamps
|
|
43
|
+
* order by instant, never as text: across a DST change the engine stamps
|
|
44
|
+
* `…+0200` and `…+0100`, and the string order is then off by up to an hour.
|
|
45
|
+
*/
|
|
46
|
+
export declare function engineDateMillis(value: string | null | undefined): number | null;
|
|
47
|
+
/** The newest of the given engine timestamps by instant (as given); null when none parses. */
|
|
48
|
+
export declare function latestEngineDate(values: Iterable<string | null | undefined>): string | null;
|
|
49
|
+
/** The oldest of the given engine timestamps by instant (as given); null when none parses. */
|
|
50
|
+
export declare function earliestEngineDate(values: Iterable<string | null | undefined>): string | null;
|
|
51
|
+
/**
|
|
52
|
+
* Milliseconds of an engine timestamp (`2024-05-01T10:00:00.000+0200`), or undefined. Read by
|
|
53
|
+
* `Date.parse`: unlike {@link engineDateMillis} it also reads a time without an offset (in the
|
|
54
|
+
* local zone).
|
|
55
|
+
*/
|
|
56
|
+
export declare function engineTime(value: string | undefined): number | undefined;
|
|
57
|
+
/** An instant in the engine format, in UTC: `2024-05-01T08:00:00.000+0000`. */
|
|
58
|
+
export declare function engineFormat(ms: number): string;
|
|
59
|
+
//# sourceMappingURL=dates.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dates.d.ts","sourceRoot":"","sources":["../src/dates.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,0FAA0F;AAC1F,eAAO,MAAM,eAAe,oBAAoB,CAAA;AAEhD,6DAA6D;AAC7D,eAAO,MAAM,kBAAkB,uBAAuB,CAAA;AAEtD;;;;GAIG;AACH,MAAM,MAAM,gBAAgB,GAAG,OAAO,eAAe,GAAG,OAAO,kBAAkB,CAAA;AAwBjF,2GAA2G;AAC3G,eAAO,MAAM,uBAAuB,iIAC4F,CAAA;AAuGhI,mEAAmE;AACnE,wBAAgB,iBAAiB,CAC/B,KAAK,EAAE,MAAM,EACb,OAAO,GAAE,gBAAkC,GAC1C,OAAO,CAET;AAED,0FAA0F;AAC1F,wBAAgB,eAAe,CAC7B,KAAK,EAAE,MAAM,EACb,OAAO,GAAE,gBAAkC,GAC1C,MAAM,GAAG,SAAS,CAMpB;AAED;;;;;;GAMG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,MAAM,CAUzD;AAED,gFAAgF;AAChF,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS,CAElF;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,MAAM,GAAG,IAAI,CAgBhF;AAiBD,8FAA8F;AAC9F,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,QAAQ,CAAC,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC,GAAG,MAAM,GAAG,IAAI,CAE3F;AAED,8FAA8F;AAC9F,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,QAAQ,CAAC,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC,GAAG,MAAM,GAAG,IAAI,CAE7F;AAKD;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS,CAIxE;AAED,+EAA+E;AAC/E,wBAAgB,YAAY,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,CAE/C"}
|