skedyul 1.3.0 → 1.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli/index.js CHANGED
@@ -3147,6 +3147,7 @@ function createCallToolHandler(registry, state, onMaxRequests) {
3147
3147
  };
3148
3148
  }
3149
3149
  const errorMessage = error instanceof Error ? error.message : String(error ?? "");
3150
+ const errorCode = error && typeof error === "object" && "code" in error && typeof error.code === "string" ? error.code : "TOOL_EXECUTION_ERROR";
3150
3151
  return {
3151
3152
  output: null,
3152
3153
  billing: { credits: 0 },
@@ -3156,7 +3157,7 @@ function createCallToolHandler(registry, state, onMaxRequests) {
3156
3157
  toolName
3157
3158
  },
3158
3159
  error: {
3159
- code: "TOOL_EXECUTION_ERROR",
3160
+ code: errorCode,
3160
3161
  message: errorMessage
3161
3162
  }
3162
3163
  };
@@ -570,6 +570,7 @@ function createCallToolHandler(registry, state, onMaxRequests) {
570
570
  };
571
571
  }
572
572
  const errorMessage = error instanceof Error ? error.message : String(error ?? "");
573
+ const errorCode = error && typeof error === "object" && "code" in error && typeof error.code === "string" ? error.code : "TOOL_EXECUTION_ERROR";
573
574
  return {
574
575
  output: null,
575
576
  billing: { credits: 0 },
@@ -579,7 +580,7 @@ function createCallToolHandler(registry, state, onMaxRequests) {
579
580
  toolName
580
581
  },
581
582
  error: {
582
- code: "TOOL_EXECUTION_ERROR",
583
+ code: errorCode,
583
584
  message: errorMessage
584
585
  }
585
586
  };
@@ -3586,6 +3586,7 @@ function createCallToolHandler(registry, state, onMaxRequests) {
3586
3586
  };
3587
3587
  }
3588
3588
  const errorMessage = error instanceof Error ? error.message : String(error ?? "");
3589
+ const errorCode = error && typeof error === "object" && "code" in error && typeof error.code === "string" ? error.code : "TOOL_EXECUTION_ERROR";
3589
3590
  return {
3590
3591
  output: null,
3591
3592
  billing: { credits: 0 },
@@ -3595,7 +3596,7 @@ function createCallToolHandler(registry, state, onMaxRequests) {
3595
3596
  toolName
3596
3597
  },
3597
3598
  error: {
3598
- code: "TOOL_EXECUTION_ERROR",
3599
+ code: errorCode,
3599
3600
  message: errorMessage
3600
3601
  }
3601
3602
  };
@@ -5584,7 +5585,7 @@ async function callRateLimitApi(path6, body) {
5584
5585
  const token2 = getApiToken();
5585
5586
  if (!baseUrl || !token2) {
5586
5587
  throw new RateLimitBackendError(
5587
- "SKEDYUL_API_URL and SKEDYUL_API_TOKEN are required for platform rate limiting"
5588
+ "SKEDYUL_API_URL and SKEDYUL_API_TOKEN are required for platform queue coordination"
5588
5589
  );
5589
5590
  }
5590
5591
  const response = await fetch(`${baseUrl}/api/internal/ratelimit/${path6}`, {
@@ -5597,11 +5598,11 @@ async function callRateLimitApi(path6, body) {
5597
5598
  });
5598
5599
  const payload = await response.json().catch(() => null);
5599
5600
  if (!response.ok || payload?.success === false) {
5600
- const message = payload?.errors?.[0]?.message ?? `Rate limit API ${path6} failed with status ${response.status}`;
5601
+ const message = payload?.errors?.[0]?.message ?? `Queue coordination API ${path6} failed with status ${response.status}`;
5601
5602
  throw new RateLimitBackendError(message, response.status);
5602
5603
  }
5603
5604
  if (!payload?.data) {
5604
- throw new RateLimitBackendError(`Rate limit API ${path6} returned empty data`);
5605
+ throw new RateLimitBackendError(`Queue coordination API ${path6} returned empty data`);
5605
5606
  }
5606
5607
  return payload.data;
5607
5608
  }
@@ -5740,7 +5741,7 @@ var MemoryRateLimitBackend = class {
5740
5741
  state.waiters.splice(idx, 1);
5741
5742
  }
5742
5743
  reject(
5743
- new Error(`Rate limit acquire timed out after ${timeoutMs}ms for ${queueKey}`)
5744
+ new Error(`Queue slot acquire timed out after ${timeoutMs}ms for ${queueKey}`)
5744
5745
  );
5745
5746
  }, timeoutMs);
5746
5747
  }
@@ -7147,6 +7148,9 @@ function isTimeInWindowSlot(date, window) {
7147
7148
  const tzInfo = getTimezoneInfo(date, tz);
7148
7149
  return allowedDays.includes(tzInfo.day) && tzInfo.totalMinutes >= windowStartMinutes && tzInfo.totalMinutes < windowEndMinutes;
7149
7150
  }
7151
+ function getLocalDateKey(date, timezone) {
7152
+ return date.toLocaleDateString("en-CA", { timeZone: timezone });
7153
+ }
7150
7154
  function calculateWaitTime(step, now) {
7151
7155
  const nowTime = now.getTime();
7152
7156
  switch (step.mode) {
@@ -7215,7 +7219,7 @@ function calculateWaitTime(step, now) {
7215
7219
  }
7216
7220
  }
7217
7221
  let earliestScheduledTime = null;
7218
- let earliestWaitTime = Infinity;
7222
+ let earliestWaitFromNow = Infinity;
7219
7223
  for (const window of step.windows) {
7220
7224
  if (!window || window.startTime === void 0 || window.endTime === void 0) {
7221
7225
  continue;
@@ -7233,12 +7237,10 @@ function calculateWaitTime(step, now) {
7233
7237
  const currentHour = targetTzInfo.hour;
7234
7238
  const currentMinute = targetTzInfo.minute;
7235
7239
  const currentTotalMinutes = targetTzInfo.totalMinutes;
7236
- let windowWaitTime;
7237
- let windowScheduledTime;
7240
+ let msUntilWindowStart;
7238
7241
  if (allowedDays.includes(currentDay) && currentTotalMinutes < windowStartMinutes) {
7239
7242
  const minutesUntilWindow = windowStartMinutes - currentTotalMinutes;
7240
- windowWaitTime = minutesUntilWindow * 60 * 1e3;
7241
- windowScheduledTime = new Date(targetDate.getTime() + windowWaitTime);
7243
+ msUntilWindowStart = minutesUntilWindow * 60 * 1e3;
7242
7244
  } else {
7243
7245
  let daysToAdd = 7;
7244
7246
  for (let i = 1; i <= 7; i++) {
@@ -7254,17 +7256,20 @@ function calculateWaitTime(step, now) {
7254
7256
  const daysMs = daysToAdd * millisecondsPerDay;
7255
7257
  const hoursAdjustment = (windowStartHour - currentHour) * millisecondsPerHour;
7256
7258
  const minutesAdjustment = (windowStartMinute - currentMinute) * millisecondsPerMinute;
7257
- windowWaitTime = daysMs + hoursAdjustment + minutesAdjustment;
7258
- windowScheduledTime = new Date(targetDate.getTime() + windowWaitTime);
7259
+ msUntilWindowStart = daysMs + hoursAdjustment + minutesAdjustment;
7259
7260
  }
7260
- if (windowWaitTime < earliestWaitTime) {
7261
- earliestWaitTime = windowWaitTime;
7261
+ const windowStartTimeMs = targetDate.getTime() + msUntilWindowStart;
7262
+ const sameLocalDayAsNow = getLocalDateKey(now, tz) === getLocalDateKey(targetDate, tz);
7263
+ const windowScheduledTime = sameLocalDayAsNow ? new Date(windowStartTimeMs + relativeDelay) : new Date(windowStartTimeMs);
7264
+ const waitFromNow = windowScheduledTime.getTime() - nowTime;
7265
+ if (waitFromNow < earliestWaitFromNow) {
7266
+ earliestWaitFromNow = waitFromNow;
7262
7267
  earliestScheduledTime = windowScheduledTime;
7263
7268
  }
7264
7269
  }
7265
7270
  if (earliestScheduledTime) {
7266
7271
  return {
7267
- waitTime: relativeDelay + earliestWaitTime,
7272
+ waitTime: Math.max(0, earliestScheduledTime.getTime() - nowTime),
7268
7273
  scheduledAt: earliestScheduledTime
7269
7274
  };
7270
7275
  }
package/dist/index.js CHANGED
@@ -3911,6 +3911,7 @@ function createCallToolHandler(registry, state, onMaxRequests) {
3911
3911
  };
3912
3912
  }
3913
3913
  const errorMessage = error instanceof Error ? error.message : String(error ?? "");
3914
+ const errorCode = error && typeof error === "object" && "code" in error && typeof error.code === "string" ? error.code : "TOOL_EXECUTION_ERROR";
3914
3915
  return {
3915
3916
  output: null,
3916
3917
  billing: { credits: 0 },
@@ -3920,7 +3921,7 @@ function createCallToolHandler(registry, state, onMaxRequests) {
3920
3921
  toolName
3921
3922
  },
3922
3923
  error: {
3923
- code: "TOOL_EXECUTION_ERROR",
3924
+ code: errorCode,
3924
3925
  message: errorMessage
3925
3926
  }
3926
3927
  };
@@ -5909,7 +5910,7 @@ async function callRateLimitApi(path6, body) {
5909
5910
  const token2 = getApiToken();
5910
5911
  if (!baseUrl || !token2) {
5911
5912
  throw new RateLimitBackendError(
5912
- "SKEDYUL_API_URL and SKEDYUL_API_TOKEN are required for platform rate limiting"
5913
+ "SKEDYUL_API_URL and SKEDYUL_API_TOKEN are required for platform queue coordination"
5913
5914
  );
5914
5915
  }
5915
5916
  const response = await fetch(`${baseUrl}/api/internal/ratelimit/${path6}`, {
@@ -5922,11 +5923,11 @@ async function callRateLimitApi(path6, body) {
5922
5923
  });
5923
5924
  const payload = await response.json().catch(() => null);
5924
5925
  if (!response.ok || payload?.success === false) {
5925
- const message = payload?.errors?.[0]?.message ?? `Rate limit API ${path6} failed with status ${response.status}`;
5926
+ const message = payload?.errors?.[0]?.message ?? `Queue coordination API ${path6} failed with status ${response.status}`;
5926
5927
  throw new RateLimitBackendError(message, response.status);
5927
5928
  }
5928
5929
  if (!payload?.data) {
5929
- throw new RateLimitBackendError(`Rate limit API ${path6} returned empty data`);
5930
+ throw new RateLimitBackendError(`Queue coordination API ${path6} returned empty data`);
5930
5931
  }
5931
5932
  return payload.data;
5932
5933
  }
@@ -6065,7 +6066,7 @@ var MemoryRateLimitBackend = class {
6065
6066
  state.waiters.splice(idx, 1);
6066
6067
  }
6067
6068
  reject(
6068
- new Error(`Rate limit acquire timed out after ${timeoutMs}ms for ${queueKey}`)
6069
+ new Error(`Queue slot acquire timed out after ${timeoutMs}ms for ${queueKey}`)
6069
6070
  );
6070
6071
  }, timeoutMs);
6071
6072
  }
@@ -7472,6 +7473,9 @@ function isTimeInWindowSlot(date, window) {
7472
7473
  const tzInfo = getTimezoneInfo(date, tz);
7473
7474
  return allowedDays.includes(tzInfo.day) && tzInfo.totalMinutes >= windowStartMinutes && tzInfo.totalMinutes < windowEndMinutes;
7474
7475
  }
7476
+ function getLocalDateKey(date, timezone) {
7477
+ return date.toLocaleDateString("en-CA", { timeZone: timezone });
7478
+ }
7475
7479
  function calculateWaitTime(step, now) {
7476
7480
  const nowTime = now.getTime();
7477
7481
  switch (step.mode) {
@@ -7540,7 +7544,7 @@ function calculateWaitTime(step, now) {
7540
7544
  }
7541
7545
  }
7542
7546
  let earliestScheduledTime = null;
7543
- let earliestWaitTime = Infinity;
7547
+ let earliestWaitFromNow = Infinity;
7544
7548
  for (const window of step.windows) {
7545
7549
  if (!window || window.startTime === void 0 || window.endTime === void 0) {
7546
7550
  continue;
@@ -7558,12 +7562,10 @@ function calculateWaitTime(step, now) {
7558
7562
  const currentHour = targetTzInfo.hour;
7559
7563
  const currentMinute = targetTzInfo.minute;
7560
7564
  const currentTotalMinutes = targetTzInfo.totalMinutes;
7561
- let windowWaitTime;
7562
- let windowScheduledTime;
7565
+ let msUntilWindowStart;
7563
7566
  if (allowedDays.includes(currentDay) && currentTotalMinutes < windowStartMinutes) {
7564
7567
  const minutesUntilWindow = windowStartMinutes - currentTotalMinutes;
7565
- windowWaitTime = minutesUntilWindow * 60 * 1e3;
7566
- windowScheduledTime = new Date(targetDate.getTime() + windowWaitTime);
7568
+ msUntilWindowStart = minutesUntilWindow * 60 * 1e3;
7567
7569
  } else {
7568
7570
  let daysToAdd = 7;
7569
7571
  for (let i = 1; i <= 7; i++) {
@@ -7579,17 +7581,20 @@ function calculateWaitTime(step, now) {
7579
7581
  const daysMs = daysToAdd * millisecondsPerDay;
7580
7582
  const hoursAdjustment = (windowStartHour - currentHour) * millisecondsPerHour;
7581
7583
  const minutesAdjustment = (windowStartMinute - currentMinute) * millisecondsPerMinute;
7582
- windowWaitTime = daysMs + hoursAdjustment + minutesAdjustment;
7583
- windowScheduledTime = new Date(targetDate.getTime() + windowWaitTime);
7584
+ msUntilWindowStart = daysMs + hoursAdjustment + minutesAdjustment;
7584
7585
  }
7585
- if (windowWaitTime < earliestWaitTime) {
7586
- earliestWaitTime = windowWaitTime;
7586
+ const windowStartTimeMs = targetDate.getTime() + msUntilWindowStart;
7587
+ const sameLocalDayAsNow = getLocalDateKey(now, tz) === getLocalDateKey(targetDate, tz);
7588
+ const windowScheduledTime = sameLocalDayAsNow ? new Date(windowStartTimeMs + relativeDelay) : new Date(windowStartTimeMs);
7589
+ const waitFromNow = windowScheduledTime.getTime() - nowTime;
7590
+ if (waitFromNow < earliestWaitFromNow) {
7591
+ earliestWaitFromNow = waitFromNow;
7587
7592
  earliestScheduledTime = windowScheduledTime;
7588
7593
  }
7589
7594
  }
7590
7595
  if (earliestScheduledTime) {
7591
7596
  return {
7592
- waitTime: relativeDelay + earliestWaitTime,
7597
+ waitTime: Math.max(0, earliestScheduledTime.getTime() - nowTime),
7593
7598
  scheduledAt: earliestScheduledTime
7594
7599
  };
7595
7600
  }
@@ -114,6 +114,9 @@ function isTimeInWindowSlot(date, window) {
114
114
  const tzInfo = getTimezoneInfo(date, tz);
115
115
  return allowedDays.includes(tzInfo.day) && tzInfo.totalMinutes >= windowStartMinutes && tzInfo.totalMinutes < windowEndMinutes;
116
116
  }
117
+ function getLocalDateKey(date, timezone) {
118
+ return date.toLocaleDateString("en-CA", { timeZone: timezone });
119
+ }
117
120
  function calculateWaitTime(step, now) {
118
121
  const nowTime = now.getTime();
119
122
  switch (step.mode) {
@@ -182,7 +185,7 @@ function calculateWaitTime(step, now) {
182
185
  }
183
186
  }
184
187
  let earliestScheduledTime = null;
185
- let earliestWaitTime = Infinity;
188
+ let earliestWaitFromNow = Infinity;
186
189
  for (const window of step.windows) {
187
190
  if (!window || window.startTime === void 0 || window.endTime === void 0) {
188
191
  continue;
@@ -200,12 +203,10 @@ function calculateWaitTime(step, now) {
200
203
  const currentHour = targetTzInfo.hour;
201
204
  const currentMinute = targetTzInfo.minute;
202
205
  const currentTotalMinutes = targetTzInfo.totalMinutes;
203
- let windowWaitTime;
204
- let windowScheduledTime;
206
+ let msUntilWindowStart;
205
207
  if (allowedDays.includes(currentDay) && currentTotalMinutes < windowStartMinutes) {
206
208
  const minutesUntilWindow = windowStartMinutes - currentTotalMinutes;
207
- windowWaitTime = minutesUntilWindow * 60 * 1e3;
208
- windowScheduledTime = new Date(targetDate.getTime() + windowWaitTime);
209
+ msUntilWindowStart = minutesUntilWindow * 60 * 1e3;
209
210
  } else {
210
211
  let daysToAdd = 7;
211
212
  for (let i = 1; i <= 7; i++) {
@@ -221,17 +222,20 @@ function calculateWaitTime(step, now) {
221
222
  const daysMs = daysToAdd * millisecondsPerDay;
222
223
  const hoursAdjustment = (windowStartHour - currentHour) * millisecondsPerHour;
223
224
  const minutesAdjustment = (windowStartMinute - currentMinute) * millisecondsPerMinute;
224
- windowWaitTime = daysMs + hoursAdjustment + minutesAdjustment;
225
- windowScheduledTime = new Date(targetDate.getTime() + windowWaitTime);
225
+ msUntilWindowStart = daysMs + hoursAdjustment + minutesAdjustment;
226
226
  }
227
- if (windowWaitTime < earliestWaitTime) {
228
- earliestWaitTime = windowWaitTime;
227
+ const windowStartTimeMs = targetDate.getTime() + msUntilWindowStart;
228
+ const sameLocalDayAsNow = getLocalDateKey(now, tz) === getLocalDateKey(targetDate, tz);
229
+ const windowScheduledTime = sameLocalDayAsNow ? new Date(windowStartTimeMs + relativeDelay) : new Date(windowStartTimeMs);
230
+ const waitFromNow = windowScheduledTime.getTime() - nowTime;
231
+ if (waitFromNow < earliestWaitFromNow) {
232
+ earliestWaitFromNow = waitFromNow;
229
233
  earliestScheduledTime = windowScheduledTime;
230
234
  }
231
235
  }
232
236
  if (earliestScheduledTime) {
233
237
  return {
234
- waitTime: relativeDelay + earliestWaitTime,
238
+ waitTime: Math.max(0, earliestScheduledTime.getTime() - nowTime),
235
239
  scheduledAt: earliestScheduledTime
236
240
  };
237
241
  }
@@ -86,6 +86,9 @@ function isTimeInWindowSlot(date, window) {
86
86
  const tzInfo = getTimezoneInfo(date, tz);
87
87
  return allowedDays.includes(tzInfo.day) && tzInfo.totalMinutes >= windowStartMinutes && tzInfo.totalMinutes < windowEndMinutes;
88
88
  }
89
+ function getLocalDateKey(date, timezone) {
90
+ return date.toLocaleDateString("en-CA", { timeZone: timezone });
91
+ }
89
92
  function calculateWaitTime(step, now) {
90
93
  const nowTime = now.getTime();
91
94
  switch (step.mode) {
@@ -154,7 +157,7 @@ function calculateWaitTime(step, now) {
154
157
  }
155
158
  }
156
159
  let earliestScheduledTime = null;
157
- let earliestWaitTime = Infinity;
160
+ let earliestWaitFromNow = Infinity;
158
161
  for (const window of step.windows) {
159
162
  if (!window || window.startTime === void 0 || window.endTime === void 0) {
160
163
  continue;
@@ -172,12 +175,10 @@ function calculateWaitTime(step, now) {
172
175
  const currentHour = targetTzInfo.hour;
173
176
  const currentMinute = targetTzInfo.minute;
174
177
  const currentTotalMinutes = targetTzInfo.totalMinutes;
175
- let windowWaitTime;
176
- let windowScheduledTime;
178
+ let msUntilWindowStart;
177
179
  if (allowedDays.includes(currentDay) && currentTotalMinutes < windowStartMinutes) {
178
180
  const minutesUntilWindow = windowStartMinutes - currentTotalMinutes;
179
- windowWaitTime = minutesUntilWindow * 60 * 1e3;
180
- windowScheduledTime = new Date(targetDate.getTime() + windowWaitTime);
181
+ msUntilWindowStart = minutesUntilWindow * 60 * 1e3;
181
182
  } else {
182
183
  let daysToAdd = 7;
183
184
  for (let i = 1; i <= 7; i++) {
@@ -193,17 +194,20 @@ function calculateWaitTime(step, now) {
193
194
  const daysMs = daysToAdd * millisecondsPerDay;
194
195
  const hoursAdjustment = (windowStartHour - currentHour) * millisecondsPerHour;
195
196
  const minutesAdjustment = (windowStartMinute - currentMinute) * millisecondsPerMinute;
196
- windowWaitTime = daysMs + hoursAdjustment + minutesAdjustment;
197
- windowScheduledTime = new Date(targetDate.getTime() + windowWaitTime);
197
+ msUntilWindowStart = daysMs + hoursAdjustment + minutesAdjustment;
198
198
  }
199
- if (windowWaitTime < earliestWaitTime) {
200
- earliestWaitTime = windowWaitTime;
199
+ const windowStartTimeMs = targetDate.getTime() + msUntilWindowStart;
200
+ const sameLocalDayAsNow = getLocalDateKey(now, tz) === getLocalDateKey(targetDate, tz);
201
+ const windowScheduledTime = sameLocalDayAsNow ? new Date(windowStartTimeMs + relativeDelay) : new Date(windowStartTimeMs);
202
+ const waitFromNow = windowScheduledTime.getTime() - nowTime;
203
+ if (waitFromNow < earliestWaitFromNow) {
204
+ earliestWaitFromNow = waitFromNow;
201
205
  earliestScheduledTime = windowScheduledTime;
202
206
  }
203
207
  }
204
208
  if (earliestScheduledTime) {
205
209
  return {
206
- waitTime: relativeDelay + earliestWaitTime,
210
+ waitTime: Math.max(0, earliestScheduledTime.getTime() - nowTime),
207
211
  scheduledAt: earliestScheduledTime
208
212
  };
209
213
  }
package/dist/server.js CHANGED
@@ -570,6 +570,7 @@ function createCallToolHandler(registry, state, onMaxRequests) {
570
570
  };
571
571
  }
572
572
  const errorMessage = error instanceof Error ? error.message : String(error ?? "");
573
+ const errorCode = error && typeof error === "object" && "code" in error && typeof error.code === "string" ? error.code : "TOOL_EXECUTION_ERROR";
573
574
  return {
574
575
  output: null,
575
576
  billing: { credits: 0 },
@@ -579,7 +580,7 @@ function createCallToolHandler(registry, state, onMaxRequests) {
579
580
  toolName
580
581
  },
581
582
  error: {
582
- code: "TOOL_EXECUTION_ERROR",
583
+ code: errorCode,
583
584
  message: errorMessage
584
585
  }
585
586
  };
@@ -531,6 +531,7 @@ function createCallToolHandler(registry, state, onMaxRequests) {
531
531
  };
532
532
  }
533
533
  const errorMessage = error instanceof Error ? error.message : String(error ?? "");
534
+ const errorCode = error && typeof error === "object" && "code" in error && typeof error.code === "string" ? error.code : "TOOL_EXECUTION_ERROR";
534
535
  return {
535
536
  output: null,
536
537
  billing: { credits: 0 },
@@ -540,7 +541,7 @@ function createCallToolHandler(registry, state, onMaxRequests) {
540
541
  toolName
541
542
  },
542
543
  error: {
543
- code: "TOOL_EXECUTION_ERROR",
544
+ code: errorCode,
544
545
  message: errorMessage
545
546
  }
546
547
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "skedyul",
3
- "version": "1.3.0",
3
+ "version": "1.3.1",
4
4
  "description": "The Skedyul SDK for Node.js",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",