@cronwatch/sdk 0.6.1 → 0.8.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/README.md +2 -0
- package/dist/anthropic.cjs +13 -2
- package/dist/anthropic.cjs.map +1 -1
- package/dist/anthropic.d.cts +1 -1
- package/dist/anthropic.d.ts +1 -1
- package/dist/anthropic.js +13 -2
- package/dist/anthropic.js.map +1 -1
- package/dist/bugsnag.cjs +8 -1
- package/dist/bugsnag.cjs.map +1 -1
- package/dist/bugsnag.d.cts +1 -1
- package/dist/bugsnag.d.ts +1 -1
- package/dist/bugsnag.js +8 -1
- package/dist/bugsnag.js.map +1 -1
- package/dist/{client-B7bqnkI5.d.cts → client-B5hM4l-D.d.ts} +5 -2
- package/dist/{client-pmqH3apS.d.ts → client-Di5HAWQz.d.cts} +5 -2
- package/dist/d1.cjs +4 -1
- package/dist/d1.cjs.map +1 -1
- package/dist/d1.d.cts +1 -1
- package/dist/d1.d.ts +1 -1
- package/dist/d1.js +4 -1
- package/dist/d1.js.map +1 -1
- package/dist/datadog.cjs.map +1 -1
- package/dist/datadog.d.cts +1 -1
- package/dist/datadog.d.ts +1 -1
- package/dist/datadog.js.map +1 -1
- package/dist/discord.cjs.map +1 -1
- package/dist/discord.d.cts +1 -1
- package/dist/discord.d.ts +1 -1
- package/dist/discord.js.map +1 -1
- package/dist/{email-_H0faCh3.d.ts → email-Ciq7GRn4.d.ts} +1 -1
- package/dist/{email-BJ-z_epD.d.cts → email-DX6gkd5H.d.cts} +1 -1
- package/dist/honeybadger.cjs +8 -1
- package/dist/honeybadger.cjs.map +1 -1
- package/dist/honeybadger.d.cts +1 -1
- package/dist/honeybadger.d.ts +1 -1
- package/dist/honeybadger.js +8 -1
- package/dist/honeybadger.js.map +1 -1
- package/dist/index.cjs +98 -22
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +4 -4
- package/dist/index.d.ts +4 -4
- package/dist/index.js +98 -22
- package/dist/index.js.map +1 -1
- package/dist/mailgun.cjs.map +1 -1
- package/dist/mailgun.d.cts +2 -2
- package/dist/mailgun.d.ts +2 -2
- package/dist/mailgun.js.map +1 -1
- package/dist/newrelic.cjs.map +1 -1
- package/dist/newrelic.d.cts +1 -1
- package/dist/newrelic.d.ts +1 -1
- package/dist/newrelic.js.map +1 -1
- package/dist/pg-cron.cjs +8 -1
- package/dist/pg-cron.cjs.map +1 -1
- package/dist/pg-cron.d.cts +2 -2
- package/dist/pg-cron.d.ts +2 -2
- package/dist/pg-cron.js +8 -1
- package/dist/pg-cron.js.map +1 -1
- package/dist/postgres.cjs +6 -1
- package/dist/postgres.cjs.map +1 -1
- package/dist/postgres.d.cts +1 -1
- package/dist/postgres.d.ts +1 -1
- package/dist/postgres.js +6 -1
- package/dist/postgres.js.map +1 -1
- package/dist/postmark.cjs.map +1 -1
- package/dist/postmark.d.cts +2 -2
- package/dist/postmark.d.ts +2 -2
- package/dist/postmark.js.map +1 -1
- package/dist/resend.cjs.map +1 -1
- package/dist/resend.d.cts +2 -2
- package/dist/resend.d.ts +2 -2
- package/dist/resend.js.map +1 -1
- package/dist/rollbar.cjs +8 -1
- package/dist/rollbar.cjs.map +1 -1
- package/dist/rollbar.d.cts +1 -1
- package/dist/rollbar.d.ts +1 -1
- package/dist/rollbar.js +8 -1
- package/dist/rollbar.js.map +1 -1
- package/dist/sendgrid.cjs.map +1 -1
- package/dist/sendgrid.d.cts +2 -2
- package/dist/sendgrid.d.ts +2 -2
- package/dist/sendgrid.js.map +1 -1
- package/dist/sentry.cjs +8 -1
- package/dist/sentry.cjs.map +1 -1
- package/dist/sentry.d.cts +1 -1
- package/dist/sentry.d.ts +1 -1
- package/dist/sentry.js +8 -1
- package/dist/sentry.js.map +1 -1
- package/dist/ses.cjs.map +1 -1
- package/dist/ses.d.cts +2 -2
- package/dist/ses.d.ts +2 -2
- package/dist/ses.js.map +1 -1
- package/dist/slack.cjs.map +1 -1
- package/dist/slack.d.cts +1 -1
- package/dist/slack.d.ts +1 -1
- package/dist/slack.js.map +1 -1
- package/dist/sqlite.cjs +4 -1
- package/dist/sqlite.cjs.map +1 -1
- package/dist/sqlite.d.cts +1 -1
- package/dist/sqlite.d.ts +1 -1
- package/dist/sqlite.js +4 -1
- package/dist/sqlite.js.map +1 -1
- package/dist/twilio.cjs.map +1 -1
- package/dist/twilio.d.cts +1 -1
- package/dist/twilio.d.ts +1 -1
- package/dist/twilio.js.map +1 -1
- package/dist/{types-Ddq1MUPL.d.cts → types-BjBbCGeJ.d.cts} +4 -1
- package/dist/{types-Ddq1MUPL.d.ts → types-BjBbCGeJ.d.ts} +4 -1
- package/dist/webhook.cjs.map +1 -1
- package/dist/webhook.d.cts +1 -1
- package/dist/webhook.d.ts +1 -1
- package/dist/webhook.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.cts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { C as CronWatchOptions, a as CronWatch } from './client-
|
|
2
|
-
export { F as FetchHandler, H as HandlerFn, b as HandlerOptions, J as JobContext, c as JobFn, d as JobHandle, R as RecordRunOptions, e as Routes, f as RoutesOptions, g as RunHandle, h as RunOutcome, S as Source, i as SourceHost, j as StartOptions, k as consoleChannel, l as createRoutes, m as custom } from './client-
|
|
3
|
-
import { S as Store, D as Duration, b as AlertDraft, c as StoredJobDefinition, A as Alert } from './types-
|
|
4
|
-
export { a as AlertChannel, d as AlertDetails, e as AlertType, B as BudgetBreach, C as ChannelContext, f as CheckResult, g as Condition, E as ExpectRule, J as JobDefinition, h as JobHealth, i as JobOptions, j as JobState, k as JobSummary, R as Run, l as RunStatus, m as StoredJob, T as TriageContext, n as TriageFn } from './types-
|
|
1
|
+
import { C as CronWatchOptions, a as CronWatch } from './client-Di5HAWQz.cjs';
|
|
2
|
+
export { F as FetchHandler, H as HandlerFn, b as HandlerOptions, J as JobContext, c as JobFn, d as JobHandle, R as RecordRunOptions, e as Routes, f as RoutesOptions, g as RunHandle, h as RunOutcome, S as Source, i as SourceHost, j as StartOptions, k as consoleChannel, l as createRoutes, m as custom } from './client-Di5HAWQz.cjs';
|
|
3
|
+
import { S as Store, D as Duration, b as AlertDraft, c as StoredJobDefinition, A as Alert } from './types-BjBbCGeJ.cjs';
|
|
4
|
+
export { a as AlertChannel, d as AlertDetails, e as AlertType, B as BudgetBreach, C as ChannelContext, f as CheckResult, g as Condition, E as ExpectRule, J as JobDefinition, h as JobHealth, i as JobOptions, j as JobState, k as JobSummary, R as Run, l as RunStatus, m as StoredJob, T as TriageContext, n as TriageFn } from './types-BjBbCGeJ.cjs';
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
7
|
* Keeps everything in process memory. The default when no store is given,
|
package/dist/index.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { C as CronWatchOptions, a as CronWatch } from './client-
|
|
2
|
-
export { F as FetchHandler, H as HandlerFn, b as HandlerOptions, J as JobContext, c as JobFn, d as JobHandle, R as RecordRunOptions, e as Routes, f as RoutesOptions, g as RunHandle, h as RunOutcome, S as Source, i as SourceHost, j as StartOptions, k as consoleChannel, l as createRoutes, m as custom } from './client-
|
|
3
|
-
import { S as Store, D as Duration, b as AlertDraft, c as StoredJobDefinition, A as Alert } from './types-
|
|
4
|
-
export { a as AlertChannel, d as AlertDetails, e as AlertType, B as BudgetBreach, C as ChannelContext, f as CheckResult, g as Condition, E as ExpectRule, J as JobDefinition, h as JobHealth, i as JobOptions, j as JobState, k as JobSummary, R as Run, l as RunStatus, m as StoredJob, T as TriageContext, n as TriageFn } from './types-
|
|
1
|
+
import { C as CronWatchOptions, a as CronWatch } from './client-B5hM4l-D.js';
|
|
2
|
+
export { F as FetchHandler, H as HandlerFn, b as HandlerOptions, J as JobContext, c as JobFn, d as JobHandle, R as RecordRunOptions, e as Routes, f as RoutesOptions, g as RunHandle, h as RunOutcome, S as Source, i as SourceHost, j as StartOptions, k as consoleChannel, l as createRoutes, m as custom } from './client-B5hM4l-D.js';
|
|
3
|
+
import { S as Store, D as Duration, b as AlertDraft, c as StoredJobDefinition, A as Alert } from './types-BjBbCGeJ.js';
|
|
4
|
+
export { a as AlertChannel, d as AlertDetails, e as AlertType, B as BudgetBreach, C as ChannelContext, f as CheckResult, g as Condition, E as ExpectRule, J as JobDefinition, h as JobHealth, i as JobOptions, j as JobState, k as JobSummary, R as Run, l as RunStatus, m as StoredJob, T as TriageContext, n as TriageFn } from './types-BjBbCGeJ.js';
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
7
|
* Keeps everything in process memory. The default when no store is given,
|
package/dist/index.js
CHANGED
|
@@ -9,11 +9,14 @@ var UNIT_MS = {
|
|
|
9
9
|
d: 864e5,
|
|
10
10
|
w: 6048e5
|
|
11
11
|
};
|
|
12
|
+
var MAX_LENGTH = 64;
|
|
13
|
+
var QUOTED = 32;
|
|
12
14
|
function parseDuration(value, label = "duration") {
|
|
13
15
|
if (typeof value === "number") {
|
|
14
16
|
if (!Number.isFinite(value) || value < 0) throw new Error(`${label} must be a non-negative number of milliseconds`);
|
|
15
17
|
return value;
|
|
16
18
|
}
|
|
19
|
+
if (value.length > MAX_LENGTH) tooLong(value, label);
|
|
17
20
|
const text = value.trim().toLowerCase();
|
|
18
21
|
if (text === "") throw new Error(`${label} is empty`);
|
|
19
22
|
const re = /(\d+(?:\.\d+)?)\s*(ms|s|m|h|d|w)/g;
|
|
@@ -29,6 +32,16 @@ function parseDuration(value, label = "duration") {
|
|
|
29
32
|
}
|
|
30
33
|
return Math.round(total);
|
|
31
34
|
}
|
|
35
|
+
function tooLong(value, label) {
|
|
36
|
+
let count = 0;
|
|
37
|
+
let head = "";
|
|
38
|
+
for (const char of value) {
|
|
39
|
+
if (count < QUOTED) head += char;
|
|
40
|
+
if (++count > MAX_LENGTH) {
|
|
41
|
+
throw new Error(`${label} "${head}..." is too long for a duration (more than ${MAX_LENGTH} characters)`);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
}
|
|
32
45
|
function formatDuration(ms) {
|
|
33
46
|
if (!Number.isFinite(ms)) return "?";
|
|
34
47
|
if (ms < 1e3) return `${Math.round(ms)}ms`;
|
|
@@ -52,6 +65,14 @@ function formatRelative(at, now) {
|
|
|
52
65
|
if (abs < 5e3) return text;
|
|
53
66
|
return diff < 0 ? `${text} ago` : `in ${text}`;
|
|
54
67
|
}
|
|
68
|
+
var FIRST_DATE_MS = -621355968e5;
|
|
69
|
+
var LAST_DATE_MS = 253402300799999;
|
|
70
|
+
function isoTime(at) {
|
|
71
|
+
return at >= FIRST_DATE_MS && at <= LAST_DATE_MS ? new Date(at).toISOString() : null;
|
|
72
|
+
}
|
|
73
|
+
function beyondDates(at) {
|
|
74
|
+
return at > LAST_DATE_MS ? "after 9999-12-31 23:59:59 UTC" : "before 0001-01-01 00:00:00 UTC";
|
|
75
|
+
}
|
|
55
76
|
|
|
56
77
|
// src/env.ts
|
|
57
78
|
function readEnv(name) {
|
|
@@ -89,15 +110,36 @@ function parseSchedule(schedule, timezone) {
|
|
|
89
110
|
cache.set(key, parsed);
|
|
90
111
|
return parsed;
|
|
91
112
|
}
|
|
113
|
+
var CYCLE_MS = 146097 * 864e5;
|
|
114
|
+
var CRONER_FIRST_MS = Date.UTC(400, 0, 1);
|
|
115
|
+
var CRONER_LAST_MS = Date.UTC(2800, 0, 1);
|
|
116
|
+
function runsAfter(cron, n, from) {
|
|
117
|
+
let shift = 0;
|
|
118
|
+
if (from < CRONER_FIRST_MS) shift = Math.ceil((CRONER_FIRST_MS - from) / CYCLE_MS) * CYCLE_MS;
|
|
119
|
+
else if (from >= CRONER_LAST_MS) shift = -(Math.floor((from - CRONER_LAST_MS) / CYCLE_MS) + 1) * CYCLE_MS;
|
|
120
|
+
const out = [];
|
|
121
|
+
for (const date of cron.nextRuns(n, new Date(from + shift))) {
|
|
122
|
+
const t = date.getTime() - shift;
|
|
123
|
+
if (t > LAST_DATE_MS) break;
|
|
124
|
+
out.push(t);
|
|
125
|
+
}
|
|
126
|
+
return out;
|
|
127
|
+
}
|
|
128
|
+
function countFrom(from) {
|
|
129
|
+
if (from >= LAST_DATE_MS) return null;
|
|
130
|
+
return from >= FIRST_DATE_MS ? from : FIRST_DATE_MS - 1;
|
|
131
|
+
}
|
|
92
132
|
function fireAfter(parsed, from) {
|
|
93
133
|
const cron = crons.get(parsed);
|
|
94
134
|
if (!cron) throw new Error(`schedule "${parsed.source}" was not made by parseSchedule`);
|
|
95
|
-
|
|
135
|
+
const start = countFrom(from);
|
|
136
|
+
if (start === null) return null;
|
|
137
|
+
let probe = start;
|
|
96
138
|
for (let attempt = 0; attempt < 4; attempt++) {
|
|
97
|
-
const runs = cron
|
|
139
|
+
const runs = runsAfter(cron, 8, probe);
|
|
98
140
|
if (runs.length === 0) return null;
|
|
99
|
-
const found = runs.find((
|
|
100
|
-
if (found) return found
|
|
141
|
+
const found = runs.find((t) => t > start);
|
|
142
|
+
if (found !== void 0) return found;
|
|
101
143
|
probe += 36e5;
|
|
102
144
|
}
|
|
103
145
|
return null;
|
|
@@ -106,20 +148,21 @@ function firesBetween(parsed, from, to, limit) {
|
|
|
106
148
|
const cron = crons.get(parsed);
|
|
107
149
|
if (!cron) throw new Error(`schedule "${parsed.source}" was not made by parseSchedule`);
|
|
108
150
|
const out = [];
|
|
109
|
-
|
|
110
|
-
|
|
151
|
+
const start = countFrom(from);
|
|
152
|
+
if (start === null) return out;
|
|
153
|
+
let probe = start;
|
|
154
|
+
let last = start;
|
|
111
155
|
for (let guard = 0; guard < 1e3; guard++) {
|
|
112
|
-
const batch = cron
|
|
156
|
+
const batch = runsAfter(cron, Math.min(limit + 1 - out.length, 24), probe);
|
|
113
157
|
if (batch.length === 0) return out;
|
|
114
|
-
for (const
|
|
115
|
-
const t = date.getTime();
|
|
158
|
+
for (const t of batch) {
|
|
116
159
|
if (t <= last) continue;
|
|
117
160
|
if (t > to) return out;
|
|
118
161
|
out.push(t);
|
|
119
162
|
last = t;
|
|
120
163
|
if (out.length > limit) return null;
|
|
121
164
|
}
|
|
122
|
-
const end = batch[batch.length - 1]
|
|
165
|
+
const end = batch[batch.length - 1];
|
|
123
166
|
probe = end > probe ? end : probe + 36e5;
|
|
124
167
|
}
|
|
125
168
|
return out;
|
|
@@ -155,6 +198,7 @@ function runCovers(startedAt, dueAt, followingAt = null) {
|
|
|
155
198
|
}
|
|
156
199
|
function inSpringForwardGap(parsed, startedAt, fireAt) {
|
|
157
200
|
const LOOKBACK = 3 * 36e5;
|
|
201
|
+
if (fireAt - LOOKBACK < FIRST_DATE_MS) return false;
|
|
158
202
|
const after2 = utcOffset(fireAt, parsed.timezone);
|
|
159
203
|
const before = utcOffset(fireAt - LOOKBACK, parsed.timezone);
|
|
160
204
|
const gap = after2 - before;
|
|
@@ -191,8 +235,10 @@ function utcOffset(at, timezone) {
|
|
|
191
235
|
for (const part of format.formatToParts(new Date(at))) {
|
|
192
236
|
if (part.type !== "literal") parts[part.type] = Number(part.value);
|
|
193
237
|
}
|
|
194
|
-
const wall =
|
|
195
|
-
|
|
238
|
+
const wall = /* @__PURE__ */ new Date(0);
|
|
239
|
+
wall.setUTCFullYear(parts.year, parts.month - 1, parts.day);
|
|
240
|
+
wall.setUTCHours(parts.hour, parts.minute, parts.second);
|
|
241
|
+
return wall.getTime() - Math.floor(at / 1e3) * 1e3;
|
|
196
242
|
}
|
|
197
243
|
|
|
198
244
|
// src/stats.ts
|
|
@@ -215,6 +261,15 @@ var DEFAULT_TIMEOUT_MS = 60 * 6e4;
|
|
|
215
261
|
var SLOW_FLOOR_MS = 1e4;
|
|
216
262
|
var BASELINE_MIN_RUNS = 5;
|
|
217
263
|
var BASELINE_WINDOW = 20;
|
|
264
|
+
var MAX_DURATION_MS = Number.MAX_SAFE_INTEGER;
|
|
265
|
+
function runDuration(startedAt, finishedAt) {
|
|
266
|
+
const ms = finishedAt - startedAt;
|
|
267
|
+
return ms > 0 ? Math.min(ms, MAX_DURATION_MS) : 0;
|
|
268
|
+
}
|
|
269
|
+
function stateVersion(state) {
|
|
270
|
+
const version = state?.version;
|
|
271
|
+
return typeof version === "number" && Number.isSafeInteger(version) && version >= 0 ? version + 0 : 0;
|
|
272
|
+
}
|
|
218
273
|
function emptyState(job) {
|
|
219
274
|
return { job, open: {}, consecutiveFailures: 0, silencedUntil: null, lastAlertAt: null, pendingRecovery: [], undelivered: [] };
|
|
220
275
|
}
|
|
@@ -425,7 +480,9 @@ function summary(stored, recent, state, nextExpectedAt, health) {
|
|
|
425
480
|
// src/format.ts
|
|
426
481
|
function when(at, now) {
|
|
427
482
|
if (at === null || at === void 0) return "never";
|
|
428
|
-
|
|
483
|
+
const iso = isoTime(at);
|
|
484
|
+
if (iso === null) return beyondDates(at);
|
|
485
|
+
return `${iso.replace("T", " ").slice(0, 19)} UTC (${formatRelative(at, now)})`;
|
|
429
486
|
}
|
|
430
487
|
function firstLines(text, n) {
|
|
431
488
|
if (!text) return "";
|
|
@@ -821,9 +878,13 @@ function dayLabel(t) {
|
|
|
821
878
|
return `${WEEKDAYS[d.getUTCDay()]} ${d.getUTCDate()} ${MONTHS[d.getUTCMonth()]}`;
|
|
822
879
|
}
|
|
823
880
|
function when2(t, now) {
|
|
881
|
+
if (t > LAST_DATE_MS) return "after 31 Dec 9999 23:59";
|
|
882
|
+
if (!(t >= FIRST_DATE_MS)) return "before 1 Jan 0001 00:00";
|
|
824
883
|
if (Math.floor(t / DAY) === Math.floor(now / DAY)) return clock(t);
|
|
825
884
|
const d = new Date(t);
|
|
826
|
-
|
|
885
|
+
const year = d.getUTCFullYear();
|
|
886
|
+
const other = year === new Date(now).getUTCFullYear() ? "" : ` ${String(year).padStart(4, "0")}`;
|
|
887
|
+
return `${d.getUTCDate()} ${MONTHS[d.getUTCMonth()]}${other} ${clock(t)}`;
|
|
827
888
|
}
|
|
828
889
|
function parsedSchedule(job) {
|
|
829
890
|
if (!job.definition.schedule) return null;
|
|
@@ -1314,7 +1375,8 @@ function sparkline(runs) {
|
|
|
1314
1375
|
}
|
|
1315
1376
|
function stamp(at, now) {
|
|
1316
1377
|
if (at === null) return `<span class="muted">never</span>`;
|
|
1317
|
-
const iso =
|
|
1378
|
+
const iso = isoTime(at);
|
|
1379
|
+
if (iso === null) return `<span class="nowrap">${beyondDates(at)}</span>`;
|
|
1318
1380
|
return `<time class="nowrap" datetime="${iso}" title="${iso.replace("T", " ").slice(0, 19)} UTC">${h(formatRelative(at, now))}</time>`;
|
|
1319
1381
|
}
|
|
1320
1382
|
function healthFigures(jobs) {
|
|
@@ -1480,7 +1542,20 @@ function developmentToken() {
|
|
|
1480
1542
|
return btoa(String.fromCharCode(...bytes)).replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
|
|
1481
1543
|
}
|
|
1482
1544
|
function developmentSignInLine(origin, base, token) {
|
|
1483
|
-
|
|
1545
|
+
const intro = "[cronwatch] CRONWATCH_TOKEN is not set, so this development server made a token for the dashboard. Sign in: ";
|
|
1546
|
+
return origin === null ? `${intro}${base}/?token=${token} on this server (the first request's host is not local, so the link leaves it out)` : `${intro}${origin}${base}/?token=${token}`;
|
|
1547
|
+
}
|
|
1548
|
+
function isLoopbackOrigin(origin) {
|
|
1549
|
+
let host;
|
|
1550
|
+
try {
|
|
1551
|
+
host = new URL(origin).hostname.toLowerCase();
|
|
1552
|
+
} catch {
|
|
1553
|
+
return false;
|
|
1554
|
+
}
|
|
1555
|
+
if (host === "localhost" || host.endsWith(".localhost")) return true;
|
|
1556
|
+
if (host === "[::1]") return true;
|
|
1557
|
+
const octets = /^127\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$/.exec(host);
|
|
1558
|
+
return octets !== null && octets.slice(1).every((o) => Number(o) <= 255);
|
|
1484
1559
|
}
|
|
1485
1560
|
function safeDecode(value) {
|
|
1486
1561
|
try {
|
|
@@ -1585,7 +1660,8 @@ function createRoutes(cw, options = {}) {
|
|
|
1585
1660
|
const publicOrigin = originOf(request, url);
|
|
1586
1661
|
if (generated && !announced) {
|
|
1587
1662
|
announced = true;
|
|
1588
|
-
|
|
1663
|
+
const shown = fixedOrigin ?? (isLoopbackOrigin(publicOrigin) ? publicOrigin : null);
|
|
1664
|
+
console.info(developmentSignInLine(shown, base, token));
|
|
1589
1665
|
}
|
|
1590
1666
|
if (method === "GET" || method === "HEAD") {
|
|
1591
1667
|
if (path === "/offline") {
|
|
@@ -1833,7 +1909,7 @@ function memory() {
|
|
|
1833
1909
|
states.set(state.job, clone(state));
|
|
1834
1910
|
},
|
|
1835
1911
|
async compareAndSetState(state, expectedVersion) {
|
|
1836
|
-
if ((states.get(state.job)
|
|
1912
|
+
if (stateVersion(states.get(state.job)) !== expectedVersion) return false;
|
|
1837
1913
|
states.set(state.job, clone(state));
|
|
1838
1914
|
return true;
|
|
1839
1915
|
},
|
|
@@ -2103,7 +2179,7 @@ var CronWatch = class {
|
|
|
2103
2179
|
const current = await this.readState(job);
|
|
2104
2180
|
const { state, result } = await change(current);
|
|
2105
2181
|
if (sameState(state, current)) return { state: current, result };
|
|
2106
|
-
const version = current
|
|
2182
|
+
const version = stateVersion(current);
|
|
2107
2183
|
const next = { ...state, version: version + 1 };
|
|
2108
2184
|
if (await this.writeState(next, version)) return { state: next, result };
|
|
2109
2185
|
if (attempt >= STATE_ATTEMPTS) {
|
|
@@ -2163,7 +2239,7 @@ var CronWatch = class {
|
|
|
2163
2239
|
}
|
|
2164
2240
|
const finishedAt = this.now();
|
|
2165
2241
|
run.finishedAt = finishedAt;
|
|
2166
|
-
run.durationMs =
|
|
2242
|
+
run.durationMs = runDuration(startedAt, finishedAt);
|
|
2167
2243
|
run.metrics = recorder.metrics();
|
|
2168
2244
|
run.output = recorder.output() ?? (typeof result === "string" ? capOutput(result) : null);
|
|
2169
2245
|
this.conclude(definition, run, result, error, threw, recorder.expectText() ?? (typeof result === "string" ? result : null));
|
|
@@ -2397,7 +2473,7 @@ ${id}`;
|
|
|
2397
2473
|
...from,
|
|
2398
2474
|
status: "running",
|
|
2399
2475
|
finishedAt,
|
|
2400
|
-
durationMs:
|
|
2476
|
+
durationMs: runDuration(from.startedAt, finishedAt),
|
|
2401
2477
|
error: null,
|
|
2402
2478
|
output: joinOutput(from.output, added),
|
|
2403
2479
|
metrics: { ...from.metrics, ...recorder.metrics() }
|
|
@@ -2586,7 +2662,7 @@ ${id}`;
|
|
|
2586
2662
|
const timeout = timeoutMs(definition);
|
|
2587
2663
|
run.status = "timeout";
|
|
2588
2664
|
run.finishedAt = now;
|
|
2589
|
-
run.durationMs =
|
|
2665
|
+
run.durationMs = runDuration(run.startedAt, now);
|
|
2590
2666
|
run.error = `Still running after ${formatDuration(timeout)}; marked as timed out`;
|
|
2591
2667
|
if (!await this.writeRunIf(run, ["running"])) continue;
|
|
2592
2668
|
alerts.push(...await this.finishRun(definition, run, now));
|