@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/dist/port.js
ADDED
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The engine port of the Camunda 7 REST API family: the operations a workflow sends, by the
|
|
3
|
+
* operation ids of the REST API, and the read rules every caller shares (paging, missing
|
|
4
|
+
* resources, text answers). A caller supplies the transport; vendors are its runtime config.
|
|
5
|
+
*/
|
|
6
|
+
import { records } from "./records.js";
|
|
7
|
+
/** Most parallel requests of one round. */
|
|
8
|
+
export const PARALLEL = 8;
|
|
9
|
+
const PAGE_SIZE = 500;
|
|
10
|
+
/**
|
|
11
|
+
* An engine 404 that names a missing resource: status 404 with an engine exception type other than
|
|
12
|
+
* NotFoundException (JAX-RS: no such endpoint, a wrong REST root) and QueryParamException (an
|
|
13
|
+
* unreadable query value).
|
|
14
|
+
*/
|
|
15
|
+
export function isMissing(failure) {
|
|
16
|
+
const type = failure?.engineType;
|
|
17
|
+
return (failure?.status === 404 &&
|
|
18
|
+
type !== undefined &&
|
|
19
|
+
type !== "NotFoundException" &&
|
|
20
|
+
type !== "QueryParamException");
|
|
21
|
+
}
|
|
22
|
+
/** The query of a page of `list`. */
|
|
23
|
+
export function pageQuery(query, first, size) {
|
|
24
|
+
return { ...query, firstResult: String(first), maxResults: String(size) };
|
|
25
|
+
}
|
|
26
|
+
/** Page size of the next page: one item more than `cap` in total tells whether more exist. */
|
|
27
|
+
function pageSize(loaded, cap) {
|
|
28
|
+
return Math.min(PAGE_SIZE, cap + 1 - loaded);
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* The port over `transport`: a plain object of closures, never a class instance, so a caller can
|
|
32
|
+
* spread it and add its own methods.
|
|
33
|
+
*/
|
|
34
|
+
export function createEnginePort(transport) {
|
|
35
|
+
const missing = (error) => isMissing(transport.failure(error));
|
|
36
|
+
return {
|
|
37
|
+
async json(operationId, input) {
|
|
38
|
+
return transport.json(await transport.send(operationId, input));
|
|
39
|
+
},
|
|
40
|
+
failure: (error) => transport.failure(error),
|
|
41
|
+
async find(operationId, input) {
|
|
42
|
+
try {
|
|
43
|
+
return transport.json(await transport.send(operationId, input));
|
|
44
|
+
}
|
|
45
|
+
catch (error) {
|
|
46
|
+
if (missing(error))
|
|
47
|
+
return undefined;
|
|
48
|
+
throw error;
|
|
49
|
+
}
|
|
50
|
+
},
|
|
51
|
+
async list(operationId, query, cap = Number.POSITIVE_INFINITY) {
|
|
52
|
+
const items = [];
|
|
53
|
+
for (let size = pageSize(0, cap);; size = pageSize(items.length, cap)) {
|
|
54
|
+
const input = { pathArgs: [], query: pageQuery(query, items.length, size) };
|
|
55
|
+
const page = records(transport.json(await transport.send(operationId, input)));
|
|
56
|
+
for (const item of page)
|
|
57
|
+
items.push(item);
|
|
58
|
+
// a page of a different size is the last one (shorter, or the engine ignored the paging)
|
|
59
|
+
if (page.length !== size || items.length > cap)
|
|
60
|
+
break;
|
|
61
|
+
}
|
|
62
|
+
return { items: items.slice(0, cap), truncated: items.length > cap };
|
|
63
|
+
},
|
|
64
|
+
async text(operationId, pathArgs) {
|
|
65
|
+
try {
|
|
66
|
+
const text = transport.text(await transport.send(operationId, { pathArgs, query: {} }));
|
|
67
|
+
return text !== undefined && text.trim() !== "" ? text : undefined;
|
|
68
|
+
}
|
|
69
|
+
catch (error) {
|
|
70
|
+
if (missing(error))
|
|
71
|
+
return undefined;
|
|
72
|
+
throw error;
|
|
73
|
+
}
|
|
74
|
+
},
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* At most `limit` requests in flight: the rounds of a workflow may start more at once, the
|
|
79
|
+
* others wait for a free slot (a released slot passes straight to the next waiter).
|
|
80
|
+
*/
|
|
81
|
+
export class Slots {
|
|
82
|
+
limit;
|
|
83
|
+
active = 0;
|
|
84
|
+
waiting = [];
|
|
85
|
+
constructor(limit = PARALLEL) {
|
|
86
|
+
this.limit = limit;
|
|
87
|
+
}
|
|
88
|
+
async acquire() {
|
|
89
|
+
if (this.active < this.limit) {
|
|
90
|
+
this.active += 1;
|
|
91
|
+
return;
|
|
92
|
+
}
|
|
93
|
+
await new Promise((resolve) => this.waiting.push(resolve));
|
|
94
|
+
}
|
|
95
|
+
release() {
|
|
96
|
+
const next = this.waiting.shift();
|
|
97
|
+
if (next === undefined)
|
|
98
|
+
this.active -= 1;
|
|
99
|
+
else
|
|
100
|
+
next();
|
|
101
|
+
}
|
|
102
|
+
/** Runs `fn` in a slot: waits for one, frees it when `fn` settles. */
|
|
103
|
+
async run(fn) {
|
|
104
|
+
await this.acquire();
|
|
105
|
+
try {
|
|
106
|
+
return await fn();
|
|
107
|
+
}
|
|
108
|
+
finally {
|
|
109
|
+
this.release();
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
//# sourceMappingURL=port.js.map
|
package/dist/port.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"port.js","sourceRoot":"","sources":["../src/port.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Typed reads of engine response objects (DTOs) and their order (timestamps read in dates.ts). The workflow commands
|
|
3
|
+
* never trust the shape of a response: a missing or mistyped property reads as undefined. Pure.
|
|
4
|
+
*/
|
|
5
|
+
/** An engine DTO. */
|
|
6
|
+
export type Rec = Readonly<Record<string, unknown>>;
|
|
7
|
+
/** The objects of a JSON array (anything else gives an empty list). */
|
|
8
|
+
export declare function records(value: unknown): Rec[];
|
|
9
|
+
/** A non-empty string property. */
|
|
10
|
+
export declare function str(record: Rec | undefined, key: string): string | undefined;
|
|
11
|
+
/** A string property, or an empty string when it is missing (identifiers the engine always sends). */
|
|
12
|
+
export declare function field(record: Rec | undefined, key: string): string;
|
|
13
|
+
/** A number property (also a BigInt of `parseJson`, as a number). */
|
|
14
|
+
export declare function num(record: Rec | undefined, key: string): number | undefined;
|
|
15
|
+
/** A number property, or 0 when it is missing (counts). */
|
|
16
|
+
export declare function amount(record: Rec | undefined, key: string): number;
|
|
17
|
+
/** True only for a boolean `true`. */
|
|
18
|
+
export declare function yes(record: Rec | undefined, key: string): boolean;
|
|
19
|
+
/** `count` of a `CountResultDto`, 0 when absent. */
|
|
20
|
+
export declare function countOf(value: unknown): number;
|
|
21
|
+
/** The key part of a process definition id (`order:3:1f2...` → `order`). */
|
|
22
|
+
export declare function definitionKeyOf(definitionId: string | undefined): string | undefined;
|
|
23
|
+
/** Ordinal string order, independent of the locale. */
|
|
24
|
+
export declare function compareText(left: string, right: string): number;
|
|
25
|
+
/** Order of optional timestamps: earlier first, missing ones last. */
|
|
26
|
+
export declare function compareTime(left: string | undefined, right: string | undefined): number;
|
|
27
|
+
//# sourceMappingURL=records.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"records.d.ts","sourceRoot":"","sources":["../src/records.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAKH,qBAAqB;AACrB,MAAM,MAAM,GAAG,GAAG,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAA;AAEnD,uEAAuE;AACvE,wBAAgB,OAAO,CAAC,KAAK,EAAE,OAAO,GAAG,GAAG,EAAE,CAE7C;AAED,mCAAmC;AACnC,wBAAgB,GAAG,CAAC,MAAM,EAAE,GAAG,GAAG,SAAS,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAG5E;AAED,sGAAsG;AACtG,wBAAgB,KAAK,CAAC,MAAM,EAAE,GAAG,GAAG,SAAS,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAElE;AAED,qEAAqE;AACrE,wBAAgB,GAAG,CAAC,MAAM,EAAE,GAAG,GAAG,SAAS,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAI5E;AAED,2DAA2D;AAC3D,wBAAgB,MAAM,CAAC,MAAM,EAAE,GAAG,GAAG,SAAS,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAEnE;AAED,sCAAsC;AACtC,wBAAgB,GAAG,CAAC,MAAM,EAAE,GAAG,GAAG,SAAS,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAEjE;AAED,oDAAoD;AACpD,wBAAgB,OAAO,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAE9C;AAED,4EAA4E;AAC5E,wBAAgB,eAAe,CAAC,YAAY,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS,CAGpF;AAED,uDAAuD;AACvD,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAG/D;AAED,sEAAsE;AACtE,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,EAAE,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,CAKvF"}
|
package/dist/records.js
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Typed reads of engine response objects (DTOs) and their order (timestamps read in dates.ts). The workflow commands
|
|
3
|
+
* never trust the shape of a response: a missing or mistyped property reads as undefined. Pure.
|
|
4
|
+
*/
|
|
5
|
+
import { engineTime } from "./dates.js";
|
|
6
|
+
import { isRecord } from "./util.js";
|
|
7
|
+
/** The objects of a JSON array (anything else gives an empty list). */
|
|
8
|
+
export function records(value) {
|
|
9
|
+
return Array.isArray(value) ? value.filter(isRecord) : [];
|
|
10
|
+
}
|
|
11
|
+
/** A non-empty string property. */
|
|
12
|
+
export function str(record, key) {
|
|
13
|
+
const value = record?.[key];
|
|
14
|
+
return typeof value === "string" && value !== "" ? value : undefined;
|
|
15
|
+
}
|
|
16
|
+
/** A string property, or an empty string when it is missing (identifiers the engine always sends). */
|
|
17
|
+
export function field(record, key) {
|
|
18
|
+
return str(record, key) ?? "";
|
|
19
|
+
}
|
|
20
|
+
/** A number property (also a BigInt of `parseJson`, as a number). */
|
|
21
|
+
export function num(record, key) {
|
|
22
|
+
const value = record?.[key];
|
|
23
|
+
if (typeof value === "bigint")
|
|
24
|
+
return Number(value);
|
|
25
|
+
return typeof value === "number" ? value : undefined;
|
|
26
|
+
}
|
|
27
|
+
/** A number property, or 0 when it is missing (counts). */
|
|
28
|
+
export function amount(record, key) {
|
|
29
|
+
return num(record, key) ?? 0;
|
|
30
|
+
}
|
|
31
|
+
/** True only for a boolean `true`. */
|
|
32
|
+
export function yes(record, key) {
|
|
33
|
+
return record?.[key] === true;
|
|
34
|
+
}
|
|
35
|
+
/** `count` of a `CountResultDto`, 0 when absent. */
|
|
36
|
+
export function countOf(value) {
|
|
37
|
+
return isRecord(value) ? amount(value, "count") : 0;
|
|
38
|
+
}
|
|
39
|
+
/** The key part of a process definition id (`order:3:1f2...` → `order`). */
|
|
40
|
+
export function definitionKeyOf(definitionId) {
|
|
41
|
+
const key = definitionId?.split(":")[0] ?? "";
|
|
42
|
+
return key === "" ? undefined : key;
|
|
43
|
+
}
|
|
44
|
+
/** Ordinal string order, independent of the locale. */
|
|
45
|
+
export function compareText(left, right) {
|
|
46
|
+
if (left < right)
|
|
47
|
+
return -1;
|
|
48
|
+
return left > right ? 1 : 0;
|
|
49
|
+
}
|
|
50
|
+
/** Order of optional timestamps: earlier first, missing ones last. */
|
|
51
|
+
export function compareTime(left, right) {
|
|
52
|
+
const a = engineTime(left) ?? Number.POSITIVE_INFINITY;
|
|
53
|
+
const b = engineTime(right) ?? Number.POSITIVE_INFINITY;
|
|
54
|
+
if (a === b)
|
|
55
|
+
return 0;
|
|
56
|
+
return a < b ? -1 : 1;
|
|
57
|
+
}
|
|
58
|
+
//# sourceMappingURL=records.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"records.js","sourceRoot":"","sources":["../src/records.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAA;AACvC,OAAO,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAA;AAKpC,uEAAuE;AACvE,MAAM,UAAU,OAAO,CAAC,KAAc;IACpC,OAAO,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAE,KAAmB,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,EAAE,CAAA;AAC1E,CAAC;AAED,mCAAmC;AACnC,MAAM,UAAU,GAAG,CAAC,MAAuB,EAAE,GAAW;IACtD,MAAM,KAAK,GAAG,MAAM,EAAE,CAAC,GAAG,CAAC,CAAA;IAC3B,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAA;AACtE,CAAC;AAED,sGAAsG;AACtG,MAAM,UAAU,KAAK,CAAC,MAAuB,EAAE,GAAW;IACxD,OAAO,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,IAAI,EAAE,CAAA;AAC/B,CAAC;AAED,qEAAqE;AACrE,MAAM,UAAU,GAAG,CAAC,MAAuB,EAAE,GAAW;IACtD,MAAM,KAAK,GAAG,MAAM,EAAE,CAAC,GAAG,CAAC,CAAA;IAC3B,IAAI,OAAO,KAAK,KAAK,QAAQ;QAAE,OAAO,MAAM,CAAC,KAAK,CAAC,CAAA;IACnD,OAAO,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAA;AACtD,CAAC;AAED,2DAA2D;AAC3D,MAAM,UAAU,MAAM,CAAC,MAAuB,EAAE,GAAW;IACzD,OAAO,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,IAAI,CAAC,CAAA;AAC9B,CAAC;AAED,sCAAsC;AACtC,MAAM,UAAU,GAAG,CAAC,MAAuB,EAAE,GAAW;IACtD,OAAO,MAAM,EAAE,CAAC,GAAG,CAAC,KAAK,IAAI,CAAA;AAC/B,CAAC;AAED,oDAAoD;AACpD,MAAM,UAAU,OAAO,CAAC,KAAc;IACpC,OAAO,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;AACrD,CAAC;AAED,4EAA4E;AAC5E,MAAM,UAAU,eAAe,CAAC,YAAgC;IAC9D,MAAM,GAAG,GAAG,YAAY,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAA;IAC7C,OAAO,GAAG,KAAK,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,GAAG,CAAA;AACrC,CAAC;AAED,uDAAuD;AACvD,MAAM,UAAU,WAAW,CAAC,IAAY,EAAE,KAAa;IACrD,IAAI,IAAI,GAAG,KAAK;QAAE,OAAO,CAAC,CAAC,CAAA;IAC3B,OAAO,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;AAC7B,CAAC;AAED,sEAAsE;AACtE,MAAM,UAAU,WAAW,CAAC,IAAwB,EAAE,KAAyB;IAC7E,MAAM,CAAC,GAAG,UAAU,CAAC,IAAI,CAAC,IAAI,MAAM,CAAC,iBAAiB,CAAA;IACtD,MAAM,CAAC,GAAG,UAAU,CAAC,KAAK,CAAC,IAAI,MAAM,CAAC,iBAAiB,CAAA;IACvD,IAAI,CAAC,KAAK,CAAC;QAAE,OAAO,CAAC,CAAA;IACrB,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;AACvB,CAAC"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/** Requests over id lists: chunks of 50 ids, at most `PARALLEL` at a time. */
|
|
2
|
+
import { type EnginePort, type OperationInput, type Query } from "./port.js";
|
|
3
|
+
import { type Rec } from "./records.js";
|
|
4
|
+
/** Ids per request of a query parameter that takes a comma separated list (URL length). */
|
|
5
|
+
export declare const ID_CHUNK = 50;
|
|
6
|
+
/** A request without path arguments. */
|
|
7
|
+
export declare function queryInput(query: Query): OperationInput;
|
|
8
|
+
/** A list or count request over an id list (`processInstanceIds`, ...): `key` takes the ids. */
|
|
9
|
+
export interface IdRequest {
|
|
10
|
+
readonly operationId: string;
|
|
11
|
+
readonly key: string;
|
|
12
|
+
readonly ids: readonly string[];
|
|
13
|
+
readonly query?: Query;
|
|
14
|
+
/** Items per chunk at most (lists only). */
|
|
15
|
+
readonly cap?: number;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* The summed `count` of a count operation over an id list, sent in chunks of 50 ids; no ids give
|
|
19
|
+
* 0 without a request.
|
|
20
|
+
*/
|
|
21
|
+
export declare function countByIds(port: EnginePort, request: IdRequest): Promise<number>;
|
|
22
|
+
/** The items of a list operation over an id list, chunked like `countByIds` and concatenated. */
|
|
23
|
+
export declare function listByIds(port: EnginePort, request: IdRequest): Promise<Rec[]>;
|
|
24
|
+
//# sourceMappingURL=requests.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"requests.d.ts","sourceRoot":"","sources":["../src/requests.ts"],"names":[],"mappings":"AAAA,8EAA8E;AAE9E,OAAO,EAAE,KAAK,UAAU,EAAE,KAAK,cAAc,EAAY,KAAK,KAAK,EAAE,MAAM,WAAW,CAAA;AACtF,OAAO,EAAW,KAAK,GAAG,EAAE,MAAM,cAAc,CAAA;AAGhD,2FAA2F;AAC3F,eAAO,MAAM,QAAQ,KAAK,CAAA;AAE1B,wCAAwC;AACxC,wBAAgB,UAAU,CAAC,KAAK,EAAE,KAAK,GAAG,cAAc,CAEvD;AAWD,gGAAgG;AAChG,MAAM,WAAW,SAAS;IACxB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAA;IAC5B,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;IACpB,QAAQ,CAAC,GAAG,EAAE,SAAS,MAAM,EAAE,CAAA;IAC/B,QAAQ,CAAC,KAAK,CAAC,EAAE,KAAK,CAAA;IACtB,4CAA4C;IAC5C,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAA;CACtB;AAED;;;GAGG;AACH,wBAAsB,UAAU,CAAC,IAAI,EAAE,UAAU,EAAE,OAAO,EAAE,SAAS,GAAG,OAAO,CAAC,MAAM,CAAC,CAMtF;AAED,iGAAiG;AACjG,wBAAsB,SAAS,CAAC,IAAI,EAAE,UAAU,EAAE,OAAO,EAAE,SAAS,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC,CAKpF"}
|
package/dist/requests.js
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/** Requests over id lists: chunks of 50 ids, at most `PARALLEL` at a time. */
|
|
2
|
+
import { PARALLEL } from "./port.js";
|
|
3
|
+
import { countOf } from "./records.js";
|
|
4
|
+
import { mapLimit } from "./util.js";
|
|
5
|
+
/** Ids per request of a query parameter that takes a comma separated list (URL length). */
|
|
6
|
+
export const ID_CHUNK = 50;
|
|
7
|
+
/** A request without path arguments. */
|
|
8
|
+
export function queryInput(query) {
|
|
9
|
+
return { pathArgs: [], query };
|
|
10
|
+
}
|
|
11
|
+
/** `ids` in chunks of `ID_CHUNK`, each joined with commas. */
|
|
12
|
+
function idChunks(ids) {
|
|
13
|
+
const chunks = [];
|
|
14
|
+
for (let start = 0; start < ids.length; start += ID_CHUNK) {
|
|
15
|
+
chunks.push(ids.slice(start, start + ID_CHUNK).join(","));
|
|
16
|
+
}
|
|
17
|
+
return chunks;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* The summed `count` of a count operation over an id list, sent in chunks of 50 ids; no ids give
|
|
21
|
+
* 0 without a request.
|
|
22
|
+
*/
|
|
23
|
+
export async function countByIds(port, request) {
|
|
24
|
+
const counts = await mapLimit(idChunks(request.ids), PARALLEL, async (chunk) => {
|
|
25
|
+
const query = { ...request.query, [request.key]: chunk };
|
|
26
|
+
return countOf(await port.json(request.operationId, queryInput(query)));
|
|
27
|
+
});
|
|
28
|
+
return counts.reduce((sum, count) => sum + count, 0);
|
|
29
|
+
}
|
|
30
|
+
/** The items of a list operation over an id list, chunked like `countByIds` and concatenated. */
|
|
31
|
+
export async function listByIds(port, request) {
|
|
32
|
+
const pages = await mapLimit(idChunks(request.ids), PARALLEL, async (chunk) => port.list(request.operationId, { ...request.query, [request.key]: chunk }, request.cap));
|
|
33
|
+
return pages.flatMap((page) => page.items);
|
|
34
|
+
}
|
|
35
|
+
//# sourceMappingURL=requests.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"requests.js","sourceRoot":"","sources":["../src/requests.ts"],"names":[],"mappings":"AAAA,8EAA8E;AAE9E,OAAO,EAAwC,QAAQ,EAAc,MAAM,WAAW,CAAA;AACtF,OAAO,EAAE,OAAO,EAAY,MAAM,cAAc,CAAA;AAChD,OAAO,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAA;AAEpC,2FAA2F;AAC3F,MAAM,CAAC,MAAM,QAAQ,GAAG,EAAE,CAAA;AAE1B,wCAAwC;AACxC,MAAM,UAAU,UAAU,CAAC,KAAY;IACrC,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,KAAK,EAAE,CAAA;AAChC,CAAC;AAED,8DAA8D;AAC9D,SAAS,QAAQ,CAAC,GAAsB;IACtC,MAAM,MAAM,GAAa,EAAE,CAAA;IAC3B,KAAK,IAAI,KAAK,GAAG,CAAC,EAAE,KAAK,GAAG,GAAG,CAAC,MAAM,EAAE,KAAK,IAAI,QAAQ,EAAE,CAAC;QAC1D,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,EAAE,KAAK,GAAG,QAAQ,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAA;IAC3D,CAAC;IACD,OAAO,MAAM,CAAA;AACf,CAAC;AAYD;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,IAAgB,EAAE,OAAkB;IACnE,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,QAAQ,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE;QAC7E,MAAM,KAAK,GAAG,EAAE,GAAG,OAAO,CAAC,KAAK,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,KAAK,EAAE,CAAA;QACxD,OAAO,OAAO,CAAC,MAAM,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,WAAW,EAAE,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC,CAAA;IACzE,CAAC,CAAC,CAAA;IACF,OAAO,MAAM,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,KAAK,EAAE,EAAE,CAAC,GAAG,GAAG,KAAK,EAAE,CAAC,CAAC,CAAA;AACtD,CAAC;AAED,iGAAiG;AACjG,MAAM,CAAC,KAAK,UAAU,SAAS,CAAC,IAAgB,EAAE,OAAkB;IAClE,MAAM,KAAK,GAAG,MAAM,QAAQ,CAAC,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,QAAQ,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE,CAC5E,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,WAAW,EAAE,EAAE,GAAG,OAAO,CAAC,KAAK,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,KAAK,EAAE,EAAE,OAAO,CAAC,GAAG,CAAC,CACxF,CAAA;IACD,OAAO,KAAK,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;AAC5C,CAAC"}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Planning of retry: the selection mode, the root cause incidents to retry and the requests per
|
|
3
|
+
* incident type. Pure.
|
|
4
|
+
*/
|
|
5
|
+
import type { PlannedWrite } from "./port.js";
|
|
6
|
+
import { type Rec } from "./records.js";
|
|
7
|
+
import type { Selection } from "./types.js";
|
|
8
|
+
export type RetryMode = "instance" | "incidents" | "definition";
|
|
9
|
+
/** The selection mode: exactly one of instance, incidents and definition. */
|
|
10
|
+
export declare function retryMode(selection: Selection, incidentIds: readonly string[]): RetryMode;
|
|
11
|
+
/** Retrying every incident of a definition is a bulk operation. */
|
|
12
|
+
export declare function retryEffect(mode: RetryMode): "write" | "bulk";
|
|
13
|
+
/** A root cause incident and what retry does about it. */
|
|
14
|
+
export interface PlanEntry {
|
|
15
|
+
readonly incidentId: string;
|
|
16
|
+
readonly type: string;
|
|
17
|
+
readonly activityId: string;
|
|
18
|
+
readonly processInstanceId: string;
|
|
19
|
+
readonly message?: string;
|
|
20
|
+
readonly jobId?: string;
|
|
21
|
+
readonly externalTaskId?: string;
|
|
22
|
+
/** `job`, `externalTask`, or `skip` for incident types retry cannot fix. */
|
|
23
|
+
readonly action: "job" | "externalTask" | "skip";
|
|
24
|
+
}
|
|
25
|
+
/** Root cause ids of propagated incidents that were not loaded. */
|
|
26
|
+
export declare function missingRoots(incidents: readonly Rec[]): string[];
|
|
27
|
+
export interface RetryFilter {
|
|
28
|
+
readonly activityId?: string;
|
|
29
|
+
readonly incidentType?: string;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* The root causes of the incidents (propagated ones replaced by their loaded root cause,
|
|
33
|
+
* deduplicated), filtered by activity and type, by time and id.
|
|
34
|
+
*/
|
|
35
|
+
export declare function planRetry(incidents: readonly Rec[], filter: RetryFilter): PlanEntry[];
|
|
36
|
+
/** Too many incidents to retry one by one: refused before any write. */
|
|
37
|
+
export declare function checkRetryCount(entries: readonly PlanEntry[], truncated: boolean, key: string | undefined): void;
|
|
38
|
+
/** The retries request of an entry; undefined for skipped ones. */
|
|
39
|
+
export declare function retriesWrite(entry: PlanEntry, retries: number): PlannedWrite | undefined;
|
|
40
|
+
/** The execute request of a job entry (retry now). */
|
|
41
|
+
export declare function executeWrite(entry: PlanEntry): PlannedWrite | undefined;
|
|
42
|
+
/** What to do about an incident retry cannot fix: resolve it. */
|
|
43
|
+
export interface SkipStep {
|
|
44
|
+
readonly action: "resolveIncident";
|
|
45
|
+
readonly incidentId: string;
|
|
46
|
+
}
|
|
47
|
+
/** The plan a preview shows: counts per kind and the skipped incidents. */
|
|
48
|
+
export declare function retryPlanView(mode: RetryMode, entries: readonly PlanEntry[]): {
|
|
49
|
+
mode: RetryMode;
|
|
50
|
+
incidents: number;
|
|
51
|
+
jobs: number;
|
|
52
|
+
externalTasks: number;
|
|
53
|
+
skipped: {
|
|
54
|
+
incidentId: string;
|
|
55
|
+
type: string;
|
|
56
|
+
next: {
|
|
57
|
+
action: "resolveIncident";
|
|
58
|
+
incidentId: string;
|
|
59
|
+
};
|
|
60
|
+
}[];
|
|
61
|
+
};
|
|
62
|
+
//# sourceMappingURL=retry-plan.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"retry-plan.d.ts","sourceRoot":"","sources":["../src/retry-plan.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,WAAW,CAAA;AAC7C,OAAO,EAAmC,KAAK,GAAG,EAAO,MAAM,cAAc,CAAA;AAC7E,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAA;AAG3C,MAAM,MAAM,SAAS,GAAG,UAAU,GAAG,WAAW,GAAG,YAAY,CAAA;AAK/D,6EAA6E;AAC7E,wBAAgB,SAAS,CAAC,SAAS,EAAE,SAAS,EAAE,WAAW,EAAE,SAAS,MAAM,EAAE,GAAG,SAAS,CAYzF;AAED,mEAAmE;AACnE,wBAAgB,WAAW,CAAC,IAAI,EAAE,SAAS,GAAG,OAAO,GAAG,MAAM,CAE7D;AAED,0DAA0D;AAC1D,MAAM,WAAW,SAAS;IACxB,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAA;IAC3B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAA;IAC3B,QAAQ,CAAC,iBAAiB,EAAE,MAAM,CAAA;IAClC,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAA;IACzB,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAA;IACvB,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,CAAA;IAChC,4EAA4E;IAC5E,QAAQ,CAAC,MAAM,EAAE,KAAK,GAAG,cAAc,GAAG,MAAM,CAAA;CACjD;AAMD,mEAAmE;AACnE,wBAAgB,YAAY,CAAC,SAAS,EAAE,SAAS,GAAG,EAAE,GAAG,MAAM,EAAE,CAMhE;AAgCD,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAA;IAC5B,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAA;CAC/B;AAED;;;GAGG;AACH,wBAAgB,SAAS,CAAC,SAAS,EAAE,SAAS,GAAG,EAAE,EAAE,MAAM,EAAE,WAAW,GAAG,SAAS,EAAE,CAsBrF;AAED,wEAAwE;AACxE,wBAAgB,eAAe,CAC7B,OAAO,EAAE,SAAS,SAAS,EAAE,EAC7B,SAAS,EAAE,OAAO,EAClB,GAAG,EAAE,MAAM,GAAG,SAAS,GACtB,IAAI,CAQN;AAED,mEAAmE;AACnE,wBAAgB,YAAY,CAAC,KAAK,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,GAAG,YAAY,GAAG,SAAS,CAexF;AAED,sDAAsD;AACtD,wBAAgB,YAAY,CAAC,KAAK,EAAE,SAAS,GAAG,YAAY,GAAG,SAAS,CAOvE;AAED,iEAAiE;AACjE,MAAM,WAAW,QAAQ;IACvB,QAAQ,CAAC,MAAM,EAAE,iBAAiB,CAAA;IAClC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAA;CAC5B;AAED,2EAA2E;AAC3E,wBAAgB,aAAa,CAAC,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,SAAS,SAAS,EAAE;;;;;;;;;;;;;EAa3E"}
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Planning of retry: the selection mode, the root cause incidents to retry and the requests per
|
|
3
|
+
* incident type. Pure.
|
|
4
|
+
*/
|
|
5
|
+
import { WorkflowError } from "./errors.js";
|
|
6
|
+
import { incidentRecovery } from "./incident-recovery.js";
|
|
7
|
+
import { compareText, compareTime, field, str } from "./records.js";
|
|
8
|
+
import { compact } from "./util.js";
|
|
9
|
+
/** More retryable incidents than this are pointed to the asynchronous bulk operations. */
|
|
10
|
+
const MAX_RETRIES = 1000;
|
|
11
|
+
/** The selection mode: exactly one of instance, incidents and definition. */
|
|
12
|
+
export function retryMode(selection, incidentIds) {
|
|
13
|
+
const instance = selection.id !== undefined || selection.businessKey !== undefined || selection.latest;
|
|
14
|
+
if (incidentIds.length > 0) {
|
|
15
|
+
if (instance || selection.processDefinitionKey !== undefined) {
|
|
16
|
+
throw new WorkflowError({ kind: "retry-selection-conflict" });
|
|
17
|
+
}
|
|
18
|
+
return "incidents";
|
|
19
|
+
}
|
|
20
|
+
if (instance)
|
|
21
|
+
return "instance";
|
|
22
|
+
if (selection.processDefinitionKey !== undefined)
|
|
23
|
+
return "definition";
|
|
24
|
+
throw new WorkflowError({ kind: "retry-selection-missing" });
|
|
25
|
+
}
|
|
26
|
+
/** Retrying every incident of a definition is a bulk operation. */
|
|
27
|
+
export function retryEffect(mode) {
|
|
28
|
+
return mode === "definition" ? "bulk" : "write";
|
|
29
|
+
}
|
|
30
|
+
function isRoot(incident) {
|
|
31
|
+
return str(incident, "id") === str(incident, "rootCauseIncidentId");
|
|
32
|
+
}
|
|
33
|
+
/** Root cause ids of propagated incidents that were not loaded. */
|
|
34
|
+
export function missingRoots(incidents) {
|
|
35
|
+
const loaded = new Set(incidents.map((incident) => str(incident, "id")));
|
|
36
|
+
const roots = incidents.flatMap((incident) => isRoot(incident) ? [] : (str(incident, "rootCauseIncidentId") ?? []));
|
|
37
|
+
return [...new Set(roots)].filter((id) => !loaded.has(id)).sort(compareText);
|
|
38
|
+
}
|
|
39
|
+
/** The plan's action per recovery: retry fixes only what a retry clears. */
|
|
40
|
+
const ACTIONS = {
|
|
41
|
+
"retry-job": "job",
|
|
42
|
+
"retry-external-task": "externalTask",
|
|
43
|
+
resolve: "skip",
|
|
44
|
+
none: "skip",
|
|
45
|
+
};
|
|
46
|
+
function actionOf(type, configuration) {
|
|
47
|
+
return ACTIONS[incidentRecovery({ incidentType: type, configuration }).action];
|
|
48
|
+
}
|
|
49
|
+
function entryOf(incident) {
|
|
50
|
+
const type = field(incident, "incidentType");
|
|
51
|
+
const configuration = str(incident, "configuration");
|
|
52
|
+
const action = actionOf(type, configuration);
|
|
53
|
+
return {
|
|
54
|
+
incidentId: field(incident, "id"),
|
|
55
|
+
type,
|
|
56
|
+
activityId: field(incident, "activityId"),
|
|
57
|
+
processInstanceId: field(incident, "processInstanceId"),
|
|
58
|
+
...compact({
|
|
59
|
+
message: str(incident, "incidentMessage"),
|
|
60
|
+
jobId: action === "job" ? configuration : undefined,
|
|
61
|
+
externalTaskId: action === "externalTask" ? configuration : undefined,
|
|
62
|
+
}),
|
|
63
|
+
action,
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* The root causes of the incidents (propagated ones replaced by their loaded root cause,
|
|
68
|
+
* deduplicated), filtered by activity and type, by time and id.
|
|
69
|
+
*/
|
|
70
|
+
export function planRetry(incidents, filter) {
|
|
71
|
+
const byId = new Map(incidents.map((incident) => [str(incident, "id"), incident]));
|
|
72
|
+
const roots = new Map();
|
|
73
|
+
for (const incident of incidents) {
|
|
74
|
+
const root = isRoot(incident) ? incident : byId.get(str(incident, "rootCauseIncidentId"));
|
|
75
|
+
const id = str(root, "id");
|
|
76
|
+
if (root !== undefined && id !== undefined && isRoot(root))
|
|
77
|
+
roots.set(id, root);
|
|
78
|
+
}
|
|
79
|
+
return [...roots.values()]
|
|
80
|
+
.filter((root) => filter.activityId === undefined || str(root, "activityId") === filter.activityId)
|
|
81
|
+
.filter((root) => filter.incidentType === undefined || str(root, "incidentType") === filter.incidentType)
|
|
82
|
+
.toSorted((left, right) => compareTime(str(left, "incidentTimestamp"), str(right, "incidentTimestamp")) ||
|
|
83
|
+
compareText(field(left, "id"), field(right, "id")))
|
|
84
|
+
.map(entryOf);
|
|
85
|
+
}
|
|
86
|
+
/** Too many incidents to retry one by one: refused before any write. */
|
|
87
|
+
export function checkRetryCount(entries, truncated, key) {
|
|
88
|
+
const retryable = entries.filter((entry) => entry.action !== "skip").length;
|
|
89
|
+
if (!truncated && retryable <= MAX_RETRIES)
|
|
90
|
+
return;
|
|
91
|
+
throw new WorkflowError({
|
|
92
|
+
kind: "retry-too-many",
|
|
93
|
+
max: MAX_RETRIES,
|
|
94
|
+
...compact({ processDefinitionKey: key }),
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
/** The retries request of an entry; undefined for skipped ones. */
|
|
98
|
+
export function retriesWrite(entry, retries) {
|
|
99
|
+
const body = { retries };
|
|
100
|
+
if (entry.jobId !== undefined) {
|
|
101
|
+
return {
|
|
102
|
+
label: `set the retries of job ${entry.jobId} to ${retries}`,
|
|
103
|
+
operationId: "setJobRetries",
|
|
104
|
+
input: { pathArgs: [entry.jobId], query: {}, body },
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
if (entry.externalTaskId === undefined)
|
|
108
|
+
return undefined;
|
|
109
|
+
return {
|
|
110
|
+
label: `set the retries of external task ${entry.externalTaskId} to ${retries}`,
|
|
111
|
+
operationId: "setExternalTaskResourceRetries",
|
|
112
|
+
input: { pathArgs: [entry.externalTaskId], query: {}, body },
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
/** The execute request of a job entry (retry now). */
|
|
116
|
+
export function executeWrite(entry) {
|
|
117
|
+
if (entry.jobId === undefined)
|
|
118
|
+
return undefined;
|
|
119
|
+
return {
|
|
120
|
+
label: `execute job ${entry.jobId}`,
|
|
121
|
+
operationId: "executeJob",
|
|
122
|
+
input: { pathArgs: [entry.jobId], query: {} },
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
/** The plan a preview shows: counts per kind and the skipped incidents. */
|
|
126
|
+
export function retryPlanView(mode, entries) {
|
|
127
|
+
const skipped = entries.filter((entry) => entry.action === "skip");
|
|
128
|
+
return {
|
|
129
|
+
mode,
|
|
130
|
+
incidents: entries.length,
|
|
131
|
+
jobs: entries.filter((entry) => entry.action === "job").length,
|
|
132
|
+
externalTasks: entries.filter((entry) => entry.action === "externalTask").length,
|
|
133
|
+
skipped: skipped.map((entry) => ({
|
|
134
|
+
incidentId: entry.incidentId,
|
|
135
|
+
type: entry.type,
|
|
136
|
+
next: { action: "resolveIncident", incidentId: entry.incidentId },
|
|
137
|
+
})),
|
|
138
|
+
};
|
|
139
|
+
}
|
|
140
|
+
//# sourceMappingURL=retry-plan.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"retry-plan.js","sourceRoot":"","sources":["../src/retry-plan.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The root cause of a failure: one line out of a Java stacktrace or an external
|
|
3
|
+
* task's error details. Pure.
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* The last `Caused by: ` line (prefix removed), else the first non-blank line; a leading
|
|
7
|
+
* qualified class name shortened to its simple name; whitespace collapsed; at most 300
|
|
8
|
+
* characters. Undefined for a blank text.
|
|
9
|
+
*/
|
|
10
|
+
export declare function rootCause(text: string): string | undefined;
|
|
11
|
+
/**
|
|
12
|
+
* The index of the last `Caused by: ` line (the line {@link rootCause} takes its cause from), in
|
|
13
|
+
* the lines of `text` split at CRLF, LF and CR; undefined without one. A viewer opens the text
|
|
14
|
+
* there.
|
|
15
|
+
*/
|
|
16
|
+
export declare function rootCauseLine(text: string): number | undefined;
|
|
17
|
+
//# sourceMappingURL=root-cause.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"root-cause.d.ts","sourceRoot":"","sources":["../src/root-cause.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAQH;;;;GAIG;AACH,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAO1D;AAED;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAG9D"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The root cause of a failure: one line out of a Java stacktrace or an external
|
|
3
|
+
* task's error details. Pure.
|
|
4
|
+
*/
|
|
5
|
+
const CAUSED_BY = "Caused by: ";
|
|
6
|
+
const MAX_LENGTH = 300;
|
|
7
|
+
/** A leading qualified Java class name: `org.camunda.bpm.engine.ProcessEngineException`. */
|
|
8
|
+
const QUALIFIED_CLASS = /^(?:[a-z_$][\w$]*\.)+([A-Z][\w$]*)(?=:|\s|$)/;
|
|
9
|
+
/**
|
|
10
|
+
* The last `Caused by: ` line (prefix removed), else the first non-blank line; a leading
|
|
11
|
+
* qualified class name shortened to its simple name; whitespace collapsed; at most 300
|
|
12
|
+
* characters. Undefined for a blank text.
|
|
13
|
+
*/
|
|
14
|
+
export function rootCause(text) {
|
|
15
|
+
const lines = linesOf(text);
|
|
16
|
+
const caused = lines.filter((line) => line.startsWith(CAUSED_BY)).at(-1);
|
|
17
|
+
const line = caused?.slice(CAUSED_BY.length) ?? lines.find((candidate) => candidate !== "");
|
|
18
|
+
if (line === undefined)
|
|
19
|
+
return undefined;
|
|
20
|
+
const simple = line.replace(QUALIFIED_CLASS, "$1").replace(/\s+/g, " ").trim();
|
|
21
|
+
return simple.length > MAX_LENGTH ? `${simple.slice(0, MAX_LENGTH - 1)}…` : simple;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* The index of the last `Caused by: ` line (the line {@link rootCause} takes its cause from), in
|
|
25
|
+
* the lines of `text` split at CRLF, LF and CR; undefined without one. A viewer opens the text
|
|
26
|
+
* there.
|
|
27
|
+
*/
|
|
28
|
+
export function rootCauseLine(text) {
|
|
29
|
+
const index = linesOf(text).findLastIndex((line) => line.startsWith(CAUSED_BY));
|
|
30
|
+
return index === -1 ? undefined : index;
|
|
31
|
+
}
|
|
32
|
+
function linesOf(text) {
|
|
33
|
+
return text.split(/\r\n|[\n\r]/).map((line) => line.trim());
|
|
34
|
+
}
|
|
35
|
+
//# sourceMappingURL=root-cause.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"root-cause.js","sourceRoot":"","sources":["../src/root-cause.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,SAAS,GAAG,aAAa,CAAA;AAC/B,MAAM,UAAU,GAAG,GAAG,CAAA;AAEtB,4FAA4F;AAC5F,MAAM,eAAe,GAAG,8CAA8C,CAAA;AAEtE;;;;GAIG;AACH,MAAM,UAAU,SAAS,CAAC,IAAY;IACpC,MAAM,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IAC3B,MAAM,MAAM,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAA;IACxE,MAAM,IAAI,GAAG,MAAM,EAAE,KAAK,CAAC,SAAS,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,IAAI,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,SAAS,KAAK,EAAE,CAAC,CAAA;IAC3F,IAAI,IAAI,KAAK,SAAS;QAAE,OAAO,SAAS,CAAA;IACxC,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,eAAe,EAAE,IAAI,CAAC,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,IAAI,EAAE,CAAA;IAC9E,OAAO,MAAM,CAAC,MAAM,GAAG,UAAU,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,UAAU,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,CAAA;AACpF,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,aAAa,CAAC,IAAY;IACxC,MAAM,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,aAAa,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC,CAAA;IAC/E,OAAO,KAAK,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,KAAK,CAAA;AACzC,CAAC;AAED,SAAS,OAAO,CAAC,IAAY;IAC3B,OAAO,IAAI,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAA;AAC7D,CAAC"}
|
package/dist/select.d.ts
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Instance selection: a process instance id, or a business key and/or a process definition key
|
|
3
|
+
* (with `latest`) resolved against history and runtime.
|
|
4
|
+
*/
|
|
5
|
+
import type { EnginePort, PlannedRequest } from "./port.js";
|
|
6
|
+
import { type Rec } from "./records.js";
|
|
7
|
+
import type { Candidate, Selection } from "./types.js";
|
|
8
|
+
/** The rules of a selection; nothing is sent before this passed. */
|
|
9
|
+
export declare function checkSelection(selection: Selection): void;
|
|
10
|
+
/** The requests that resolve the filters (history, runtime); none for an id. */
|
|
11
|
+
export declare function selectionRequests(selection: Selection): PlannedRequest[];
|
|
12
|
+
/** Merged by id (history first), active before ended, then the most recently started first. */
|
|
13
|
+
export declare function mergeCandidates(history: readonly Rec[], runtime: readonly Rec[]): Candidate[];
|
|
14
|
+
/** The id of the selected instance; filters are resolved in parallel against history and runtime. */
|
|
15
|
+
export declare function selectInstance(port: EnginePort, selection: Selection): Promise<string>;
|
|
16
|
+
//# sourceMappingURL=select.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"select.d.ts","sourceRoot":"","sources":["../src/select.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,KAAK,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,WAAW,CAAA;AAC3D,OAAO,EAAqC,KAAK,GAAG,EAAqB,MAAM,cAAc,CAAA;AAG7F,OAAO,KAAK,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,YAAY,CAAA;AAStD,oEAAoE;AACpE,wBAAgB,cAAc,CAAC,SAAS,EAAE,SAAS,GAAG,IAAI,CASzD;AA0BD,gFAAgF;AAChF,wBAAgB,iBAAiB,CAAC,SAAS,EAAE,SAAS,GAAG,cAAc,EAAE,CAExE;AAqCD,+FAA+F;AAC/F,wBAAgB,eAAe,CAAC,OAAO,EAAE,SAAS,GAAG,EAAE,EAAE,OAAO,EAAE,SAAS,GAAG,EAAE,GAAG,SAAS,EAAE,CAW7F;AAYD,qGAAqG;AACrG,wBAAsB,cAAc,CAAC,IAAI,EAAE,UAAU,EAAE,SAAS,EAAE,SAAS,GAAG,OAAO,CAAC,MAAM,CAAC,CAsB5F"}
|