@cronwatch/sdk 0.5.1 → 0.6.1
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/dist/index.cjs +31 -19
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +31 -19
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -155,15 +155,15 @@ function runCovers(startedAt, dueAt, followingAt = null) {
|
|
|
155
155
|
}
|
|
156
156
|
function inSpringForwardGap(parsed, startedAt, fireAt) {
|
|
157
157
|
const LOOKBACK = 3 * 36e5;
|
|
158
|
-
const
|
|
158
|
+
const after2 = utcOffset(fireAt, parsed.timezone);
|
|
159
159
|
const before = utcOffset(fireAt - LOOKBACK, parsed.timezone);
|
|
160
|
-
const gap =
|
|
160
|
+
const gap = after2 - before;
|
|
161
161
|
if (gap <= 0) return false;
|
|
162
162
|
let lo = fireAt - LOOKBACK;
|
|
163
163
|
let hi = fireAt;
|
|
164
164
|
while (hi - lo > 6e4) {
|
|
165
165
|
const mid = lo + Math.floor((hi - lo) / 2);
|
|
166
|
-
if (utcOffset(mid, parsed.timezone) ===
|
|
166
|
+
if (utcOffset(mid, parsed.timezone) === after2) hi = mid;
|
|
167
167
|
else lo = mid;
|
|
168
168
|
}
|
|
169
169
|
const jumpAt = Math.floor(hi / 6e4) * 6e4;
|
|
@@ -501,8 +501,8 @@ ${out}`);
|
|
|
501
501
|
break;
|
|
502
502
|
}
|
|
503
503
|
title = `${name} recovered`;
|
|
504
|
-
const
|
|
505
|
-
lines.push(`A run ${run ? when(run.startedAt, now) : "just now"} succeeded${
|
|
504
|
+
const after2 = draft.details.after.map((c) => c.replace("_", " ")).join(", ");
|
|
505
|
+
lines.push(`A run ${run ? when(run.startedAt, now) : "just now"} succeeded${after2 ? ` after: ${after2}` : ""}.`);
|
|
506
506
|
if (run?.durationMs !== null && run?.durationMs !== void 0) lines.push(`Ran ${formatDuration(run.durationMs)}.`);
|
|
507
507
|
break;
|
|
508
508
|
}
|
|
@@ -689,6 +689,9 @@ function checkExpectation(expect, output) {
|
|
|
689
689
|
function escapeHtml(value) {
|
|
690
690
|
return String(value ?? "").replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """).replace(/'/g, "'");
|
|
691
691
|
}
|
|
692
|
+
function escapeName(value) {
|
|
693
|
+
return escapeHtml(value).replace(/([_:./-]+)(?=[^_:./-])/g, "$1<wbr>");
|
|
694
|
+
}
|
|
692
695
|
|
|
693
696
|
// src/routes/icons.ts
|
|
694
697
|
var ICON_SVG = '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 40 40"><rect width="40" height="40" rx="10" fill="#141417"/><rect x="0.5" y="0.5" width="39" height="39" rx="9.5" fill="none" stroke="#2a2a2f"/><circle cx="20" cy="20" r="10.5" fill="none" stroke="#f3f3f1" stroke-width="2"/><path d="M20 12.5V20h6" fill="none" stroke="#f3f3f1" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg>';
|
|
@@ -1035,7 +1038,7 @@ function dayTimeline(lanes, span, base, total) {
|
|
|
1035
1038
|
const { job } = input;
|
|
1036
1039
|
const parts = lane(input, span, { nowInLane: false, label: job.name });
|
|
1037
1040
|
return {
|
|
1038
|
-
html: `<li class="lane"><div class="who"><i class="sq ${stateClass(job)}" aria-hidden="true"></i><a class="name" href="${escapeHtml(base)}/jobs/${encodeURIComponent(job.name)}">${
|
|
1041
|
+
html: `<li class="lane"><div class="who"><i class="sq ${stateClass(job)}" aria-hidden="true"></i><a class="name" href="${escapeHtml(base)}/jobs/${encodeURIComponent(job.name)}">${escapeName(job.name)}</a><span class="sched">${escapeHtml(job.definition.schedule ?? "no schedule")}</span></div><div class="track">${parts.svg}${parts.note}</div></li>`,
|
|
1039
1042
|
words: `<li>${escapeHtml(`${job.name} (${job.definition.schedule ?? "no schedule"}): ${parts.words}.`)}</li>`
|
|
1040
1043
|
};
|
|
1041
1044
|
});
|
|
@@ -1275,7 +1278,7 @@ ${options.refresh ? `<meta http-equiv="refresh" content="${options.refresh}">` :
|
|
|
1275
1278
|
}
|
|
1276
1279
|
function brand(base, crumb) {
|
|
1277
1280
|
const home = `<a href="${h(base)}/">${MARK}<span>CronWatch</span></a>`;
|
|
1278
|
-
return crumb === void 0 ? `<p class="brand">${home}</p>` : `<p class="brand">${home}<span class="slash" aria-hidden="true">/</span><span class="crumb">${
|
|
1281
|
+
return crumb === void 0 ? `<p class="brand">${home}</p>` : `<p class="brand">${home}<span class="slash" aria-hidden="true">/</span><span class="crumb">${escapeName(crumb)}</span></p>`;
|
|
1279
1282
|
}
|
|
1280
1283
|
var HEALTH = {
|
|
1281
1284
|
failing: ["bad", "failing"],
|
|
@@ -1328,7 +1331,7 @@ function dashboardPage(jobs, runsByJob, now, base, checkedAt, lanes = jobs.slice
|
|
|
1328
1331
|
const last = job.lastRun;
|
|
1329
1332
|
const d = job.definition;
|
|
1330
1333
|
return `<tr>
|
|
1331
|
-
<td class="job"><a class="name" href="${h(base)}/jobs/${encodeURIComponent(job.name)}">${
|
|
1334
|
+
<td class="job"><a class="name" href="${h(base)}/jobs/${encodeURIComponent(job.name)}">${escapeName(job.name)}</a>${d.description ? `<span class="desc">${h(d.description)}</span>` : ""}</td>
|
|
1332
1335
|
<td class="health">${healthState(job)}</td>
|
|
1333
1336
|
<td class="nowrap hide-sm">${d.schedule ? `${h(d.schedule)}${d.timezone ? `<span class="tz">${h(d.timezone)}</span>` : ""}` : `<span class="muted">no schedule</span>`}</td>
|
|
1334
1337
|
<td class="nowrap last">${last ? `${runState(last)} ${stamp(last.startedAt, now)}${last.durationMs !== null ? `<span class="sub">took ${h(formatDuration(last.durationMs))}</span>` : ""}` : `<span class="muted">never</span>`}</td>
|
|
@@ -1400,7 +1403,7 @@ function jobPage(job, runs, now, base, complete = true) {
|
|
|
1400
1403
|
<section class="sec intro" aria-label="Job">
|
|
1401
1404
|
<h2>Job</h2>
|
|
1402
1405
|
<div>
|
|
1403
|
-
<h1 class="jobname">${
|
|
1406
|
+
<h1 class="jobname">${escapeName(job.name)}</h1>
|
|
1404
1407
|
${d.description ? `<p class="desc">${h(d.description)}</p>` : ""}
|
|
1405
1408
|
<p class="stateline">${healthState(job)}${why ? `<span class="why">${h(why)}</span>` : ""}</p>
|
|
1406
1409
|
<div class="actions">
|
|
@@ -2146,8 +2149,7 @@ var CronWatch = class {
|
|
|
2146
2149
|
const started = recorded ? this.updateState(name, (before) => ({ state: onRunStart(before), result: void 0 })).then(() => {
|
|
2147
2150
|
}, (e) => this.onError(e, `starting ${name}`)) : Promise.resolve();
|
|
2148
2151
|
const recorder = createRecorder(run);
|
|
2149
|
-
const
|
|
2150
|
-
if (typeof timer === "object" && "unref" in timer) timer.unref();
|
|
2152
|
+
const clearTimer = after(timeoutMs(definition), () => recorder.abort());
|
|
2151
2153
|
let result;
|
|
2152
2154
|
let error;
|
|
2153
2155
|
let threw = false;
|
|
@@ -2157,7 +2159,7 @@ var CronWatch = class {
|
|
|
2157
2159
|
error = e;
|
|
2158
2160
|
threw = true;
|
|
2159
2161
|
} finally {
|
|
2160
|
-
|
|
2162
|
+
clearTimer();
|
|
2161
2163
|
}
|
|
2162
2164
|
const finishedAt = this.now();
|
|
2163
2165
|
run.finishedAt = finishedAt;
|
|
@@ -2712,7 +2714,7 @@ ${id}`;
|
|
|
2712
2714
|
*/
|
|
2713
2715
|
start(every = "1m") {
|
|
2714
2716
|
if (this.timer) return;
|
|
2715
|
-
const ms = Math.max(5e3, parseDuration(every, "check interval"));
|
|
2717
|
+
const ms = Math.min(TIMER_MAX_MS, Math.max(5e3, parseDuration(every, "check interval")));
|
|
2716
2718
|
if (this.deferDelivery && !this.warnedDeferredStart) {
|
|
2717
2719
|
this.warnedDeferredStart = true;
|
|
2718
2720
|
console.warn('[cronwatch] start() was called with deliver: "check", so these checks send no alerts. Another process must run checks with deliver: "now" (the default) to send them.');
|
|
@@ -2851,20 +2853,30 @@ function checkRunId(job, id, method) {
|
|
|
2851
2853
|
throw new Error(`job "${job}": ${method}() cannot take a run id starting with "${RESERVED_RUN_ID_PREFIX}", which the pg_cron source uses for its runs`);
|
|
2852
2854
|
}
|
|
2853
2855
|
}
|
|
2854
|
-
function joinLines(before,
|
|
2855
|
-
if (before === null || before === "") return
|
|
2856
|
-
if (
|
|
2856
|
+
function joinLines(before, after2) {
|
|
2857
|
+
if (before === null || before === "") return after2;
|
|
2858
|
+
if (after2 === null) return before;
|
|
2857
2859
|
return `${before}
|
|
2858
|
-
${
|
|
2860
|
+
${after2}`;
|
|
2859
2861
|
}
|
|
2860
|
-
function joinOutput(before,
|
|
2861
|
-
const joined = joinLines(before,
|
|
2862
|
+
function joinOutput(before, after2) {
|
|
2863
|
+
const joined = joinLines(before, after2);
|
|
2862
2864
|
return joined === null ? null : capOutput(joined);
|
|
2863
2865
|
}
|
|
2864
2866
|
function clampLimit(limit, fallback, min) {
|
|
2865
2867
|
const n = typeof limit === "number" && Number.isFinite(limit) ? Math.trunc(limit) : fallback;
|
|
2866
2868
|
return Math.min(500, Math.max(min, n));
|
|
2867
2869
|
}
|
|
2870
|
+
var TIMER_MAX_MS = 2 ** 31 - 1;
|
|
2871
|
+
function after(ms, fn) {
|
|
2872
|
+
let timer;
|
|
2873
|
+
const arm = (left) => {
|
|
2874
|
+
timer = left > TIMER_MAX_MS ? setTimeout(() => arm(left - TIMER_MAX_MS), TIMER_MAX_MS) : setTimeout(fn, left);
|
|
2875
|
+
if (typeof timer === "object" && "unref" in timer) timer.unref();
|
|
2876
|
+
};
|
|
2877
|
+
arm(ms);
|
|
2878
|
+
return () => clearTimeout(timer);
|
|
2879
|
+
}
|
|
2868
2880
|
function withTimeout(promise, ms) {
|
|
2869
2881
|
return new Promise((resolve, reject) => {
|
|
2870
2882
|
const t = setTimeout(() => reject(new Error(`timed out after ${ms}ms`)), ms);
|