@todu/engine 0.1.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/dist/change-observer.d.ts +15 -0
- package/dist/change-observer.d.ts.map +1 -0
- package/dist/change-observer.js +64 -0
- package/dist/change-observer.js.map +1 -0
- package/dist/habits.d.ts +6 -0
- package/dist/habits.d.ts.map +1 -0
- package/dist/habits.js +397 -0
- package/dist/habits.js.map +1 -0
- package/dist/index.d.ts +25 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +104 -0
- package/dist/index.js.map +1 -0
- package/dist/labels.d.ts +5 -0
- package/dist/labels.d.ts.map +1 -0
- package/dist/labels.js +113 -0
- package/dist/labels.js.map +1 -0
- package/dist/notes.d.ts +5 -0
- package/dist/notes.d.ts.map +1 -0
- package/dist/notes.js +163 -0
- package/dist/notes.js.map +1 -0
- package/dist/projects.d.ts +5 -0
- package/dist/projects.d.ts.map +1 -0
- package/dist/projects.js +117 -0
- package/dist/projects.js.map +1 -0
- package/dist/recurring.d.ts +23 -0
- package/dist/recurring.d.ts.map +1 -0
- package/dist/recurring.js +372 -0
- package/dist/recurring.js.map +1 -0
- package/dist/schedule.d.ts +38 -0
- package/dist/schedule.d.ts.map +1 -0
- package/dist/schedule.js +330 -0
- package/dist/schedule.js.map +1 -0
- package/dist/scheduling.d.ts +62 -0
- package/dist/scheduling.d.ts.map +1 -0
- package/dist/scheduling.js +58 -0
- package/dist/scheduling.js.map +1 -0
- package/dist/storage.d.ts +34 -0
- package/dist/storage.d.ts.map +1 -0
- package/dist/storage.js +204 -0
- package/dist/storage.js.map +1 -0
- package/dist/sync-client.d.ts +16 -0
- package/dist/sync-client.d.ts.map +1 -0
- package/dist/sync-client.js +54 -0
- package/dist/sync-client.js.map +1 -0
- package/dist/sync-server.d.ts +12 -0
- package/dist/sync-server.d.ts.map +1 -0
- package/dist/sync-server.js +21 -0
- package/dist/sync-server.js.map +1 -0
- package/dist/tasks.d.ts +18 -0
- package/dist/tasks.d.ts.map +1 -0
- package/dist/tasks.js +396 -0
- package/dist/tasks.js.map +1 -0
- package/dist/todu.d.ts +115 -0
- package/dist/todu.d.ts.map +1 -0
- package/dist/todu.js +76 -0
- package/dist/todu.js.map +1 -0
- package/package.json +52 -0
|
@@ -0,0 +1,372 @@
|
|
|
1
|
+
import crypto from "node:crypto";
|
|
2
|
+
import { createRecurringId, err, generateScheduledTaskId, notFound, ok, validateCreateRecurringInput, validateUpdateRecurringInput, validationError, } from "@todu/core";
|
|
3
|
+
import { describeSchedule, isScheduledDate, nextOccurrence, nextOccurrences, todayInTimezone, } from "./schedule.js";
|
|
4
|
+
import { registerProcessor } from "./scheduling.js";
|
|
5
|
+
import { createTaskNamespace } from "./tasks.js";
|
|
6
|
+
// ============================================================================
|
|
7
|
+
// Recurring template namespace — CRUD + task generation
|
|
8
|
+
// ============================================================================
|
|
9
|
+
export function createRecurringNamespace(catalog, repo) {
|
|
10
|
+
const taskNs = createTaskNamespace(catalog, repo);
|
|
11
|
+
return {
|
|
12
|
+
async create(input) {
|
|
13
|
+
const validationErr = validateCreateRecurringInput(input);
|
|
14
|
+
if (validationErr)
|
|
15
|
+
return err(validationErr);
|
|
16
|
+
// Verify project exists
|
|
17
|
+
const doc = catalog.doc();
|
|
18
|
+
if (doc) {
|
|
19
|
+
const project = doc.projects.find((p) => p.id === input.projectId);
|
|
20
|
+
if (!project)
|
|
21
|
+
return err(notFound("project", input.projectId));
|
|
22
|
+
}
|
|
23
|
+
const now = new Date().toISOString();
|
|
24
|
+
const id = createRecurringId(`rec-${crypto.randomUUID().slice(0, 8)}`);
|
|
25
|
+
// Calculate initial nextDue from RRULE + startDate
|
|
26
|
+
const today = todayInTimezone(input.timezone);
|
|
27
|
+
let initialNextDue;
|
|
28
|
+
if (input.startDate >= today) {
|
|
29
|
+
// Start date is in the future or today — check if startDate itself is an occurrence
|
|
30
|
+
initialNextDue = input.startDate;
|
|
31
|
+
}
|
|
32
|
+
else {
|
|
33
|
+
// Start date is in the past — find next occurrence after yesterday
|
|
34
|
+
// (so today is included if it's an occurrence)
|
|
35
|
+
const yesterday = shiftDate(today, -1);
|
|
36
|
+
const next = nextOccurrence(input.schedule, input.startDate, input.timezone, yesterday, input.endDate);
|
|
37
|
+
initialNextDue = next || input.startDate; // fallback shouldn't happen for valid schedules
|
|
38
|
+
}
|
|
39
|
+
const template = {
|
|
40
|
+
id,
|
|
41
|
+
title: input.title.trim(),
|
|
42
|
+
projectId: input.projectId,
|
|
43
|
+
labels: input.labels || [],
|
|
44
|
+
priority: input.priority || "medium",
|
|
45
|
+
schedule: input.schedule,
|
|
46
|
+
timezone: input.timezone,
|
|
47
|
+
startDate: input.startDate,
|
|
48
|
+
nextDue: initialNextDue,
|
|
49
|
+
skippedDates: [],
|
|
50
|
+
paused: false,
|
|
51
|
+
createdAt: now,
|
|
52
|
+
updatedAt: now,
|
|
53
|
+
};
|
|
54
|
+
if (input.description !== undefined) {
|
|
55
|
+
template.description = input.description;
|
|
56
|
+
}
|
|
57
|
+
if (input.endDate !== undefined) {
|
|
58
|
+
template.endDate = input.endDate;
|
|
59
|
+
}
|
|
60
|
+
catalog.change((doc) => {
|
|
61
|
+
doc.recurringTemplates.push(template);
|
|
62
|
+
});
|
|
63
|
+
return ok(template);
|
|
64
|
+
},
|
|
65
|
+
async list(filter) {
|
|
66
|
+
const doc = catalog.doc();
|
|
67
|
+
if (!doc)
|
|
68
|
+
return ok([]);
|
|
69
|
+
let templates = doc.recurringTemplates.map(cloneTemplate);
|
|
70
|
+
if (filter?.paused !== undefined) {
|
|
71
|
+
templates = templates.filter((t) => t.paused === filter.paused);
|
|
72
|
+
}
|
|
73
|
+
if (filter?.projectId !== undefined) {
|
|
74
|
+
templates = templates.filter((t) => t.projectId === filter.projectId);
|
|
75
|
+
}
|
|
76
|
+
if (filter?.search) {
|
|
77
|
+
const lowerQuery = filter.search.toLowerCase();
|
|
78
|
+
templates = templates.filter((t) => t.title.toLowerCase().includes(lowerQuery));
|
|
79
|
+
}
|
|
80
|
+
return ok(templates);
|
|
81
|
+
},
|
|
82
|
+
async get(id) {
|
|
83
|
+
const doc = catalog.doc();
|
|
84
|
+
if (!doc)
|
|
85
|
+
return err(notFound("recurring template", id));
|
|
86
|
+
const template = doc.recurringTemplates.find((t) => t.id === id);
|
|
87
|
+
if (!template)
|
|
88
|
+
return err(notFound("recurring template", id));
|
|
89
|
+
return ok(cloneTemplate(template));
|
|
90
|
+
},
|
|
91
|
+
async update(id, input) {
|
|
92
|
+
const validationErr = validateUpdateRecurringInput(input);
|
|
93
|
+
if (validationErr)
|
|
94
|
+
return err(validationErr);
|
|
95
|
+
const doc = catalog.doc();
|
|
96
|
+
if (!doc)
|
|
97
|
+
return err(notFound("recurring template", id));
|
|
98
|
+
const index = doc.recurringTemplates.findIndex((t) => t.id === id);
|
|
99
|
+
if (index === -1)
|
|
100
|
+
return err(notFound("recurring template", id));
|
|
101
|
+
// If changing project, verify it exists
|
|
102
|
+
if (input.projectId !== undefined) {
|
|
103
|
+
const project = doc.projects.find((p) => p.id === input.projectId);
|
|
104
|
+
if (!project)
|
|
105
|
+
return err(notFound("project", input.projectId));
|
|
106
|
+
}
|
|
107
|
+
const scheduleChanged = input.schedule !== undefined || input.timezone !== undefined;
|
|
108
|
+
catalog.change((doc) => {
|
|
109
|
+
const t = doc.recurringTemplates[index];
|
|
110
|
+
if (input.title !== undefined)
|
|
111
|
+
t.title = input.title.trim();
|
|
112
|
+
if (input.description !== undefined)
|
|
113
|
+
t.description = input.description;
|
|
114
|
+
if (input.projectId !== undefined)
|
|
115
|
+
t.projectId = input.projectId;
|
|
116
|
+
if (input.labels !== undefined)
|
|
117
|
+
t.labels = input.labels;
|
|
118
|
+
if (input.priority !== undefined)
|
|
119
|
+
t.priority = input.priority;
|
|
120
|
+
if (input.schedule !== undefined)
|
|
121
|
+
t.schedule = input.schedule;
|
|
122
|
+
if (input.timezone !== undefined)
|
|
123
|
+
t.timezone = input.timezone;
|
|
124
|
+
if (input.endDate !== undefined)
|
|
125
|
+
t.endDate = input.endDate;
|
|
126
|
+
if (input.paused !== undefined)
|
|
127
|
+
t.paused = input.paused;
|
|
128
|
+
t.updatedAt = new Date().toISOString();
|
|
129
|
+
});
|
|
130
|
+
// Recalculate nextDue if schedule changed
|
|
131
|
+
if (scheduleChanged) {
|
|
132
|
+
const updated = catalog.doc().recurringTemplates[index];
|
|
133
|
+
const today = todayInTimezone(updated.timezone);
|
|
134
|
+
const yesterday = shiftDate(today, -1);
|
|
135
|
+
const next = nextOccurrence(updated.schedule, updated.startDate, updated.timezone, yesterday, updated.endDate);
|
|
136
|
+
if (next) {
|
|
137
|
+
catalog.change((doc) => {
|
|
138
|
+
doc.recurringTemplates[index].nextDue = next;
|
|
139
|
+
});
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
const result = catalog.doc().recurringTemplates[index];
|
|
143
|
+
return ok(cloneTemplate(result));
|
|
144
|
+
},
|
|
145
|
+
async delete(id) {
|
|
146
|
+
const doc = catalog.doc();
|
|
147
|
+
if (!doc)
|
|
148
|
+
return err(notFound("recurring template", id));
|
|
149
|
+
const index = doc.recurringTemplates.findIndex((t) => t.id === id);
|
|
150
|
+
if (index === -1)
|
|
151
|
+
return err(notFound("recurring template", id));
|
|
152
|
+
catalog.change((doc) => {
|
|
153
|
+
doc.recurringTemplates.splice(index, 1);
|
|
154
|
+
});
|
|
155
|
+
return ok(undefined);
|
|
156
|
+
},
|
|
157
|
+
async pause(id) {
|
|
158
|
+
const doc = catalog.doc();
|
|
159
|
+
if (!doc)
|
|
160
|
+
return err(notFound("recurring template", id));
|
|
161
|
+
const index = doc.recurringTemplates.findIndex((t) => t.id === id);
|
|
162
|
+
if (index === -1)
|
|
163
|
+
return err(notFound("recurring template", id));
|
|
164
|
+
catalog.change((doc) => {
|
|
165
|
+
doc.recurringTemplates[index].paused = true;
|
|
166
|
+
doc.recurringTemplates[index].updatedAt = new Date().toISOString();
|
|
167
|
+
});
|
|
168
|
+
return ok(cloneTemplate(catalog.doc().recurringTemplates[index]));
|
|
169
|
+
},
|
|
170
|
+
async resume(id) {
|
|
171
|
+
const doc = catalog.doc();
|
|
172
|
+
if (!doc)
|
|
173
|
+
return err(notFound("recurring template", id));
|
|
174
|
+
const index = doc.recurringTemplates.findIndex((t) => t.id === id);
|
|
175
|
+
if (index === -1)
|
|
176
|
+
return err(notFound("recurring template", id));
|
|
177
|
+
// Recalculate nextDue on resume
|
|
178
|
+
const template = doc.recurringTemplates[index];
|
|
179
|
+
const today = todayInTimezone(template.timezone);
|
|
180
|
+
const yesterday = shiftDate(today, -1);
|
|
181
|
+
const next = nextOccurrence(template.schedule, template.startDate, template.timezone, yesterday, template.endDate);
|
|
182
|
+
catalog.change((doc) => {
|
|
183
|
+
doc.recurringTemplates[index].paused = false;
|
|
184
|
+
if (next) {
|
|
185
|
+
doc.recurringTemplates[index].nextDue = next;
|
|
186
|
+
}
|
|
187
|
+
doc.recurringTemplates[index].updatedAt = new Date().toISOString();
|
|
188
|
+
});
|
|
189
|
+
return ok(cloneTemplate(catalog.doc().recurringTemplates[index]));
|
|
190
|
+
},
|
|
191
|
+
async upcoming(options) {
|
|
192
|
+
const doc = catalog.doc();
|
|
193
|
+
if (!doc)
|
|
194
|
+
return ok([]);
|
|
195
|
+
const days = options?.days ?? 14;
|
|
196
|
+
const results = [];
|
|
197
|
+
const templates = options?.templateId
|
|
198
|
+
? doc.recurringTemplates.filter((t) => t.id === options.templateId)
|
|
199
|
+
: doc.recurringTemplates.filter((t) => !t.paused);
|
|
200
|
+
for (const template of templates) {
|
|
201
|
+
const today = todayInTimezone(template.timezone);
|
|
202
|
+
const endDate = shiftDate(today, days);
|
|
203
|
+
const effectiveEnd = template.endDate && template.endDate < endDate ? template.endDate : endDate;
|
|
204
|
+
const dates = nextOccurrences(template.schedule, template.startDate, template.timezone, today, days + 1, // request more than needed, we'll filter by date
|
|
205
|
+
effectiveEnd);
|
|
206
|
+
for (const date of dates) {
|
|
207
|
+
if (date > endDate)
|
|
208
|
+
break;
|
|
209
|
+
results.push({
|
|
210
|
+
templateId: template.id,
|
|
211
|
+
title: template.title,
|
|
212
|
+
date,
|
|
213
|
+
projectId: template.projectId,
|
|
214
|
+
priority: template.priority,
|
|
215
|
+
schedule: describeSchedule(template.schedule),
|
|
216
|
+
});
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
// Sort by date
|
|
220
|
+
results.sort((a, b) => a.date.localeCompare(b.date));
|
|
221
|
+
return ok(results);
|
|
222
|
+
},
|
|
223
|
+
async generate(templateId, date) {
|
|
224
|
+
const doc = catalog.doc();
|
|
225
|
+
if (!doc)
|
|
226
|
+
return err(notFound("recurring template", templateId));
|
|
227
|
+
const template = doc.recurringTemplates.find((t) => t.id === templateId);
|
|
228
|
+
if (!template)
|
|
229
|
+
return err(notFound("recurring template", templateId));
|
|
230
|
+
// Validate the date is a valid occurrence
|
|
231
|
+
if (!isScheduledDate(template.schedule, template.startDate, template.timezone, date, template.endDate)) {
|
|
232
|
+
return err(validationError("date", `${date} is not a valid occurrence for this template`));
|
|
233
|
+
}
|
|
234
|
+
// Generate the task with deterministic ID
|
|
235
|
+
return generateTaskFromTemplate(template, date, catalog, taskNs);
|
|
236
|
+
},
|
|
237
|
+
async process() {
|
|
238
|
+
return processRecurringTemplates(catalog, taskNs);
|
|
239
|
+
},
|
|
240
|
+
};
|
|
241
|
+
}
|
|
242
|
+
// ============================================================================
|
|
243
|
+
// Task generation from templates
|
|
244
|
+
// ============================================================================
|
|
245
|
+
async function generateTaskFromTemplate(template, date, catalog, taskNs) {
|
|
246
|
+
const taskId = generateScheduledTaskId(template.id, date);
|
|
247
|
+
// Check if task already exists
|
|
248
|
+
const doc = catalog.doc();
|
|
249
|
+
if (doc) {
|
|
250
|
+
for (const docId of Object.values(doc.taskListDocIds)) {
|
|
251
|
+
const handle = await taskNs._repo.find(docId);
|
|
252
|
+
const listDoc = handle.doc();
|
|
253
|
+
if (listDoc) {
|
|
254
|
+
const existing = listDoc.tasks.find((t) => t.id === taskId);
|
|
255
|
+
if (existing)
|
|
256
|
+
return ok(existing);
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
// Create the task
|
|
261
|
+
const input = {
|
|
262
|
+
title: template.title,
|
|
263
|
+
projectId: template.projectId,
|
|
264
|
+
priority: template.priority,
|
|
265
|
+
labels: [...template.labels],
|
|
266
|
+
scheduledDate: date,
|
|
267
|
+
description: template.description,
|
|
268
|
+
};
|
|
269
|
+
const result = await taskNs.create(input, taskId, template.id);
|
|
270
|
+
if (!result.ok)
|
|
271
|
+
return result;
|
|
272
|
+
return ok(result.value);
|
|
273
|
+
}
|
|
274
|
+
/**
|
|
275
|
+
* Process all due recurring templates — called by the scheduling framework.
|
|
276
|
+
* Generates tasks for all missed occurrences (catch-up behavior).
|
|
277
|
+
*/
|
|
278
|
+
async function processRecurringTemplates(catalog, taskNs) {
|
|
279
|
+
const doc = catalog.doc();
|
|
280
|
+
if (!doc)
|
|
281
|
+
return ok([]);
|
|
282
|
+
const created = [];
|
|
283
|
+
for (let i = 0; i < doc.recurringTemplates.length; i++) {
|
|
284
|
+
const template = doc.recurringTemplates[i];
|
|
285
|
+
if (template.paused)
|
|
286
|
+
continue;
|
|
287
|
+
const today = todayInTimezone(template.timezone);
|
|
288
|
+
let currentNextDue = template.nextDue;
|
|
289
|
+
// Generate tasks for all due dates (catch-up)
|
|
290
|
+
while (currentNextDue <= today) {
|
|
291
|
+
// Check skip list
|
|
292
|
+
if (!template.skippedDates.includes(currentNextDue)) {
|
|
293
|
+
const result = await generateTaskFromTemplate(template, currentNextDue, catalog, taskNs);
|
|
294
|
+
if (result.ok) {
|
|
295
|
+
created.push(result.value);
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
// Advance to next occurrence
|
|
299
|
+
const next = nextOccurrence(template.schedule, template.startDate, template.timezone, currentNextDue, template.endDate);
|
|
300
|
+
if (!next)
|
|
301
|
+
break; // No more occurrences
|
|
302
|
+
currentNextDue = next;
|
|
303
|
+
}
|
|
304
|
+
// Update nextDue in catalog
|
|
305
|
+
if (currentNextDue !== template.nextDue) {
|
|
306
|
+
catalog.change((doc) => {
|
|
307
|
+
doc.recurringTemplates[i].nextDue = currentNextDue;
|
|
308
|
+
});
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
return ok(created);
|
|
312
|
+
}
|
|
313
|
+
/**
|
|
314
|
+
* Register the recurring template processor with the scheduling framework.
|
|
315
|
+
* Called once during module initialization.
|
|
316
|
+
*/
|
|
317
|
+
export function registerRecurringProcessor(catalog, repo) {
|
|
318
|
+
const taskNs = createTaskNamespace(catalog, repo);
|
|
319
|
+
registerProcessor("recurring", async () => {
|
|
320
|
+
const result = await processRecurringTemplates(catalog, taskNs);
|
|
321
|
+
return result.ok ? result.value.length : 0;
|
|
322
|
+
});
|
|
323
|
+
}
|
|
324
|
+
/**
|
|
325
|
+
* Add a date to a template's skip list.
|
|
326
|
+
* Called when a generated task is deleted.
|
|
327
|
+
*/
|
|
328
|
+
export function addToSkipList(catalog, templateId, date) {
|
|
329
|
+
const doc = catalog.doc();
|
|
330
|
+
if (!doc)
|
|
331
|
+
return;
|
|
332
|
+
const index = doc.recurringTemplates.findIndex((t) => t.id === templateId);
|
|
333
|
+
if (index === -1)
|
|
334
|
+
return;
|
|
335
|
+
const template = doc.recurringTemplates[index];
|
|
336
|
+
if (template.skippedDates.includes(date))
|
|
337
|
+
return;
|
|
338
|
+
catalog.change((doc) => {
|
|
339
|
+
doc.recurringTemplates[index].skippedDates.push(date);
|
|
340
|
+
});
|
|
341
|
+
}
|
|
342
|
+
// ============================================================================
|
|
343
|
+
// Helpers
|
|
344
|
+
// ============================================================================
|
|
345
|
+
function cloneTemplate(t) {
|
|
346
|
+
return {
|
|
347
|
+
id: t.id,
|
|
348
|
+
title: t.title,
|
|
349
|
+
description: t.description,
|
|
350
|
+
projectId: t.projectId,
|
|
351
|
+
labels: [...t.labels],
|
|
352
|
+
priority: t.priority,
|
|
353
|
+
schedule: t.schedule,
|
|
354
|
+
timezone: t.timezone,
|
|
355
|
+
startDate: t.startDate,
|
|
356
|
+
endDate: t.endDate,
|
|
357
|
+
nextDue: t.nextDue,
|
|
358
|
+
skippedDates: [...t.skippedDates],
|
|
359
|
+
paused: t.paused,
|
|
360
|
+
createdAt: t.createdAt,
|
|
361
|
+
updatedAt: t.updatedAt,
|
|
362
|
+
};
|
|
363
|
+
}
|
|
364
|
+
function shiftDate(dateStr, days) {
|
|
365
|
+
const [year, month, day] = dateStr.split("-").map(Number);
|
|
366
|
+
const date = new Date(Date.UTC(year, month - 1, day + days));
|
|
367
|
+
const y = date.getUTCFullYear();
|
|
368
|
+
const m = String(date.getUTCMonth() + 1).padStart(2, "0");
|
|
369
|
+
const d = String(date.getUTCDate()).padStart(2, "0");
|
|
370
|
+
return `${y}-${m}-${d}`;
|
|
371
|
+
}
|
|
372
|
+
//# sourceMappingURL=recurring.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"recurring.js","sourceRoot":"","sources":["../src/recurring.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Calculate the next occurrence after a given date.
|
|
3
|
+
*
|
|
4
|
+
* @param rule - RRULE string
|
|
5
|
+
* @param startDate - Schedule start date (YYYY-MM-DD)
|
|
6
|
+
* @param timezone - IANA timezone
|
|
7
|
+
* @param afterDate - Find next occurrence after this date (YYYY-MM-DD)
|
|
8
|
+
* @param endDate - Optional end date (YYYY-MM-DD) — no occurrences after this
|
|
9
|
+
* @returns Next occurrence as YYYY-MM-DD string, or null if no more occurrences
|
|
10
|
+
*/
|
|
11
|
+
export declare function nextOccurrence(rule: string, startDate: string, timezone: string, afterDate: string, endDate?: string): string | null;
|
|
12
|
+
/**
|
|
13
|
+
* Calculate the next N occurrences starting from a given date (inclusive).
|
|
14
|
+
* Used for the "upcoming" view.
|
|
15
|
+
*
|
|
16
|
+
* @param rule - RRULE string
|
|
17
|
+
* @param startDate - Schedule start date (YYYY-MM-DD)
|
|
18
|
+
* @param timezone - IANA timezone
|
|
19
|
+
* @param fromDate - Start listing from this date (YYYY-MM-DD), inclusive
|
|
20
|
+
* @param count - Number of occurrences to return
|
|
21
|
+
* @param endDate - Optional end date (YYYY-MM-DD)
|
|
22
|
+
* @returns Array of YYYY-MM-DD date strings
|
|
23
|
+
*/
|
|
24
|
+
export declare function nextOccurrences(rule: string, startDate: string, timezone: string, fromDate: string, count: number, endDate?: string): string[];
|
|
25
|
+
/**
|
|
26
|
+
* Check if a specific date is a valid occurrence of the schedule.
|
|
27
|
+
* Used to validate early materialization requests.
|
|
28
|
+
*/
|
|
29
|
+
export declare function isScheduledDate(rule: string, startDate: string, timezone: string, date: string, endDate?: string): boolean;
|
|
30
|
+
/**
|
|
31
|
+
* Convert an RRULE string to a human-readable description.
|
|
32
|
+
*/
|
|
33
|
+
export declare function describeSchedule(rule: string): string;
|
|
34
|
+
/**
|
|
35
|
+
* Get today's date in the given timezone as YYYY-MM-DD.
|
|
36
|
+
*/
|
|
37
|
+
export declare function todayInTimezone(timezone: string): string;
|
|
38
|
+
//# sourceMappingURL=schedule.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schedule.d.ts","sourceRoot":"","sources":["../src/schedule.ts"],"names":[],"mappings":"AAsEA;;;;;;;;;GASG;AACH,wBAAgB,cAAc,CAC5B,IAAI,EAAE,MAAM,EACZ,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,MAAM,EACjB,OAAO,CAAC,EAAE,MAAM,GACf,MAAM,GAAG,IAAI,CAgBf;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,eAAe,CAC7B,IAAI,EAAE,MAAM,EACZ,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,MAAM,EACb,OAAO,CAAC,EAAE,MAAM,GACf,MAAM,EAAE,CA2BV;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAC7B,IAAI,EAAE,MAAM,EACZ,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,MAAM,EACZ,OAAO,CAAC,EAAE,MAAM,GACf,OAAO,CAiBT;AA0BD;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CA8CrD;AAMD;;GAEG;AACH,wBAAgB,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAQxD"}
|