@cronwatch/sdk 0.8.0 → 0.9.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/dist/anthropic.d.cts +1 -1
- package/dist/anthropic.d.ts +1 -1
- package/dist/bugsnag.d.cts +1 -1
- package/dist/bugsnag.d.ts +1 -1
- package/dist/{client-B5hM4l-D.d.ts → client-CQm-8-mR.d.ts} +13 -2
- package/dist/{client-Di5HAWQz.d.cts → client-D35cfnNV.d.cts} +13 -2
- package/dist/d1.cjs +29 -19
- 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 +29 -19
- package/dist/d1.js.map +1 -1
- package/dist/datadog.d.cts +1 -1
- package/dist/datadog.d.ts +1 -1
- package/dist/discord.d.cts +1 -1
- package/dist/discord.d.ts +1 -1
- package/dist/{email-Ciq7GRn4.d.ts → email-BxCp9RQV.d.ts} +1 -1
- package/dist/{email-DX6gkd5H.d.cts → email-D1d5niMy.d.cts} +1 -1
- package/dist/honeybadger.d.cts +1 -1
- package/dist/honeybadger.d.ts +1 -1
- package/dist/index.cjs +50 -15
- 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 +50 -15
- package/dist/index.js.map +1 -1
- package/dist/mailgun.d.cts +2 -2
- package/dist/mailgun.d.ts +2 -2
- package/dist/newrelic.d.cts +1 -1
- package/dist/newrelic.d.ts +1 -1
- package/dist/pg-cron.cjs +45 -4
- package/dist/pg-cron.cjs.map +1 -1
- package/dist/pg-cron.d.cts +5 -2
- package/dist/pg-cron.d.ts +5 -2
- package/dist/pg-cron.js +45 -4
- package/dist/pg-cron.js.map +1 -1
- package/dist/postgres.cjs +22 -14
- 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 +22 -14
- package/dist/postgres.js.map +1 -1
- package/dist/postmark.d.cts +2 -2
- package/dist/postmark.d.ts +2 -2
- package/dist/resend.d.cts +2 -2
- package/dist/resend.d.ts +2 -2
- package/dist/rollbar.d.cts +1 -1
- package/dist/rollbar.d.ts +1 -1
- package/dist/sendgrid.d.cts +2 -2
- package/dist/sendgrid.d.ts +2 -2
- package/dist/sentry.d.cts +1 -1
- package/dist/sentry.d.ts +1 -1
- package/dist/ses.d.cts +2 -2
- package/dist/ses.d.ts +2 -2
- package/dist/slack.d.cts +1 -1
- package/dist/slack.d.ts +1 -1
- package/dist/sqlite.cjs +26 -18
- 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 +26 -18
- package/dist/sqlite.js.map +1 -1
- package/dist/twilio.d.cts +1 -1
- package/dist/twilio.d.ts +1 -1
- package/dist/{types-BjBbCGeJ.d.cts → types-Cz47Boks.d.cts} +6 -0
- package/dist/{types-BjBbCGeJ.d.ts → types-Cz47Boks.d.ts} +6 -0
- package/dist/webhook.d.cts +1 -1
- package/dist/webhook.d.ts +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-D35cfnNV.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-D35cfnNV.cjs';
|
|
3
|
+
import { S as Store, D as Duration, b as AlertDraft, c as StoredJobDefinition, A as Alert } from './types-Cz47Boks.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-Cz47Boks.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-CQm-8-mR.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-CQm-8-mR.js';
|
|
3
|
+
import { S as Store, D as Duration, b as AlertDraft, c as StoredJobDefinition, A as Alert } from './types-Cz47Boks.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-Cz47Boks.js';
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
7
|
* Keeps everything in process memory. The default when no store is given,
|
package/dist/index.js
CHANGED
|
@@ -270,6 +270,11 @@ function stateVersion(state) {
|
|
|
270
270
|
const version = state?.version;
|
|
271
271
|
return typeof version === "number" && Number.isSafeInteger(version) && version >= 0 ? version + 0 : 0;
|
|
272
272
|
}
|
|
273
|
+
function failureCount(state) {
|
|
274
|
+
const count = state?.consecutiveFailures;
|
|
275
|
+
if (typeof count !== "number" || !Number.isInteger(count) || count <= 0) return 0;
|
|
276
|
+
return Math.min(count, MAX_DURATION_MS);
|
|
277
|
+
}
|
|
273
278
|
function emptyState(job) {
|
|
274
279
|
return { job, open: {}, consecutiveFailures: 0, silencedUntil: null, lastAlertAt: null, pendingRecovery: [], undelivered: [] };
|
|
275
280
|
}
|
|
@@ -279,6 +284,7 @@ function normalizeState(state, job) {
|
|
|
279
284
|
...emptyState(job),
|
|
280
285
|
...state,
|
|
281
286
|
open: { ...state.open },
|
|
287
|
+
consecutiveFailures: failureCount(state),
|
|
282
288
|
pendingRecovery: [...state.pendingRecovery ?? []],
|
|
283
289
|
undelivered: [...state.undelivered ?? []]
|
|
284
290
|
};
|
|
@@ -377,7 +383,7 @@ function onRunFinish(def, run, state, history, now) {
|
|
|
377
383
|
}
|
|
378
384
|
return { state: next, alerts };
|
|
379
385
|
}
|
|
380
|
-
next.consecutiveFailures
|
|
386
|
+
next.consecutiveFailures = Math.min(next.consecutiveFailures + 1, MAX_DURATION_MS);
|
|
381
387
|
closeCondition(next, "missed");
|
|
382
388
|
const threshold = Math.max(1, def.failuresBeforeAlert ?? 1);
|
|
383
389
|
const condition = run.status === "timeout" ? "stuck" : "failed";
|
|
@@ -591,6 +597,9 @@ function capOutput(text) {
|
|
|
591
597
|
function stripNul(text) {
|
|
592
598
|
return text.includes("\0") ? text.replace(/\u0000/g, "") : text;
|
|
593
599
|
}
|
|
600
|
+
function stripJsonNul(json2) {
|
|
601
|
+
return json2.includes("\\u0000") ? json2.replace(/\\(u0000|[\s\S])/g, (escape, next) => next === "u0000" ? "" : escape) : json2;
|
|
602
|
+
}
|
|
594
603
|
function errorMessage(error) {
|
|
595
604
|
return capOutput(describeError(error));
|
|
596
605
|
}
|
|
@@ -1843,13 +1852,21 @@ function memory() {
|
|
|
1843
1852
|
const states = /* @__PURE__ */ new Map();
|
|
1844
1853
|
let seq = 0;
|
|
1845
1854
|
const clone = (v) => JSON.parse(JSON.stringify(v));
|
|
1855
|
+
const kept = (v) => JSON.parse(stripJsonNul(JSON.stringify(v)));
|
|
1856
|
+
const keptRun = (run) => ({
|
|
1857
|
+
...clone(run),
|
|
1858
|
+
trigger: stripNul(run.trigger),
|
|
1859
|
+
output: run.output === null ? null : stripNul(run.output),
|
|
1860
|
+
error: run.error === null ? null : stripNul(run.error),
|
|
1861
|
+
metrics: kept(run.metrics)
|
|
1862
|
+
});
|
|
1846
1863
|
const byName = (a, b) => a.name < b.name ? -1 : a.name > b.name ? 1 : 0;
|
|
1847
1864
|
return {
|
|
1848
1865
|
async upsertJob(definition, now) {
|
|
1849
1866
|
const existing = jobs.get(definition.name);
|
|
1850
1867
|
jobs.set(definition.name, {
|
|
1851
1868
|
name: definition.name,
|
|
1852
|
-
definition:
|
|
1869
|
+
definition: kept(definition),
|
|
1853
1870
|
createdAt: existing?.createdAt ?? now,
|
|
1854
1871
|
updatedAt: now
|
|
1855
1872
|
});
|
|
@@ -1871,19 +1888,19 @@ function memory() {
|
|
|
1871
1888
|
},
|
|
1872
1889
|
async insertRun(run) {
|
|
1873
1890
|
if (runs.has(run.id)) throw new Error(`run ${run.id} already exists`);
|
|
1874
|
-
runs.set(run.id,
|
|
1891
|
+
runs.set(run.id, keptRun(run));
|
|
1875
1892
|
order.set(run.id, ++seq);
|
|
1876
1893
|
},
|
|
1877
1894
|
async updateRun(run) {
|
|
1878
1895
|
const existing = runs.get(run.id);
|
|
1879
1896
|
if (!existing) return;
|
|
1880
|
-
const { status, finishedAt, durationMs, error, output, metrics } =
|
|
1897
|
+
const { status, finishedAt, durationMs, error, output, metrics } = keptRun(run);
|
|
1881
1898
|
runs.set(run.id, { ...existing, status, finishedAt, durationMs, error, output, metrics });
|
|
1882
1899
|
},
|
|
1883
1900
|
async updateRunIf(run, fromStatuses) {
|
|
1884
1901
|
const existing = runs.get(run.id);
|
|
1885
1902
|
if (!existing || !fromStatuses.includes(existing.status)) return false;
|
|
1886
|
-
const { status, finishedAt, durationMs, error, output, metrics } =
|
|
1903
|
+
const { status, finishedAt, durationMs, error, output, metrics } = keptRun(run);
|
|
1887
1904
|
runs.set(run.id, { ...existing, status, finishedAt, durationMs, error, output, metrics });
|
|
1888
1905
|
return true;
|
|
1889
1906
|
},
|
|
@@ -1906,11 +1923,11 @@ function memory() {
|
|
|
1906
1923
|
return s ? clone(s) : null;
|
|
1907
1924
|
},
|
|
1908
1925
|
async setState(state) {
|
|
1909
|
-
states.set(state.job,
|
|
1926
|
+
states.set(state.job, kept(state));
|
|
1910
1927
|
},
|
|
1911
1928
|
async compareAndSetState(state, expectedVersion) {
|
|
1912
1929
|
if (stateVersion(states.get(state.job)) !== expectedVersion) return false;
|
|
1913
|
-
states.set(state.job,
|
|
1930
|
+
states.set(state.job, kept(state));
|
|
1914
1931
|
return true;
|
|
1915
1932
|
},
|
|
1916
1933
|
async prune(before) {
|
|
@@ -1998,6 +2015,8 @@ var CronWatch = class {
|
|
|
1998
2015
|
synced = /* @__PURE__ */ new Set();
|
|
1999
2016
|
/** The tail of each job's queue of state updates. See serial(). */
|
|
2000
2017
|
queues = /* @__PURE__ */ new Map();
|
|
2018
|
+
/** The tail of each job's queue of declaration writes. See sync(). */
|
|
2019
|
+
syncing = /* @__PURE__ */ new Map();
|
|
2001
2020
|
/** start() calls with an id still in flight, so two at once in this process record one run. */
|
|
2002
2021
|
starting = /* @__PURE__ */ new Map();
|
|
2003
2022
|
ready = null;
|
|
@@ -2136,26 +2155,40 @@ var CronWatch = class {
|
|
|
2136
2155
|
}
|
|
2137
2156
|
await this.ready;
|
|
2138
2157
|
}
|
|
2158
|
+
/**
|
|
2159
|
+
* Writes the declaration of `definition`'s name as it stands, unless the
|
|
2160
|
+
* store has it. A handle kept from an earlier declaration writes the one
|
|
2161
|
+
* that replaced it, never its own over it, and one forgotten since writes
|
|
2162
|
+
* its own. The writes of one name take turns, in the order they were asked
|
|
2163
|
+
* for, so one still under way cannot land after a later one; and a name
|
|
2164
|
+
* declared again while its write was under way is still to be written.
|
|
2165
|
+
*/
|
|
2139
2166
|
async sync(definition) {
|
|
2140
2167
|
await this.ensureReady();
|
|
2141
|
-
|
|
2142
|
-
|
|
2143
|
-
this.
|
|
2168
|
+
const name = definition.name;
|
|
2169
|
+
if (this.synced.has(name)) return;
|
|
2170
|
+
await this.serial(name, async () => {
|
|
2171
|
+
if (this.synced.has(name)) return;
|
|
2172
|
+
const standing = this.definitions.get(name) ?? definition;
|
|
2173
|
+
await this.store.upsertJob(toStored(standing), this.now());
|
|
2174
|
+
if ((this.definitions.get(name) ?? standing) === standing) this.synced.add(name);
|
|
2175
|
+
}, this.syncing);
|
|
2144
2176
|
}
|
|
2145
2177
|
/**
|
|
2146
2178
|
* Runs `fn` after every earlier state update for the same job has settled,
|
|
2147
2179
|
* so two runs (or a run and a check) in this process never read and write
|
|
2148
2180
|
* the job's state over each other. Other processes are coordinated by
|
|
2149
|
-
* updateState() instead.
|
|
2181
|
+
* updateState() instead. sync() queues a job's declaration writes the same
|
|
2182
|
+
* way, in `syncing`.
|
|
2150
2183
|
*/
|
|
2151
|
-
serial(job, fn) {
|
|
2152
|
-
const result = (
|
|
2184
|
+
serial(job, fn, queues = this.queues) {
|
|
2185
|
+
const result = (queues.get(job) ?? Promise.resolve()).then(fn);
|
|
2153
2186
|
const tail2 = result.then(() => {
|
|
2154
2187
|
}, () => {
|
|
2155
2188
|
});
|
|
2156
|
-
|
|
2189
|
+
queues.set(job, tail2);
|
|
2157
2190
|
void tail2.then(() => {
|
|
2158
|
-
if (
|
|
2191
|
+
if (queues.get(job) === tail2) queues.delete(job);
|
|
2159
2192
|
});
|
|
2160
2193
|
return result;
|
|
2161
2194
|
}
|
|
@@ -2555,6 +2588,7 @@ ${id}`;
|
|
|
2555
2588
|
async recordRun(input, options = {}) {
|
|
2556
2589
|
const declared = this.definitions.get(input.job);
|
|
2557
2590
|
if (!declared) throw new Error(`recordRun: job "${input.job}" is not declared; call job() first`);
|
|
2591
|
+
if (input.id.includes("\0")) throw new Error(`recordRun: run ids cannot contain a NUL character (job "${input.job}")`);
|
|
2558
2592
|
await this.sync(declared);
|
|
2559
2593
|
const run = { ...input, metrics: { ...input.metrics } };
|
|
2560
2594
|
if (run.status === "ok") {
|
|
@@ -2925,6 +2959,7 @@ function checkRunId(job, id, method) {
|
|
|
2925
2959
|
if (typeof id !== "string" || id.length === 0 || id.length > 200) {
|
|
2926
2960
|
throw new Error(`job "${job}": ${method}() needs a run id of 1 to 200 characters (got ${typeof id === "string" ? `${id.length} characters` : typeof id})`);
|
|
2927
2961
|
}
|
|
2962
|
+
if (id.includes("\0")) throw new Error(`job "${job}": ${method}() cannot take a run id containing a NUL character`);
|
|
2928
2963
|
if (id.startsWith(RESERVED_RUN_ID_PREFIX)) {
|
|
2929
2964
|
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`);
|
|
2930
2965
|
}
|