@ancon/wildcat-utils 1.50.25 → 1.50.27

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.
@@ -41,11 +41,13 @@ declare class HangfirePoller {
41
41
  private waitForNetworkOnline;
42
42
  private executeWorkerRequest;
43
43
  private deleteWorker;
44
- createWorker(groupId: string, { workerId, url, headers, onFinished, }: {
44
+ createWorker(groupId: string, { workerId, url, headers, onFinished, maxLifeTimeMillis, }: {
45
45
  workerId: string;
46
46
  url: string;
47
47
  headers?: APIHeaders;
48
48
  onFinished?: (forced: boolean) => void | Promise<void>;
49
+ /** Max lifetime in milliseconds. When exceeded the worker executes one final request and exits. */
50
+ maxLifeTimeMillis?: number;
49
51
  }): Promise<unknown>;
50
52
  /** Trigger a worker to execute immediately, ignoring busy state */
51
53
  triggerWorker(workerId: string): void;
@@ -1 +1 @@
1
- "use strict";var x=Object.defineProperty;var W=(i,e,r)=>e in i?x(i,e,{enumerable:!0,configurable:!0,writable:!0,value:r}):i[e]=r;var o=(i,e,r)=>(W(i,typeof e!="symbol"?e+"":e,r),r);Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const y=require("axios"),l=require("@ancon/wildcat-types"),d=require("../error/createCodedError.js"),I=require("../error/isNotFoundError.js"),f=require("../error/serializeError.js"),w=require("../error/isErrorWithStatusCode.js"),q=require("../api/isNoContentResponse.js"),b=require("../shared/wait.js");require("../error/isCodedError.js");require("../error/isAPIError.js");class m{constructor(e){o(this,"busyWorkers",new Set);o(this,"enabledGroups",new Set);o(this,"groups",new Map);o(this,"workerByIdMap",new Map);o(this,"timer",null);o(this,"config",{pollerInterval:5e3,maxGroupsSize:50,maxWorkersSize:20,responseInterceptor:void 0,responseRejectionInterceptor:void 0,getIsNetworkOnline(){return!0},async getRequestHeaders(){return{}},debug(...e){console.log(...e)}});o(this,"axiosInstance");this.config={...this.config,...e??null},this.axiosInstance=y.create(),(this.config.responseInterceptor||this.config.responseRejectionInterceptor)&&this.axiosInstance.interceptors.response.use(this.config.responseInterceptor,this.config.responseRejectionInterceptor)}stopTimer(){this.timer!=null&&(this.config.debug("*stop timer*"),clearInterval(this.timer),this.timer=null)}startTimer(){if(this.timer!=null)throw d(new Error("Timer already started"),l.ErrorCode.GenericUnexpectedHangfireError);this.config.debug("*start timer*"),this.timer=setInterval(()=>{this.config.debug("*tick*",{busyWorkers:this.busyWorkers.size,enabledGroups:this.enabledGroups.size,groups:this.groups}),this.enabledGroups.forEach(e=>{const r=this.groups.get(e);r&&r.forEach(t=>this.executeWorkerRequest(t))}),this.groups.size<1&&this.stopTimer()},this.config.pollerInterval)}async waitForNetworkOnline(e=5){let r=0;for(;!this.config.getIsNetworkOnline()&&r<e+1;)r+=1,await b(1e3)}async executeWorkerRequest(e,r=!1){var a,u,h,c;const t=r!==!0&&this.busyWorkers.has(e.workerId);if(this.config.debug("*executeWorkerRequest*",{workerId:e.workerId,isBusy:t,force:r}),t){this.config.debug("*executeWorkerRequest* worker is busy",e.workerId);return}this.busyWorkers.add(e.workerId),await this.waitForNetworkOnline(),this.config.debug("*executeWorkerRequest* request",{isNetworkOnline:this.config.getIsNetworkOnline()});const g={...await this.config.getRequestHeaders(),...e.headers},p=2;let s=0;for(;s<=p;)try{const n=await this.axiosInstance({url:e.url,method:"get",timeout:this.config.pollerInterval,headers:g});q(n)?this.busyWorkers.delete(e.workerId):(e.resolve(n),(a=e.onFinished)==null||a.call(e,r),this.deleteWorker(e.groupId,e.workerId));break}catch(n){if(w(n)){if(I(n)){this.config.debug("*executeWorkerRequest* worker is expired or invalid",e.workerId);const k=f(d(new Error("The Hangfire worker is expired or invalid"),l.ErrorCode.HangfireWorkerExpiredOrInvalid));e.reject(k),(u=e.onFinished)==null||u.call(e,r)}else e.reject(n),(h=e.onFinished)==null||h.call(e,r);this.deleteWorker(e.groupId,e.workerId);break}else if(this.config.debug("*executeWorkerRequest* not an api error"),(c=this.config.logger)==null||c.warn(`Hangfire worker request error: ${JSON.stringify({attempt:s,groupId:e.groupId,workerId:e.workerId,error:f(n)})}`,{CorrelationId:g["x-correlation-id"]}),r&&s<p)s+=1,this.config.debug(`*executeWorkerRequest* retrying non-API error (attempt ${s})`),await b(500);else{this.busyWorkers.delete(e.workerId);break}}}deleteWorker(e,r){const t=this.groups.get(e);t&&(this.config.debug("*delete worker*",t.size,t),t.delete(r),this.workerByIdMap.delete(r),this.busyWorkers.delete(r),t.size<1&&(this.groups.delete(e),this.enabledGroups.delete(e),this.enabledGroups.size<1&&this.stopTimer()))}createWorker(e,{workerId:r,url:t,headers:g,onFinished:p}){if(!this.groups.has(e)){if(this.groups.size>=this.config.maxGroupsSize){const a=d(new Error("Max number of Hangfire groups exceeded"),l.ErrorCode.GenericUnexpectedHangfireError,{count:this.groups.size});throw this.destroy(),a}this.groups.set(e,new Map)}const s=this.groups.get(e);return new Promise((a,u)=>{if(s.has(r))throw d(new Error("Duplicate Hangfire worker ID"),l.ErrorCode.GenericUnexpectedHangfireError);if(s.size>=this.config.maxWorkersSize){const c=d(new Error("Max number of Hangfire workers in group exceeded"),l.ErrorCode.GenericUnexpectedHangfireError,{groupId:e,count:s.size});throw u(c),this.destroy(),c}const h={workerId:r,groupId:e,url:t,resolve:a,reject:u,headers:g,onFinished:p};s.set(r,h),this.workerByIdMap.set(r,h),this.enabledGroups.has(e)||this.enabledGroups.add(e),this.timer==null&&this.enabledGroups.size>0&&this.startTimer()})}triggerWorker(e){this.config.debug("*triggerWorker*");const r=this.workerByIdMap.get(e);r?this.executeWorkerRequest(r,!0):this.config.debug("*triggerWorker* worker not found",e)}triggerAllWorkers(){this.config.debug("*triggerAllWorkers*");for(const e of this.workerByIdMap.values())this.executeWorkerRequest(e)}enableWorkers(e){this.config.debug("*enable*",e),this.enabledGroups.add(e),this.groups.has(e)&&this.timer==null&&this.startTimer()}disableWorkers(e){this.config.debug("*disable*",e),this.enabledGroups.delete(e),this.enabledGroups.size<1&&this.stopTimer()}destroy(){this.config.debug("*destroy*"),this.groups.clear(),this.stopTimer()}}function E(i){return new m(i)}exports.HangfirePoller=m;exports.default=E;
1
+ "use strict";var y=Object.defineProperty;var I=(s,e,r)=>e in s?y(s,e,{enumerable:!0,configurable:!0,writable:!0,value:r}):s[e]=r;var o=(s,e,r)=>(I(s,typeof e!="symbol"?e+"":e,r),r);Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const k=require("axios"),u=require("@ancon/wildcat-types"),c=require("../error/createCodedError.js"),q=require("../error/isNotFoundError.js"),x=require("../error/serializeError.js"),G=require("../error/isErrorWithStatusCode.js"),w=require("../api/isNoContentResponse.js"),W=require("../shared/wait.js");require("../error/isCodedError.js");require("../error/isAPIError.js");class E{constructor(e){o(this,"busyWorkers",new Set);o(this,"enabledGroups",new Set);o(this,"groups",new Map);o(this,"workerByIdMap",new Map);o(this,"timer",null);o(this,"config",{pollerInterval:5e3,maxGroupsSize:50,maxWorkersSize:20,responseInterceptor:void 0,responseRejectionInterceptor:void 0,getIsNetworkOnline(){return!0},async getRequestHeaders(){return{}},debug(...e){console.log(...e)}});o(this,"axiosInstance");this.config={...this.config,...e??null},this.axiosInstance=k.create(),(this.config.responseInterceptor||this.config.responseRejectionInterceptor)&&this.axiosInstance.interceptors.response.use(this.config.responseInterceptor,this.config.responseRejectionInterceptor)}stopTimer(){this.timer!=null&&(this.config.debug("*stop timer*"),clearInterval(this.timer),this.timer=null)}startTimer(){if(this.timer!=null)throw c(new Error("Timer already started"),u.ErrorCode.GenericUnexpectedHangfireError);this.config.debug("*start timer*"),this.timer=setInterval(()=>{this.config.debug("*tick*",{busyWorkers:this.busyWorkers.size,enabledGroups:this.enabledGroups.size,groups:this.groups}),this.enabledGroups.forEach(e=>{const r=this.groups.get(e);r&&r.forEach(i=>this.executeWorkerRequest(i))}),this.groups.forEach((e,r)=>{this.enabledGroups.has(r)||e.forEach(i=>{i.maxLifeTimeMillis!=null&&Date.now()-i.createdAt>i.maxLifeTimeMillis&&this.executeWorkerRequest(i)})}),this.groups.size<1&&this.stopTimer()},this.config.pollerInterval)}async waitForNetworkOnline(e=5){let r=0;for(;!this.config.getIsNetworkOnline()&&r<e+1;)r+=1,await W(1e3)}async executeWorkerRequest(e,r=!1){var a,d,h,g,m;const i=e.maxLifeTimeMillis!=null&&Date.now()-e.createdAt>e.maxLifeTimeMillis,l=!r&&!i&&this.busyWorkers.has(e.workerId);if(this.config.debug("*executeWorkerRequest*",{workerId:e.workerId,isBusy:l,force:r}),l){this.config.debug("*executeWorkerRequest* worker is busy",e.workerId);return}this.busyWorkers.add(e.workerId),await this.waitForNetworkOnline(),this.config.debug("*executeWorkerRequest* request",{isNetworkOnline:this.config.getIsNetworkOnline()});const f={...await this.config.getRequestHeaders(),...e.headers},p=2;let t=0;for(;t<=p;)try{const n=await this.axiosInstance({url:e.url,method:"get",timeout:this.config.pollerInterval,headers:f});if(!w(n))e.resolve(n),(a=e.onFinished)==null||a.call(e,r),this.deleteWorker(e.groupId,e.workerId);else if(i){this.config.debug("*executeWorkerRequest* worker lifetime exceeded, forcing exit",e.workerId);const b=x(c(new Error("The Hangfire worker lifetime has been exceeded"),u.ErrorCode.GenericUnexpectedHangfireError));e.reject(b),(d=e.onFinished)==null||d.call(e,!0),this.deleteWorker(e.groupId,e.workerId)}else this.busyWorkers.delete(e.workerId);break}catch(n){if(G(n)){if(q(n)){this.config.debug("*executeWorkerRequest* worker is expired or invalid",e.workerId);const b=x(c(new Error("The Hangfire worker is expired or invalid"),u.ErrorCode.HangfireWorkerExpiredOrInvalid));e.reject(b),(h=e.onFinished)==null||h.call(e,r)}else e.reject(n),(g=e.onFinished)==null||g.call(e,r);this.deleteWorker(e.groupId,e.workerId);break}else if(this.config.debug("*executeWorkerRequest* not an api error"),(m=this.config.logger)==null||m.warn(`Hangfire worker request error: ${JSON.stringify({attempt:t,groupId:e.groupId,workerId:e.workerId,error:x(n)})}`,{CorrelationId:f["x-correlation-id"]}),r&&t<p)t+=1,this.config.debug(`*executeWorkerRequest* retrying non-API error (attempt ${t})`),await W(500);else{this.busyWorkers.delete(e.workerId);break}}}deleteWorker(e,r){const i=this.groups.get(e);i&&(this.config.debug("*delete worker*",i.size,i),i.delete(r),this.workerByIdMap.delete(r),this.busyWorkers.delete(r),i.size<1&&(this.groups.delete(e),this.enabledGroups.delete(e),this.enabledGroups.size<1&&this.stopTimer()))}createWorker(e,{workerId:r,url:i,headers:l,onFinished:f,maxLifeTimeMillis:p}){if(!this.groups.has(e)){if(this.groups.size>=this.config.maxGroupsSize){const a=c(new Error("Max number of Hangfire groups exceeded"),u.ErrorCode.GenericUnexpectedHangfireError,{count:this.groups.size});throw this.destroy(),a}this.groups.set(e,new Map)}const t=this.groups.get(e);return new Promise((a,d)=>{if(t.has(r))throw c(new Error("Duplicate Hangfire worker ID"),u.ErrorCode.GenericUnexpectedHangfireError);if(t.size>=this.config.maxWorkersSize){const g=c(new Error("Max number of Hangfire workers in group exceeded"),u.ErrorCode.GenericUnexpectedHangfireError,{groupId:e,count:t.size});throw d(g),this.destroy(),g}const h={workerId:r,groupId:e,url:i,resolve:a,reject:d,headers:l,onFinished:f,createdAt:Date.now(),maxLifeTimeMillis:p};t.set(r,h),this.workerByIdMap.set(r,h),this.enabledGroups.has(e)||this.enabledGroups.add(e),this.timer==null&&this.enabledGroups.size>0&&this.startTimer()})}triggerWorker(e){this.config.debug("*triggerWorker*");const r=this.workerByIdMap.get(e);r?this.executeWorkerRequest(r,!0):this.config.debug("*triggerWorker* worker not found",e)}triggerAllWorkers(){this.config.debug("*triggerAllWorkers*");for(const e of this.workerByIdMap.values())this.executeWorkerRequest(e)}enableWorkers(e){this.config.debug("*enable*",e),this.enabledGroups.add(e),this.groups.has(e)&&this.timer==null&&this.startTimer()}disableWorkers(e){this.config.debug("*disable*",e),this.enabledGroups.delete(e);const r=this.groups.size>0&&[...this.workerByIdMap.values()].some(i=>i.maxLifeTimeMillis!=null);this.enabledGroups.size<1&&!r&&this.stopTimer()}destroy(){this.config.debug("*destroy*"),this.groups.clear(),this.stopTimer()}}function z(s){return new E(s)}exports.HangfirePoller=E;exports.default=z;
@@ -1,17 +1,17 @@
1
- var x = Object.defineProperty;
2
- var k = (s, e, r) => e in s ? x(s, e, { enumerable: !0, configurable: !0, writable: !0, value: r }) : s[e] = r;
3
- var o = (s, e, r) => (k(s, typeof e != "symbol" ? e + "" : e, r), r);
4
- import W from "axios";
5
- import { ErrorCode as g } from "@ancon/wildcat-types";
6
- import l from "../error/createCodedError.mjs";
7
- import y from "../error/isNotFoundError.mjs";
8
- import f from "../error/serializeError.mjs";
9
- import I from "../error/isErrorWithStatusCode.mjs";
1
+ var I = Object.defineProperty;
2
+ var E = (s, e, t) => e in s ? I(s, e, { enumerable: !0, configurable: !0, writable: !0, value: t }) : s[e] = t;
3
+ var o = (s, e, t) => (E(s, typeof e != "symbol" ? e + "" : e, t), t);
4
+ import y from "axios";
5
+ import { ErrorCode as h } from "@ancon/wildcat-types";
6
+ import u from "../error/createCodedError.mjs";
7
+ import k from "../error/isNotFoundError.mjs";
8
+ import b from "../error/serializeError.mjs";
9
+ import G from "../error/isErrorWithStatusCode.mjs";
10
10
  import w from "../api/isNoContentResponse.mjs";
11
- import m from "../shared/wait.mjs";
11
+ import W from "../shared/wait.mjs";
12
12
  import "../error/isCodedError.mjs";
13
13
  import "../error/isAPIError.mjs";
14
- class E {
14
+ class z {
15
15
  constructor(e) {
16
16
  /** Workers currently executing a request */
17
17
  o(this, "busyWorkers", /* @__PURE__ */ new Set());
@@ -42,7 +42,7 @@ class E {
42
42
  this.config = {
43
43
  ...this.config,
44
44
  ...e ?? null
45
- }, this.axiosInstance = W.create(), (this.config.responseInterceptor || this.config.responseRejectionInterceptor) && this.axiosInstance.interceptors.response.use(
45
+ }, this.axiosInstance = y.create(), (this.config.responseInterceptor || this.config.responseRejectionInterceptor) && this.axiosInstance.interceptors.response.use(
46
46
  this.config.responseInterceptor,
47
47
  this.config.responseRejectionInterceptor
48
48
  );
@@ -52,9 +52,9 @@ class E {
52
52
  }
53
53
  startTimer() {
54
54
  if (this.timer != null)
55
- throw l(
55
+ throw u(
56
56
  new Error("Timer already started"),
57
- g.GenericUnexpectedHangfireError
57
+ h.GenericUnexpectedHangfireError
58
58
  );
59
59
  this.config.debug("*start timer*"), this.timer = setInterval(() => {
60
60
  this.config.debug("*tick*", {
@@ -62,24 +62,28 @@ class E {
62
62
  enabledGroups: this.enabledGroups.size,
63
63
  groups: this.groups
64
64
  }), this.enabledGroups.forEach((e) => {
65
- const r = this.groups.get(e);
66
- r && r.forEach((t) => this.executeWorkerRequest(t));
65
+ const t = this.groups.get(e);
66
+ t && t.forEach((i) => this.executeWorkerRequest(i));
67
+ }), this.groups.forEach((e, t) => {
68
+ this.enabledGroups.has(t) || e.forEach((i) => {
69
+ i.maxLifeTimeMillis != null && Date.now() - i.createdAt > i.maxLifeTimeMillis && this.executeWorkerRequest(i);
70
+ });
67
71
  }), this.groups.size < 1 && this.stopTimer();
68
72
  }, this.config.pollerInterval);
69
73
  }
70
74
  async waitForNetworkOnline(e = 5) {
71
- let r = 0;
72
- for (; !this.config.getIsNetworkOnline() && r < e + 1; )
73
- r += 1, await m(1e3);
75
+ let t = 0;
76
+ for (; !this.config.getIsNetworkOnline() && t < e + 1; )
77
+ t += 1, await W(1e3);
74
78
  }
75
- async executeWorkerRequest(e, r = !1) {
76
- var a, h, u, c;
77
- const t = r !== !0 && this.busyWorkers.has(e.workerId);
79
+ async executeWorkerRequest(e, t = !1) {
80
+ var a, c, d, g, x;
81
+ const i = e.maxLifeTimeMillis != null && Date.now() - e.createdAt > e.maxLifeTimeMillis, l = !t && !i && this.busyWorkers.has(e.workerId);
78
82
  if (this.config.debug("*executeWorkerRequest*", {
79
83
  workerId: e.workerId,
80
- isBusy: t,
81
- force: r
82
- }), t) {
84
+ isBusy: l,
85
+ force: t
86
+ }), l) {
83
87
  this.config.debug(
84
88
  "*executeWorkerRequest* worker is busy",
85
89
  e.workerId
@@ -89,112 +93,130 @@ class E {
89
93
  this.busyWorkers.add(e.workerId), await this.waitForNetworkOnline(), this.config.debug("*executeWorkerRequest* request", {
90
94
  isNetworkOnline: this.config.getIsNetworkOnline()
91
95
  });
92
- const d = {
96
+ const f = {
93
97
  ...await this.config.getRequestHeaders(),
94
98
  ...e.headers
95
99
  }, p = 2;
96
- let i = 0;
97
- for (; i <= p; )
100
+ let r = 0;
101
+ for (; r <= p; )
98
102
  try {
99
103
  const n = await this.axiosInstance({
100
104
  url: e.url,
101
105
  method: "get",
102
106
  timeout: this.config.pollerInterval,
103
- headers: d
107
+ headers: f
104
108
  });
105
- w(n) ? this.busyWorkers.delete(e.workerId) : (e.resolve(n), (a = e.onFinished) == null || a.call(e, r), this.deleteWorker(e.groupId, e.workerId));
109
+ if (!w(n))
110
+ e.resolve(n), (a = e.onFinished) == null || a.call(e, t), this.deleteWorker(e.groupId, e.workerId);
111
+ else if (i) {
112
+ this.config.debug(
113
+ "*executeWorkerRequest* worker lifetime exceeded, forcing exit",
114
+ e.workerId
115
+ );
116
+ const m = b(
117
+ u(
118
+ new Error("The Hangfire worker lifetime has been exceeded"),
119
+ h.GenericUnexpectedHangfireError
120
+ )
121
+ );
122
+ e.reject(m), (c = e.onFinished) == null || c.call(e, !0), this.deleteWorker(e.groupId, e.workerId);
123
+ } else
124
+ this.busyWorkers.delete(e.workerId);
106
125
  break;
107
126
  } catch (n) {
108
- if (I(n)) {
109
- if (y(n)) {
127
+ if (G(n)) {
128
+ if (k(n)) {
110
129
  this.config.debug(
111
130
  "*executeWorkerRequest* worker is expired or invalid",
112
131
  e.workerId
113
132
  );
114
- const b = f(
115
- l(
133
+ const m = b(
134
+ u(
116
135
  new Error("The Hangfire worker is expired or invalid"),
117
- g.HangfireWorkerExpiredOrInvalid
136
+ h.HangfireWorkerExpiredOrInvalid
118
137
  )
119
138
  );
120
- e.reject(b), (h = e.onFinished) == null || h.call(e, r);
139
+ e.reject(m), (d = e.onFinished) == null || d.call(e, t);
121
140
  } else
122
- e.reject(n), (u = e.onFinished) == null || u.call(e, r);
141
+ e.reject(n), (g = e.onFinished) == null || g.call(e, t);
123
142
  this.deleteWorker(e.groupId, e.workerId);
124
143
  break;
125
- } else if (this.config.debug("*executeWorkerRequest* not an api error"), (c = this.config.logger) == null || c.warn(
144
+ } else if (this.config.debug("*executeWorkerRequest* not an api error"), (x = this.config.logger) == null || x.warn(
126
145
  `Hangfire worker request error: ${JSON.stringify({
127
- attempt: i,
146
+ attempt: r,
128
147
  groupId: e.groupId,
129
148
  workerId: e.workerId,
130
- error: f(n)
149
+ error: b(n)
131
150
  })}`,
132
151
  {
133
- CorrelationId: d["x-correlation-id"]
152
+ CorrelationId: f["x-correlation-id"]
134
153
  }
135
- ), r && i < p)
136
- i += 1, this.config.debug(
137
- `*executeWorkerRequest* retrying non-API error (attempt ${i})`
138
- ), await m(500);
154
+ ), t && r < p)
155
+ r += 1, this.config.debug(
156
+ `*executeWorkerRequest* retrying non-API error (attempt ${r})`
157
+ ), await W(500);
139
158
  else {
140
159
  this.busyWorkers.delete(e.workerId);
141
160
  break;
142
161
  }
143
162
  }
144
163
  }
145
- deleteWorker(e, r) {
146
- const t = this.groups.get(e);
147
- t && (this.config.debug("*delete worker*", t.size, t), t.delete(r), this.workerByIdMap.delete(r), this.busyWorkers.delete(r), t.size < 1 && (this.groups.delete(e), this.enabledGroups.delete(e), this.enabledGroups.size < 1 && this.stopTimer()));
164
+ deleteWorker(e, t) {
165
+ const i = this.groups.get(e);
166
+ i && (this.config.debug("*delete worker*", i.size, i), i.delete(t), this.workerByIdMap.delete(t), this.busyWorkers.delete(t), i.size < 1 && (this.groups.delete(e), this.enabledGroups.delete(e), this.enabledGroups.size < 1 && this.stopTimer()));
148
167
  }
149
168
  createWorker(e, {
150
- workerId: r,
151
- url: t,
152
- headers: d,
153
- onFinished: p
169
+ workerId: t,
170
+ url: i,
171
+ headers: l,
172
+ onFinished: f,
173
+ maxLifeTimeMillis: p
154
174
  }) {
155
175
  if (!this.groups.has(e)) {
156
176
  if (this.groups.size >= this.config.maxGroupsSize) {
157
- const a = l(
177
+ const a = u(
158
178
  new Error("Max number of Hangfire groups exceeded"),
159
- g.GenericUnexpectedHangfireError,
179
+ h.GenericUnexpectedHangfireError,
160
180
  { count: this.groups.size }
161
181
  );
162
182
  throw this.destroy(), a;
163
183
  }
164
184
  this.groups.set(e, /* @__PURE__ */ new Map());
165
185
  }
166
- const i = this.groups.get(e);
167
- return new Promise((a, h) => {
168
- if (i.has(r))
169
- throw l(
186
+ const r = this.groups.get(e);
187
+ return new Promise((a, c) => {
188
+ if (r.has(t))
189
+ throw u(
170
190
  new Error("Duplicate Hangfire worker ID"),
171
- g.GenericUnexpectedHangfireError
191
+ h.GenericUnexpectedHangfireError
172
192
  );
173
- if (i.size >= this.config.maxWorkersSize) {
174
- const c = l(
193
+ if (r.size >= this.config.maxWorkersSize) {
194
+ const g = u(
175
195
  new Error("Max number of Hangfire workers in group exceeded"),
176
- g.GenericUnexpectedHangfireError,
177
- { groupId: e, count: i.size }
196
+ h.GenericUnexpectedHangfireError,
197
+ { groupId: e, count: r.size }
178
198
  );
179
- throw h(c), this.destroy(), c;
199
+ throw c(g), this.destroy(), g;
180
200
  }
181
- const u = {
182
- workerId: r,
201
+ const d = {
202
+ workerId: t,
183
203
  groupId: e,
184
- url: t,
204
+ url: i,
185
205
  resolve: a,
186
- reject: h,
187
- headers: d,
188
- onFinished: p
206
+ reject: c,
207
+ headers: l,
208
+ onFinished: f,
209
+ createdAt: Date.now(),
210
+ maxLifeTimeMillis: p
189
211
  };
190
- i.set(r, u), this.workerByIdMap.set(r, u), this.enabledGroups.has(e) || this.enabledGroups.add(e), this.timer == null && this.enabledGroups.size > 0 && this.startTimer();
212
+ r.set(t, d), this.workerByIdMap.set(t, d), this.enabledGroups.has(e) || this.enabledGroups.add(e), this.timer == null && this.enabledGroups.size > 0 && this.startTimer();
191
213
  });
192
214
  }
193
215
  /** Trigger a worker to execute immediately, ignoring busy state */
194
216
  triggerWorker(e) {
195
217
  this.config.debug("*triggerWorker*");
196
- const r = this.workerByIdMap.get(e);
197
- r ? this.executeWorkerRequest(r, !0) : this.config.debug("*triggerWorker* worker not found", e);
218
+ const t = this.workerByIdMap.get(e);
219
+ t ? this.executeWorkerRequest(t, !0) : this.config.debug("*triggerWorker* worker not found", e);
198
220
  }
199
221
  /** Trigger all workers to execute immediately */
200
222
  triggerAllWorkers() {
@@ -207,16 +229,18 @@ class E {
207
229
  this.config.debug("*enable*", e), this.enabledGroups.add(e), this.groups.has(e) && this.timer == null && this.startTimer();
208
230
  }
209
231
  disableWorkers(e) {
210
- this.config.debug("*disable*", e), this.enabledGroups.delete(e), this.enabledGroups.size < 1 && this.stopTimer();
232
+ this.config.debug("*disable*", e), this.enabledGroups.delete(e);
233
+ const t = this.groups.size > 0 && [...this.workerByIdMap.values()].some((i) => i.maxLifeTimeMillis != null);
234
+ this.enabledGroups.size < 1 && !t && this.stopTimer();
211
235
  }
212
236
  destroy() {
213
237
  this.config.debug("*destroy*"), this.groups.clear(), this.stopTimer();
214
238
  }
215
239
  }
216
240
  function B(s) {
217
- return new E(s);
241
+ return new z(s);
218
242
  }
219
243
  export {
220
- E as HangfirePoller,
244
+ z as HangfirePoller,
221
245
  B as default
222
246
  };
@@ -14,6 +14,8 @@ declare type MakeHangfireRequestOptions = {
14
14
  * @param forced Forced indicates it was triggered by an event rather than via polling
15
15
  */
16
16
  onWorkerFinished?: (forced: boolean) => void | Promise<void>;
17
+ /** Max lifetime of the worker in milliseconds. When exceeded the worker executes one final request and exits. */
18
+ maxLifeTimeMillis?: number;
17
19
  };
18
20
  /**
19
21
  *
@@ -1 +1 @@
1
- "use strict";const k=require("./isHangfireResponse.js");require("../api/isAcceptedResponse.js");const l=/v\d+\.\d+/;function q(a,d,u){const f=a.config.baseURL;let r=a.config.url;return r&&u&&(r=r.replace(l,`v${u}`)),`${f??""}/${r??""}/status/${d}`}function n(a){return async function(u,f,r,h,e){var R;const c=await u(f,r,e==null?void 0:e.headers);if(await((R=e==null?void 0:e.onInitResponse)==null?void 0:R.call(e)),k(c)){const g=c.data.id;return a.createWorker(h,{workerId:g,url:q(c,g,e==null?void 0:e.version),headers:e==null?void 0:e.headers,onFinished:e==null?void 0:e.onWorkerFinished})}return c}}module.exports=n;
1
+ "use strict";const h=require("./isHangfireResponse.js");require("../api/isAcceptedResponse.js");const k=/v\d+\.\d+/;function m(a,d,u){const f=a.config.baseURL;let r=a.config.url;return r&&u&&(r=r.replace(k,`v${u}`)),`${f??""}/${r??""}/status/${d}`}function q(a){return async function(u,f,r,g,e){var l;const c=await u(f,r,e==null?void 0:e.headers);if(await((l=e==null?void 0:e.onInitResponse)==null?void 0:l.call(e)),h(c)){const R=c.data.id;return a.createWorker(g,{workerId:R,url:m(c,R,e==null?void 0:e.version),headers:e==null?void 0:e.headers,onFinished:e==null?void 0:e.onWorkerFinished,maxLifeTimeMillis:e==null?void 0:e.maxLifeTimeMillis})}return c}}module.exports=q;
@@ -1,27 +1,28 @@
1
- import l from "./isHangfireResponse.mjs";
1
+ import g from "./isHangfireResponse.mjs";
2
2
  import "../api/isAcceptedResponse.mjs";
3
- const h = /v\d+\.\d+/;
4
- function m(a, d, u) {
5
- const f = a.config.baseURL;
3
+ const k = /v\d+\.\d+/;
4
+ function h(a, d, f) {
5
+ const c = a.config.baseURL;
6
6
  let r = a.config.url;
7
- return r && u && (r = r.replace(h, `v${u}`)), `${f ?? ""}/${r ?? ""}/status/${d}`;
7
+ return r && f && (r = r.replace(k, `v${f}`)), `${c ?? ""}/${r ?? ""}/status/${d}`;
8
8
  }
9
- function q(a) {
10
- return async function(u, f, r, k, e) {
11
- var R;
12
- const c = await u(f, r, e == null ? void 0 : e.headers);
13
- if (await ((R = e == null ? void 0 : e.onInitResponse) == null ? void 0 : R.call(e)), l(c)) {
14
- const g = c.data.id;
15
- return a.createWorker(k, {
16
- workerId: g,
17
- url: m(c, g, e == null ? void 0 : e.version),
9
+ function U(a) {
10
+ return async function(f, c, r, R, e) {
11
+ var l;
12
+ const u = await f(c, r, e == null ? void 0 : e.headers);
13
+ if (await ((l = e == null ? void 0 : e.onInitResponse) == null ? void 0 : l.call(e)), g(u)) {
14
+ const m = u.data.id;
15
+ return a.createWorker(R, {
16
+ workerId: m,
17
+ url: h(u, m, e == null ? void 0 : e.version),
18
18
  headers: e == null ? void 0 : e.headers,
19
- onFinished: e == null ? void 0 : e.onWorkerFinished
19
+ onFinished: e == null ? void 0 : e.onWorkerFinished,
20
+ maxLifeTimeMillis: e == null ? void 0 : e.maxLifeTimeMillis
20
21
  });
21
22
  }
22
- return c;
23
+ return u;
23
24
  };
24
25
  }
25
26
  export {
26
- q as default
27
+ U as default
27
28
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ancon/wildcat-utils",
3
- "version": "1.50.25",
3
+ "version": "1.50.27",
4
4
  "private": false,
5
5
  "main": "index.js",
6
6
  "module": "index.mjs",
@@ -1,4 +1,6 @@
1
- import { CheckoutOrderType } from '@ancon/wildcat-types';
2
- export default function isGroupPreOrder<T extends {
3
- orderType?: CheckoutOrderType;
4
- }>(preOrder: T): boolean;
1
+ import { OrderType } from '@ancon/wildcat-types';
2
+ declare type Order = {
3
+ orderType?: OrderType;
4
+ };
5
+ export default function isGroupPreOrder<T extends Order>(preOrder: T): boolean;
6
+ export {};
@@ -1 +1 @@
1
- "use strict";const e=require("@ancon/wildcat-types");function o(t){return(t==null?void 0:t.orderType)===e.CheckoutOrderType.GroupPreOrder}module.exports=o;
1
+ "use strict";const e=require("@ancon/wildcat-types");function o(t){return(t==null?void 0:t.orderType)===e.OrderType.GroupPreOrder}module.exports=o;
@@ -1,7 +1,7 @@
1
- import { CheckoutOrderType as t } from "@ancon/wildcat-types";
2
- function r(o) {
3
- return (o == null ? void 0 : o.orderType) === t.GroupPreOrder;
1
+ import { OrderType as r } from "@ancon/wildcat-types";
2
+ function u(o) {
3
+ return (o == null ? void 0 : o.orderType) === r.GroupPreOrder;
4
4
  }
5
5
  export {
6
- r as default
6
+ u as default
7
7
  };
@@ -1,4 +1,6 @@
1
- import { CheckoutOrderType } from '@ancon/wildcat-types';
2
- export default function isPreOrderLink<T extends {
3
- orderType?: CheckoutOrderType;
4
- }>(preOrder: T): boolean;
1
+ import { OrderType } from '@ancon/wildcat-types';
2
+ declare type Order = {
3
+ orderType?: OrderType;
4
+ };
5
+ export default function isPreOrderLink<T extends Order>(preOrder: T): boolean;
6
+ export {};
@@ -1 +1 @@
1
- "use strict";const e=require("@ancon/wildcat-types");function i(t){return(t==null?void 0:t.orderType)===e.CheckoutOrderType.PreOrderLink}module.exports=i;
1
+ "use strict";const t=require("@ancon/wildcat-types");function e(i){return(i==null?void 0:i.orderType)===t.OrderType.PreOrderLink}module.exports=e;
@@ -1,7 +1,7 @@
1
- import { CheckoutOrderType as t } from "@ancon/wildcat-types";
2
- function n(o) {
3
- return (o == null ? void 0 : o.orderType) === t.PreOrderLink;
1
+ import { OrderType as n } from "@ancon/wildcat-types";
2
+ function t(i) {
3
+ return (i == null ? void 0 : i.orderType) === n.PreOrderLink;
4
4
  }
5
5
  export {
6
- n as default
6
+ t as default
7
7
  };
@@ -1,4 +1,6 @@
1
- import { CheckoutOrderType } from '@ancon/wildcat-types';
2
- export default function isPreOrderSharable<T extends {
3
- orderType?: CheckoutOrderType;
4
- }>(preOrder: T): boolean;
1
+ import { OrderType } from '@ancon/wildcat-types';
2
+ declare type Order = {
3
+ orderType?: OrderType;
4
+ };
5
+ export default function isPreOrderSharable<T extends Order>(preOrder: T): boolean;
6
+ export {};
@@ -1 +1 @@
1
- "use strict";const t=require("@ancon/wildcat-types");function o(e){const r=e==null?void 0:e.orderType;return r===t.CheckoutOrderType.PreOrderLink||r===t.CheckoutOrderType.GroupPreOrder}module.exports=o;
1
+ "use strict";const t=require("@ancon/wildcat-types");function o(e){const r=e==null?void 0:e.orderType;return r===t.OrderType.PreOrderLink||r===t.OrderType.GroupPreOrder}module.exports=o;
@@ -1,4 +1,4 @@
1
- import { CheckoutOrderType as o } from "@ancon/wildcat-types";
1
+ import { OrderType as o } from "@ancon/wildcat-types";
2
2
  function n(r) {
3
3
  const e = r == null ? void 0 : r.orderType;
4
4
  return e === o.PreOrderLink || e === o.GroupPreOrder;