@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.
Files changed (57) hide show
  1. package/dist/change-observer.d.ts +15 -0
  2. package/dist/change-observer.d.ts.map +1 -0
  3. package/dist/change-observer.js +64 -0
  4. package/dist/change-observer.js.map +1 -0
  5. package/dist/habits.d.ts +6 -0
  6. package/dist/habits.d.ts.map +1 -0
  7. package/dist/habits.js +397 -0
  8. package/dist/habits.js.map +1 -0
  9. package/dist/index.d.ts +25 -0
  10. package/dist/index.d.ts.map +1 -0
  11. package/dist/index.js +104 -0
  12. package/dist/index.js.map +1 -0
  13. package/dist/labels.d.ts +5 -0
  14. package/dist/labels.d.ts.map +1 -0
  15. package/dist/labels.js +113 -0
  16. package/dist/labels.js.map +1 -0
  17. package/dist/notes.d.ts +5 -0
  18. package/dist/notes.d.ts.map +1 -0
  19. package/dist/notes.js +163 -0
  20. package/dist/notes.js.map +1 -0
  21. package/dist/projects.d.ts +5 -0
  22. package/dist/projects.d.ts.map +1 -0
  23. package/dist/projects.js +117 -0
  24. package/dist/projects.js.map +1 -0
  25. package/dist/recurring.d.ts +23 -0
  26. package/dist/recurring.d.ts.map +1 -0
  27. package/dist/recurring.js +372 -0
  28. package/dist/recurring.js.map +1 -0
  29. package/dist/schedule.d.ts +38 -0
  30. package/dist/schedule.d.ts.map +1 -0
  31. package/dist/schedule.js +330 -0
  32. package/dist/schedule.js.map +1 -0
  33. package/dist/scheduling.d.ts +62 -0
  34. package/dist/scheduling.d.ts.map +1 -0
  35. package/dist/scheduling.js +58 -0
  36. package/dist/scheduling.js.map +1 -0
  37. package/dist/storage.d.ts +34 -0
  38. package/dist/storage.d.ts.map +1 -0
  39. package/dist/storage.js +204 -0
  40. package/dist/storage.js.map +1 -0
  41. package/dist/sync-client.d.ts +16 -0
  42. package/dist/sync-client.d.ts.map +1 -0
  43. package/dist/sync-client.js +54 -0
  44. package/dist/sync-client.js.map +1 -0
  45. package/dist/sync-server.d.ts +12 -0
  46. package/dist/sync-server.d.ts.map +1 -0
  47. package/dist/sync-server.js +21 -0
  48. package/dist/sync-server.js.map +1 -0
  49. package/dist/tasks.d.ts +18 -0
  50. package/dist/tasks.d.ts.map +1 -0
  51. package/dist/tasks.js +396 -0
  52. package/dist/tasks.js.map +1 -0
  53. package/dist/todu.d.ts +115 -0
  54. package/dist/todu.d.ts.map +1 -0
  55. package/dist/todu.js +76 -0
  56. package/dist/todu.js.map +1 -0
  57. 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"}