@happyvertical/smrt-jobs 0.55.21 → 0.55.24
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/AGENTS.md +2 -2
- package/README.md +5 -1
- package/dist/chunks/{runner-B8_TYooy.js → runner-CbKjN2tD.js} +2 -2
- package/dist/chunks/{runner-B8_TYooy.js.map → runner-CbKjN2tD.js.map} +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +140 -39
- package/dist/index.js.map +1 -1
- package/dist/manifest.json +1 -1
- package/dist/runner.js +1 -1
- package/dist/schedule-runner.d.ts +30 -4
- package/dist/schedule-runner.d.ts.map +1 -1
- package/dist/smrt-knowledge.json +5 -5
- package/dist/svelte/components/JobList.svelte +2 -2
- package/package.json +11 -11
package/dist/index.d.ts
CHANGED
|
@@ -43,7 +43,7 @@ export { type CreateMcpTaskInput, createMcpTaskResult, getMcpTaskMarker, MCP_TAS
|
|
|
43
43
|
export { type BackgroundCapable, type BgOptions, withBackgroundJobs, } from './object-extension.js';
|
|
44
44
|
export { DEFAULT_JOB_RETENTION, DEFAULT_RETENTION_SWEEP_INTERVAL_MS, JOB_EVENTS_RETENTION_TASK, JOBS_RETENTION_TASK, type JobRetentionOptions, type RetentionSweeper, type RetentionSweeperOptions, registerJobRetentionTasks, startRetentionSweeper, unregisterJobRetentionTasks, } from './retention.js';
|
|
45
45
|
export { createTaskRunner, getActiveJobExecutionContext, isRunnerExecutionContext, JobTimeoutError, TaskRunner, type TaskRunnerConfig, type TaskRunnerEvents, } from './runner.js';
|
|
46
|
-
export { createScheduleRunner, getNextCronDate, type ScheduleInfo, ScheduleRunner, type ScheduleRunnerConfig, type ScheduleRunnerEvents, validateCronExpression, } from './schedule-runner.js';
|
|
46
|
+
export { createScheduleRunner, getNextCronDate, SCHEDULED_JOB_QUEUE, type ScheduleInfo, ScheduleRunner, type ScheduleRunnerConfig, type ScheduleRunnerEvents, validateCronExpression, } from './schedule-runner.js';
|
|
47
47
|
export { type ClaimReadyOptions, type JobStatus, type ListReadyOptions, SmrtJob, SmrtJobCollection, type SmrtJobData, type TimeoutBehavior, } from './smrt-job.js';
|
|
48
48
|
export { type JobEventCursor, type ListJobEventsOptions, type ListTerminalOutcomesOptions, SmrtJobEvent, SmrtJobEventCollection, type SmrtJobEventData, type SmrtJobEventLevel, type SmrtJobEventType, type SmrtJobTerminalOutcome, type SmrtJobTerminalOutcomePage, type SmrtJobTerminalStatus, } from './smrt-job-event.js';
|
|
49
49
|
export { type RegisterWorkerInput, SmrtWorker, SmrtWorkerCollection, } from './smrt-worker.js';
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AAKH,OAAO,wBAAwB,CAAC;AAYhC,OAAO,EACL,6BAA6B,EAC7B,KAAK,uBAAuB,EAC5B,kBAAkB,EAClB,YAAY,EACZ,sBAAsB,EACtB,4BAA4B,EAC5B,0BAA0B,EAC1B,eAAe,EACf,sBAAsB,EACtB,yBAAyB,GAC1B,MAAM,wBAAwB,CAAC;AAChC,OAAO,EACL,iCAAiC,EACjC,KAAK,0BAA0B,EAC/B,KAAK,uBAAuB,GAC7B,MAAM,gCAAgC,CAAC;AAExC,OAAO,EACL,yBAAyB,EACzB,kBAAkB,GACnB,MAAM,sBAAsB,CAAC;AAE9B,OAAO,EACL,KAAK,qBAAqB,EAC1B,KAAK,wBAAwB,EAC7B,KAAK,yBAAyB,EAC9B,aAAa,EACb,uBAAuB,EACvB,KAAK,mBAAmB,EACxB,KAAK,gBAAgB,EACrB,KAAK,yBAAyB,EAC9B,KAAK,wBAAwB,EAC7B,yBAAyB,EACzB,KAAK,sBAAsB,EAC3B,sBAAsB,EACtB,KAAK,6BAA6B,EAClC,KAAK,cAAc,GACpB,MAAM,uBAAuB,CAAC;AAE/B,OAAO,EACL,UAAU,EACV,KAAK,QAAQ,EACb,UAAU,EACV,gBAAgB,GACjB,MAAM,kBAAkB,CAAC;AAG1B,OAAO,EACL,SAAS,EACT,KAAK,SAAS,EACd,KAAK,WAAW,GACjB,MAAM,iBAAiB,CAAC;AAEzB,OAAO,EACL,KAAK,UAAU,EACf,gBAAgB,EAChB,KAAK,aAAa,EAClB,KAAK,mBAAmB,EACxB,KAAK,gBAAgB,GACtB,MAAM,uBAAuB,CAAC;AAE/B,OAAO,EACL,KAAK,kBAAkB,EACvB,mBAAmB,EACnB,gBAAgB,EAChB,mBAAmB,EACnB,KAAK,OAAO,EACZ,KAAK,gBAAgB,EACrB,qBAAqB,EACrB,KAAK,mBAAmB,EACxB,KAAK,gBAAgB,EACrB,oBAAoB,EACpB,KAAK,aAAa,EAClB,YAAY,EACZ,qBAAqB,EACrB,0BAA0B,EAC1B,mBAAmB,EACnB,WAAW,GACZ,MAAM,eAAe,CAAC;AAEvB,OAAO,EACL,KAAK,iBAAiB,EACtB,KAAK,SAAS,EACd,kBAAkB,GACnB,MAAM,uBAAuB,CAAC;AAE/B,OAAO,EACL,qBAAqB,EACrB,mCAAmC,EACnC,yBAAyB,EACzB,mBAAmB,EACnB,KAAK,mBAAmB,EACxB,KAAK,gBAAgB,EACrB,KAAK,uBAAuB,EAC5B,yBAAyB,EACzB,qBAAqB,EACrB,2BAA2B,GAC5B,MAAM,gBAAgB,CAAC;AAExB,OAAO,EACL,gBAAgB,EAChB,4BAA4B,EAC5B,wBAAwB,EACxB,eAAe,EACf,UAAU,EACV,KAAK,gBAAgB,EACrB,KAAK,gBAAgB,GACtB,MAAM,aAAa,CAAC;AAGrB,OAAO,EACL,oBAAoB,EACpB,eAAe,EACf,KAAK,YAAY,EACjB,cAAc,EACd,KAAK,oBAAoB,EACzB,KAAK,oBAAoB,EACzB,sBAAsB,GACvB,MAAM,sBAAsB,CAAC;AAE9B,OAAO,EACL,KAAK,iBAAiB,EACtB,KAAK,SAAS,EACd,KAAK,gBAAgB,EACrB,OAAO,EACP,iBAAiB,EACjB,KAAK,WAAW,EAChB,KAAK,eAAe,GACrB,MAAM,eAAe,CAAC;AAGvB,OAAO,EACL,KAAK,cAAc,EACnB,KAAK,oBAAoB,EACzB,KAAK,2BAA2B,EAChC,YAAY,EACZ,sBAAsB,EACtB,KAAK,gBAAgB,EACrB,KAAK,iBAAiB,EACtB,KAAK,gBAAgB,EACrB,KAAK,sBAAsB,EAC3B,KAAK,0BAA0B,EAC/B,KAAK,qBAAqB,GAC3B,MAAM,qBAAqB,CAAC;AAG7B,OAAO,EACL,KAAK,mBAAmB,EACxB,UAAU,EACV,oBAAoB,GACrB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EACL,eAAe,EACf,aAAa,EACb,kBAAkB,EAClB,oBAAoB,GACrB,MAAM,sBAAsB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { A as SmrtJobCollection, B as isBackgroundEligibleMethod, C as DEFAULT_RETENTION_SWEEP_INTERVAL_MS, D as startRetentionSweeper, E as registerJobRetentionTasks, F as TenantJobCapExceededError, I as assertWithinTenantCreationCap, L as backgroundEligible, M as SmrtJobEventCollection, N as DEFAULT_TENANT_JOB_CAP, O as unregisterJobRetentionTasks, P as MAX_JOB_RETRIES, R as clampRetries, S as DEFAULT_JOB_RETENTION, T as JOB_EVENTS_RETENTION_TASK, V as markBackgroundEligible, _ as requestMcpTaskInput, a as isRunnerExecutionContext, b as redactErrorForPersistence, c as SmrtWorkerCollection, d as McpTaskNotFoundError, f as McpTaskStore, g as requestMcpTaskContinuation, h as getMcpTaskMarker, i as getActiveJobExecutionContext, j as SmrtJobEvent, k as SmrtJob, l as MCP_TASKS_EXTENSION, m as createMcpTaskResult, n as TaskRunner, o as DEFAULT_TASK_HEARTBEAT_INTERVAL_MS, p as McpTaskSuspendedError, r as createTaskRunner, s as SmrtWorker, t as JobTimeoutError, u as McpTaskCancelledError, v as taskFromJob, w as JOBS_RETENTION_TASK, x as redactErrorMessage, y as JobContextLogger, z as getBackgroundEligibleMethods } from "./chunks/runner-
|
|
1
|
+
import { A as SmrtJobCollection, B as isBackgroundEligibleMethod, C as DEFAULT_RETENTION_SWEEP_INTERVAL_MS, D as startRetentionSweeper, E as registerJobRetentionTasks, F as TenantJobCapExceededError, I as assertWithinTenantCreationCap, L as backgroundEligible, M as SmrtJobEventCollection, N as DEFAULT_TENANT_JOB_CAP, O as unregisterJobRetentionTasks, P as MAX_JOB_RETRIES, R as clampRetries, S as DEFAULT_JOB_RETENTION, T as JOB_EVENTS_RETENTION_TASK, V as markBackgroundEligible, _ as requestMcpTaskInput, a as isRunnerExecutionContext, b as redactErrorForPersistence, c as SmrtWorkerCollection, d as McpTaskNotFoundError, f as McpTaskStore, g as requestMcpTaskContinuation, h as getMcpTaskMarker, i as getActiveJobExecutionContext, j as SmrtJobEvent, k as SmrtJob, l as MCP_TASKS_EXTENSION, m as createMcpTaskResult, n as TaskRunner, o as DEFAULT_TASK_HEARTBEAT_INTERVAL_MS, p as McpTaskSuspendedError, r as createTaskRunner, s as SmrtWorker, t as JobTimeoutError, u as McpTaskCancelledError, v as taskFromJob, w as JOBS_RETENTION_TASK, x as redactErrorMessage, y as JobContextLogger, z as getBackgroundEligibleMethods } from "./chunks/runner-CbKjN2tD.js";
|
|
2
2
|
import { c as unregisterLiveWorker, i as registerLiveWorker, n as isWorkerAlive, t as createWorkerKey } from "./chunks/worker-liveness-C1Gjnhax.js";
|
|
3
3
|
import { ObjectRegistry, SmrtCollection, SmrtObject, detectEngine, field, smrt } from "@happyvertical/smrt-core";
|
|
4
4
|
import { createLogger } from "@happyvertical/logger";
|
|
@@ -875,6 +875,7 @@ function withBackgroundJobs(BaseClass) {
|
|
|
875
875
|
}
|
|
876
876
|
//#endregion
|
|
877
877
|
//#region src/schedule-runner.ts
|
|
878
|
+
var SCHEDULED_JOB_QUEUE = "agents";
|
|
878
879
|
var DEFAULT_CONFIG = {
|
|
879
880
|
id: "",
|
|
880
881
|
pollInterval: 6e4,
|
|
@@ -1114,7 +1115,22 @@ var ScheduleRunner = class extends EventEmitter {
|
|
|
1114
1115
|
if (schedule.method_args) methodArgs = typeof schedule.method_args === "string" ? JSON.parse(schedule.method_args) : schedule.method_args;
|
|
1115
1116
|
let agentConfig = {};
|
|
1116
1117
|
if (schedule.agent_config) agentConfig = typeof schedule.agent_config === "string" ? JSON.parse(schedule.agent_config) : schedule.agent_config;
|
|
1117
|
-
const
|
|
1118
|
+
const timezone = typeof schedule.timezone === "string" && schedule.timezone.trim() ? schedule.timezone.trim() : "UTC";
|
|
1119
|
+
try {
|
|
1120
|
+
validateCronExpression(schedule.cron);
|
|
1121
|
+
validateCronTimezone(timezone);
|
|
1122
|
+
} catch (error) {
|
|
1123
|
+
await this.db.query(`UPDATE _smrt_agent_schedules
|
|
1124
|
+
SET status = 'error', last_error = ?
|
|
1125
|
+
WHERE id = ?`, redactErrorForPersistence(error), schedule.id);
|
|
1126
|
+
this.emit("schedule:error", scheduleInfo, error);
|
|
1127
|
+
this.logger.error("Schedule has an invalid cron or time zone", {
|
|
1128
|
+
scheduleId: schedule.id,
|
|
1129
|
+
error
|
|
1130
|
+
});
|
|
1131
|
+
return;
|
|
1132
|
+
}
|
|
1133
|
+
const nextRun = getNextCronDate(schedule.cron, timezone);
|
|
1118
1134
|
const args = {
|
|
1119
1135
|
...methodArgs,
|
|
1120
1136
|
_scheduleId: schedule.id
|
|
@@ -1122,7 +1138,7 @@ var ScheduleRunner = class extends EventEmitter {
|
|
|
1122
1138
|
if (Object.keys(agentConfig).length > 0) args._agentConfig = agentConfig;
|
|
1123
1139
|
const job = await this.jobCollection.enqueueJob({
|
|
1124
1140
|
tenantId: typeof schedule.tenant_id === "string" && schedule.tenant_id.length > 0 ? schedule.tenant_id : null,
|
|
1125
|
-
queue:
|
|
1141
|
+
queue: SCHEDULED_JOB_QUEUE,
|
|
1126
1142
|
objectType: canonicalAgentType,
|
|
1127
1143
|
objectId: schedule.agent_id,
|
|
1128
1144
|
method: schedule.method || "run",
|
|
@@ -1223,48 +1239,133 @@ function validateCronExpression(cron) {
|
|
|
1223
1239
|
});
|
|
1224
1240
|
return parts;
|
|
1225
1241
|
}
|
|
1226
|
-
|
|
1242
|
+
var MINUTE_MS = 6e4;
|
|
1243
|
+
var DAY_MS = 24 * (60 * MINUTE_MS);
|
|
1244
|
+
var CRON_SEARCH_HORIZON_MS = 525600 * MINUTE_MS;
|
|
1245
|
+
var zoneFormatters = /* @__PURE__ */ new Map();
|
|
1246
|
+
function resolveZoneOffset(timezone) {
|
|
1247
|
+
if (timezone === void 0 || timezone === null) return (epochMs) => -new Date(epochMs).getTimezoneOffset() * MINUTE_MS;
|
|
1248
|
+
let formatter = zoneFormatters.get(timezone);
|
|
1249
|
+
if (!formatter) {
|
|
1250
|
+
try {
|
|
1251
|
+
formatter = new Intl.DateTimeFormat("en-US", {
|
|
1252
|
+
timeZone: timezone,
|
|
1253
|
+
hourCycle: "h23",
|
|
1254
|
+
year: "numeric",
|
|
1255
|
+
month: "numeric",
|
|
1256
|
+
day: "numeric",
|
|
1257
|
+
hour: "numeric",
|
|
1258
|
+
minute: "numeric",
|
|
1259
|
+
second: "numeric"
|
|
1260
|
+
});
|
|
1261
|
+
} catch {
|
|
1262
|
+
throw new Error(`Invalid cron timezone: "${timezone}" is not a recognized IANA time zone`);
|
|
1263
|
+
}
|
|
1264
|
+
zoneFormatters.set(timezone, formatter);
|
|
1265
|
+
}
|
|
1266
|
+
const zoned = formatter;
|
|
1267
|
+
return (epochMs) => {
|
|
1268
|
+
const fields = {};
|
|
1269
|
+
for (const part of zoned.formatToParts(epochMs)) if (part.type !== "literal") fields[part.type] = Number(part.value);
|
|
1270
|
+
return Date.UTC(fields.year, fields.month - 1, fields.day, fields.hour % 24, fields.minute, fields.second) - (epochMs - (epochMs % 1e3 + 1e3) % 1e3);
|
|
1271
|
+
};
|
|
1272
|
+
}
|
|
1273
|
+
function wallTimeInstants(wallMs, offsetAt) {
|
|
1274
|
+
const offsetBefore = offsetAt(wallMs - DAY_MS);
|
|
1275
|
+
const offsetAfter = offsetAt(wallMs + DAY_MS);
|
|
1276
|
+
const instants = [];
|
|
1277
|
+
for (const offset of /* @__PURE__ */ new Set([offsetBefore, offsetAfter])) {
|
|
1278
|
+
const instant = wallMs - offset;
|
|
1279
|
+
if (offsetAt(instant) === offset) instants.push(instant);
|
|
1280
|
+
}
|
|
1281
|
+
instants.sort((a, b) => a - b);
|
|
1282
|
+
return {
|
|
1283
|
+
instants,
|
|
1284
|
+
offsetBefore,
|
|
1285
|
+
offsetAfter
|
|
1286
|
+
};
|
|
1287
|
+
}
|
|
1288
|
+
function validateCronTimezone(timezone) {
|
|
1289
|
+
resolveZoneOffset(timezone);
|
|
1290
|
+
}
|
|
1291
|
+
function getNextCronDate(cron, timezone) {
|
|
1227
1292
|
const [minuteExpr, hourExpr, dayExpr, monthExpr, dowExpr] = validateCronExpression(cron);
|
|
1228
|
-
const
|
|
1229
|
-
candidate.setSeconds(0);
|
|
1230
|
-
candidate.setMilliseconds(0);
|
|
1231
|
-
candidate.setMinutes(candidate.getMinutes() + 1);
|
|
1293
|
+
const offsetAt = resolveZoneOffset(timezone);
|
|
1232
1294
|
const dayIsWildcard = dayExpr === "*";
|
|
1233
1295
|
const dowIsWildcard = dowExpr === "*";
|
|
1234
|
-
const
|
|
1235
|
-
|
|
1236
|
-
const
|
|
1237
|
-
const dow =
|
|
1238
|
-
const dowMatches = matchesCronField(dow, dowExpr) || dow === 0 && matchesCronField(7, dowExpr);
|
|
1239
|
-
|
|
1240
|
-
if (!dayIsWildcard
|
|
1241
|
-
|
|
1242
|
-
|
|
1243
|
-
|
|
1244
|
-
|
|
1245
|
-
|
|
1296
|
+
const fixedTime = !minuteExpr.includes("*") && !hourExpr.includes("*");
|
|
1297
|
+
const dayMatches = (wall) => {
|
|
1298
|
+
const domMatches = matchesCronField(wall.getUTCDate(), dayExpr, CRON_FIELD_RANGES[2]);
|
|
1299
|
+
const dow = wall.getUTCDay();
|
|
1300
|
+
const dowMatches = matchesCronField(dow, dowExpr, CRON_FIELD_RANGES[4]) || dow === 0 && matchesCronField(7, dowExpr, CRON_FIELD_RANGES[4]);
|
|
1301
|
+
if (!dayIsWildcard && !dowIsWildcard) return domMatches || dowMatches;
|
|
1302
|
+
if (!dayIsWildcard) return domMatches;
|
|
1303
|
+
if (!dowIsWildcard) return dowMatches;
|
|
1304
|
+
return true;
|
|
1305
|
+
};
|
|
1306
|
+
const now = Date.now();
|
|
1307
|
+
const threshold = now - (now % MINUTE_MS + MINUTE_MS) % MINUTE_MS + MINUTE_MS;
|
|
1308
|
+
const thresholdOffset = offsetAt(threshold);
|
|
1309
|
+
const thresholdSpread = Math.abs(offsetAt(threshold - DAY_MS) - offsetAt(threshold + DAY_MS));
|
|
1310
|
+
let wallMs = threshold + thresholdOffset - thresholdSpread;
|
|
1311
|
+
const wallEnd = threshold + thresholdOffset + CRON_SEARCH_HORIZON_MS;
|
|
1312
|
+
let best = null;
|
|
1313
|
+
let stopAfterWall = Number.POSITIVE_INFINITY;
|
|
1314
|
+
while (wallMs <= wallEnd && wallMs <= stopAfterWall) {
|
|
1315
|
+
const wall = new Date(wallMs);
|
|
1316
|
+
const year = wall.getUTCFullYear();
|
|
1317
|
+
const month = wall.getUTCMonth();
|
|
1318
|
+
const day = wall.getUTCDate();
|
|
1319
|
+
const hour = wall.getUTCHours();
|
|
1320
|
+
if (!matchesCronField(month + 1, monthExpr, CRON_FIELD_RANGES[3])) {
|
|
1321
|
+
wallMs = Date.UTC(year, month + 1, 1);
|
|
1322
|
+
continue;
|
|
1323
|
+
}
|
|
1324
|
+
if (!dayMatches(wall)) {
|
|
1325
|
+
wallMs = Date.UTC(year, month, day + 1);
|
|
1326
|
+
continue;
|
|
1327
|
+
}
|
|
1328
|
+
if (!matchesCronField(hour, hourExpr, CRON_FIELD_RANGES[1])) {
|
|
1329
|
+
wallMs = Date.UTC(year, month, day, hour + 1);
|
|
1330
|
+
continue;
|
|
1331
|
+
}
|
|
1332
|
+
if (!matchesCronField(wall.getUTCMinutes(), minuteExpr, CRON_FIELD_RANGES[0])) {
|
|
1333
|
+
wallMs += MINUTE_MS;
|
|
1334
|
+
continue;
|
|
1335
|
+
}
|
|
1336
|
+
const { instants, offsetBefore, offsetAfter } = wallTimeInstants(wallMs, offsetAt);
|
|
1337
|
+
let candidates = instants;
|
|
1338
|
+
if (instants.length === 0) candidates = fixedTime ? [wallMs - offsetBefore] : [];
|
|
1339
|
+
else if (instants.length > 1 && fixedTime) candidates = [instants[0]];
|
|
1340
|
+
for (const instant of candidates) if (instant >= threshold && (best === null || instant < best)) {
|
|
1341
|
+
if (best === null) stopAfterWall = wallMs + Math.abs(offsetBefore - offsetAfter);
|
|
1342
|
+
best = instant;
|
|
1343
|
+
}
|
|
1344
|
+
wallMs += MINUTE_MS;
|
|
1246
1345
|
}
|
|
1247
|
-
throw new Error(`Could not find next run date for cron: ${cron}`);
|
|
1346
|
+
if (best === null) throw new Error(`Could not find next run date for cron: ${cron}`);
|
|
1347
|
+
return new Date(best);
|
|
1248
1348
|
}
|
|
1249
|
-
function matchesCronField(value, expr) {
|
|
1349
|
+
function matchesCronField(value, expr, range) {
|
|
1250
1350
|
if (expr === "*") return true;
|
|
1251
|
-
|
|
1252
|
-
const [
|
|
1253
|
-
const step = parseInt(stepStr, 10);
|
|
1254
|
-
|
|
1255
|
-
|
|
1256
|
-
|
|
1257
|
-
|
|
1258
|
-
|
|
1259
|
-
|
|
1351
|
+
return expr.split(",").some((term) => {
|
|
1352
|
+
const [body, stepStr] = term.split("/");
|
|
1353
|
+
const step = stepStr === void 0 ? 1 : parseInt(stepStr, 10);
|
|
1354
|
+
let start;
|
|
1355
|
+
let end;
|
|
1356
|
+
if (body === "*") {
|
|
1357
|
+
start = range.min;
|
|
1358
|
+
end = range.max;
|
|
1359
|
+
} else if (body.includes("-")) {
|
|
1360
|
+
const [startStr, endStr] = body.split("-");
|
|
1361
|
+
start = parseInt(startStr, 10);
|
|
1362
|
+
end = parseInt(endStr, 10);
|
|
1363
|
+
} else {
|
|
1364
|
+
start = parseInt(body, 10);
|
|
1365
|
+
end = stepStr === void 0 ? start : range.max;
|
|
1260
1366
|
}
|
|
1261
|
-
|
|
1262
|
-
|
|
1263
|
-
const [startStr, endStr] = expr.split("-");
|
|
1264
|
-
return value >= parseInt(startStr, 10) && value <= parseInt(endStr, 10);
|
|
1265
|
-
}
|
|
1266
|
-
if (expr.includes(",")) return expr.split(",").map((v) => parseInt(v.trim(), 10)).includes(value);
|
|
1267
|
-
return value === parseInt(expr, 10);
|
|
1367
|
+
return value >= start && value <= end && (value - start) % step === 0;
|
|
1368
|
+
});
|
|
1268
1369
|
}
|
|
1269
1370
|
function createScheduleRunner(config) {
|
|
1270
1371
|
return new ScheduleRunner(config);
|
|
@@ -1273,6 +1374,6 @@ function createScheduleRunner(config) {
|
|
|
1273
1374
|
//#region src/index.ts
|
|
1274
1375
|
registerJobRetentionTasks();
|
|
1275
1376
|
//#endregion
|
|
1276
|
-
export { DEFAULT_JOB_RETENTION, DEFAULT_RETENTION_SWEEP_INTERVAL_MS, DEFAULT_TENANT_JOB_CAP, ForgeDelivery, ForgeDeliveryCollection, ForgeProjectionCheckpoint, ForgeProjectionRuntime, JOBS_RETENTION_TASK, JOB_EVENTS_RETENTION_TASK, JobBuilder, JobContextLogger, JobHandle, JobTimeoutError, MAX_JOB_RETRIES, MCP_TASKS_EXTENSION, McpTaskCancelledError, McpTaskNotFoundError, McpTaskStore, McpTaskSuspendedError, ScheduleRunner, SmrtJob, SmrtJobCollection, SmrtJobEvent, SmrtJobEventCollection, SmrtWorker, SmrtWorkerCollection, TaskRunner, TenantJobCapExceededError, assertWithinTenantCreationCap, backgroundEligible, clampRetries, createHmacDurableJobPayloadSigner, createMcpTaskResult, createScheduleRunner, createTaskRunner, createWorkerKey, getActiveJobExecutionContext, getBackgroundEligibleMethods, getMcpTaskMarker, getNextCronDate, isBackgroundEligibleMethod, isRunnerExecutionContext, isWorkerAlive, markBackgroundEligible, parseDelay, priorityToNumber, redactErrorForPersistence, redactErrorMessage, registerJobRetentionTasks, registerLiveWorker, requestMcpTaskContinuation, requestMcpTaskInput, startRetentionSweeper, taskFromJob, unregisterJobRetentionTasks, unregisterLiveWorker, validateCronExpression, withBackgroundJobs };
|
|
1377
|
+
export { DEFAULT_JOB_RETENTION, DEFAULT_RETENTION_SWEEP_INTERVAL_MS, DEFAULT_TENANT_JOB_CAP, ForgeDelivery, ForgeDeliveryCollection, ForgeProjectionCheckpoint, ForgeProjectionRuntime, JOBS_RETENTION_TASK, JOB_EVENTS_RETENTION_TASK, JobBuilder, JobContextLogger, JobHandle, JobTimeoutError, MAX_JOB_RETRIES, MCP_TASKS_EXTENSION, McpTaskCancelledError, McpTaskNotFoundError, McpTaskStore, McpTaskSuspendedError, SCHEDULED_JOB_QUEUE, ScheduleRunner, SmrtJob, SmrtJobCollection, SmrtJobEvent, SmrtJobEventCollection, SmrtWorker, SmrtWorkerCollection, TaskRunner, TenantJobCapExceededError, assertWithinTenantCreationCap, backgroundEligible, clampRetries, createHmacDurableJobPayloadSigner, createMcpTaskResult, createScheduleRunner, createTaskRunner, createWorkerKey, getActiveJobExecutionContext, getBackgroundEligibleMethods, getMcpTaskMarker, getNextCronDate, isBackgroundEligibleMethod, isRunnerExecutionContext, isWorkerAlive, markBackgroundEligible, parseDelay, priorityToNumber, redactErrorForPersistence, redactErrorMessage, registerJobRetentionTasks, registerLiveWorker, requestMcpTaskContinuation, requestMcpTaskInput, startRetentionSweeper, taskFromJob, unregisterJobRetentionTasks, unregisterLiveWorker, validateCronExpression, withBackgroundJobs };
|
|
1277
1378
|
|
|
1278
1379
|
//# sourceMappingURL=index.js.map
|