@harperfast/harper 5.2.0-alpha.6 → 5.2.0-beta.2
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/bin/cliOperations.ts +76 -12
- package/bin/run.ts +10 -0
- package/bin/status.ts +1 -1
- package/components/Application.ts +146 -83
- package/components/Scope.ts +4 -0
- package/components/componentLoader.ts +7 -0
- package/components/operations.js +21 -1
- package/config/configUtils.ts +139 -5
- package/config-app.schema.json +70 -0
- package/dataLayer/harperBridge/ResourceBridge.ts +7 -0
- package/dist/bin/cliOperations.js +76 -12
- package/dist/bin/cliOperations.js.map +1 -1
- package/dist/bin/run.js +9 -0
- package/dist/bin/run.js.map +1 -1
- package/dist/bin/status.js +1 -1
- package/dist/bin/status.js.map +1 -1
- package/dist/components/Application.d.ts +12 -5
- package/dist/components/Application.js +121 -60
- package/dist/components/Application.js.map +1 -1
- package/dist/components/Scope.d.ts +1 -0
- package/dist/components/Scope.js +4 -0
- package/dist/components/Scope.js.map +1 -1
- package/dist/components/componentLoader.js +7 -0
- package/dist/components/componentLoader.js.map +1 -1
- package/dist/components/operations.js +20 -1
- package/dist/components/operations.js.map +1 -1
- package/dist/config/configUtils.d.ts +31 -0
- package/dist/config/configUtils.js +127 -5
- package/dist/config/configUtils.js.map +1 -1
- package/dist/dataLayer/harperBridge/ResourceBridge.js +8 -0
- package/dist/dataLayer/harperBridge/ResourceBridge.js.map +1 -1
- package/dist/resources/DatabaseTransaction.d.ts +12 -0
- package/dist/resources/DatabaseTransaction.js +97 -0
- package/dist/resources/DatabaseTransaction.js.map +1 -1
- package/dist/resources/RequestTarget.js +13 -3
- package/dist/resources/RequestTarget.js.map +1 -1
- package/dist/resources/Resource.js +21 -2
- package/dist/resources/Resource.js.map +1 -1
- package/dist/resources/Table.d.ts +3 -1
- package/dist/resources/Table.js +48 -5
- package/dist/resources/Table.js.map +1 -1
- package/dist/resources/analytics/metadata.d.ts +3 -0
- package/dist/resources/analytics/metadata.js +3 -0
- package/dist/resources/analytics/metadata.js.map +1 -1
- package/dist/resources/analytics/write.js +22 -0
- package/dist/resources/analytics/write.js.map +1 -1
- package/dist/resources/databases.js +21 -0
- package/dist/resources/databases.js.map +1 -1
- package/dist/resources/defineResource.js +20 -7
- package/dist/resources/defineResource.js.map +1 -1
- package/dist/resources/jsResource.d.ts +24 -0
- package/dist/resources/jsResource.js +58 -2
- package/dist/resources/jsResource.js.map +1 -1
- package/dist/resources/openApi.js +45 -20
- package/dist/resources/openApi.js.map +1 -1
- package/dist/resources/scheduler/CronExpression.d.ts +71 -0
- package/dist/resources/scheduler/CronExpression.js +367 -0
- package/dist/resources/scheduler/CronExpression.js.map +1 -0
- package/dist/resources/scheduler/engine.d.ts +91 -0
- package/dist/resources/scheduler/engine.js +767 -0
- package/dist/resources/scheduler/engine.js.map +1 -0
- package/dist/resources/scheduler/scheduler.d.ts +33 -0
- package/dist/resources/scheduler/scheduler.js +200 -0
- package/dist/resources/scheduler/scheduler.js.map +1 -0
- package/dist/security/auth.js +1 -0
- package/dist/security/auth.js.map +1 -1
- package/dist/security/jsLoader.js +8 -0
- package/dist/security/jsLoader.js.map +1 -1
- package/dist/security/keys.d.ts +32 -0
- package/dist/security/keys.js +147 -0
- package/dist/security/keys.js.map +1 -1
- package/dist/server/REST.js +67 -1
- package/dist/server/REST.js.map +1 -1
- package/dist/server/Server.d.ts +6 -0
- package/dist/server/Server.js.map +1 -1
- package/dist/server/http.d.ts +2 -0
- package/dist/server/http.js +139 -14
- package/dist/server/http.js.map +1 -1
- package/dist/server/operationsServer.js +3 -3
- package/dist/server/operationsServer.js.map +1 -1
- package/dist/server/serverHelpers/progressEmitter.js +5 -1
- package/dist/server/serverHelpers/progressEmitter.js.map +1 -1
- package/dist/server/threads/threadServer.js +9 -5
- package/dist/server/threads/threadServer.js.map +1 -1
- package/dist/sqlEngine/binder/bind.d.ts +72 -0
- package/dist/sqlEngine/binder/bind.js +289 -0
- package/dist/sqlEngine/binder/bind.js.map +1 -0
- package/dist/sqlEngine/config.d.ts +35 -0
- package/dist/sqlEngine/config.js +62 -0
- package/dist/sqlEngine/config.js.map +1 -0
- package/dist/sqlEngine/diff/differential.d.ts +23 -0
- package/dist/sqlEngine/diff/differential.js +90 -0
- package/dist/sqlEngine/diff/differential.js.map +1 -0
- package/dist/sqlEngine/errors.d.ts +22 -0
- package/dist/sqlEngine/errors.js +36 -0
- package/dist/sqlEngine/errors.js.map +1 -0
- package/dist/sqlEngine/executor/runMutation.d.ts +35 -0
- package/dist/sqlEngine/executor/runMutation.js +352 -0
- package/dist/sqlEngine/executor/runMutation.js.map +1 -0
- package/dist/sqlEngine/executor/runSelect.d.ts +7 -0
- package/dist/sqlEngine/executor/runSelect.js +14 -0
- package/dist/sqlEngine/executor/runSelect.js.map +1 -0
- package/dist/sqlEngine/expressions/compile.d.ts +24 -0
- package/dist/sqlEngine/expressions/compile.js +326 -0
- package/dist/sqlEngine/expressions/compile.js.map +1 -0
- package/dist/sqlEngine/functions/aggregates.d.ts +12 -0
- package/dist/sqlEngine/functions/aggregates.js +299 -0
- package/dist/sqlEngine/functions/aggregates.js.map +1 -0
- package/dist/sqlEngine/functions/registry.d.ts +36 -0
- package/dist/sqlEngine/functions/registry.js +33 -0
- package/dist/sqlEngine/functions/registry.js.map +1 -0
- package/dist/sqlEngine/functions/standard.d.ts +9 -0
- package/dist/sqlEngine/functions/standard.js +86 -0
- package/dist/sqlEngine/functions/standard.js.map +1 -0
- package/dist/sqlEngine/index.d.ts +29 -0
- package/dist/sqlEngine/index.js +62 -0
- package/dist/sqlEngine/index.js.map +1 -0
- package/dist/sqlEngine/logical/build.d.ts +20 -0
- package/dist/sqlEngine/logical/build.js +326 -0
- package/dist/sqlEngine/logical/build.js.map +1 -0
- package/dist/sqlEngine/logical/op.d.ts +105 -0
- package/dist/sqlEngine/logical/op.js +10 -0
- package/dist/sqlEngine/logical/op.js.map +1 -0
- package/dist/sqlEngine/optimizer/joinAnalysis.d.ts +37 -0
- package/dist/sqlEngine/optimizer/joinAnalysis.js +144 -0
- package/dist/sqlEngine/optimizer/joinAnalysis.js.map +1 -0
- package/dist/sqlEngine/optimizer/optimize.d.ts +13 -0
- package/dist/sqlEngine/optimizer/optimize.js +53 -0
- package/dist/sqlEngine/optimizer/optimize.js.map +1 -0
- package/dist/sqlEngine/optimizer/ruleEngine.d.ts +7 -0
- package/dist/sqlEngine/optimizer/ruleEngine.js +26 -0
- package/dist/sqlEngine/optimizer/ruleEngine.js.map +1 -0
- package/dist/sqlEngine/optimizer/rules/limitPushdown.d.ts +19 -0
- package/dist/sqlEngine/optimizer/rules/limitPushdown.js +55 -0
- package/dist/sqlEngine/optimizer/rules/limitPushdown.js.map +1 -0
- package/dist/sqlEngine/optimizer/rules/planJoins.d.ts +19 -0
- package/dist/sqlEngine/optimizer/rules/planJoins.js +62 -0
- package/dist/sqlEngine/optimizer/rules/planJoins.js.map +1 -0
- package/dist/sqlEngine/optimizer/rules/predicateNormalize.d.ts +18 -0
- package/dist/sqlEngine/optimizer/rules/predicateNormalize.js +80 -0
- package/dist/sqlEngine/optimizer/rules/predicateNormalize.js.map +1 -0
- package/dist/sqlEngine/optimizer/rules/predicatePushdown.d.ts +11 -0
- package/dist/sqlEngine/optimizer/rules/predicatePushdown.js +48 -0
- package/dist/sqlEngine/optimizer/rules/predicatePushdown.js.map +1 -0
- package/dist/sqlEngine/optimizer/rules/projectionPushdown.d.ts +23 -0
- package/dist/sqlEngine/optimizer/rules/projectionPushdown.js +160 -0
- package/dist/sqlEngine/optimizer/rules/projectionPushdown.js.map +1 -0
- package/dist/sqlEngine/optimizer/rules/sortFromIndex.d.ts +14 -0
- package/dist/sqlEngine/optimizer/rules/sortFromIndex.js +49 -0
- package/dist/sqlEngine/optimizer/rules/sortFromIndex.js.map +1 -0
- package/dist/sqlEngine/optimizer/rules/validateScannable.d.ts +15 -0
- package/dist/sqlEngine/optimizer/rules/validateScannable.js +60 -0
- package/dist/sqlEngine/optimizer/rules/validateScannable.js.map +1 -0
- package/dist/sqlEngine/optimizer/whereToConditions.d.ts +85 -0
- package/dist/sqlEngine/optimizer/whereToConditions.js +484 -0
- package/dist/sqlEngine/optimizer/whereToConditions.js.map +1 -0
- package/dist/sqlEngine/parser/ast.d.ts +139 -0
- package/dist/sqlEngine/parser/ast.js +10 -0
- package/dist/sqlEngine/parser/ast.js.map +1 -0
- package/dist/sqlEngine/parser/normalizer.d.ts +28 -0
- package/dist/sqlEngine/parser/normalizer.js +413 -0
- package/dist/sqlEngine/parser/normalizer.js.map +1 -0
- package/dist/sqlEngine/parser/parse.d.ts +14 -0
- package/dist/sqlEngine/parser/parse.js +20 -0
- package/dist/sqlEngine/parser/parse.js.map +1 -0
- package/dist/sqlEngine/physical/PhysicalDistinct.d.ts +9 -0
- package/dist/sqlEngine/physical/PhysicalDistinct.js +29 -0
- package/dist/sqlEngine/physical/PhysicalDistinct.js.map +1 -0
- package/dist/sqlEngine/physical/PhysicalFilter.d.ts +10 -0
- package/dist/sqlEngine/physical/PhysicalFilter.js +25 -0
- package/dist/sqlEngine/physical/PhysicalFilter.js.map +1 -0
- package/dist/sqlEngine/physical/PhysicalHashAggregate.d.ts +27 -0
- package/dist/sqlEngine/physical/PhysicalHashAggregate.js +100 -0
- package/dist/sqlEngine/physical/PhysicalHashAggregate.js.map +1 -0
- package/dist/sqlEngine/physical/PhysicalHashJoin.d.ts +29 -0
- package/dist/sqlEngine/physical/PhysicalHashJoin.js +93 -0
- package/dist/sqlEngine/physical/PhysicalHashJoin.js.map +1 -0
- package/dist/sqlEngine/physical/PhysicalIndexNestedLoopJoin.d.ts +36 -0
- package/dist/sqlEngine/physical/PhysicalIndexNestedLoopJoin.js +78 -0
- package/dist/sqlEngine/physical/PhysicalIndexNestedLoopJoin.js.map +1 -0
- package/dist/sqlEngine/physical/PhysicalIndexScan.d.ts +22 -0
- package/dist/sqlEngine/physical/PhysicalIndexScan.js +77 -0
- package/dist/sqlEngine/physical/PhysicalIndexScan.js.map +1 -0
- package/dist/sqlEngine/physical/PhysicalLimit.d.ts +5 -0
- package/dist/sqlEngine/physical/PhysicalLimit.js +28 -0
- package/dist/sqlEngine/physical/PhysicalLimit.js.map +1 -0
- package/dist/sqlEngine/physical/PhysicalNestedLoopJoin.d.ts +20 -0
- package/dist/sqlEngine/physical/PhysicalNestedLoopJoin.js +51 -0
- package/dist/sqlEngine/physical/PhysicalNestedLoopJoin.js.map +1 -0
- package/dist/sqlEngine/physical/PhysicalProject.d.ts +18 -0
- package/dist/sqlEngine/physical/PhysicalProject.js +117 -0
- package/dist/sqlEngine/physical/PhysicalProject.js.map +1 -0
- package/dist/sqlEngine/physical/PhysicalQualify.d.ts +13 -0
- package/dist/sqlEngine/physical/PhysicalQualify.js +29 -0
- package/dist/sqlEngine/physical/PhysicalQualify.js.map +1 -0
- package/dist/sqlEngine/physical/PhysicalSort.d.ts +12 -0
- package/dist/sqlEngine/physical/PhysicalSort.js +59 -0
- package/dist/sqlEngine/physical/PhysicalSort.js.map +1 -0
- package/dist/sqlEngine/physical/op.d.ts +11 -0
- package/dist/sqlEngine/physical/op.js +9 -0
- package/dist/sqlEngine/physical/op.js.map +1 -0
- package/dist/sqlEngine/physical/plan.d.ts +23 -0
- package/dist/sqlEngine/physical/plan.js +162 -0
- package/dist/sqlEngine/physical/plan.js.map +1 -0
- package/dist/sqlEngine/router.d.ts +26 -0
- package/dist/sqlEngine/router.js +48 -0
- package/dist/sqlEngine/router.js.map +1 -0
- package/dist/sqlEngine/types.d.ts +37 -0
- package/dist/sqlEngine/types.js +13 -0
- package/dist/sqlEngine/types.js.map +1 -0
- package/dist/sqlTranslator/index.js +7 -1
- package/dist/sqlTranslator/index.js.map +1 -1
- package/dist/utility/common_utils.js +25 -0
- package/dist/utility/common_utils.js.map +1 -1
- package/dist/utility/install/installer.d.ts +9 -1
- package/dist/utility/install/installer.js +21 -0
- package/dist/utility/install/installer.js.map +1 -1
- package/dist/validation/configValidator.js +3 -0
- package/dist/validation/configValidator.js.map +1 -1
- package/dist/validation/deleteValidator.js +10 -2
- package/dist/validation/deleteValidator.js.map +1 -1
- package/npm-shrinkwrap.json +272 -230
- package/package.json +3 -3
- package/resources/DESIGN.md +17 -16
- package/resources/DatabaseTransaction.ts +95 -0
- package/resources/RequestTarget.ts +12 -3
- package/resources/Resource.ts +23 -2
- package/resources/Table.ts +57 -6
- package/resources/analytics/metadata.ts +3 -0
- package/resources/analytics/write.ts +23 -0
- package/resources/databases.ts +24 -0
- package/resources/defineResource.ts +17 -4
- package/resources/jsResource.ts +61 -2
- package/resources/openApi.ts +44 -19
- package/resources/scheduler/CronExpression.ts +394 -0
- package/resources/scheduler/engine.ts +812 -0
- package/resources/scheduler/scheduler.ts +236 -0
- package/security/auth.ts +1 -0
- package/security/jsLoader.ts +8 -0
- package/security/keys.ts +152 -0
- package/server/REST.ts +70 -1
- package/server/Server.ts +6 -0
- package/server/http.ts +122 -15
- package/server/operationsServer.ts +5 -3
- package/server/serverHelpers/progressEmitter.ts +5 -1
- package/server/threads/threadServer.js +9 -5
- package/sqlTranslator/index.ts +16 -6
- package/studio/web/assets/{Chat-CTjtL8Z4.js → Chat-DHP4XpID.js} +2 -2
- package/studio/web/assets/{Chat-CTjtL8Z4.js.map → Chat-DHP4XpID.js.map} +1 -1
- package/studio/web/assets/{FloatingChat-CafHR4Ur.js → FloatingChat-CJ7PssCv.js} +4 -4
- package/studio/web/assets/{FloatingChat-CafHR4Ur.js.map → FloatingChat-CJ7PssCv.js.map} +1 -1
- package/studio/web/assets/{applications-Buh_q0Vj.js → applications-DxXiGpsR.js} +2 -2
- package/studio/web/assets/{applications-Buh_q0Vj.js.map → applications-DxXiGpsR.js.map} +1 -1
- package/studio/web/assets/{index-0hXeECkS.js → index-BdbBanDP.js} +6 -6
- package/studio/web/assets/{index-0hXeECkS.js.map → index-BdbBanDP.js.map} +1 -1
- package/studio/web/assets/{index.lazy-B00B7VBT.js → index.lazy-B2eH28zD.js} +4 -4
- package/studio/web/assets/{index.lazy-B00B7VBT.js.map → index.lazy-B2eH28zD.js.map} +1 -1
- package/studio/web/assets/{profile-Cg2wwYPn.js → profile-DK5hgucv.js} +2 -2
- package/studio/web/assets/{profile-Cg2wwYPn.js.map → profile-DK5hgucv.js.map} +1 -1
- package/studio/web/assets/{setComponentFile-DCaDIvyB.js → setComponentFile-BVDWRYxx.js} +2 -2
- package/studio/web/assets/{setComponentFile-DCaDIvyB.js.map → setComponentFile-BVDWRYxx.js.map} +1 -1
- package/studio/web/assets/{setup-CAVcAQjK.js → setup-DJ9BInoK.js} +2 -2
- package/studio/web/assets/{setup-CAVcAQjK.js.map → setup-DJ9BInoK.js.map} +1 -1
- package/studio/web/assets/{status-BRXorNdD.js → status-B_qzmgfD.js} +2 -2
- package/studio/web/assets/{status-BRXorNdD.js.map → status-B_qzmgfD.js.map} +1 -1
- package/studio/web/assets/{swagger-ui-react-Dy1D62vO.js → swagger-ui-react-DOL5jCqg.js} +2 -2
- package/studio/web/assets/{swagger-ui-react-Dy1D62vO.js.map → swagger-ui-react-DOL5jCqg.js.map} +1 -1
- package/studio/web/assets/{tsMode-A8gbL74v.js → tsMode-DpxUxfTW.js} +2 -2
- package/studio/web/assets/{tsMode-A8gbL74v.js.map → tsMode-DpxUxfTW.js.map} +1 -1
- package/studio/web/assets/{useEntityRestURL-cDodrVcQ.js → useEntityRestURL-CU_lY6XW.js} +2 -2
- package/studio/web/assets/{useEntityRestURL-cDodrVcQ.js.map → useEntityRestURL-CU_lY6XW.js.map} +1 -1
- package/studio/web/index.html +1 -1
- package/utility/common_utils.ts +26 -0
- package/utility/install/installer.ts +26 -1
- package/validation/configValidator.ts +3 -0
- package/validation/deleteValidator.ts +11 -2
|
@@ -0,0 +1,367 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.CronExpression = exports.InvalidCronExpressionError = void 0;
|
|
4
|
+
exports.validateTimezone = validateTimezone;
|
|
5
|
+
exports.getSystemTimezone = getSystemTimezone;
|
|
6
|
+
exports.toZonedWallTime = toZonedWallTime;
|
|
7
|
+
exports.fromZonedWallTime = fromZonedWallTime;
|
|
8
|
+
const hdbError_ts_1 = require("../../utility/errors/hdbError.js");
|
|
9
|
+
/**
|
|
10
|
+
* Thrown when a cron expression cannot be parsed, or a schedule can never fire
|
|
11
|
+
* (e.g. `0 0 30 2 *` — February 30th).
|
|
12
|
+
*/
|
|
13
|
+
class InvalidCronExpressionError extends hdbError_ts_1.ClientError {
|
|
14
|
+
constructor(message) {
|
|
15
|
+
super(message, 400);
|
|
16
|
+
this.name = 'InvalidCronExpressionError';
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
exports.InvalidCronExpressionError = InvalidCronExpressionError;
|
|
20
|
+
const MONTH_NAMES = ['JAN', 'FEB', 'MAR', 'APR', 'MAY', 'JUN', 'JUL', 'AUG', 'SEP', 'OCT', 'NOV', 'DEC'];
|
|
21
|
+
const DAY_OF_WEEK_NAMES = ['SUN', 'MON', 'TUE', 'WED', 'THU', 'FRI', 'SAT'];
|
|
22
|
+
const MACROS = {
|
|
23
|
+
'@yearly': '0 0 1 1 *',
|
|
24
|
+
'@annually': '0 0 1 1 *',
|
|
25
|
+
'@monthly': '0 0 1 * *',
|
|
26
|
+
'@weekly': '0 0 * * 0',
|
|
27
|
+
'@daily': '0 0 * * *',
|
|
28
|
+
'@midnight': '0 0 * * *',
|
|
29
|
+
'@hourly': '0 * * * *',
|
|
30
|
+
};
|
|
31
|
+
// How far ahead/behind nextDate/prevDate will search before concluding the
|
|
32
|
+
// schedule can never fire. Eight years covers leap-day schedules even across
|
|
33
|
+
// a century non-leap year (2096 -> 2104 is the longest Feb 29 gap).
|
|
34
|
+
const MAX_SEARCH_YEARS = 8;
|
|
35
|
+
// DST transitions shift offsets by at most two hours in the IANA database
|
|
36
|
+
const MAX_DST_DELTA_MS = 2 * 60 * 60 * 1000;
|
|
37
|
+
const MINUTE_FIELD = { min: 0, max: 59 };
|
|
38
|
+
const HOUR_FIELD = { min: 0, max: 23 };
|
|
39
|
+
const DAY_OF_MONTH_FIELD = { min: 1, max: 31 };
|
|
40
|
+
const MONTH_FIELD = { min: 1, max: 12, names: MONTH_NAMES, nameOffset: 1 };
|
|
41
|
+
const DAY_OF_WEEK_FIELD = { min: 0, max: 7, names: DAY_OF_WEEK_NAMES, nameOffset: 0 };
|
|
42
|
+
/**
|
|
43
|
+
* Parse one cron field (e.g. `1,15,30-45`, `MON-FRI`, or a step like `0-59/15`)
|
|
44
|
+
* into a boolean lookup keyed by value. Supports `*`, single values, ranges,
|
|
45
|
+
* steps, lists, and the standard month/day names.
|
|
46
|
+
*/
|
|
47
|
+
function parseField(fieldValue, spec, fieldName, expression) {
|
|
48
|
+
const allowed = new Array(spec.max + 1).fill(false);
|
|
49
|
+
const fail = (reason) => {
|
|
50
|
+
throw new InvalidCronExpressionError(`Invalid ${fieldName} field "${fieldValue}" in cron expression "${expression}": ${reason}`);
|
|
51
|
+
};
|
|
52
|
+
const parseValue = (raw) => {
|
|
53
|
+
if (spec.names) {
|
|
54
|
+
const nameIndex = spec.names.indexOf(raw.toUpperCase());
|
|
55
|
+
if (nameIndex >= 0)
|
|
56
|
+
return nameIndex + (spec.nameOffset ?? 0);
|
|
57
|
+
}
|
|
58
|
+
if (!/^\d+$/.test(raw))
|
|
59
|
+
fail(`"${raw}" is not a number${spec.names ? ' or recognized name' : ''}`);
|
|
60
|
+
const value = Number(raw);
|
|
61
|
+
if (value < spec.min || value > spec.max)
|
|
62
|
+
fail(`${value} is outside the allowed range ${spec.min}-${spec.max}`);
|
|
63
|
+
return value;
|
|
64
|
+
};
|
|
65
|
+
for (const part of fieldValue.split(',')) {
|
|
66
|
+
if (part === '')
|
|
67
|
+
fail('empty list entry');
|
|
68
|
+
const [base, stepText, extra] = part.split('/');
|
|
69
|
+
if (extra !== undefined)
|
|
70
|
+
fail('multiple "/" step separators');
|
|
71
|
+
let step = 1;
|
|
72
|
+
if (stepText !== undefined) {
|
|
73
|
+
if (!/^\d+$/.test(stepText) || Number(stepText) < 1)
|
|
74
|
+
fail(`step "${stepText}" must be a positive integer`);
|
|
75
|
+
step = Number(stepText);
|
|
76
|
+
}
|
|
77
|
+
let rangeStart;
|
|
78
|
+
let rangeEnd;
|
|
79
|
+
if (base === '*') {
|
|
80
|
+
rangeStart = spec.min;
|
|
81
|
+
rangeEnd = spec.max;
|
|
82
|
+
}
|
|
83
|
+
else if (base.includes('-')) {
|
|
84
|
+
const [startText, endText, extraRange] = base.split('-');
|
|
85
|
+
if (extraRange !== undefined || startText === '' || endText === '')
|
|
86
|
+
fail('malformed range');
|
|
87
|
+
rangeStart = parseValue(startText);
|
|
88
|
+
rangeEnd = parseValue(endText);
|
|
89
|
+
if (rangeStart > rangeEnd)
|
|
90
|
+
fail(`range start ${rangeStart} is greater than range end ${rangeEnd}`);
|
|
91
|
+
}
|
|
92
|
+
else {
|
|
93
|
+
rangeStart = parseValue(base);
|
|
94
|
+
// `5/15` means "every 15 starting at 5"; a bare `5` means just 5
|
|
95
|
+
rangeEnd = stepText !== undefined ? spec.max : rangeStart;
|
|
96
|
+
}
|
|
97
|
+
for (let value = rangeStart; value <= rangeEnd; value += step) {
|
|
98
|
+
allowed[value] = true;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
return allowed;
|
|
102
|
+
}
|
|
103
|
+
// Cache one formatter per timezone: Intl.DateTimeFormat construction is
|
|
104
|
+
// expensive relative to formatting, and the same few zones recur.
|
|
105
|
+
const zoneFormatters = new Map();
|
|
106
|
+
function getZoneFormatter(timezone) {
|
|
107
|
+
let formatter = zoneFormatters.get(timezone);
|
|
108
|
+
if (!formatter) {
|
|
109
|
+
formatter = new Intl.DateTimeFormat('en-US', {
|
|
110
|
+
timeZone: timezone,
|
|
111
|
+
year: 'numeric',
|
|
112
|
+
month: '2-digit',
|
|
113
|
+
day: '2-digit',
|
|
114
|
+
hour: '2-digit',
|
|
115
|
+
minute: '2-digit',
|
|
116
|
+
second: '2-digit',
|
|
117
|
+
hourCycle: 'h23',
|
|
118
|
+
});
|
|
119
|
+
zoneFormatters.set(timezone, formatter);
|
|
120
|
+
}
|
|
121
|
+
return formatter;
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* Validate an IANA timezone name. Returns the normalized name, or throws.
|
|
125
|
+
*/
|
|
126
|
+
function validateTimezone(timezone) {
|
|
127
|
+
try {
|
|
128
|
+
getZoneFormatter(timezone);
|
|
129
|
+
return timezone;
|
|
130
|
+
}
|
|
131
|
+
catch (error) {
|
|
132
|
+
zoneFormatters.delete(timezone);
|
|
133
|
+
throw new hdbError_ts_1.ClientError(`Unknown timezone "${timezone}": ${error.message}`, 400);
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
let systemTimezone;
|
|
137
|
+
function getSystemTimezone() {
|
|
138
|
+
systemTimezone ??= Intl.DateTimeFormat().resolvedOptions().timeZone;
|
|
139
|
+
return systemTimezone;
|
|
140
|
+
}
|
|
141
|
+
/**
|
|
142
|
+
* Shift a real instant so its UTC fields carry the wall-clock time in the given
|
|
143
|
+
* timezone. The evaluator works entirely on these "zoned wall time" Dates
|
|
144
|
+
* (reading getUTC* fields), keeping the schedule math independent of the
|
|
145
|
+
* system timezone.
|
|
146
|
+
*/
|
|
147
|
+
function toZonedWallTime(date, timezone) {
|
|
148
|
+
const parts = {};
|
|
149
|
+
for (const part of getZoneFormatter(timezone).formatToParts(date)) {
|
|
150
|
+
parts[part.type] = part.value;
|
|
151
|
+
}
|
|
152
|
+
return new Date(Date.UTC(Number(parts.year), Number(parts.month) - 1, Number(parts.day),
|
|
153
|
+
// hourCycle h23 should prevent "24", but guard anyway — some ICU
|
|
154
|
+
// versions have produced it for midnight
|
|
155
|
+
Number(parts.hour === '24' ? '0' : parts.hour), Number(parts.minute), Number(parts.second)));
|
|
156
|
+
}
|
|
157
|
+
/**
|
|
158
|
+
* Inverse of toZonedWallTime: given a Date whose UTC fields represent
|
|
159
|
+
* wall-clock time in `timezone`, return the real instant.
|
|
160
|
+
*
|
|
161
|
+
* Offsets are discovered by probing the zone at the wall time misread as UTC,
|
|
162
|
+
* at the candidate instant that offset implies, and two hours either side of
|
|
163
|
+
* it (DST deltas never exceed 2h), so both sides of a nearby transition are
|
|
164
|
+
* seen regardless of hemisphere or offset sign — a single re-probe missed the
|
|
165
|
+
* pre-transition offset in eastern zones (a Sydney gap job fired an hour
|
|
166
|
+
* EARLY; Lord Howe ambiguous times resolved to their second occurrence).
|
|
167
|
+
* Resolution is then deterministic in every zone: a wall time that exists
|
|
168
|
+
* maps to its instant; an ambiguous (fall-back overlap) wall time maps to its
|
|
169
|
+
* FIRST occurrence; a nonexistent (spring-forward gap) wall time maps to the
|
|
170
|
+
* first instant after the gap.
|
|
171
|
+
*/
|
|
172
|
+
function fromZonedWallTime(wallTime, timezone) {
|
|
173
|
+
const asUtc = wallTime.getTime();
|
|
174
|
+
const offsetAt = (instant) => toZonedWallTime(new Date(instant), timezone).getTime() - instant;
|
|
175
|
+
const firstOffset = offsetAt(asUtc);
|
|
176
|
+
const nearCandidate = asUtc - firstOffset;
|
|
177
|
+
const candidateOffsets = new Set([
|
|
178
|
+
firstOffset,
|
|
179
|
+
offsetAt(nearCandidate),
|
|
180
|
+
offsetAt(nearCandidate - MAX_DST_DELTA_MS),
|
|
181
|
+
offsetAt(nearCandidate + MAX_DST_DELTA_MS),
|
|
182
|
+
]);
|
|
183
|
+
let earliestRoundTrip = Infinity;
|
|
184
|
+
let latestCandidate = -Infinity;
|
|
185
|
+
for (const offset of candidateOffsets) {
|
|
186
|
+
const instant = asUtc - offset;
|
|
187
|
+
latestCandidate = Math.max(latestCandidate, instant);
|
|
188
|
+
if (offsetAt(instant) === offset) {
|
|
189
|
+
earliestRoundTrip = Math.min(earliestRoundTrip, instant);
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
// No candidate reproduces this wall time: it falls in a spring-forward gap;
|
|
193
|
+
// the latest candidate is the first instant after the transition
|
|
194
|
+
return new Date(Number.isFinite(earliestRoundTrip) ? earliestRoundTrip : latestCandidate);
|
|
195
|
+
}
|
|
196
|
+
const MINUTE_MS = 60_000;
|
|
197
|
+
// DST overlaps are at most ~2h (Lord Howe aside, offsets change by <=1h in
|
|
198
|
+
// practice; 3h covers every IANA zone with margin), so occurrence convergence
|
|
199
|
+
// through a fall-back never needs to look further than this past the reference
|
|
200
|
+
const DST_CONVERGENCE_HORIZON_MS = 3 * 60 * 60 * 1000;
|
|
201
|
+
// A minutely cron converging through a 2h overlap needs ~120 occurrences;
|
|
202
|
+
// each iteration is cheap, so the cap is safety against pathologies only
|
|
203
|
+
const MAX_CONVERGENCE_ATTEMPTS = 400;
|
|
204
|
+
/**
|
|
205
|
+
* A parsed five-field POSIX cron expression (minute, hour, day-of-month,
|
|
206
|
+
* month, day-of-week) supporting `*`, lists, ranges, steps, month/day names,
|
|
207
|
+
* and the common `@daily`-style macros. Follows the standard rule that when
|
|
208
|
+
* both day-of-month and day-of-week are restricted, a date matches if EITHER
|
|
209
|
+
* matches.
|
|
210
|
+
*/
|
|
211
|
+
class CronExpression {
|
|
212
|
+
expression;
|
|
213
|
+
#minutes;
|
|
214
|
+
#hours;
|
|
215
|
+
#daysOfMonth;
|
|
216
|
+
#months;
|
|
217
|
+
#daysOfWeek;
|
|
218
|
+
#dayOfMonthRestricted;
|
|
219
|
+
#dayOfWeekRestricted;
|
|
220
|
+
constructor(expression) {
|
|
221
|
+
this.expression = expression;
|
|
222
|
+
const normalized = (MACROS[expression.trim().toLowerCase()] ?? expression).trim();
|
|
223
|
+
const fields = normalized.split(/\s+/);
|
|
224
|
+
if (fields.length !== 5) {
|
|
225
|
+
throw new InvalidCronExpressionError(`Cron expression "${expression}" has ${fields.length} fields; expected 5 (minute hour day-of-month month day-of-week)`);
|
|
226
|
+
}
|
|
227
|
+
this.#minutes = parseField(fields[0], MINUTE_FIELD, 'minute', expression);
|
|
228
|
+
this.#hours = parseField(fields[1], HOUR_FIELD, 'hour', expression);
|
|
229
|
+
this.#daysOfMonth = parseField(fields[2], DAY_OF_MONTH_FIELD, 'day-of-month', expression);
|
|
230
|
+
this.#months = parseField(fields[3], MONTH_FIELD, 'month', expression);
|
|
231
|
+
this.#daysOfWeek = parseField(fields[4], DAY_OF_WEEK_FIELD, 'day-of-week', expression);
|
|
232
|
+
// 7 is an alias for Sunday
|
|
233
|
+
if (this.#daysOfWeek[7])
|
|
234
|
+
this.#daysOfWeek[0] = true;
|
|
235
|
+
this.#dayOfMonthRestricted = fields[2] !== '*';
|
|
236
|
+
this.#dayOfWeekRestricted = fields[4] !== '*';
|
|
237
|
+
// Surface never-firing schedules (e.g. February 30th) at parse time
|
|
238
|
+
// rather than as a silently idle job
|
|
239
|
+
if (this.nextWallTime(new Date()) === null) {
|
|
240
|
+
throw new InvalidCronExpressionError(`Cron expression "${expression}" can never fire`);
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
#dayMatches(wallTime) {
|
|
244
|
+
const dayOfMonthMatch = this.#daysOfMonth[wallTime.getUTCDate()];
|
|
245
|
+
const dayOfWeekMatch = this.#daysOfWeek[wallTime.getUTCDay()];
|
|
246
|
+
if (this.#dayOfMonthRestricted && this.#dayOfWeekRestricted)
|
|
247
|
+
return dayOfMonthMatch || dayOfWeekMatch;
|
|
248
|
+
if (this.#dayOfMonthRestricted)
|
|
249
|
+
return dayOfMonthMatch;
|
|
250
|
+
if (this.#dayOfWeekRestricted)
|
|
251
|
+
return dayOfWeekMatch;
|
|
252
|
+
return true;
|
|
253
|
+
}
|
|
254
|
+
/**
|
|
255
|
+
* The next matching wall-clock time strictly after `afterWallTime` (both as
|
|
256
|
+
* "zoned wall time" Dates — see toZonedWallTime). Returns null if no match
|
|
257
|
+
* exists within the search horizon.
|
|
258
|
+
*/
|
|
259
|
+
nextWallTime(afterWallTime) {
|
|
260
|
+
// Truncate to the minute, then step forward
|
|
261
|
+
let candidate = new Date(Math.floor(afterWallTime.getTime() / MINUTE_MS) * MINUTE_MS + MINUTE_MS);
|
|
262
|
+
const horizon = afterWallTime.getTime() + MAX_SEARCH_YEARS * 366 * 24 * 60 * MINUTE_MS;
|
|
263
|
+
while (candidate.getTime() <= horizon) {
|
|
264
|
+
if (!this.#months[candidate.getUTCMonth() + 1]) {
|
|
265
|
+
// First minute of the next month
|
|
266
|
+
candidate = new Date(Date.UTC(candidate.getUTCFullYear(), candidate.getUTCMonth() + 1, 1));
|
|
267
|
+
continue;
|
|
268
|
+
}
|
|
269
|
+
if (!this.#dayMatches(candidate)) {
|
|
270
|
+
candidate = new Date(Date.UTC(candidate.getUTCFullYear(), candidate.getUTCMonth(), candidate.getUTCDate() + 1));
|
|
271
|
+
continue;
|
|
272
|
+
}
|
|
273
|
+
if (!this.#hours[candidate.getUTCHours()]) {
|
|
274
|
+
candidate = new Date(Date.UTC(candidate.getUTCFullYear(), candidate.getUTCMonth(), candidate.getUTCDate(), candidate.getUTCHours() + 1));
|
|
275
|
+
continue;
|
|
276
|
+
}
|
|
277
|
+
if (!this.#minutes[candidate.getUTCMinutes()]) {
|
|
278
|
+
candidate = new Date(candidate.getTime() + MINUTE_MS);
|
|
279
|
+
continue;
|
|
280
|
+
}
|
|
281
|
+
return candidate;
|
|
282
|
+
}
|
|
283
|
+
return null;
|
|
284
|
+
}
|
|
285
|
+
/**
|
|
286
|
+
* The latest matching wall-clock time strictly before `beforeWallTime`
|
|
287
|
+
* (zoned wall time in, zoned wall time out). Returns null if no match
|
|
288
|
+
* exists within the search horizon.
|
|
289
|
+
*/
|
|
290
|
+
previousWallTime(beforeWallTime) {
|
|
291
|
+
let candidate = new Date(Math.ceil(beforeWallTime.getTime() / MINUTE_MS) * MINUTE_MS - MINUTE_MS);
|
|
292
|
+
const horizon = beforeWallTime.getTime() - MAX_SEARCH_YEARS * 366 * 24 * 60 * MINUTE_MS;
|
|
293
|
+
while (candidate.getTime() >= horizon) {
|
|
294
|
+
if (!this.#months[candidate.getUTCMonth() + 1]) {
|
|
295
|
+
// Last minute of the previous month
|
|
296
|
+
candidate = new Date(Date.UTC(candidate.getUTCFullYear(), candidate.getUTCMonth(), 1) - MINUTE_MS);
|
|
297
|
+
continue;
|
|
298
|
+
}
|
|
299
|
+
if (!this.#dayMatches(candidate)) {
|
|
300
|
+
// Last minute of the previous day
|
|
301
|
+
candidate = new Date(Date.UTC(candidate.getUTCFullYear(), candidate.getUTCMonth(), candidate.getUTCDate()) - MINUTE_MS);
|
|
302
|
+
continue;
|
|
303
|
+
}
|
|
304
|
+
if (!this.#hours[candidate.getUTCHours()]) {
|
|
305
|
+
// Last minute of the previous hour
|
|
306
|
+
candidate = new Date(Date.UTC(candidate.getUTCFullYear(), candidate.getUTCMonth(), candidate.getUTCDate(), candidate.getUTCHours()) - MINUTE_MS);
|
|
307
|
+
continue;
|
|
308
|
+
}
|
|
309
|
+
if (!this.#minutes[candidate.getUTCMinutes()]) {
|
|
310
|
+
candidate = new Date(candidate.getTime() - MINUTE_MS);
|
|
311
|
+
continue;
|
|
312
|
+
}
|
|
313
|
+
return candidate;
|
|
314
|
+
}
|
|
315
|
+
return null;
|
|
316
|
+
}
|
|
317
|
+
/**
|
|
318
|
+
* The next real instant strictly after `after` at which this expression
|
|
319
|
+
* fires in the given timezone (defaults to the system timezone). Returns
|
|
320
|
+
* null for schedules with no future occurrence in the search horizon.
|
|
321
|
+
*/
|
|
322
|
+
nextDate(after, timezone = getSystemTimezone()) {
|
|
323
|
+
let wall = toZonedWallTime(after, timezone);
|
|
324
|
+
// A DST fall-back overlap maps repeated-hour wall times to their FIRST
|
|
325
|
+
// occurrence, which can sit at or before `after` when `after` is inside
|
|
326
|
+
// the second pass — advance occurrences until we cross it. The bound is
|
|
327
|
+
// wall-clock distance, not attempt count: a minutely cron needs ~an
|
|
328
|
+
// hour's worth of occurrences to converge through the overlap (surfaced
|
|
329
|
+
// empirically in review; a fixed small attempt cap wedged sub-hourly
|
|
330
|
+
// jobs for the whole window).
|
|
331
|
+
const wallHorizon = wall.getTime() + DST_CONVERGENCE_HORIZON_MS;
|
|
332
|
+
for (let attempts = 0; attempts < MAX_CONVERGENCE_ATTEMPTS; attempts++) {
|
|
333
|
+
const nextWall = this.nextWallTime(wall);
|
|
334
|
+
if (nextWall === null)
|
|
335
|
+
return null;
|
|
336
|
+
const instant = fromZonedWallTime(nextWall, timezone);
|
|
337
|
+
if (instant.getTime() > after.getTime())
|
|
338
|
+
return instant;
|
|
339
|
+
if (nextWall.getTime() > wallHorizon)
|
|
340
|
+
return null;
|
|
341
|
+
wall = nextWall;
|
|
342
|
+
}
|
|
343
|
+
return null;
|
|
344
|
+
}
|
|
345
|
+
/**
|
|
346
|
+
* The most recent real instant strictly before `before` at which this
|
|
347
|
+
* expression fired in the given timezone (defaults to the system timezone).
|
|
348
|
+
*/
|
|
349
|
+
previousDate(before, timezone = getSystemTimezone()) {
|
|
350
|
+
let wall = toZonedWallTime(before, timezone);
|
|
351
|
+
const wallHorizon = wall.getTime() - DST_CONVERGENCE_HORIZON_MS;
|
|
352
|
+
for (let attempts = 0; attempts < MAX_CONVERGENCE_ATTEMPTS; attempts++) {
|
|
353
|
+
const previousWall = this.previousWallTime(wall);
|
|
354
|
+
if (previousWall === null)
|
|
355
|
+
return null;
|
|
356
|
+
const instant = fromZonedWallTime(previousWall, timezone);
|
|
357
|
+
if (instant.getTime() < before.getTime())
|
|
358
|
+
return instant;
|
|
359
|
+
if (previousWall.getTime() < wallHorizon)
|
|
360
|
+
return null;
|
|
361
|
+
wall = previousWall;
|
|
362
|
+
}
|
|
363
|
+
return null;
|
|
364
|
+
}
|
|
365
|
+
}
|
|
366
|
+
exports.CronExpression = CronExpression;
|
|
367
|
+
//# sourceMappingURL=CronExpression.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CronExpression.js","sourceRoot":"","sources":["../../../resources/scheduler/CronExpression.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import { CronExpression } from './CronExpression.ts';
|
|
2
|
+
export declare const HEARTBEAT_INTERVAL_MS: number;
|
|
3
|
+
export declare const STALE_THRESHOLD_MS: number;
|
|
4
|
+
export declare const FAILOVER_WATCHER_INTERVAL_MS: number;
|
|
5
|
+
export interface JobRunContext {
|
|
6
|
+
jobName: string;
|
|
7
|
+
scheduledAt: Date;
|
|
8
|
+
catchUp: boolean;
|
|
9
|
+
}
|
|
10
|
+
export interface ScheduledJob {
|
|
11
|
+
name: string;
|
|
12
|
+
componentName: string;
|
|
13
|
+
cron?: CronExpression;
|
|
14
|
+
intervalMs?: number;
|
|
15
|
+
timezone?: string;
|
|
16
|
+
handler: (context: JobRunContext) => unknown;
|
|
17
|
+
}
|
|
18
|
+
type EngineRole = 'inactive' | 'follower' | 'leader';
|
|
19
|
+
/**
|
|
20
|
+
* Job handlers and storage drivers can throw anything — including objects
|
|
21
|
+
* whose property getters themselves throw — so even reading .message is
|
|
22
|
+
* guarded here (surfaced by review).
|
|
23
|
+
*/
|
|
24
|
+
export declare function safeErrorMessage(error: unknown): string;
|
|
25
|
+
/**
|
|
26
|
+
* Deterministic election: the alphabetically-first node wins, excluding a
|
|
27
|
+
* stale leader so a wedged node cannot immediately re-elect itself. Every node
|
|
28
|
+
* evaluates this identically against the same replicated state, so no
|
|
29
|
+
* consensus round is needed.
|
|
30
|
+
*/
|
|
31
|
+
export declare function pickNextLeader(roster: string[], staleLeader: string | null): string | null;
|
|
32
|
+
export declare function isHeartbeatStale(lastHeartbeat: string | undefined, now?: number): boolean;
|
|
33
|
+
export declare const PROMOTION_ESCALATION_MS: number;
|
|
34
|
+
/**
|
|
35
|
+
* How long this node should observe a leaderless cluster before promoting
|
|
36
|
+
* itself. The preferred (alphabetically-first eligible) node promotes
|
|
37
|
+
* immediately; each subsequent node adds one escalation interval, so a dead or
|
|
38
|
+
* never-started preferred node cannot deadlock the cluster — the next node in
|
|
39
|
+
* line claims leadership one rung later, and sticky leadership plus the
|
|
40
|
+
* heartbeat takeover check heal any race between rungs.
|
|
41
|
+
*/
|
|
42
|
+
export declare function promotionWaitMs(roster: string[], self: string, staleLeader: string | null): number;
|
|
43
|
+
/**
|
|
44
|
+
* The cron occurrence that should have fired but didn't, or null if the job is
|
|
45
|
+
* up to date. `baseline` is the job's last run (or when it was first seen, so
|
|
46
|
+
* a newly-deployed job waits for its first scheduled time instead of firing
|
|
47
|
+
* immediately).
|
|
48
|
+
*/
|
|
49
|
+
export declare function findMissedCronOccurrence(cron: CronExpression, timezone: string | undefined, baseline: Date, now: Date): Date | null;
|
|
50
|
+
/**
|
|
51
|
+
* Register (or replace) the scheduled jobs for a component. Called from the
|
|
52
|
+
* scheduler plugin's handleApplication on the scheduling worker; safe to call
|
|
53
|
+
* repeatedly — a reload or redeploy replaces the component's whole job set.
|
|
54
|
+
*/
|
|
55
|
+
export declare function registerComponentJobs(componentName: string, jobs: ScheduledJob[]): void;
|
|
56
|
+
/**
|
|
57
|
+
* Cancel timers and forget the jobs of a component (its scope is closing —
|
|
58
|
+
* worker shutdown, redeploy, or a discarded deploy-validation load).
|
|
59
|
+
*
|
|
60
|
+
* Leadership is deliberately retained even if this empties the job set: the
|
|
61
|
+
* common cause is a reload that re-registers moments later, and stepping down
|
|
62
|
+
* here would leave the engine unable to re-elect (startSchedulerEngine is
|
|
63
|
+
* one-shot per worker). An idle leader heartbeating a zero-job cluster is
|
|
64
|
+
* harmless and resolves on the next worker restart.
|
|
65
|
+
*/
|
|
66
|
+
export declare function unregisterComponentJobs(componentName: string): void;
|
|
67
|
+
/**
|
|
68
|
+
* Start the engine's cluster role (leader or follower). Idempotent; called
|
|
69
|
+
* once per scheduling worker regardless of how many components declare jobs.
|
|
70
|
+
* All the real work happens asynchronously so the caller (handleApplication,
|
|
71
|
+
* which holds a cross-thread load lock with a 30s timeout) returns fast.
|
|
72
|
+
*/
|
|
73
|
+
export declare function startSchedulerEngine(): void;
|
|
74
|
+
/** @internal — testing only: resolves when the initial election has settled */
|
|
75
|
+
export declare function electionSettledForTests(): Promise<void>;
|
|
76
|
+
/**
|
|
77
|
+
* @internal — testing only: run one heartbeat tick immediately (same body the
|
|
78
|
+
* interval runs), so tests can drive lease renewal / takeover checks without
|
|
79
|
+
* waiting out HEARTBEAT_INTERVAL_MS. Same seam pattern as
|
|
80
|
+
* setCoolingFunctionForTests in transactionLogCooling.
|
|
81
|
+
*/
|
|
82
|
+
export declare function runHeartbeatForTests(): Promise<void>;
|
|
83
|
+
/** @internal — testing only: run one failover-watcher tick immediately */
|
|
84
|
+
export declare function runFailoverCheckForTests(): Promise<void>;
|
|
85
|
+
/** Reset all engine state and timers. Intended for tests. */
|
|
86
|
+
export declare function stopSchedulerEngine(): void;
|
|
87
|
+
export declare function getEngineRole(): EngineRole;
|
|
88
|
+
/** @internal — testing only */
|
|
89
|
+
export declare function getRegisteredJobNames(componentName: string): string[];
|
|
90
|
+
export declare function sanitizeStoredError(message: string): string;
|
|
91
|
+
export {};
|