@pg-boss/dashboard 1.1.1 → 1.1.3
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/build/client/assets/MenuTrigger-BUdpY9vj.js +1 -0
- package/build/client/assets/{_index-9fLquIe1.js → _index-DXfER9RD.js} +1 -1
- package/build/client/assets/{badge-B5ZugmiV.js → badge-to3cY6Nn.js} +1 -1
- package/build/client/assets/{button-Djse56Dx.js → button-CudTDtZF.js} +1 -1
- package/build/client/assets/{chevron-down-B4tDL9Ah.js → chevron-down-ClrMXFFn.js} +1 -1
- package/build/client/assets/chunk-EVOBXE3Y-CmKRT32p.js +26 -0
- package/build/client/assets/{createLucideIcon-B0YqJFaz.js → createLucideIcon-C5Bm8BOS.js} +1 -1
- package/build/client/assets/db-link-BzIwSws3.js +1 -0
- package/build/client/assets/dialog-BBFR7NS6.js +1 -0
- package/build/client/assets/{entry.client-Szv-xmaE.js → entry.client-B-bLoJqf.js} +4 -4
- package/build/client/assets/{error-card-CXoOCvsg.js → error-card--OB_TuOC.js} +1 -1
- package/build/client/assets/{filter-select-DXyBBVm8.js → filter-select-07am_j5T.js} +1 -1
- package/build/client/assets/{index-x2yWco1W.js → index-By5u-yQ6.js} +1 -1
- package/build/client/assets/{jobs-CM6xcK-O.js → jobs-Gp0x24mG.js} +1 -1
- package/build/client/assets/manifest-560249af.js +1 -0
- package/build/client/assets/{pagination-C4yyCmBA.js → pagination-DCEs769S.js} +1 -1
- package/build/client/assets/{queues._index-Dn3ieC5d.js → queues._index-DxMtAiK3.js} +1 -1
- package/build/client/assets/{queues._name-GrviLLx2.js → queues._name-DqI0ZH4S.js} +1 -1
- package/build/client/assets/{queues._name.jobs._jobId-s_wYs79w.js → queues._name.jobs._jobId-BEwVDYH6.js} +1 -1
- package/build/client/assets/{queues.create-Ch3Mqw52.js → queues.create-aEr8z6Lt.js} +1 -1
- package/build/client/assets/{root-D0qqtdF7.js → root-Cubm0m9Y.js} +1 -1
- package/build/client/assets/{schedules-DwnuuhxF.js → schedules-BacoSVY9.js} +1 -1
- package/build/client/assets/{schedules._name._key-DJn-u3Cm.js → schedules._name._key-zuc0HZqU.js} +1 -1
- package/build/client/assets/{schedules.new-CQuE2Uhz.js → schedules.new-CrK1w4GF.js} +1 -1
- package/build/client/assets/{send-DVfuC6NR.js → send-wPFbslqy.js} +1 -1
- package/build/client/assets/{table-CtSLyG7m.js → table-CV0K56fY.js} +1 -1
- package/build/client/assets/useOpenInteractionType-C7OfDyTB.js +1 -0
- package/build/client/assets/{warnings-DqRQYomb.js → warnings-DLjttltF.js} +1 -1
- package/build/server/assets/server-build.js +134 -58
- package/package.json +17 -17
- package/build/client/assets/MenuTrigger-CEHCnGow.js +0 -1
- package/build/client/assets/chunk-LFPYN7LY-Cj1DJmJR.js +0 -26
- package/build/client/assets/db-link-DmvfwdX4.js +0 -1
- package/build/client/assets/dialog-CQzw3QVH.js +0 -1
- package/build/client/assets/manifest-acaa4b8e.js +0 -1
- package/build/client/assets/useOpenInteractionType-Ss_6xZdw.js +0 -12
|
@@ -1906,7 +1906,7 @@ function deleteJobsById(schema, table) {
|
|
|
1906
1906
|
WITH results as (
|
|
1907
1907
|
DELETE FROM ${schema}.${table}
|
|
1908
1908
|
WHERE name = $1
|
|
1909
|
-
AND id IN (SELECT UNNEST($2::uuid[]))
|
|
1909
|
+
AND id IN (SELECT UNNEST($2::uuid[]))
|
|
1910
1910
|
RETURNING 1
|
|
1911
1911
|
)
|
|
1912
1912
|
SELECT COUNT(*) from results
|
|
@@ -1999,10 +1999,12 @@ function insertVersion(schema, version) {
|
|
|
1999
1999
|
return `INSERT INTO ${schema}.version(version) VALUES ('${version}')`;
|
|
2000
2000
|
}
|
|
2001
2001
|
function buildFetchParams(options) {
|
|
2002
|
-
const { ignoreSingletons, ignoreGroups, groupConcurrency } = options;
|
|
2002
|
+
const { ignoreSingletons, ignoreGroups, groupConcurrency, minPriority, maxPriority } = options;
|
|
2003
2003
|
const hasIgnoreSingletons = ignoreSingletons != null && ignoreSingletons.length > 0;
|
|
2004
2004
|
const hasIgnoreGroups = ignoreGroups != null && ignoreGroups.length > 0;
|
|
2005
2005
|
const hasGroupConcurrency = groupConcurrency != null;
|
|
2006
|
+
const hasMinPriority = minPriority != null;
|
|
2007
|
+
const hasMaxPriority = maxPriority != null;
|
|
2006
2008
|
const groupConcurrencyConfig = hasGroupConcurrency ? typeof groupConcurrency === "number" ? { default: groupConcurrency } : groupConcurrency : null;
|
|
2007
2009
|
const hasTiers = groupConcurrencyConfig?.tiers && Object.keys(groupConcurrencyConfig.tiers).length > 0;
|
|
2008
2010
|
const values = [];
|
|
@@ -2011,6 +2013,8 @@ function buildFetchParams(options) {
|
|
|
2011
2013
|
let ignoreGroupsParam = "";
|
|
2012
2014
|
let defaultGroupLimitParam = "";
|
|
2013
2015
|
let tiersParam = "";
|
|
2016
|
+
let minPriorityParam = "";
|
|
2017
|
+
let maxPriorityParam = "";
|
|
2014
2018
|
if (hasIgnoreSingletons) {
|
|
2015
2019
|
paramIndex++;
|
|
2016
2020
|
ignoreSingletonsParam = `$${paramIndex}::text[]`;
|
|
@@ -2031,42 +2035,60 @@ function buildFetchParams(options) {
|
|
|
2031
2035
|
values.push(JSON.stringify(groupConcurrencyConfig.tiers));
|
|
2032
2036
|
}
|
|
2033
2037
|
}
|
|
2034
|
-
|
|
2038
|
+
if (hasMinPriority) {
|
|
2039
|
+
paramIndex++;
|
|
2040
|
+
minPriorityParam = `$${paramIndex}::int`;
|
|
2041
|
+
values.push(minPriority);
|
|
2042
|
+
}
|
|
2043
|
+
if (hasMaxPriority) {
|
|
2044
|
+
paramIndex++;
|
|
2045
|
+
maxPriorityParam = `$${paramIndex}::int`;
|
|
2046
|
+
values.push(maxPriority);
|
|
2047
|
+
}
|
|
2048
|
+
return { values, ignoreSingletonsParam, ignoreGroupsParam, defaultGroupLimitParam, tiersParam, minPriorityParam, maxPriorityParam };
|
|
2035
2049
|
}
|
|
2036
2050
|
function fetchNextJob(options) {
|
|
2037
|
-
const { schema, table, name, policy, limit, includeMetadata, priority = true, orderByCreatedOn = true, ignoreStartAfter = false, groupConcurrency } = options;
|
|
2051
|
+
const { schema, table, name, policy, limit, includeMetadata, priority = true, orderByCreatedOn = true, ignoreStartAfter = false, groupConcurrency, minPriority, maxPriority } = options;
|
|
2038
2052
|
const singletonFetch = limit > 1 && (policy === QUEUE_POLICIES.singleton || policy === QUEUE_POLICIES.stately);
|
|
2039
2053
|
const hasIgnoreSingletons = options.ignoreSingletons != null && options.ignoreSingletons.length > 0;
|
|
2040
2054
|
const hasIgnoreGroups = options.ignoreGroups != null && options.ignoreGroups.length > 0;
|
|
2041
2055
|
const hasGroupConcurrency = groupConcurrency != null;
|
|
2056
|
+
const hasMinPriority = minPriority != null;
|
|
2057
|
+
const hasMaxPriority = maxPriority != null;
|
|
2042
2058
|
const hasTiers = hasGroupConcurrency && typeof groupConcurrency === "object" && groupConcurrency.tiers && Object.keys(groupConcurrency.tiers).length > 0;
|
|
2043
2059
|
const params = buildFetchParams(options);
|
|
2044
|
-
const whereConditions = [
|
|
2045
|
-
`name = '${name}'`,
|
|
2046
|
-
`state < '${JOB_STATES.active}'`,
|
|
2047
|
-
!ignoreStartAfter ? "start_after < now()" : "",
|
|
2048
|
-
hasIgnoreSingletons ? `singleton_key <> ALL(${params.ignoreSingletonsParam})` : "",
|
|
2049
|
-
hasIgnoreGroups ? `(group_id IS NULL OR group_id <> ALL(${params.ignoreGroupsParam}))` : ""
|
|
2050
|
-
].filter(Boolean).join(" AND ");
|
|
2051
2060
|
const selectCols = [
|
|
2052
|
-
"id",
|
|
2053
|
-
singletonFetch ? "singleton_key" : "",
|
|
2054
|
-
hasGroupConcurrency ? "group_id, group_tier" : ""
|
|
2061
|
+
"j.id",
|
|
2062
|
+
singletonFetch ? "j.singleton_key" : "",
|
|
2063
|
+
hasGroupConcurrency ? "j.group_id, j.group_tier" : ""
|
|
2055
2064
|
].filter(Boolean).join(", ");
|
|
2056
|
-
const activeGroupCountsCte = hasGroupConcurrency ? `active_group_counts AS (
|
|
2065
|
+
const activeGroupCountsCte = hasGroupConcurrency ? `active_group_counts AS MATERIALIZED (
|
|
2057
2066
|
SELECT group_id, COUNT(*)::int as active_cnt
|
|
2058
2067
|
FROM ${schema}.${table}
|
|
2059
2068
|
WHERE name = '${name}' AND state = '${JOB_STATES.active}' AND group_id IS NOT NULL
|
|
2060
2069
|
GROUP BY group_id
|
|
2061
2070
|
), ` : "";
|
|
2071
|
+
const whereConditions = [
|
|
2072
|
+
`j.name = '${name}'`,
|
|
2073
|
+
`j.state < '${JOB_STATES.active}'`,
|
|
2074
|
+
!ignoreStartAfter ? "j.start_after < now()" : "",
|
|
2075
|
+
hasIgnoreSingletons ? `j.singleton_key <> ALL(${params.ignoreSingletonsParam})` : "",
|
|
2076
|
+
hasIgnoreGroups ? `(j.group_id IS NULL OR j.group_id <> ALL(${params.ignoreGroupsParam}))` : "",
|
|
2077
|
+
hasMinPriority ? `j.priority >= ${params.minPriorityParam}` : "",
|
|
2078
|
+
hasMaxPriority ? `j.priority <= ${params.maxPriorityParam}` : "",
|
|
2079
|
+
hasGroupConcurrency ? `(j.group_id IS NULL
|
|
2080
|
+
OR agc.active_cnt IS NULL
|
|
2081
|
+
OR agc.active_cnt < ${hasTiers ? `COALESCE((${params.tiersParam} ->> j.group_tier)::int, ${params.defaultGroupLimitParam})` : params.defaultGroupLimitParam})` : ""
|
|
2082
|
+
].filter(Boolean).join("\n AND ");
|
|
2062
2083
|
const nextCte = `
|
|
2063
2084
|
next AS (
|
|
2064
2085
|
SELECT ${selectCols}
|
|
2065
|
-
FROM ${schema}.${table}
|
|
2086
|
+
FROM ${schema}.${table} j
|
|
2087
|
+
${hasGroupConcurrency ? "LEFT JOIN active_group_counts agc ON j.group_id = agc.group_id" : ""}
|
|
2066
2088
|
WHERE ${whereConditions}
|
|
2067
|
-
ORDER BY ${priority ? "priority desc, " : ""}${orderByCreatedOn ? "created_on, " : ""}id
|
|
2089
|
+
ORDER BY ${priority ? "j.priority desc, " : ""}${orderByCreatedOn ? "j.created_on, " : ""}j.id
|
|
2068
2090
|
LIMIT ${limit}
|
|
2069
|
-
FOR UPDATE SKIP LOCKED
|
|
2091
|
+
FOR UPDATE OF j SKIP LOCKED
|
|
2070
2092
|
)`;
|
|
2071
2093
|
const singletonCte = singletonFetch ? `, singleton_ranking AS (
|
|
2072
2094
|
SELECT id, ${hasGroupConcurrency ? "group_id, group_tier, " : ""}
|
|
@@ -2688,6 +2710,17 @@ function validateGroupConcurrencyValue(value, optionName) {
|
|
|
2688
2710
|
}
|
|
2689
2711
|
}
|
|
2690
2712
|
}
|
|
2713
|
+
function validatePriorityRangeConfig(config) {
|
|
2714
|
+
if (config.minPriority !== void 0) {
|
|
2715
|
+
assert(Number.isInteger(config.minPriority), "minPriority must be an integer");
|
|
2716
|
+
}
|
|
2717
|
+
if (config.maxPriority !== void 0) {
|
|
2718
|
+
assert(Number.isInteger(config.maxPriority), "maxPriority must be an integer");
|
|
2719
|
+
}
|
|
2720
|
+
if (config.minPriority !== void 0 && config.maxPriority !== void 0) {
|
|
2721
|
+
assert(config.minPriority <= config.maxPriority, "minPriority must be <= maxPriority");
|
|
2722
|
+
}
|
|
2723
|
+
}
|
|
2691
2724
|
function validateGroupConcurrencyConfig(config) {
|
|
2692
2725
|
const hasGlobal = config.groupConcurrency != null;
|
|
2693
2726
|
const hasLocal = config.localGroupConcurrency != null;
|
|
@@ -2741,6 +2774,7 @@ function checkWorkArgs(name, args) {
|
|
|
2741
2774
|
assert(!("includeMetadata" in options) || typeof options.includeMetadata === "boolean", "includeMetadata must be a boolean");
|
|
2742
2775
|
assert(!("priority" in options) || typeof options.priority === "boolean", "priority must be a boolean");
|
|
2743
2776
|
assert(!("localConcurrency" in options) || Number.isInteger(options.localConcurrency) && options.localConcurrency >= 1, "localConcurrency must be an integer >= 1");
|
|
2777
|
+
validatePriorityRangeConfig(options);
|
|
2744
2778
|
validateGroupConcurrencyConfig(options);
|
|
2745
2779
|
validateHeartbeatRefreshConfig(options);
|
|
2746
2780
|
return { options, callback };
|
|
@@ -2751,6 +2785,7 @@ function checkFetchArgs(name, options) {
|
|
|
2751
2785
|
assert(!("includeMetadata" in options) || typeof options.includeMetadata === "boolean", "includeMetadata must be a boolean");
|
|
2752
2786
|
assert(!("priority" in options) || typeof options.priority === "boolean", "priority must be a boolean");
|
|
2753
2787
|
assert(!("ignoreStartAfter" in options) || typeof options.ignoreStartAfter === "boolean", "ignoreStartAfter must be a boolean");
|
|
2788
|
+
validatePriorityRangeConfig(options);
|
|
2754
2789
|
}
|
|
2755
2790
|
function getConfig(value) {
|
|
2756
2791
|
assert(
|
|
@@ -3797,6 +3832,41 @@ class Contractor {
|
|
|
3797
3832
|
await this.db.executeSql(commands);
|
|
3798
3833
|
}
|
|
3799
3834
|
}
|
|
3835
|
+
function unwrapSQLResult(result) {
|
|
3836
|
+
if (Array.isArray(result)) {
|
|
3837
|
+
return { rows: result.flatMap((i) => i.rows) };
|
|
3838
|
+
}
|
|
3839
|
+
return result;
|
|
3840
|
+
}
|
|
3841
|
+
function delay(ms, error, abortController) {
|
|
3842
|
+
const ac = abortController || new AbortController();
|
|
3843
|
+
const promise = new Promise((resolve, reject) => {
|
|
3844
|
+
setTimeout$1(ms, null, { signal: ac.signal }).then(() => {
|
|
3845
|
+
if (error) {
|
|
3846
|
+
reject(new Error(error));
|
|
3847
|
+
} else {
|
|
3848
|
+
resolve();
|
|
3849
|
+
}
|
|
3850
|
+
}).catch(resolve);
|
|
3851
|
+
});
|
|
3852
|
+
promise.abort = () => {
|
|
3853
|
+
if (!ac.signal.aborted) {
|
|
3854
|
+
ac.abort();
|
|
3855
|
+
}
|
|
3856
|
+
};
|
|
3857
|
+
return promise;
|
|
3858
|
+
}
|
|
3859
|
+
async function resolveWithinSeconds(promise, seconds, message, abortController) {
|
|
3860
|
+
const timeout = Math.max(1, seconds) * 1e3;
|
|
3861
|
+
const reject = delay(timeout, message, abortController);
|
|
3862
|
+
let result;
|
|
3863
|
+
try {
|
|
3864
|
+
result = await Promise.race([promise, reject]);
|
|
3865
|
+
} finally {
|
|
3866
|
+
reject.abort();
|
|
3867
|
+
}
|
|
3868
|
+
return result;
|
|
3869
|
+
}
|
|
3800
3870
|
async function emitAndPersistWarning(ctx, type, message, data) {
|
|
3801
3871
|
ctx.emitter.emit(ctx.warningEvent, { message, data });
|
|
3802
3872
|
if (ctx.persistWarnings) {
|
|
@@ -3832,6 +3902,7 @@ class Timekeeper extends EventEmitter {
|
|
|
3832
3902
|
cronMonitorInterval;
|
|
3833
3903
|
skewMonitorInterval;
|
|
3834
3904
|
timekeeping;
|
|
3905
|
+
_checkingSkew = false;
|
|
3835
3906
|
clockSkew = 0;
|
|
3836
3907
|
events = EVENTS;
|
|
3837
3908
|
constructor(db, manager, config) {
|
|
@@ -3840,6 +3911,9 @@ class Timekeeper extends EventEmitter {
|
|
|
3840
3911
|
this.config = config;
|
|
3841
3912
|
this.manager = manager;
|
|
3842
3913
|
}
|
|
3914
|
+
get checkingSkew() {
|
|
3915
|
+
return this._checkingSkew;
|
|
3916
|
+
}
|
|
3843
3917
|
get warningContext() {
|
|
3844
3918
|
return {
|
|
3845
3919
|
emitter: this,
|
|
@@ -3877,13 +3951,20 @@ class Timekeeper extends EventEmitter {
|
|
|
3877
3951
|
clearInterval(this.cronMonitorInterval);
|
|
3878
3952
|
this.cronMonitorInterval = null;
|
|
3879
3953
|
}
|
|
3954
|
+
while (this.timekeeping || this._checkingSkew) {
|
|
3955
|
+
await delay(10);
|
|
3956
|
+
}
|
|
3880
3957
|
}
|
|
3881
3958
|
async cacheClockSkew() {
|
|
3882
3959
|
let skew = 0;
|
|
3960
|
+
this._checkingSkew = true;
|
|
3883
3961
|
try {
|
|
3884
3962
|
if (this.config.__test__force_clock_monitoring_error) {
|
|
3885
3963
|
throw new Error(this.config.__test__force_clock_monitoring_error);
|
|
3886
3964
|
}
|
|
3965
|
+
if (this.config.__test__delay_clock_skew_ms) {
|
|
3966
|
+
await delay(this.config.__test__delay_clock_skew_ms);
|
|
3967
|
+
}
|
|
3887
3968
|
const { rows } = await this.db.executeSql(getTime());
|
|
3888
3969
|
const local = Date.now();
|
|
3889
3970
|
const dbTime = parseFloat(rows[0].time);
|
|
@@ -3901,6 +3982,7 @@ class Timekeeper extends EventEmitter {
|
|
|
3901
3982
|
this.emit(this.events.error, err);
|
|
3902
3983
|
} finally {
|
|
3903
3984
|
this.clockSkew = skew;
|
|
3985
|
+
this._checkingSkew = false;
|
|
3904
3986
|
}
|
|
3905
3987
|
}
|
|
3906
3988
|
async onCron() {
|
|
@@ -3970,41 +4052,6 @@ class Timekeeper extends EventEmitter {
|
|
|
3970
4052
|
await this.db.executeSql(sql, [name, key]);
|
|
3971
4053
|
}
|
|
3972
4054
|
}
|
|
3973
|
-
function unwrapSQLResult(result) {
|
|
3974
|
-
if (Array.isArray(result)) {
|
|
3975
|
-
return { rows: result.flatMap((i) => i.rows) };
|
|
3976
|
-
}
|
|
3977
|
-
return result;
|
|
3978
|
-
}
|
|
3979
|
-
function delay(ms, error, abortController) {
|
|
3980
|
-
const ac = abortController || new AbortController();
|
|
3981
|
-
const promise = new Promise((resolve, reject) => {
|
|
3982
|
-
setTimeout$1(ms, null, { signal: ac.signal }).then(() => {
|
|
3983
|
-
if (error) {
|
|
3984
|
-
reject(new Error(error));
|
|
3985
|
-
} else {
|
|
3986
|
-
resolve();
|
|
3987
|
-
}
|
|
3988
|
-
}).catch(resolve);
|
|
3989
|
-
});
|
|
3990
|
-
promise.abort = () => {
|
|
3991
|
-
if (!ac.signal.aborted) {
|
|
3992
|
-
ac.abort();
|
|
3993
|
-
}
|
|
3994
|
-
};
|
|
3995
|
-
return promise;
|
|
3996
|
-
}
|
|
3997
|
-
async function resolveWithinSeconds(promise, seconds, message, abortController) {
|
|
3998
|
-
const timeout = Math.max(1, seconds) * 1e3;
|
|
3999
|
-
const reject = delay(timeout, message, abortController);
|
|
4000
|
-
let result;
|
|
4001
|
-
try {
|
|
4002
|
-
result = await Promise.race([promise, reject]);
|
|
4003
|
-
} finally {
|
|
4004
|
-
reject.abort();
|
|
4005
|
-
}
|
|
4006
|
-
return result;
|
|
4007
|
-
}
|
|
4008
4055
|
const WORKER_STATES = {
|
|
4009
4056
|
created: "created",
|
|
4010
4057
|
active: "active",
|
|
@@ -4209,7 +4256,7 @@ class Manager extends EventEmitter {
|
|
|
4209
4256
|
this.db = db;
|
|
4210
4257
|
this.wipTs = Date.now();
|
|
4211
4258
|
this.workers = /* @__PURE__ */ new Map();
|
|
4212
|
-
this.queues =
|
|
4259
|
+
this.queues = {};
|
|
4213
4260
|
this.pendingOffWorkCleanups = /* @__PURE__ */ new Set();
|
|
4214
4261
|
this.#spies = /* @__PURE__ */ new Map();
|
|
4215
4262
|
this.#localGroupActive = /* @__PURE__ */ new Map();
|
|
@@ -4436,7 +4483,9 @@ class Manager extends EventEmitter {
|
|
|
4436
4483
|
localGroupConcurrency,
|
|
4437
4484
|
groupConcurrency,
|
|
4438
4485
|
orderByCreatedOn = true,
|
|
4439
|
-
heartbeatRefreshSeconds
|
|
4486
|
+
heartbeatRefreshSeconds,
|
|
4487
|
+
minPriority,
|
|
4488
|
+
maxPriority
|
|
4440
4489
|
} = options;
|
|
4441
4490
|
if (localGroupConcurrency != null) {
|
|
4442
4491
|
this.#storeLocalGroupConfig(name, localGroupConcurrency);
|
|
@@ -4445,7 +4494,7 @@ class Manager extends EventEmitter {
|
|
|
4445
4494
|
const createWorker = (workerId) => {
|
|
4446
4495
|
const fetch = () => {
|
|
4447
4496
|
const ignoreGroups = localGroupConcurrency != null ? this.#getGroupsAtLocalCapacity(name) : void 0;
|
|
4448
|
-
return this.fetch(name, { batchSize, includeMetadata, priority, orderByCreatedOn, groupConcurrency, ignoreGroups });
|
|
4497
|
+
return this.fetch(name, { batchSize, includeMetadata, priority, orderByCreatedOn, groupConcurrency, ignoreGroups, minPriority, maxPriority });
|
|
4449
4498
|
};
|
|
4450
4499
|
const onFetch = async (jobs2) => {
|
|
4451
4500
|
if (!jobs2.length) return;
|
|
@@ -4994,6 +5043,9 @@ class Boss extends EventEmitter {
|
|
|
4994
5043
|
WARNINGS.LARGE_QUEUE.size = config.warningQueueSize;
|
|
4995
5044
|
}
|
|
4996
5045
|
}
|
|
5046
|
+
get maintaining() {
|
|
5047
|
+
return !!this.#maintaining;
|
|
5048
|
+
}
|
|
4997
5049
|
async start() {
|
|
4998
5050
|
if (this.#stopped) {
|
|
4999
5051
|
this.#stopping = false;
|
|
@@ -5009,6 +5061,9 @@ class Boss extends EventEmitter {
|
|
|
5009
5061
|
this.#stopping = true;
|
|
5010
5062
|
if (this.#superviseInterval) clearInterval(this.#superviseInterval);
|
|
5011
5063
|
this.#stopped = true;
|
|
5064
|
+
while (this.#maintaining) {
|
|
5065
|
+
await delay(10);
|
|
5066
|
+
}
|
|
5012
5067
|
}
|
|
5013
5068
|
}
|
|
5014
5069
|
get #warningContext() {
|
|
@@ -5046,6 +5101,9 @@ class Boss extends EventEmitter {
|
|
|
5046
5101
|
throw new Error(this.#config.__test__throw_maint);
|
|
5047
5102
|
}
|
|
5048
5103
|
this.#maintaining = true;
|
|
5104
|
+
if (this.#config.__test__delay_maint_ms) {
|
|
5105
|
+
await delay(this.#config.__test__delay_maint_ms);
|
|
5106
|
+
}
|
|
5049
5107
|
const queues = await this.#manager.getQueues();
|
|
5050
5108
|
!this.#stopped && await this.supervise(queues);
|
|
5051
5109
|
!this.#stopped && await this.#maintainWarnings();
|
|
@@ -5157,6 +5215,9 @@ class Bam extends EventEmitter {
|
|
|
5157
5215
|
this.#stopped = true;
|
|
5158
5216
|
this.#working = false;
|
|
5159
5217
|
}
|
|
5218
|
+
get working() {
|
|
5219
|
+
return this.#working;
|
|
5220
|
+
}
|
|
5160
5221
|
async start() {
|
|
5161
5222
|
if (!this.#stopped) return;
|
|
5162
5223
|
this.#stopped = false;
|
|
@@ -5173,6 +5234,9 @@ class Bam extends EventEmitter {
|
|
|
5173
5234
|
clearInterval(this.#pollInterval);
|
|
5174
5235
|
this.#pollInterval = void 0;
|
|
5175
5236
|
}
|
|
5237
|
+
while (this.#working) {
|
|
5238
|
+
await delay(10);
|
|
5239
|
+
}
|
|
5176
5240
|
}
|
|
5177
5241
|
async #onPoll() {
|
|
5178
5242
|
if (this.#stopped || this.#working || !this.#config.migrate) return;
|
|
@@ -5181,6 +5245,9 @@ class Bam extends EventEmitter {
|
|
|
5181
5245
|
if (this.#config.__test__throw_bam) {
|
|
5182
5246
|
throw new Error(this.#config.__test__throw_bam);
|
|
5183
5247
|
}
|
|
5248
|
+
if (this.#config.__test__delay_bam_ms) {
|
|
5249
|
+
await delay(this.#config.__test__delay_bam_ms);
|
|
5250
|
+
}
|
|
5184
5251
|
const sql = trySetBamTime(
|
|
5185
5252
|
this.#config.schema,
|
|
5186
5253
|
this.#config.bamIntervalSeconds
|
|
@@ -5483,6 +5550,15 @@ class PgBoss extends EventEmitter {
|
|
|
5483
5550
|
getQueueStats(name) {
|
|
5484
5551
|
return this.#manager.getQueueStats(name);
|
|
5485
5552
|
}
|
|
5553
|
+
isMaintaining() {
|
|
5554
|
+
return this.#boss.maintaining;
|
|
5555
|
+
}
|
|
5556
|
+
isBamWorking() {
|
|
5557
|
+
return this.#bam.working;
|
|
5558
|
+
}
|
|
5559
|
+
isCheckingSkew() {
|
|
5560
|
+
return this.#timekeeper.checkingSkew;
|
|
5561
|
+
}
|
|
5486
5562
|
supervise(name) {
|
|
5487
5563
|
return this.#boss.supervise(name);
|
|
5488
5564
|
}
|
|
@@ -9825,10 +9901,10 @@ const route11 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.definePrope
|
|
|
9825
9901
|
default: warnings,
|
|
9826
9902
|
loader
|
|
9827
9903
|
}, Symbol.toStringTag, { value: "Module" }));
|
|
9828
|
-
const serverManifest = { "entry": { "module": "/assets/entry.client-
|
|
9904
|
+
const serverManifest = { "entry": { "module": "/assets/entry.client-B-bLoJqf.js", "imports": ["/assets/chunk-EVOBXE3Y-CmKRT32p.js", "/assets/index-By5u-yQ6.js"], "css": [] }, "routes": { "root": { "id": "root", "parentId": void 0, "path": "", "index": void 0, "caseSensitive": void 0, "hasAction": false, "hasLoader": true, "hasClientAction": false, "hasClientLoader": false, "hasClientMiddleware": false, "hasDefaultExport": true, "hasErrorBoundary": true, "module": "/assets/root-Cubm0m9Y.js", "imports": ["/assets/chunk-EVOBXE3Y-CmKRT32p.js", "/assets/index-By5u-yQ6.js", "/assets/db-link-BzIwSws3.js", "/assets/createLucideIcon-C5Bm8BOS.js", "/assets/MenuTrigger-BUdpY9vj.js", "/assets/useOpenInteractionType-C7OfDyTB.js"], "css": ["/assets/root-Bpb4WtY4.css"], "clientActionModule": void 0, "clientLoaderModule": void 0, "clientMiddlewareModule": void 0, "hydrateFallbackModule": void 0 }, "routes/_index": { "id": "routes/_index", "parentId": "root", "path": void 0, "index": true, "caseSensitive": void 0, "hasAction": false, "hasLoader": true, "hasClientAction": false, "hasClientLoader": false, "hasClientMiddleware": false, "hasDefaultExport": true, "hasErrorBoundary": true, "module": "/assets/_index-DXfER9RD.js", "imports": ["/assets/chunk-EVOBXE3Y-CmKRT32p.js", "/assets/db-link-BzIwSws3.js", "/assets/button-CudTDtZF.js", "/assets/badge-to3cY6Nn.js", "/assets/table-CV0K56fY.js", "/assets/error-card--OB_TuOC.js"], "css": [], "clientActionModule": void 0, "clientLoaderModule": void 0, "clientMiddlewareModule": void 0, "hydrateFallbackModule": void 0 }, "routes/jobs": { "id": "routes/jobs", "parentId": "root", "path": "jobs", "index": void 0, "caseSensitive": void 0, "hasAction": false, "hasLoader": true, "hasClientAction": false, "hasClientLoader": false, "hasClientMiddleware": false, "hasDefaultExport": true, "hasErrorBoundary": true, "module": "/assets/jobs-Gp0x24mG.js", "imports": ["/assets/chunk-EVOBXE3Y-CmKRT32p.js", "/assets/db-link-BzIwSws3.js", "/assets/button-CudTDtZF.js", "/assets/badge-to3cY6Nn.js", "/assets/table-CV0K56fY.js", "/assets/pagination-DCEs769S.js", "/assets/filter-select-07am_j5T.js", "/assets/error-card--OB_TuOC.js"], "css": [], "clientActionModule": void 0, "clientLoaderModule": void 0, "clientMiddlewareModule": void 0, "hydrateFallbackModule": void 0 }, "routes/queues._index": { "id": "routes/queues._index", "parentId": "root", "path": "queues", "index": void 0, "caseSensitive": void 0, "hasAction": false, "hasLoader": true, "hasClientAction": false, "hasClientLoader": false, "hasClientMiddleware": false, "hasDefaultExport": true, "hasErrorBoundary": true, "module": "/assets/queues._index-DxMtAiK3.js", "imports": ["/assets/chunk-EVOBXE3Y-CmKRT32p.js", "/assets/db-link-BzIwSws3.js", "/assets/button-CudTDtZF.js", "/assets/badge-to3cY6Nn.js", "/assets/filter-select-07am_j5T.js", "/assets/table-CV0K56fY.js"], "css": [], "clientActionModule": void 0, "clientLoaderModule": void 0, "clientMiddlewareModule": void 0, "hydrateFallbackModule": void 0 }, "routes/queues.create": { "id": "routes/queues.create", "parentId": "root", "path": "queues/create", "index": void 0, "caseSensitive": void 0, "hasAction": true, "hasLoader": true, "hasClientAction": false, "hasClientLoader": false, "hasClientMiddleware": false, "hasDefaultExport": true, "hasErrorBoundary": true, "module": "/assets/queues.create-aEr8z6Lt.js", "imports": ["/assets/chunk-EVOBXE3Y-CmKRT32p.js", "/assets/db-link-BzIwSws3.js", "/assets/button-CudTDtZF.js", "/assets/chevron-down-ClrMXFFn.js", "/assets/error-card--OB_TuOC.js", "/assets/createLucideIcon-C5Bm8BOS.js"], "css": [], "clientActionModule": void 0, "clientLoaderModule": void 0, "clientMiddlewareModule": void 0, "hydrateFallbackModule": void 0 }, "routes/queues.$name": { "id": "routes/queues.$name", "parentId": "root", "path": "queues/:name", "index": void 0, "caseSensitive": void 0, "hasAction": true, "hasLoader": true, "hasClientAction": false, "hasClientLoader": false, "hasClientMiddleware": false, "hasDefaultExport": true, "hasErrorBoundary": true, "module": "/assets/queues._name-DqI0ZH4S.js", "imports": ["/assets/chunk-EVOBXE3Y-CmKRT32p.js", "/assets/db-link-BzIwSws3.js", "/assets/button-CudTDtZF.js", "/assets/badge-to3cY6Nn.js", "/assets/table-CV0K56fY.js", "/assets/pagination-DCEs769S.js", "/assets/filter-select-07am_j5T.js", "/assets/dialog-BBFR7NS6.js", "/assets/error-card--OB_TuOC.js", "/assets/chevron-down-ClrMXFFn.js", "/assets/createLucideIcon-C5Bm8BOS.js", "/assets/MenuTrigger-BUdpY9vj.js", "/assets/useOpenInteractionType-C7OfDyTB.js", "/assets/index-By5u-yQ6.js"], "css": [], "clientActionModule": void 0, "clientLoaderModule": void 0, "clientMiddlewareModule": void 0, "hydrateFallbackModule": void 0 }, "routes/queues.$name.jobs.$jobId": { "id": "routes/queues.$name.jobs.$jobId", "parentId": "root", "path": "queues/:name/jobs/:jobId", "index": void 0, "caseSensitive": void 0, "hasAction": true, "hasLoader": true, "hasClientAction": false, "hasClientLoader": false, "hasClientMiddleware": false, "hasDefaultExport": true, "hasErrorBoundary": true, "module": "/assets/queues._name.jobs._jobId-BEwVDYH6.js", "imports": ["/assets/chunk-EVOBXE3Y-CmKRT32p.js", "/assets/db-link-BzIwSws3.js", "/assets/button-CudTDtZF.js", "/assets/badge-to3cY6Nn.js", "/assets/dialog-BBFR7NS6.js", "/assets/error-card--OB_TuOC.js", "/assets/createLucideIcon-C5Bm8BOS.js", "/assets/useOpenInteractionType-C7OfDyTB.js", "/assets/index-By5u-yQ6.js"], "css": [], "clientActionModule": void 0, "clientLoaderModule": void 0, "clientMiddlewareModule": void 0, "hydrateFallbackModule": void 0 }, "routes/schedules": { "id": "routes/schedules", "parentId": "root", "path": "schedules", "index": void 0, "caseSensitive": void 0, "hasAction": false, "hasLoader": true, "hasClientAction": false, "hasClientLoader": false, "hasClientMiddleware": false, "hasDefaultExport": true, "hasErrorBoundary": true, "module": "/assets/schedules-BacoSVY9.js", "imports": ["/assets/chunk-EVOBXE3Y-CmKRT32p.js", "/assets/db-link-BzIwSws3.js", "/assets/button-CudTDtZF.js", "/assets/table-CV0K56fY.js", "/assets/pagination-DCEs769S.js", "/assets/error-card--OB_TuOC.js"], "css": [], "clientActionModule": void 0, "clientLoaderModule": void 0, "clientMiddlewareModule": void 0, "hydrateFallbackModule": void 0 }, "routes/schedules.$name.$key": { "id": "routes/schedules.$name.$key", "parentId": "root", "path": "schedules/:name/:key", "index": void 0, "caseSensitive": void 0, "hasAction": true, "hasLoader": true, "hasClientAction": false, "hasClientLoader": false, "hasClientMiddleware": false, "hasDefaultExport": true, "hasErrorBoundary": true, "module": "/assets/schedules._name._key-zuc0HZqU.js", "imports": ["/assets/chunk-EVOBXE3Y-CmKRT32p.js", "/assets/db-link-BzIwSws3.js", "/assets/button-CudTDtZF.js", "/assets/dialog-BBFR7NS6.js", "/assets/error-card--OB_TuOC.js", "/assets/createLucideIcon-C5Bm8BOS.js", "/assets/useOpenInteractionType-C7OfDyTB.js", "/assets/index-By5u-yQ6.js"], "css": [], "clientActionModule": void 0, "clientLoaderModule": void 0, "clientMiddlewareModule": void 0, "hydrateFallbackModule": void 0 }, "routes/schedules.new": { "id": "routes/schedules.new", "parentId": "root", "path": "schedules/new", "index": void 0, "caseSensitive": void 0, "hasAction": true, "hasLoader": true, "hasClientAction": false, "hasClientLoader": false, "hasClientMiddleware": false, "hasDefaultExport": true, "hasErrorBoundary": true, "module": "/assets/schedules.new-CrK1w4GF.js", "imports": ["/assets/chunk-EVOBXE3Y-CmKRT32p.js", "/assets/db-link-BzIwSws3.js", "/assets/button-CudTDtZF.js", "/assets/error-card--OB_TuOC.js"], "css": [], "clientActionModule": void 0, "clientLoaderModule": void 0, "clientMiddlewareModule": void 0, "hydrateFallbackModule": void 0 }, "routes/send": { "id": "routes/send", "parentId": "root", "path": "send", "index": void 0, "caseSensitive": void 0, "hasAction": true, "hasLoader": true, "hasClientAction": false, "hasClientLoader": false, "hasClientMiddleware": false, "hasDefaultExport": true, "hasErrorBoundary": true, "module": "/assets/send-wPFbslqy.js", "imports": ["/assets/chunk-EVOBXE3Y-CmKRT32p.js", "/assets/db-link-BzIwSws3.js", "/assets/button-CudTDtZF.js", "/assets/error-card--OB_TuOC.js"], "css": [], "clientActionModule": void 0, "clientLoaderModule": void 0, "clientMiddlewareModule": void 0, "hydrateFallbackModule": void 0 }, "routes/warnings": { "id": "routes/warnings", "parentId": "root", "path": "warnings", "index": void 0, "caseSensitive": void 0, "hasAction": false, "hasLoader": true, "hasClientAction": false, "hasClientLoader": false, "hasClientMiddleware": false, "hasDefaultExport": true, "hasErrorBoundary": true, "module": "/assets/warnings-DLjttltF.js", "imports": ["/assets/chunk-EVOBXE3Y-CmKRT32p.js", "/assets/button-CudTDtZF.js", "/assets/badge-to3cY6Nn.js", "/assets/table-CV0K56fY.js", "/assets/pagination-DCEs769S.js", "/assets/filter-select-07am_j5T.js", "/assets/error-card--OB_TuOC.js", "/assets/db-link-BzIwSws3.js"], "css": [], "clientActionModule": void 0, "clientLoaderModule": void 0, "clientMiddlewareModule": void 0, "hydrateFallbackModule": void 0 } }, "url": "/assets/manifest-560249af.js", "version": "560249af", "sri": void 0 };
|
|
9829
9905
|
const assetsBuildDirectory = "build/client";
|
|
9830
9906
|
const basename = "/";
|
|
9831
|
-
const future = { "unstable_optimizeDeps": false, "unstable_subResourceIntegrity": false, "unstable_trailingSlashAwareDataRequests": false, "unstable_previewServerPrerendering": false, "v8_middleware": false, "v8_splitRouteModules": false, "v8_viteEnvironmentApi": false };
|
|
9907
|
+
const future = { "unstable_optimizeDeps": false, "unstable_passThroughRequests": false, "unstable_subResourceIntegrity": false, "unstable_trailingSlashAwareDataRequests": false, "unstable_previewServerPrerendering": false, "v8_middleware": false, "v8_splitRouteModules": false, "v8_viteEnvironmentApi": false };
|
|
9832
9908
|
const ssr = true;
|
|
9833
9909
|
const isSpaMode = false;
|
|
9834
9910
|
const prerender = [];
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pg-boss/dashboard",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.3",
|
|
4
4
|
"description": "Web dashboard for monitoring and managing pg-boss job queues",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"pg-boss",
|
|
@@ -41,41 +41,41 @@
|
|
|
41
41
|
"ci": "npm run typecheck && npm run cover:frontend && cross-env DATABASE_URL=postgres://postgres:postgres@127.0.0.1:5432/pgboss npm run cover:server"
|
|
42
42
|
},
|
|
43
43
|
"dependencies": {
|
|
44
|
-
"@base-ui/react": "^1.
|
|
45
|
-
"@hono/node-server": "^1.19.
|
|
44
|
+
"@base-ui/react": "^1.4.1",
|
|
45
|
+
"@hono/node-server": "^1.19.12",
|
|
46
46
|
"@react-router/node": "^7.13.0",
|
|
47
47
|
"class-variance-authority": "^0.7.1",
|
|
48
48
|
"clsx": "^2.1.1",
|
|
49
|
-
"hono": "^4.12.
|
|
50
|
-
"isbot": "^5.1.
|
|
49
|
+
"hono": "^4.12.14",
|
|
50
|
+
"isbot": "^5.1.39",
|
|
51
51
|
"lucide-react": "^0.575.0",
|
|
52
|
-
"pg": "^8.
|
|
53
|
-
"pg-boss": "^12.
|
|
54
|
-
"react": "^19.2.
|
|
55
|
-
"react-dom": "^19.2.
|
|
52
|
+
"pg": "^8.20.0",
|
|
53
|
+
"pg-boss": "^12.16.0",
|
|
54
|
+
"react": "^19.2.5",
|
|
55
|
+
"react-dom": "^19.2.5",
|
|
56
56
|
"react-router": "^7.13.0",
|
|
57
|
-
"react-router-hono-server": "^2.25.
|
|
57
|
+
"react-router-hono-server": "^2.25.3",
|
|
58
58
|
"tailwind-merge": "^3.5.0"
|
|
59
59
|
},
|
|
60
60
|
"devDependencies": {
|
|
61
|
-
"@react-router/dev": "^7.
|
|
62
|
-
"@tailwindcss/vite": "^4.2.
|
|
61
|
+
"@react-router/dev": "^7.14.2",
|
|
62
|
+
"@tailwindcss/vite": "^4.2.4",
|
|
63
63
|
"@testing-library/dom": "^10.4.1",
|
|
64
64
|
"@testing-library/jest-dom": "^6.9.1",
|
|
65
65
|
"@testing-library/react": "^16.3.2",
|
|
66
66
|
"@testing-library/user-event": "^14.6.1",
|
|
67
|
-
"@types/node": "^22.19.
|
|
68
|
-
"@types/pg": "^8.
|
|
67
|
+
"@types/node": "^22.19.17",
|
|
68
|
+
"@types/pg": "^8.20.0",
|
|
69
69
|
"@types/react": "^19.2.14",
|
|
70
70
|
"@types/react-dom": "^19.2.3",
|
|
71
|
-
"@vitejs/plugin-react": "^5.
|
|
72
|
-
"@vitest/coverage-v8": "^4.
|
|
71
|
+
"@vitejs/plugin-react": "^5.2.0",
|
|
72
|
+
"@vitest/coverage-v8": "^4.1.2",
|
|
73
73
|
"cross-env": "^10.1.0",
|
|
74
74
|
"jsdom": "^28.1.0",
|
|
75
75
|
"tailwindcss": "^4.1.18",
|
|
76
76
|
"tsx": "^4.21.0",
|
|
77
77
|
"typescript": "^5.9.3",
|
|
78
|
-
"vite": "^7.3.
|
|
78
|
+
"vite": "^7.3.2",
|
|
79
79
|
"vitest": "^4.0.18"
|
|
80
80
|
},
|
|
81
81
|
"repository": {
|