@procedures/schedule 0.0.0-stage → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +48 -0
- package/LICENSE +21 -0
- package/README.md +98 -2
- package/dist/.tsbuildinfo +1 -0
- package/dist/cron.d.ts +47 -0
- package/dist/cron.d.ts.map +1 -0
- package/dist/cron.js +197 -0
- package/dist/cron.js.map +1 -0
- package/dist/errors.d.ts +22 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +13 -0
- package/dist/errors.js.map +1 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +11 -0
- package/dist/index.js.map +1 -0
- package/dist/module.d.ts +42 -0
- package/dist/module.d.ts.map +1 -0
- package/dist/module.js +174 -0
- package/dist/module.js.map +1 -0
- package/dist/procedures/schedule/add.d.ts +17 -0
- package/dist/procedures/schedule/add.d.ts.map +1 -0
- package/dist/procedures/schedule/add.js +66 -0
- package/dist/procedures/schedule/add.js.map +1 -0
- package/dist/procedures/schedule/index.d.ts +5 -0
- package/dist/procedures/schedule/index.d.ts.map +1 -0
- package/dist/procedures/schedule/index.js +5 -0
- package/dist/procedures/schedule/index.js.map +1 -0
- package/dist/procedures/schedule/list.d.ts +12 -0
- package/dist/procedures/schedule/list.d.ts.map +1 -0
- package/dist/procedures/schedule/list.js +18 -0
- package/dist/procedures/schedule/list.js.map +1 -0
- package/dist/procedures/schedule/next.d.ts +13 -0
- package/dist/procedures/schedule/next.d.ts.map +1 -0
- package/dist/procedures/schedule/next.js +24 -0
- package/dist/procedures/schedule/next.js.map +1 -0
- package/dist/procedures/schedule/remove.d.ts +12 -0
- package/dist/procedures/schedule/remove.d.ts.map +1 -0
- package/dist/procedures/schedule/remove.js +13 -0
- package/dist/procedures/schedule/remove.js.map +1 -0
- package/dist/programs.d.ts +26 -0
- package/dist/programs.d.ts.map +1 -0
- package/dist/programs.js +34 -0
- package/dist/programs.js.map +1 -0
- package/dist/register.d.ts +6 -0
- package/dist/register.d.ts.map +1 -0
- package/dist/register.js +8 -0
- package/dist/register.js.map +1 -0
- package/dist/scheduler.d.ts +106 -0
- package/dist/scheduler.d.ts.map +1 -0
- package/dist/scheduler.js +274 -0
- package/dist/scheduler.js.map +1 -0
- package/dist/store.d.ts +62 -0
- package/dist/store.d.ts.map +1 -0
- package/dist/store.js +188 -0
- package/dist/store.js.map +1 -0
- package/dist/types.d.ts +100 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +8 -0
- package/dist/types.js.map +1 -0
- package/package.json +78 -3
- package/src/cron.ts +230 -0
- package/src/errors.ts +27 -0
- package/src/index.ts +10 -0
- package/src/module.ts +227 -0
- package/src/procedures/schedule/add.ts +66 -0
- package/src/procedures/schedule/index.ts +4 -0
- package/src/procedures/schedule/list.ts +20 -0
- package/src/procedures/schedule/next.ts +25 -0
- package/src/procedures/schedule/remove.ts +15 -0
- package/src/programs.ts +43 -0
- package/src/register.ts +10 -0
- package/src/scheduler.ts +331 -0
- package/src/store.ts +213 -0
- package/src/types.ts +122 -0
package/dist/cron.js
ADDED
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cron expressions (roadmap R46): the parse and the next times.
|
|
3
|
+
*
|
|
4
|
+
* This package parses cron itself. The format is small, and a dependency for it gives a time
|
|
5
|
+
* zone database or a second format that this package does not need.
|
|
6
|
+
*
|
|
7
|
+
* - 5 fields: minute (0-59), hour (0-23), day of the month (1-31), month (1-12), day of the week
|
|
8
|
+
* (0-7, with 0 and 7 for Sunday).
|
|
9
|
+
* - Each field: `*`, a number, a range `a-b`, a step `*` + `/n`, `a-b/n` or `a/n` (from `a` to the
|
|
10
|
+
* end), and lists of these with commas.
|
|
11
|
+
* - The names of the months (`jan` to `dec`) and of the days (`sun` to `sat`), in each case.
|
|
12
|
+
* - The names `@yearly` (`@annually`), `@monthly`, `@weekly`, `@daily` (`@midnight`) and `@hourly`.
|
|
13
|
+
* - The days, as in Vixie cron: when the two day fields have a limit (they do not start with
|
|
14
|
+
* `*`), a day matches when one of the two matches. Else the field with a limit decides.
|
|
15
|
+
*
|
|
16
|
+
* The times are in UTC or in the local time of the host. In local time, a time that the change
|
|
17
|
+
* to summer time skips does not run, and a time that the change back repeats can run two times.
|
|
18
|
+
*/
|
|
19
|
+
import { ScheduleError } from "./errors.js";
|
|
20
|
+
const MONTHS = ["jan", "feb", "mar", "apr", "may", "jun", "jul", "aug", "sep", "oct", "nov", "dec"];
|
|
21
|
+
const DAYS = ["sun", "mon", "tue", "wed", "thu", "fri", "sat"];
|
|
22
|
+
const FIELDS = [
|
|
23
|
+
{ name: "minute", min: 0, max: 59 },
|
|
24
|
+
{ name: "hour", min: 0, max: 23 },
|
|
25
|
+
{ name: "day of the month", min: 1, max: 31 },
|
|
26
|
+
{ name: "month", min: 1, max: 12, names: MONTHS, first: 1 },
|
|
27
|
+
{ name: "day of the week", min: 0, max: 7, names: DAYS, first: 0 },
|
|
28
|
+
];
|
|
29
|
+
/** The names of the expressions that are one name. */
|
|
30
|
+
export const CRON_NAMES = Object.freeze({
|
|
31
|
+
"@yearly": "0 0 1 1 *",
|
|
32
|
+
"@annually": "0 0 1 1 *",
|
|
33
|
+
"@monthly": "0 0 1 * *",
|
|
34
|
+
"@weekly": "0 0 * * 0",
|
|
35
|
+
"@daily": "0 0 * * *",
|
|
36
|
+
"@midnight": "0 0 * * *",
|
|
37
|
+
"@hourly": "0 * * * *",
|
|
38
|
+
});
|
|
39
|
+
function fail(source, message) {
|
|
40
|
+
throw new ScheduleError("BAD_CRON", `The cron expression ${JSON.stringify(source)} is not correct: ${message}`);
|
|
41
|
+
}
|
|
42
|
+
/** The value of one token of a field: a number or a name. */
|
|
43
|
+
function valueOf(token, spec, source) {
|
|
44
|
+
if (/^\d+$/.test(token)) {
|
|
45
|
+
const value = Number(token);
|
|
46
|
+
if (value < spec.min || value > spec.max)
|
|
47
|
+
fail(source, `${token} is out of the ${spec.name} range ${spec.min}-${spec.max}`);
|
|
48
|
+
return value;
|
|
49
|
+
}
|
|
50
|
+
const index = spec.names?.indexOf(token.toLowerCase()) ?? -1;
|
|
51
|
+
if (index < 0)
|
|
52
|
+
fail(source, `${JSON.stringify(token)} is not a ${spec.name}`);
|
|
53
|
+
return index + (spec.first ?? 0);
|
|
54
|
+
}
|
|
55
|
+
/** The values of one field. */
|
|
56
|
+
function parseField(text, spec, source) {
|
|
57
|
+
const values = new Set();
|
|
58
|
+
for (const part of text.split(",")) {
|
|
59
|
+
if (part === "")
|
|
60
|
+
fail(source, `the ${spec.name} field has an empty part`);
|
|
61
|
+
const pieces = part.split("/");
|
|
62
|
+
if (pieces.length > 2)
|
|
63
|
+
fail(source, `${JSON.stringify(part)} has more than one step`);
|
|
64
|
+
const [range, stepText] = pieces;
|
|
65
|
+
let step = 1;
|
|
66
|
+
if (stepText !== undefined) {
|
|
67
|
+
if (!/^\d+$/.test(stepText) || Number(stepText) < 1)
|
|
68
|
+
fail(source, `the step ${JSON.stringify(stepText)} must be a whole number of 1 or more`);
|
|
69
|
+
step = Number(stepText);
|
|
70
|
+
}
|
|
71
|
+
let low;
|
|
72
|
+
let high;
|
|
73
|
+
if (range === "*") {
|
|
74
|
+
low = spec.min;
|
|
75
|
+
// The day of the week: * is 0-6, not 0-7
|
|
76
|
+
high = spec.names === DAYS ? 6 : spec.max;
|
|
77
|
+
}
|
|
78
|
+
else if (range.includes("-")) {
|
|
79
|
+
const bounds = range.split("-");
|
|
80
|
+
if (bounds.length !== 2)
|
|
81
|
+
fail(source, `${JSON.stringify(range)} is not a range`);
|
|
82
|
+
low = valueOf(bounds[0], spec, source);
|
|
83
|
+
high = valueOf(bounds[1], spec, source);
|
|
84
|
+
if (low > high)
|
|
85
|
+
fail(source, `the range ${range} goes down`);
|
|
86
|
+
}
|
|
87
|
+
else {
|
|
88
|
+
low = valueOf(range, spec, source);
|
|
89
|
+
high = stepText === undefined ? low : spec.max;
|
|
90
|
+
}
|
|
91
|
+
for (let value = low; value <= high; value += step)
|
|
92
|
+
values.add(spec.names === DAYS && value === 7 ? 0 : value);
|
|
93
|
+
}
|
|
94
|
+
return values;
|
|
95
|
+
}
|
|
96
|
+
/** This function parses a cron expression. It throws a `BAD_CRON` error that tells the problem. */
|
|
97
|
+
export function parseCron(text) {
|
|
98
|
+
const source = text.trim();
|
|
99
|
+
const expanded = source.startsWith("@") ? CRON_NAMES[source.toLowerCase()] : source;
|
|
100
|
+
if (expanded === undefined)
|
|
101
|
+
fail(source, `${source} is not a known name (${Object.keys(CRON_NAMES).join(", ")})`);
|
|
102
|
+
const fields = expanded.split(/\s+/).filter((field) => field !== "");
|
|
103
|
+
if (fields.length !== 5)
|
|
104
|
+
fail(source, `it has ${fields.length} fields, and a cron expression has 5: minute, hour, day of the month, month, day of the week`);
|
|
105
|
+
const [minutes, hours, days, months, weekdays] = fields.map((field, index) => parseField(field, FIELDS[index], source));
|
|
106
|
+
return {
|
|
107
|
+
source,
|
|
108
|
+
minutes,
|
|
109
|
+
hours,
|
|
110
|
+
days,
|
|
111
|
+
months,
|
|
112
|
+
weekdays,
|
|
113
|
+
dayLimited: !fields[2].startsWith("*"),
|
|
114
|
+
weekdayLimited: !fields[4].startsWith("*"),
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
const UTC = {
|
|
118
|
+
fields(time) {
|
|
119
|
+
const date = new Date(time);
|
|
120
|
+
return { year: date.getUTCFullYear(), month: date.getUTCMonth() + 1, day: date.getUTCDate(), hour: date.getUTCHours(), minute: date.getUTCMinutes(), weekday: date.getUTCDay() };
|
|
121
|
+
},
|
|
122
|
+
make: (year, month, day, hour, minute) => Date.UTC(year, month - 1, day, hour, minute),
|
|
123
|
+
};
|
|
124
|
+
const LOCAL = {
|
|
125
|
+
fields(time) {
|
|
126
|
+
const date = new Date(time);
|
|
127
|
+
return { year: date.getFullYear(), month: date.getMonth() + 1, day: date.getDate(), hour: date.getHours(), minute: date.getMinutes(), weekday: date.getDay() };
|
|
128
|
+
},
|
|
129
|
+
make: (year, month, day, hour, minute) => new Date(year, month - 1, day, hour, minute).getTime(),
|
|
130
|
+
};
|
|
131
|
+
/** The years that a search covers: Feb 29 can be 8 years away (2096 to 2104). */
|
|
132
|
+
const SEARCH_YEARS = 9;
|
|
133
|
+
/** True when the day of the fields matches the two day fields. */
|
|
134
|
+
function dayMatches(cron, fields) {
|
|
135
|
+
const day = cron.days.has(fields.day);
|
|
136
|
+
const weekday = cron.weekdays.has(fields.weekday);
|
|
137
|
+
if (cron.dayLimited && cron.weekdayLimited)
|
|
138
|
+
return day || weekday;
|
|
139
|
+
if (cron.dayLimited)
|
|
140
|
+
return day;
|
|
141
|
+
if (cron.weekdayLimited)
|
|
142
|
+
return weekday;
|
|
143
|
+
return true;
|
|
144
|
+
}
|
|
145
|
+
/**
|
|
146
|
+
* This function gives the first time of the expression after `after` (milliseconds since 1970),
|
|
147
|
+
* or undefined when the expression has no time in the next 9 years.
|
|
148
|
+
*/
|
|
149
|
+
export function nextTime(cron, after, timeZone = "local") {
|
|
150
|
+
const calendar = timeZone === "utc" ? UTC : LOCAL;
|
|
151
|
+
let time = Math.floor(after / 60_000) * 60_000 + 60_000;
|
|
152
|
+
const lastYear = calendar.fields(after).year + SEARCH_YEARS;
|
|
153
|
+
for (let step = 0; step < 1_000_000; step++) {
|
|
154
|
+
const fields = calendar.fields(time);
|
|
155
|
+
if (fields.year > lastYear)
|
|
156
|
+
return undefined;
|
|
157
|
+
let next;
|
|
158
|
+
if (!cron.months.has(fields.month))
|
|
159
|
+
next = calendar.make(fields.year, fields.month + 1, 1, 0, 0);
|
|
160
|
+
else if (!dayMatches(cron, fields))
|
|
161
|
+
next = calendar.make(fields.year, fields.month, fields.day + 1, 0, 0);
|
|
162
|
+
else if (!cron.hours.has(fields.hour))
|
|
163
|
+
next = calendar.make(fields.year, fields.month, fields.day, fields.hour + 1, 0);
|
|
164
|
+
else if (!cron.minutes.has(fields.minute))
|
|
165
|
+
next = time + 60_000;
|
|
166
|
+
else
|
|
167
|
+
return time;
|
|
168
|
+
// A change of the clock can give a time that is not later: go one minute on
|
|
169
|
+
time = next > time ? next : time + 60_000;
|
|
170
|
+
}
|
|
171
|
+
return undefined;
|
|
172
|
+
}
|
|
173
|
+
/** This function gives the next `count` times of the expression after `after`. */
|
|
174
|
+
export function nextTimes(cron, after, count, timeZone = "local") {
|
|
175
|
+
const times = [];
|
|
176
|
+
let from = after;
|
|
177
|
+
while (times.length < count) {
|
|
178
|
+
const time = nextTime(cron, from, timeZone);
|
|
179
|
+
if (time === undefined)
|
|
180
|
+
break;
|
|
181
|
+
times.push(time);
|
|
182
|
+
from = time;
|
|
183
|
+
}
|
|
184
|
+
return times;
|
|
185
|
+
}
|
|
186
|
+
const pad = (value, length = 2) => String(value).padStart(length, "0");
|
|
187
|
+
/** The ISO text of a time in a time zone: `2026-10-17T09:00:00Z`, or with the offset of the host: `2026-10-17T09:00:00+02:00`. */
|
|
188
|
+
export function formatTime(time, timeZone = "local") {
|
|
189
|
+
const date = new Date(time);
|
|
190
|
+
if (timeZone === "utc")
|
|
191
|
+
return `${date.toISOString().slice(0, 19)}Z`;
|
|
192
|
+
const offset = -date.getTimezoneOffset();
|
|
193
|
+
const sign = offset >= 0 ? "+" : "-";
|
|
194
|
+
const zone = offset === 0 ? "Z" : `${sign}${pad(Math.floor(Math.abs(offset) / 60))}:${pad(Math.abs(offset) % 60)}`;
|
|
195
|
+
return `${pad(date.getFullYear(), 4)}-${pad(date.getMonth() + 1)}-${pad(date.getDate())}T${pad(date.getHours())}:${pad(date.getMinutes())}:${pad(date.getSeconds())}${zone}`;
|
|
196
|
+
}
|
|
197
|
+
//# sourceMappingURL=cron.js.map
|
package/dist/cron.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cron.js","sourceRoot":"","sources":["../src/cron.ts"],"names":[],"mappings":"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"}
|
package/dist/errors.d.ts
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The errors of the schedule procedures and of the scheduler.
|
|
3
|
+
*/
|
|
4
|
+
/** The reason of a `ScheduleError`. */
|
|
5
|
+
export type ScheduleErrorCode =
|
|
6
|
+
/** The cron expression is not correct, or it has no time in the next 9 years. */
|
|
7
|
+
"BAD_CRON"
|
|
8
|
+
/** A schedule of the name exists, and the input does not replace it. */
|
|
9
|
+
| "EXISTS"
|
|
10
|
+
/** No stored program has the key: not in the registry, not in the program store. */
|
|
11
|
+
| "NOT_FOUND"
|
|
12
|
+
/** The key names a procedure of code, not a stored program. */
|
|
13
|
+
| "NOT_A_PROGRAM"
|
|
14
|
+
/** The file of a `FileScheduleStore` is not correct. */
|
|
15
|
+
| "BAD_STORE";
|
|
16
|
+
/** An error of the schedules. */
|
|
17
|
+
export declare class ScheduleError extends Error {
|
|
18
|
+
readonly name = "ScheduleError";
|
|
19
|
+
readonly code: ScheduleErrorCode;
|
|
20
|
+
constructor(code: ScheduleErrorCode, message: string);
|
|
21
|
+
}
|
|
22
|
+
//# sourceMappingURL=errors.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,uCAAuC;AACvC,MAAM,MAAM,iBAAiB;AAC3B,iFAAiF;AAC/E,UAAU;AACZ,wEAAwE;GACtE,QAAQ;AACV,oFAAoF;GAClF,WAAW;AACb,+DAA+D;GAC7D,eAAe;AACjB,wDAAwD;GACtD,WAAW,CAAC;AAEhB,iCAAiC;AACjC,qBAAa,aAAc,SAAQ,KAAK;IACtC,SAAkB,IAAI,mBAAmB;IACzC,QAAQ,CAAC,IAAI,EAAE,iBAAiB,CAAC;IAEjC,YAAY,IAAI,EAAE,iBAAiB,EAAE,OAAO,EAAE,MAAM,EAGnD;CACF"}
|
package/dist/errors.js
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The errors of the schedule procedures and of the scheduler.
|
|
3
|
+
*/
|
|
4
|
+
/** An error of the schedules. */
|
|
5
|
+
export class ScheduleError extends Error {
|
|
6
|
+
name = "ScheduleError";
|
|
7
|
+
code;
|
|
8
|
+
constructor(code, message) {
|
|
9
|
+
super(message);
|
|
10
|
+
this.code = code;
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
//# sourceMappingURL=errors.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA;;GAEG;AAeH,iCAAiC;AACjC,MAAM,OAAO,aAAc,SAAQ,KAAK;IACpB,IAAI,GAAG,eAAe,CAAC;IAChC,IAAI,CAAoB;IAEjC,YAAY,IAAuB,EAAE,OAAe;QAClD,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;IACnB,CAAC;CACF"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export * from "./module.js";
|
|
2
|
+
export * from "./types.js";
|
|
3
|
+
export { scheduleAdd, scheduleList, scheduleRemove, scheduleNext, viewOf } from "./procedures/schedule/index.js";
|
|
4
|
+
export { CRON_NAMES, formatTime, nextTime, nextTimes, parseCron, type CronExpression } from "./cron.js";
|
|
5
|
+
export { ScheduleError, type ScheduleErrorCode } from "./errors.js";
|
|
6
|
+
export { checkSchedule, defaultScheduleStore, FileScheduleStore, MemoryScheduleStore, type ScheduleStore } from "./store.js";
|
|
7
|
+
export { DEFAULT_SCHEDULE_SETTINGS, findProgram, PROGRAM_KEY, type ScheduleSettings } from "./programs.js";
|
|
8
|
+
export { DEFAULT_RUN_TIMEOUT_MS, Scheduler, type ScheduleRunEvent, type SchedulerOptions } from "./scheduler.js";
|
|
9
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,cAAc,aAAa,CAAC;AAC5B,cAAc,YAAY,CAAC;AAC3B,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,EAAE,MAAM,gCAAgC,CAAC;AAEjH,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,QAAQ,EAAE,SAAS,EAAE,SAAS,EAAE,KAAK,cAAc,EAAE,MAAM,WAAW,CAAC;AACxG,OAAO,EAAE,aAAa,EAAE,KAAK,iBAAiB,EAAE,MAAM,aAAa,CAAC;AACpE,OAAO,EAAE,aAAa,EAAE,oBAAoB,EAAE,iBAAiB,EAAE,mBAAmB,EAAE,KAAK,aAAa,EAAE,MAAM,YAAY,CAAC;AAC7H,OAAO,EAAE,yBAAyB,EAAE,WAAW,EAAE,WAAW,EAAE,KAAK,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAC3G,OAAO,EAAE,sBAAsB,EAAE,SAAS,EAAE,KAAK,gBAAgB,EAAE,KAAK,gBAAgB,EAAE,MAAM,gBAAgB,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
// The root registers nothing: import "<package>/register", or give the module to createRegistry()
|
|
2
|
+
export * from "./module.js";
|
|
3
|
+
export * from "./types.js";
|
|
4
|
+
export { scheduleAdd, scheduleList, scheduleRemove, scheduleNext, viewOf } from "./procedures/schedule/index.js";
|
|
5
|
+
// The cron expressions, the stores and the scheduler (roadmap R46)
|
|
6
|
+
export { CRON_NAMES, formatTime, nextTime, nextTimes, parseCron } from "./cron.js";
|
|
7
|
+
export { ScheduleError } from "./errors.js";
|
|
8
|
+
export { checkSchedule, defaultScheduleStore, FileScheduleStore, MemoryScheduleStore } from "./store.js";
|
|
9
|
+
export { DEFAULT_SCHEDULE_SETTINGS, findProgram, PROGRAM_KEY } from "./programs.js";
|
|
10
|
+
export { DEFAULT_RUN_TIMEOUT_MS, Scheduler } from "./scheduler.js";
|
|
11
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,kGAAkG;AAClG,cAAc,aAAa,CAAC;AAC5B,cAAc,YAAY,CAAC;AAC3B,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,EAAE,MAAM,gCAAgC,CAAC;AACjH,mEAAmE;AACnE,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,QAAQ,EAAE,SAAS,EAAE,SAAS,EAAuB,MAAM,WAAW,CAAC;AACxG,OAAO,EAAE,aAAa,EAA0B,MAAM,aAAa,CAAC;AACpE,OAAO,EAAE,aAAa,EAAE,oBAAoB,EAAE,iBAAiB,EAAE,mBAAmB,EAAsB,MAAM,YAAY,CAAC;AAC7H,OAAO,EAAE,yBAAyB,EAAE,WAAW,EAAE,WAAW,EAAyB,MAAM,eAAe,CAAC;AAC3G,OAAO,EAAE,sBAAsB,EAAE,SAAS,EAAgD,MAAM,gBAAgB,CAAC"}
|
package/dist/module.d.ts
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The procedures of @procedures/schedule as data. Importing this file registers nothing.
|
|
3
|
+
*
|
|
4
|
+
* Scaffold a procedure with: mark procedure new <name> --path packages/schedule
|
|
5
|
+
*
|
|
6
|
+
* `scheduleModule` keeps the schedules in `defaultScheduleStore` (memory). `createScheduleModule()`
|
|
7
|
+
* gives the same procedures with the store of the host, for example a `FileScheduleStore`. The
|
|
8
|
+
* host gives the same store to its `Scheduler` (roadmap R46).
|
|
9
|
+
*/
|
|
10
|
+
import { type ProcedureModule, type ProcedureRegistry } from "@procedures/client";
|
|
11
|
+
import type { ScheduleStore } from "./store.js";
|
|
12
|
+
/**
|
|
13
|
+
* The module of this package, for `createRegistry()`: its procedures as data, on
|
|
14
|
+
* `defaultScheduleStore`. Importing this file registers nothing.
|
|
15
|
+
*/
|
|
16
|
+
export declare const scheduleModule: ProcedureModule;
|
|
17
|
+
export default scheduleModule;
|
|
18
|
+
/** The options of `createScheduleModule()`. */
|
|
19
|
+
export interface ScheduleModuleOptions {
|
|
20
|
+
/** The store of the schedules. The default is `defaultScheduleStore` (memory). */
|
|
21
|
+
readonly store?: ScheduleStore | undefined;
|
|
22
|
+
/** The wall time, in milliseconds since 1970. The default is `Date.now`. A test gives the time of its fake clock. */
|
|
23
|
+
readonly now?: (() => number) | undefined;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* This function gives the module of this package with the store of the host. Without options, it
|
|
27
|
+
* gives `scheduleModule`. A host gives it to `createRegistry()` before its bundles, so it
|
|
28
|
+
* replaces the `scheduleModule` that a bundle requires (the first module of a name counts).
|
|
29
|
+
*
|
|
30
|
+
* ```ts
|
|
31
|
+
* const store = new FileScheduleStore("schedules.json");
|
|
32
|
+
* const registry = createRegistry(createScheduleModule({ store }), storeModule);
|
|
33
|
+
* await new Scheduler({ registry, store, policy }).start();
|
|
34
|
+
* ```
|
|
35
|
+
*/
|
|
36
|
+
export declare function createScheduleModule(options?: ScheduleModuleOptions): ProcedureModule;
|
|
37
|
+
/**
|
|
38
|
+
* This function registers the procedures of @procedures/schedule in a registry. The default is the
|
|
39
|
+
* global registry. The options are the options of `createScheduleModule()`.
|
|
40
|
+
*/
|
|
41
|
+
export declare function registerScheduleProcedures(registry?: ProcedureRegistry, options?: ScheduleModuleOptions): void;
|
|
42
|
+
//# sourceMappingURL=module.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"module.d.ts","sourceRoot":"","sources":["../src/module.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAGH,OAAO,EASL,KAAK,eAAe,EACpB,KAAK,iBAAiB,EACvB,MAAM,oBAAoB,CAAC;AAM5B,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AA4JhD;;;GAGG;AACH,eAAO,MAAM,cAAc,EAAE,eAAqG,CAAC;eAEpH,cAAc;AAE7B,+CAA+C;AAC/C,MAAM,WAAW,qBAAqB;IACpC,kFAAkF;IAClF,QAAQ,CAAC,KAAK,CAAC,EAAE,aAAa,GAAG,SAAS,CAAC;IAC3C,qHAAqH;IACrH,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC,MAAM,MAAM,CAAC,GAAG,SAAS,CAAC;CAC3C;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,GAAE,qBAA0B,GAAG,eAAe,CAOzF;AAED;;;GAGG;AACH,wBAAgB,0BAA0B,CAAC,QAAQ,GAAE,iBAAsC,EAAE,OAAO,GAAE,qBAA0B,GAAG,IAAI,CAEtI"}
|
package/dist/module.js
ADDED
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The procedures of @procedures/schedule as data. Importing this file registers nothing.
|
|
3
|
+
*
|
|
4
|
+
* Scaffold a procedure with: mark procedure new <name> --path packages/schedule
|
|
5
|
+
*
|
|
6
|
+
* `scheduleModule` keeps the schedules in `defaultScheduleStore` (memory). `createScheduleModule()`
|
|
7
|
+
* gives the same procedures with the store of the host, for example a `FileScheduleStore`. The
|
|
8
|
+
* host gives the same store to its `Scheduler` (roadmap R46).
|
|
9
|
+
*/
|
|
10
|
+
import { z } from "zod";
|
|
11
|
+
import { defineModule, registerModules, PROCEDURE_REGISTRY, createProcedure, zodAdapter, } from "@procedures/client";
|
|
12
|
+
import { scheduleAdd } from "./procedures/schedule/add.js";
|
|
13
|
+
import { scheduleList } from "./procedures/schedule/list.js";
|
|
14
|
+
import { scheduleRemove } from "./procedures/schedule/remove.js";
|
|
15
|
+
import { scheduleNext } from "./procedures/schedule/next.js";
|
|
16
|
+
import { DEFAULT_SCHEDULE_SETTINGS, PROGRAM_KEY } from "./programs.js";
|
|
17
|
+
// =============================================================================
|
|
18
|
+
// Schemas
|
|
19
|
+
// =============================================================================
|
|
20
|
+
const cron = z.string().min(1).max(200).describe("The cron expression: 5 fields (minute hour day month weekday), or @hourly, @daily, @weekly, @monthly, @yearly");
|
|
21
|
+
const timeZone = z.enum(["utc", "local"]).describe("The time zone of the expression (default local)");
|
|
22
|
+
const scheduleId = z
|
|
23
|
+
.string()
|
|
24
|
+
.regex(/^[A-Za-z0-9._:-]{1,200}$/, "Letters, digits, and . _ : -")
|
|
25
|
+
.describe("The name of the schedule");
|
|
26
|
+
const programKey = z.string().max(500).regex(PROGRAM_KEY, "A dotted key: reports.weekly").describe("The dotted key of the stored program");
|
|
27
|
+
const run = z.object({
|
|
28
|
+
startedAt: z.number().describe("The start, in milliseconds since 1970"),
|
|
29
|
+
durationMs: z.number(),
|
|
30
|
+
outcome: z.enum(["success", "failure"]),
|
|
31
|
+
error: z.object({ code: z.string().optional(), message: z.string() }).optional(),
|
|
32
|
+
});
|
|
33
|
+
const view = z.object({
|
|
34
|
+
id: z.string(),
|
|
35
|
+
cron: z.string(),
|
|
36
|
+
program: z.string(),
|
|
37
|
+
input: z.unknown().optional(),
|
|
38
|
+
timeZone: z.enum(["utc", "local"]),
|
|
39
|
+
createdAt: z.number().describe("When the schedule was added, in milliseconds since 1970"),
|
|
40
|
+
capability: z
|
|
41
|
+
.custom((value) => value !== null && typeof value === "object")
|
|
42
|
+
.optional()
|
|
43
|
+
.describe("The capability of the caller that added it: its clearance and its permitted effects"),
|
|
44
|
+
lastRun: run.optional().describe("The last run"),
|
|
45
|
+
runs: z.number().int(),
|
|
46
|
+
failures: z.number().int(),
|
|
47
|
+
skipped: z.number().int().describe("The times that came during a run: no second run started"),
|
|
48
|
+
nextRunAt: z.string().nullable().describe("The next time as an ISO text, or null"),
|
|
49
|
+
});
|
|
50
|
+
const ScheduleAddInputSchema = z.object({
|
|
51
|
+
id: scheduleId.optional().describe("The name of the schedule (default: the key of the program)"),
|
|
52
|
+
cron,
|
|
53
|
+
program: programKey,
|
|
54
|
+
input: z.unknown().optional().describe("The input of the program"),
|
|
55
|
+
timeZone: timeZone.optional(),
|
|
56
|
+
replace: z.boolean().optional().describe("True: replace a schedule of the same name (default false)"),
|
|
57
|
+
});
|
|
58
|
+
const ScheduleAddOutputSchema = z.object({ schedule: view });
|
|
59
|
+
const ScheduleListInputSchema = z.object({ program: programKey.optional().describe("Only the schedules of this program") });
|
|
60
|
+
const ScheduleListOutputSchema = z.object({ schedules: z.array(view).describe("The schedules, sorted by name") });
|
|
61
|
+
const ScheduleRemoveInputSchema = z.object({ id: scheduleId });
|
|
62
|
+
const ScheduleRemoveOutputSchema = z.object({ removed: z.boolean().describe("True when the schedule existed") });
|
|
63
|
+
const ScheduleNextInputSchema = z.object({
|
|
64
|
+
cron,
|
|
65
|
+
count: z.number().int().min(1).max(100).optional().describe("The number of times, 1 to 100 (default 5)"),
|
|
66
|
+
after: z.string().max(100).optional().describe("The times come after this ISO time (default now)"),
|
|
67
|
+
timeZone: timeZone.optional(),
|
|
68
|
+
});
|
|
69
|
+
const ScheduleNextOutputSchema = z.object({ times: z.array(z.string()).describe("The next times as ISO texts") });
|
|
70
|
+
// =============================================================================
|
|
71
|
+
// Procedures
|
|
72
|
+
// =============================================================================
|
|
73
|
+
/** `schedule.add`: it reads the registry and the program store, and writes the schedules (a store can be a file). */
|
|
74
|
+
const ADDS = Object.freeze({ reads: Object.freeze(["fs", "programs", "registry", "schedules"]), writes: Object.freeze(["fs", "schedules"]) });
|
|
75
|
+
/** `schedule.list`: it reads the schedules. */
|
|
76
|
+
const LISTS = Object.freeze({ reads: Object.freeze(["fs", "schedules"]), writes: Object.freeze([]) });
|
|
77
|
+
/** `schedule.remove`: it deletes a schedule. A second call changes nothing more. */
|
|
78
|
+
const REMOVES = Object.freeze({ reads: Object.freeze(["fs", "schedules"]), writes: Object.freeze(["fs", "schedules"]), destructive: true, idempotent: true });
|
|
79
|
+
/** `schedule.next`: its output comes from its input and the time. */
|
|
80
|
+
const PURE = Object.freeze({ reads: Object.freeze([]), writes: Object.freeze([]) });
|
|
81
|
+
/** The four procedures, with handlers that use the settings. */
|
|
82
|
+
function scheduleProcedures(settings) {
|
|
83
|
+
const scheduleAddProcedure = createProcedure()
|
|
84
|
+
.path(["schedule", "add"])
|
|
85
|
+
.input(zodAdapter(ScheduleAddInputSchema))
|
|
86
|
+
.output(zodAdapter(ScheduleAddOutputSchema))
|
|
87
|
+
.meta({
|
|
88
|
+
description: "Add a schedule: a cron expression that starts a stored program with an input",
|
|
89
|
+
tags: ["schedule", "cron", "programs"],
|
|
90
|
+
args: ["cron", "program"],
|
|
91
|
+
shorts: { timeZone: "z" },
|
|
92
|
+
output: "json",
|
|
93
|
+
effects: ADDS,
|
|
94
|
+
})
|
|
95
|
+
.handler(async (input, ctx) => scheduleAdd(input, ctx, settings))
|
|
96
|
+
.build();
|
|
97
|
+
const scheduleListProcedure = createProcedure()
|
|
98
|
+
.path(["schedule", "list"])
|
|
99
|
+
.input(zodAdapter(ScheduleListInputSchema))
|
|
100
|
+
.output(zodAdapter(ScheduleListOutputSchema))
|
|
101
|
+
.meta({
|
|
102
|
+
description: "The schedules, with the next time and the last run of each",
|
|
103
|
+
tags: ["schedule", "cron"],
|
|
104
|
+
args: [],
|
|
105
|
+
shorts: {},
|
|
106
|
+
output: "json",
|
|
107
|
+
effects: LISTS,
|
|
108
|
+
})
|
|
109
|
+
.handler(async (input) => scheduleList(input, settings))
|
|
110
|
+
.build();
|
|
111
|
+
const scheduleRemoveProcedure = createProcedure()
|
|
112
|
+
.path(["schedule", "remove"])
|
|
113
|
+
.input(zodAdapter(ScheduleRemoveInputSchema))
|
|
114
|
+
.output(zodAdapter(ScheduleRemoveOutputSchema))
|
|
115
|
+
.meta({
|
|
116
|
+
description: "Remove a schedule",
|
|
117
|
+
tags: ["schedule", "cron"],
|
|
118
|
+
args: ["id"],
|
|
119
|
+
shorts: {},
|
|
120
|
+
output: "json",
|
|
121
|
+
effects: REMOVES,
|
|
122
|
+
})
|
|
123
|
+
.handler(async (input) => scheduleRemove(input, settings))
|
|
124
|
+
.build();
|
|
125
|
+
const scheduleNextProcedure = createProcedure()
|
|
126
|
+
.path(["schedule", "next"])
|
|
127
|
+
.input(zodAdapter(ScheduleNextInputSchema))
|
|
128
|
+
.output(zodAdapter(ScheduleNextOutputSchema))
|
|
129
|
+
.meta({
|
|
130
|
+
description: "The next times of a cron expression",
|
|
131
|
+
tags: ["schedule", "cron"],
|
|
132
|
+
args: ["cron"],
|
|
133
|
+
shorts: { count: "n", timeZone: "z" },
|
|
134
|
+
output: "json",
|
|
135
|
+
effects: PURE,
|
|
136
|
+
})
|
|
137
|
+
.handler(async (input) => scheduleNext(input, settings))
|
|
138
|
+
.build();
|
|
139
|
+
return [scheduleAddProcedure, scheduleListProcedure, scheduleRemoveProcedure, scheduleNextProcedure];
|
|
140
|
+
}
|
|
141
|
+
/**
|
|
142
|
+
* The module of this package, for `createRegistry()`: its procedures as data, on
|
|
143
|
+
* `defaultScheduleStore`. Importing this file registers nothing.
|
|
144
|
+
*/
|
|
145
|
+
export const scheduleModule = defineModule("@procedures/schedule", scheduleProcedures(DEFAULT_SCHEDULE_SETTINGS));
|
|
146
|
+
export default scheduleModule;
|
|
147
|
+
/**
|
|
148
|
+
* This function gives the module of this package with the store of the host. Without options, it
|
|
149
|
+
* gives `scheduleModule`. A host gives it to `createRegistry()` before its bundles, so it
|
|
150
|
+
* replaces the `scheduleModule` that a bundle requires (the first module of a name counts).
|
|
151
|
+
*
|
|
152
|
+
* ```ts
|
|
153
|
+
* const store = new FileScheduleStore("schedules.json");
|
|
154
|
+
* const registry = createRegistry(createScheduleModule({ store }), storeModule);
|
|
155
|
+
* await new Scheduler({ registry, store, policy }).start();
|
|
156
|
+
* ```
|
|
157
|
+
*/
|
|
158
|
+
export function createScheduleModule(options = {}) {
|
|
159
|
+
if (Object.values(options).every((value) => value === undefined))
|
|
160
|
+
return scheduleModule;
|
|
161
|
+
const settings = {
|
|
162
|
+
store: options.store ?? DEFAULT_SCHEDULE_SETTINGS.store,
|
|
163
|
+
now: options.now ?? DEFAULT_SCHEDULE_SETTINGS.now,
|
|
164
|
+
};
|
|
165
|
+
return defineModule("@procedures/schedule", scheduleProcedures(settings));
|
|
166
|
+
}
|
|
167
|
+
/**
|
|
168
|
+
* This function registers the procedures of @procedures/schedule in a registry. The default is the
|
|
169
|
+
* global registry. The options are the options of `createScheduleModule()`.
|
|
170
|
+
*/
|
|
171
|
+
export function registerScheduleProcedures(registry = PROCEDURE_REGISTRY, options = {}) {
|
|
172
|
+
registerModules(registry, [createScheduleModule(options)]);
|
|
173
|
+
}
|
|
174
|
+
//# sourceMappingURL=module.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"module.js","sourceRoot":"","sources":["../src/module.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* schedule.add procedure
|
|
3
|
+
*
|
|
4
|
+
* Add a schedule: a cron expression that starts a stored program with an input. The procedure
|
|
5
|
+
* examines the expression and the program, and keeps the capability of the caller: a run gets
|
|
6
|
+
* the capability of the host, narrowed by it.
|
|
7
|
+
*/
|
|
8
|
+
import { type ProcedureContext } from "@procedures/client";
|
|
9
|
+
import { type ScheduleSettings } from "../../programs.js";
|
|
10
|
+
import type { Schedule, ScheduleAddInput, ScheduleAddOutput, ScheduleView } from "../../types.js";
|
|
11
|
+
/** The view of a schedule: with its next time after `now`. */
|
|
12
|
+
export declare function viewOf(schedule: Schedule, now: number): ScheduleView;
|
|
13
|
+
/**
|
|
14
|
+
* Add a schedule: a cron expression that starts a stored program with an input
|
|
15
|
+
*/
|
|
16
|
+
export declare function scheduleAdd(input: ScheduleAddInput, ctx?: Pick<ProcedureContext, "capability" | "registry">, settings?: ScheduleSettings): Promise<ScheduleAddOutput>;
|
|
17
|
+
//# sourceMappingURL=add.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"add.d.ts","sourceRoot":"","sources":["../../../src/procedures/schedule/add.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAsB,KAAK,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAG/E,OAAO,EAA0C,KAAK,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAClG,OAAO,KAAK,EAAE,QAAQ,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAElG,8DAA8D;AAC9D,wBAAgB,MAAM,CAAC,QAAQ,EAAE,QAAQ,EAAE,GAAG,EAAE,MAAM,GAAG,YAAY,CAQpE;AAYD;;GAEG;AACH,wBAAsB,WAAW,CAAC,KAAK,EAAE,gBAAgB,EAAE,GAAG,CAAC,EAAE,IAAI,CAAC,gBAAgB,EAAE,YAAY,GAAG,UAAU,CAAC,EAAE,QAAQ,GAAE,gBAA4C,GAAG,OAAO,CAAC,iBAAiB,CAAC,CA2BtM"}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* schedule.add procedure
|
|
3
|
+
*
|
|
4
|
+
* Add a schedule: a cron expression that starts a stored program with an input. The procedure
|
|
5
|
+
* examines the expression and the program, and keeps the capability of the caller: a run gets
|
|
6
|
+
* the capability of the host, narrowed by it.
|
|
7
|
+
*/
|
|
8
|
+
import { PROCEDURE_REGISTRY } from "@procedures/client";
|
|
9
|
+
import { formatTime, nextTime, parseCron } from "../../cron.js";
|
|
10
|
+
import { ScheduleError } from "../../errors.js";
|
|
11
|
+
import { DEFAULT_SCHEDULE_SETTINGS, findProgram } from "../../programs.js";
|
|
12
|
+
/** The view of a schedule: with its next time after `now`. */
|
|
13
|
+
export function viewOf(schedule, now) {
|
|
14
|
+
let next;
|
|
15
|
+
try {
|
|
16
|
+
next = nextTime(parseCron(schedule.cron), now, schedule.timeZone);
|
|
17
|
+
}
|
|
18
|
+
catch {
|
|
19
|
+
next = undefined;
|
|
20
|
+
}
|
|
21
|
+
return { ...schedule, nextRunAt: next === undefined ? null : formatTime(next, schedule.timeZone) };
|
|
22
|
+
}
|
|
23
|
+
/** The capability of the caller to keep: its clearance and its permitted effects, without its deadline. */
|
|
24
|
+
function callerCapability(ctx) {
|
|
25
|
+
const capability = ctx?.capability;
|
|
26
|
+
if (capability === undefined)
|
|
27
|
+
return undefined;
|
|
28
|
+
const kept = {};
|
|
29
|
+
if (capability.clearance !== undefined)
|
|
30
|
+
kept.clearance = capability.clearance;
|
|
31
|
+
if (capability.effects !== undefined)
|
|
32
|
+
kept.effects = capability.effects;
|
|
33
|
+
return Object.keys(kept).length > 0 ? kept : undefined;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Add a schedule: a cron expression that starts a stored program with an input
|
|
37
|
+
*/
|
|
38
|
+
export async function scheduleAdd(input, ctx, settings = DEFAULT_SCHEDULE_SETTINGS) {
|
|
39
|
+
const now = settings.now();
|
|
40
|
+
const timeZone = input.timeZone ?? "local";
|
|
41
|
+
const cron = parseCron(input.cron);
|
|
42
|
+
if (nextTime(cron, now, timeZone) === undefined) {
|
|
43
|
+
throw new ScheduleError("BAD_CRON", `The cron expression ${JSON.stringify(input.cron)} has no time in the next 9 years`);
|
|
44
|
+
}
|
|
45
|
+
await findProgram(ctx?.registry ?? PROCEDURE_REGISTRY, input.program);
|
|
46
|
+
const id = input.id ?? input.program;
|
|
47
|
+
const capability = callerCapability(ctx);
|
|
48
|
+
const schedule = {
|
|
49
|
+
id,
|
|
50
|
+
cron: cron.source,
|
|
51
|
+
program: input.program,
|
|
52
|
+
...(input.input !== undefined ? { input: input.input } : {}),
|
|
53
|
+
timeZone,
|
|
54
|
+
createdAt: now,
|
|
55
|
+
...(capability !== undefined ? { capability } : {}),
|
|
56
|
+
runs: 0,
|
|
57
|
+
failures: 0,
|
|
58
|
+
skipped: 0,
|
|
59
|
+
};
|
|
60
|
+
if (input.replace !== true && (await settings.store.get(id)) !== undefined) {
|
|
61
|
+
throw new ScheduleError("EXISTS", `A schedule named ${id} exists: give replace: true, or another id`);
|
|
62
|
+
}
|
|
63
|
+
await settings.store.put(schedule);
|
|
64
|
+
return { schedule: viewOf(schedule, now) };
|
|
65
|
+
}
|
|
66
|
+
//# sourceMappingURL=add.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"add.js","sourceRoot":"","sources":["../../../src/procedures/schedule/add.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/procedures/schedule/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAC/C,OAAO,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AACzC,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC"}
|