@stacksjs/cron 0.70.88 → 0.70.90
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/index.d.ts +41 -0
- package/dist/index.js +2 -0
- package/dist/parser.d.ts +15 -0
- package/dist/types.d.ts +5 -0
- package/package.json +1 -1
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/// <reference path="./bun-cron.d.ts" />
|
|
2
|
+
import { parseCron } from './parser';
|
|
3
|
+
// Parse a cron expression and return the next matching Date.
|
|
4
|
+
// Uses Bun's native cron parser when available, otherwise falls back
|
|
5
|
+
// to our own 5-field parser with identical behavior.
|
|
6
|
+
//
|
|
7
|
+
// Examples:
|
|
8
|
+
// parse('0 0 * * *') → next midnight UTC
|
|
9
|
+
// parse('@hourly') → next hour
|
|
10
|
+
// parse('0,15,30,45 * * * *') → next 15-min mark
|
|
11
|
+
export declare function parse(expression: string, relativeDate?: Date | number, options?: import('./parser').ParseCronOptions): Date | null;
|
|
12
|
+
/**
|
|
13
|
+
* Register an OS-level cron job that persists across process restarts.
|
|
14
|
+
*
|
|
15
|
+
* Requires Bun's native cron support (crontab on Linux, launchd on macOS,
|
|
16
|
+
* schtasks on Windows).
|
|
17
|
+
*
|
|
18
|
+
* The target script must export a `scheduled(controller)` handler:
|
|
19
|
+
* ```ts
|
|
20
|
+
* export default {
|
|
21
|
+
* async scheduled(controller) {
|
|
22
|
+
* // controller.cron, controller.scheduledTime
|
|
23
|
+
* await doWork()
|
|
24
|
+
* }
|
|
25
|
+
* }
|
|
26
|
+
* ```
|
|
27
|
+
*
|
|
28
|
+
* @param path - Path to the script to run
|
|
29
|
+
* @param schedule - Cron expression or nickname (@daily, @hourly, etc.)
|
|
30
|
+
* @param title - Unique job identifier (alphanumeric, hyphens, underscores)
|
|
31
|
+
*/
|
|
32
|
+
export declare function register(path: string, schedule: string, title: string): Promise<void>;
|
|
33
|
+
/**
|
|
34
|
+
* Remove a previously registered OS-level cron job.
|
|
35
|
+
*
|
|
36
|
+
* @param title - The title of the cron job to remove
|
|
37
|
+
*/
|
|
38
|
+
export declare function remove(title: string): Promise<void>;
|
|
39
|
+
/// <reference path="./bun-cron.d.ts" />
|
|
40
|
+
export * from './types';
|
|
41
|
+
export { parseCron } from './parser';
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
// @bun
|
|
2
|
+
var w={"@yearly":"0 0 1 1 *","@annually":"0 0 1 1 *","@monthly":"0 0 1 * *","@weekly":"0 0 * * 0","@daily":"0 0 * * *","@midnight":"0 0 * * *","@hourly":"0 * * * *"},g={jan:1,feb:2,mar:3,apr:4,may:5,jun:6,jul:7,aug:8,sep:9,oct:10,nov:11,dec:12,january:1,february:2,march:3,april:4,june:6,july:7,august:8,september:9,october:10,november:11,december:12},D={sun:0,mon:1,tue:2,wed:3,thu:4,fri:5,sat:6,sunday:0,monday:1,tuesday:2,wednesday:3,thursday:4,friday:5,saturday:6},S=new Set;function M(G,q){if(S.has(G))return;S.add(G),console.warn(`[cron] 6-field cron expression '${G}' has seconds='${q}' \u2014 the parser is 5-field only. `+"Seconds field IGNORED. For second-precision use the scheduler's '.everySecond()' instead.")}function y(G,q){return G.replace(/[a-z]+/gi,(Q)=>{let H=q[Q.toLowerCase()];if(H===void 0)throw Error(`Invalid cron value: ${Q}`);return String(H)})}function _(G,q,Q,H){let E=H?y(G,H):G,Z=new Set;for(let Y of E.split(",")){let R=Y.match(/^(.+)\/(\d+)$/),$,K=1;if(R){if($=R[1]??"",K=Number.parseInt(R[2]??"",10),K<=0)throw Error(`Invalid step: ${K}`)}else $=Y;if($==="*")for(let J=q;J<=Q;J+=K)Z.add(J);else if($.includes("-")){let[J,V]=$.split("-"),j=Number.parseInt(J??"",10),B=Number.parseInt(V??"",10);if(Number.isNaN(j)||Number.isNaN(B))throw Error(`Invalid range: ${$}`);if(j<q||B>Q)throw Error(`Range out of bounds: ${$} (${q}-${Q})`);for(let U=j;U<=B;U+=K)Z.add(U)}else{let J=Number.parseInt($,10);if(Number.isNaN(J))throw Error(`Invalid cron value: ${$}`);if(J<q||J>Q)throw Error(`Value out of range: ${J} (${q}-${Q})`);Z.add(J)}}return Z}function b(G,q,Q={}){let H=G.trim(),Z=(w[H.toLowerCase()]??H).split(/\s+/).filter(Boolean);if(Z.length===6){let X=Z[0];if(X!=="0"&&X!=="*")M(G,X);Z=Z.slice(1)}if(Z.length!==5)throw Error(`Invalid cron expression: expected 5 fields (or 6 with leading seconds), got ${Z.length}`);let[Y,R,$,K,J]=Z,V=_(Y,0,59),j=_(R,0,23),B=_($,1,31),U=_(K,1,12,g),I=_(J,0,7,D);if(I.has(7))I.add(0),I.delete(7);let k=$==="*",z=J==="*",P=q instanceof Date?q.getTime():typeof q==="number"?q:Date.now();if(Number.isNaN(P)||!Number.isFinite(P))throw Error("Invalid date");let A=Q.tz,T=A?F(A):(X)=>({year:X.getUTCFullYear(),month:X.getUTCMonth()+1,day:X.getUTCDate(),hour:X.getUTCHours(),minute:X.getUTCMinutes(),dow:X.getUTCDay()}),L=new Date(P);L.setUTCSeconds(0,0),L.setUTCMinutes(L.getUTCMinutes()+1);let W=L.getTime()+126230400000;while(L.getTime()<W){let X=T(L);if(!U.has(X.month)){L.setUTCMonth(L.getUTCMonth()+1,1),L.setUTCHours(0,0,0,0);continue}let N=B.has(X.day),O=I.has(X.dow),C;if(k&&z)C=!0;else if(k)C=O;else if(z)C=N;else C=N||O;if(!C){L.setUTCDate(L.getUTCDate()+1),L.setUTCHours(0,0,0,0);continue}if(!j.has(X.hour)){L.setUTCHours(L.getUTCHours()+1,0,0,0);continue}if(!V.has(X.minute)){L.setUTCMinutes(L.getUTCMinutes()+1,0,0);continue}return new Date(L.getTime())}return null}function F(G){let q=new Intl.DateTimeFormat("en-US",{timeZone:G,hourCycle:"h23",year:"numeric",month:"numeric",day:"numeric",hour:"numeric",minute:"numeric",weekday:"short"}),Q={Sun:0,Mon:1,Tue:2,Wed:3,Thu:4,Fri:5,Sat:6};return(H)=>{let E=q.formatToParts(H),Z=0,Y=0,R=0,$=0,K=0,J=0;for(let V of E)if(V.type==="year")Z=Number.parseInt(V.value,10);else if(V.type==="month")Y=Number.parseInt(V.value,10);else if(V.type==="day")R=Number.parseInt(V.value,10);else if(V.type==="hour")$=Number.parseInt(V.value,10)%24;else if(V.type==="minute")K=Number.parseInt(V.value,10);else if(V.type==="weekday")J=Q[V.value]??0;return{year:Z,month:Y,day:R,hour:$,minute:K,dow:J}}}function x(G,q,Q={}){if(typeof Bun<"u"&&Bun.cron?.parse)return Bun.cron.parse(G,q);return b(G,q,Q)}async function u(G,q,Q){if(typeof Bun>"u"||!Bun.cron)throw Error("Bun.cron is not available. OS-level cron requires a Bun version with native cron support.");await Bun.cron(G,q,Q)}async function c(G){if(typeof Bun>"u"||!Bun.cron?.remove)throw Error("Bun.cron is not available. OS-level cron requires a Bun version with native cron support.");await Bun.cron.remove(G)}export{c as remove,u as register,b as parseCron,x as parse};
|
package/dist/parser.d.ts
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Parse a cron expression and return the next matching Date.
|
|
3
|
+
*
|
|
4
|
+
* @param expression - A 5-field cron expression or nickname (@daily, etc.)
|
|
5
|
+
* @param relativeDate - Starting point for the search (defaults to Date.now())
|
|
6
|
+
* @param options - Optional `{ tz }` for timezone-local interpretation
|
|
7
|
+
* @returns The next Date matching the expression, or null if no match within ~4 years
|
|
8
|
+
*/
|
|
9
|
+
export declare function parseCron(expression: string, relativeDate?: Date | number, options?: ParseCronOptions): Date | null;
|
|
10
|
+
/**
|
|
11
|
+
* Options for `parseCron` (stacksjs/stacks#1877 Cr-5).
|
|
12
|
+
*/
|
|
13
|
+
export declare interface ParseCronOptions {
|
|
14
|
+
tz?: string
|
|
15
|
+
}
|
package/dist/types.d.ts
ADDED