@j0hanz/todokit-mcp 1.0.5 → 1.0.7

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 (51) hide show
  1. package/README.md +48 -8
  2. package/dist/index.d.ts.map +1 -1
  3. package/dist/index.js +16 -2
  4. package/dist/index.js.map +1 -1
  5. package/dist/lib/db.d.ts +8 -0
  6. package/dist/lib/db.d.ts.map +1 -0
  7. package/dist/lib/db.js +177 -0
  8. package/dist/lib/db.js.map +1 -0
  9. package/dist/lib/errors.js +17 -12
  10. package/dist/lib/errors.js.map +1 -1
  11. package/dist/lib/resolve.js +1 -1
  12. package/dist/lib/resolve.js.map +1 -1
  13. package/dist/lib/storage.d.ts +7 -6
  14. package/dist/lib/storage.d.ts.map +1 -1
  15. package/dist/lib/storage.js +148 -71
  16. package/dist/lib/storage.js.map +1 -1
  17. package/dist/lib/storage_filters.d.ts +6 -6
  18. package/dist/lib/storage_filters.d.ts.map +1 -1
  19. package/dist/lib/storage_filters.js +26 -45
  20. package/dist/lib/storage_filters.js.map +1 -1
  21. package/dist/lib/storage_mutations.d.ts +8 -3
  22. package/dist/lib/storage_mutations.d.ts.map +1 -1
  23. package/dist/lib/storage_mutations.js +0 -58
  24. package/dist/lib/storage_mutations.js.map +1 -1
  25. package/dist/lib/storage_state.d.ts.map +1 -1
  26. package/dist/lib/storage_state.js +36 -2
  27. package/dist/lib/storage_state.js.map +1 -1
  28. package/dist/schemas/inputs.d.ts +74 -40
  29. package/dist/schemas/inputs.d.ts.map +1 -1
  30. package/dist/schemas/inputs.js +54 -66
  31. package/dist/schemas/inputs.js.map +1 -1
  32. package/dist/tools/complete_todo.d.ts.map +1 -1
  33. package/dist/tools/complete_todo.js +2 -1
  34. package/dist/tools/complete_todo.js.map +1 -1
  35. package/dist/tools/delete_todo.d.ts.map +1 -1
  36. package/dist/tools/delete_todo.js +4 -2
  37. package/dist/tools/delete_todo.js.map +1 -1
  38. package/dist/tools/delete_todos.d.ts +3 -0
  39. package/dist/tools/delete_todos.d.ts.map +1 -0
  40. package/dist/tools/delete_todos.js +134 -0
  41. package/dist/tools/delete_todos.js.map +1 -0
  42. package/dist/tools/index.d.ts.map +1 -1
  43. package/dist/tools/index.js +2 -0
  44. package/dist/tools/index.js.map +1 -1
  45. package/dist/tools/list_todos.d.ts.map +1 -1
  46. package/dist/tools/list_todos.js +68 -45
  47. package/dist/tools/list_todos.js.map +1 -1
  48. package/dist/tools/update_todo.d.ts.map +1 -1
  49. package/dist/tools/update_todo.js +55 -50
  50. package/dist/tools/update_todo.js.map +1 -1
  51. package/package.json +1 -1
@@ -1,13 +1,44 @@
1
1
  import { randomUUID } from 'node:crypto';
2
+ import { readTodos, withTodos } from './db.js';
2
3
  import { resolveTodoTargetFromTodos, unwrapResolution, } from './resolve.js';
3
4
  import { filterTodos, normalizeTags, } from './storage_filters.js';
4
- import { completeTodoInList, createNotFoundOutcome, updateTodoInList, } from './storage_mutations.js';
5
- import { persistTodos, queueWrite, readTodosFromDisk, waitForWrites, } from './storage_state.js';
5
+ import { createNotFoundOutcome, } from './storage_mutations.js';
6
6
  import {} from './types.js';
7
7
  export { normalizeTags };
8
+ function normalizeUpdates(updates) {
9
+ if (!updates.tags)
10
+ return updates;
11
+ return { ...updates, tags: normalizeTags(updates.tags) };
12
+ }
13
+ function areStringArraysEqual(left, right) {
14
+ if (left.length !== right.length)
15
+ return false;
16
+ for (let i = 0; i < left.length; i += 1) {
17
+ if (left[i] !== right[i])
18
+ return false;
19
+ }
20
+ return true;
21
+ }
22
+ function isStringArray(value) {
23
+ return (Array.isArray(value) && value.every((item) => typeof item === 'string'));
24
+ }
25
+ function valuesEqual(current, update) {
26
+ if (isStringArray(update) && isStringArray(current)) {
27
+ return areStringArraysEqual(update, current);
28
+ }
29
+ return Object.is(current, update);
30
+ }
31
+ function hasChanges(current, updates) {
32
+ for (const [key, value] of Object.entries(updates)) {
33
+ const currentValue = current[key];
34
+ if (!valuesEqual(currentValue, value)) {
35
+ return true;
36
+ }
37
+ }
38
+ return false;
39
+ }
8
40
  export async function getTodos(filters) {
9
- await waitForWrites();
10
- const todos = await readTodosFromDisk();
41
+ const todos = await readTodos();
11
42
  return filters ? filterTodos(todos, filters) : todos;
12
43
  }
13
44
  export async function addTodo(title, description, priority = 'normal', dueDate, tags = []) {
@@ -19,97 +50,143 @@ export async function addTodo(title, description, priority = 'normal', dueDate,
19
50
  }
20
51
  return todo;
21
52
  }
22
- export async function addTodos(items) {
23
- return queueWrite(async () => {
24
- const todos = await readTodosFromDisk();
25
- const timestamp = new Date().toISOString();
26
- const newTodos = items.map((item) => ({
27
- id: randomUUID(),
28
- title: item.title,
29
- description: item.description,
30
- completed: false,
31
- priority: item.priority ?? 'normal',
32
- dueDate: item.dueDate,
33
- tags: normalizeTags(item.tags ?? []),
34
- createdAt: timestamp,
35
- updatedAt: timestamp,
36
- completedAt: undefined,
37
- }));
38
- const nextTodos = [...todos, ...newTodos];
39
- await persistTodos(nextTodos);
40
- return newTodos;
41
- });
53
+ function createNewTodo(item, timestamp) {
54
+ return {
55
+ id: randomUUID(),
56
+ title: item.title,
57
+ description: item.description,
58
+ completed: false,
59
+ priority: item.priority ?? 'normal',
60
+ dueDate: item.dueDate,
61
+ tags: normalizeTags(item.tags ?? []),
62
+ createdAt: timestamp,
63
+ updatedAt: timestamp,
64
+ completedAt: undefined,
65
+ };
42
66
  }
43
- export async function updateTodo(id, updates) {
44
- return queueWrite(async () => {
45
- const todos = await readTodosFromDisk();
46
- const updatedTodo = updateTodoInList(todos, id, updates);
47
- if (!updatedTodo)
48
- return null;
49
- await persistTodos(todos);
50
- return updatedTodo;
67
+ export function addTodos(items) {
68
+ const timestamp = new Date().toISOString();
69
+ return withTodos((todos) => {
70
+ const newTodos = items.map((item) => createNewTodo(item, timestamp));
71
+ return { todos: [...todos, ...newTodos], result: newTodos };
51
72
  });
52
73
  }
53
- export async function deleteTodo(id) {
54
- return queueWrite(async () => {
55
- const todos = await readTodosFromDisk();
56
- const index = todos.findIndex((todo) => todo.id === id);
57
- if (index === -1)
58
- return false;
59
- todos.splice(index, 1);
60
- await persistTodos(todos);
61
- return true;
74
+ function calculateUpdatedTodo(current, updates) {
75
+ const updatedTodo = {
76
+ ...current,
77
+ ...updates,
78
+ updatedAt: new Date().toISOString(),
79
+ };
80
+ if (updates.completed !== undefined &&
81
+ updates.completed !== current.completed) {
82
+ updatedTodo.completedAt = updates.completed
83
+ ? new Date().toISOString()
84
+ : undefined;
85
+ }
86
+ return updatedTodo;
87
+ }
88
+ function applyUpdateToTodos(todos, id, updates) {
89
+ const index = todos.findIndex((todo) => todo.id === id);
90
+ if (index < 0) {
91
+ return { todos, result: null };
92
+ }
93
+ const current = todos[index];
94
+ if (!current) {
95
+ return { todos, result: null };
96
+ }
97
+ const normalizedUpdates = normalizeUpdates(updates);
98
+ if (!hasChanges(current, normalizedUpdates)) {
99
+ return { todos, result: current };
100
+ }
101
+ const updatedTodo = calculateUpdatedTodo(current, normalizedUpdates);
102
+ const nextTodos = [...todos];
103
+ nextTodos[index] = updatedTodo;
104
+ return { todos: nextTodos, result: updatedTodo };
105
+ }
106
+ export function updateTodo(id, updates) {
107
+ return withTodos((todos) => applyUpdateToTodos(todos, id, updates));
108
+ }
109
+ export function deleteTodo(id) {
110
+ return withTodos((todos) => {
111
+ const remaining = todos.filter((todo) => todo.id !== id);
112
+ return { todos: remaining, result: remaining.length !== todos.length };
62
113
  });
63
114
  }
64
115
  export async function updateTodoBySelector(input, buildUpdates) {
65
- return queueWrite(async () => {
66
- const todos = await readTodosFromDisk();
116
+ return withTodos((todos) => {
67
117
  const outcome = unwrapResolution(resolveTodoTargetFromTodos(todos, input));
68
118
  if (outcome.kind !== 'match') {
69
- return outcome;
119
+ return { todos, result: outcome };
70
120
  }
71
121
  const updates = buildUpdates(outcome.todo);
72
122
  if (!updates || Object.keys(updates).length === 0) {
73
- return { kind: 'no_updates' };
123
+ return { todos, result: { kind: 'no_updates' } };
74
124
  }
75
- const updatedTodo = updateTodoInList(todos, outcome.todo.id, updates);
76
- if (!updatedTodo) {
77
- return createNotFoundOutcome(outcome.todo.id);
125
+ const updated = applyUpdateToTodos(todos, outcome.todo.id, updates);
126
+ if (!updated.result) {
127
+ return {
128
+ todos,
129
+ result: createNotFoundOutcome(outcome.todo.id),
130
+ };
78
131
  }
79
- await persistTodos(todos);
80
- return { kind: 'match', todo: updatedTodo };
132
+ return {
133
+ todos: updated.todos,
134
+ result: { kind: 'match', todo: updated.result },
135
+ };
81
136
  });
82
137
  }
83
138
  export async function deleteTodoBySelector(input) {
84
- return queueWrite(async () => {
85
- const todos = await readTodosFromDisk();
139
+ return withTodos((todos) => {
86
140
  const outcome = unwrapResolution(resolveTodoTargetFromTodos(todos, input));
87
- if (outcome.kind !== 'match')
88
- return outcome;
89
- const index = todos.findIndex((todo) => todo.id === outcome.todo.id);
90
- if (index === -1) {
91
- return createNotFoundOutcome(outcome.todo.id);
141
+ if (outcome.kind !== 'match') {
142
+ return { todos, result: outcome };
92
143
  }
93
- const removed = todos[index];
94
- if (!removed) {
95
- return createNotFoundOutcome(outcome.todo.id);
144
+ const remaining = todos.filter((todo) => todo.id !== outcome.todo.id);
145
+ if (remaining.length === todos.length) {
146
+ return {
147
+ todos,
148
+ result: createNotFoundOutcome(outcome.todo.id),
149
+ };
96
150
  }
97
- todos.splice(index, 1);
98
- await persistTodos(todos);
99
- return { kind: 'match', todo: removed };
151
+ return { todos: remaining, result: { kind: 'match', todo: outcome.todo } };
100
152
  });
101
153
  }
102
154
  export async function completeTodoBySelector(input, completed) {
103
- return queueWrite(async () => {
104
- const todos = await readTodosFromDisk();
155
+ return withTodos((todos) => {
105
156
  const outcome = unwrapResolution(resolveTodoTargetFromTodos(todos, input));
106
- if (outcome.kind !== 'match')
107
- return outcome;
108
- const result = completeTodoInList(todos, outcome.todo.id, completed);
109
- if (result.kind === 'match') {
110
- await persistTodos(todos);
157
+ if (outcome.kind !== 'match') {
158
+ return { todos, result: outcome };
159
+ }
160
+ if (outcome.todo.completed === completed) {
161
+ return { todos, result: { kind: 'already', todo: outcome.todo } };
162
+ }
163
+ const updated = applyUpdateToTodos(todos, outcome.todo.id, { completed });
164
+ if (!updated.result) {
165
+ return {
166
+ todos,
167
+ result: createNotFoundOutcome(outcome.todo.id),
168
+ };
169
+ }
170
+ return {
171
+ todos: updated.todos,
172
+ result: { kind: 'match', todo: updated.result },
173
+ };
174
+ });
175
+ }
176
+ export function deleteTodosByIds(ids) {
177
+ const idsToDelete = new Set(ids);
178
+ return withTodos((todos) => {
179
+ const deletedIds = [];
180
+ const remaining = [];
181
+ for (const todo of todos) {
182
+ if (idsToDelete.has(todo.id)) {
183
+ deletedIds.push(todo.id);
184
+ }
185
+ else {
186
+ remaining.push(todo);
187
+ }
111
188
  }
112
- return result;
189
+ return { todos: remaining, result: deletedIds };
113
190
  });
114
191
  }
115
192
  //# sourceMappingURL=storage.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"storage.js","sourceRoot":"","sources":["../../src/lib/storage.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"storage.js","sourceRoot":"","sources":["../../src/lib/storage.ts"],"names":[],"mappings":"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"}
@@ -1,11 +1,11 @@
1
1
  import type { Todo } from './types.js';
2
2
  export interface TodoFilters {
3
- completed?: boolean;
4
- priority?: 'low' | 'normal' | 'high';
5
- tag?: string;
6
- dueBefore?: string;
7
- dueAfter?: string;
8
- query?: string;
3
+ completed?: boolean | undefined;
4
+ priority?: 'low' | 'normal' | 'high' | undefined;
5
+ tag?: string | undefined;
6
+ dueBefore?: string | undefined;
7
+ dueAfter?: string | undefined;
8
+ query?: string | undefined;
9
9
  }
10
10
  export declare function normalizeTags(tags: string[]): string[];
11
11
  export declare function filterTodos(todos: Todo[], filters: TodoFilters): Todo[];
@@ -1 +1 @@
1
- {"version":3,"file":"storage_filters.d.ts","sourceRoot":"","sources":["../../src/lib/storage_filters.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAEvC,MAAM,WAAW,WAAW;IAC1B,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,QAAQ,CAAC,EAAE,KAAK,GAAG,QAAQ,GAAG,MAAM,CAAC;IACrC,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAMD,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,MAAM,EAAE,CAKtD;AA8ED,wBAAgB,WAAW,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE,OAAO,EAAE,WAAW,GAAG,IAAI,EAAE,CAGvE"}
1
+ {"version":3,"file":"storage_filters.d.ts","sourceRoot":"","sources":["../../src/lib/storage_filters.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAEvC,MAAM,WAAW,WAAW;IAC1B,SAAS,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IAChC,QAAQ,CAAC,EAAE,KAAK,GAAG,QAAQ,GAAG,MAAM,GAAG,SAAS,CAAC;IACjD,GAAG,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACzB,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC/B,QAAQ,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC9B,KAAK,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAC5B;AAMD,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,MAAM,EAAE,CAKtD;AA6CD,wBAAgB,WAAW,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE,OAAO,EAAE,WAAW,GAAG,IAAI,EAAE,CAUvE"}
@@ -7,60 +7,41 @@ export function normalizeTags(tags) {
7
7
  .filter((tag) => tag.length > 0);
8
8
  return Array.from(new Set(normalized));
9
9
  }
10
- function matchesQuery(todo, query) {
11
- const haystack = `${todo.title} ${todo.description ?? ''} ${todo.tags.join(' ')}`.toLowerCase();
12
- return haystack.includes(query);
13
- }
14
- function normalizeQuery(query) {
15
- const trimmed = query?.trim().toLowerCase();
16
- return trimmed && trimmed.length > 0 ? trimmed : undefined;
17
- }
18
- function normalizeFilters(filters) {
19
- return {
20
- completed: filters.completed,
21
- priority: filters.priority,
22
- tag: filters.tag ? normalizeTag(filters.tag) : undefined,
23
- dueBefore: filters.dueBefore,
24
- dueAfter: filters.dueAfter,
25
- query: normalizeQuery(filters.query),
26
- };
27
- }
28
- function matchesCompletion(todo, completed) {
29
- return completed === undefined ? true : todo.completed === completed;
10
+ function matchesCompleted(todo, completed) {
11
+ return completed === undefined || todo.completed === completed;
30
12
  }
31
13
  function matchesPriority(todo, priority) {
32
- return priority ? todo.priority === priority : true;
14
+ return !priority || todo.priority === priority;
33
15
  }
34
16
  function matchesTag(todo, tag) {
35
- return tag ? todo.tags.includes(tag) : true;
17
+ return !tag || todo.tags.includes(tag);
18
+ }
19
+ function matchesBasic(todo, filters, tag) {
20
+ return (matchesCompleted(todo, filters.completed) &&
21
+ matchesPriority(todo, filters.priority) &&
22
+ matchesTag(todo, tag));
36
23
  }
37
- function matchesQueryFilter(todo, query) {
38
- return query ? matchesQuery(todo, query) : true;
24
+ function matchesDueBefore(todo, date) {
25
+ return !date || (!!todo.dueDate && todo.dueDate < date);
39
26
  }
40
- function matchesDueBefore(todo, dueBefore) {
41
- return dueBefore ? Boolean(todo.dueDate && todo.dueDate < dueBefore) : true;
27
+ function matchesDueAfter(todo, date) {
28
+ return !date || (!!todo.dueDate && todo.dueDate > date);
42
29
  }
43
- function matchesDueAfter(todo, dueAfter) {
44
- return dueAfter ? Boolean(todo.dueDate && todo.dueDate > dueAfter) : true;
30
+ function matchesDate(todo, filters) {
31
+ return (matchesDueBefore(todo, filters.dueBefore) &&
32
+ matchesDueAfter(todo, filters.dueAfter));
45
33
  }
46
- const MATCHERS = [
47
- (todo, filters) => matchesCompletion(todo, filters.completed),
48
- (todo, filters) => matchesPriority(todo, filters.priority),
49
- (todo, filters) => matchesTag(todo, filters.tag),
50
- (todo, filters) => matchesQueryFilter(todo, filters.query),
51
- (todo, filters) => matchesDueBefore(todo, filters.dueBefore),
52
- (todo, filters) => matchesDueAfter(todo, filters.dueAfter),
53
- ];
54
- function todoMatches(todo, filters) {
55
- for (const check of MATCHERS) {
56
- if (!check(todo, filters)) {
57
- return false;
58
- }
59
- }
60
- return true;
34
+ function matchesQuery(todo, query) {
35
+ if (!query)
36
+ return true;
37
+ const haystack = `${todo.title} ${todo.description ?? ''} ${todo.tags.join(' ')}`.toLowerCase();
38
+ return haystack.includes(query);
61
39
  }
62
40
  export function filterTodos(todos, filters) {
63
- const normalized = normalizeFilters(filters);
64
- return todos.filter((todo) => todoMatches(todo, normalized));
41
+ const query = filters.query?.trim().toLowerCase();
42
+ const tag = filters.tag ? normalizeTag(filters.tag) : undefined;
43
+ return todos.filter((todo) => matchesBasic(todo, filters, tag) &&
44
+ matchesDate(todo, filters) &&
45
+ matchesQuery(todo, query));
65
46
  }
66
47
  //# sourceMappingURL=storage_filters.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"storage_filters.js","sourceRoot":"","sources":["../../src/lib/storage_filters.ts"],"names":[],"mappings":"AAWA,SAAS,YAAY,CAAC,GAAW;IAC/B,OAAO,GAAG,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;AAClC,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,IAAc;IAC1C,MAAM,UAAU,GAAG,IAAI;SACpB,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC;SAC/B,MAAM,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IACnC,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC;AACzC,CAAC;AAED,SAAS,YAAY,CAAC,IAAU,EAAE,KAAa;IAC7C,MAAM,QAAQ,GAAG,GAAG,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,WAAW,IAAI,EAAE,IAAI,IAAI,CAAC,IAAI,CAAC,IAAI,CACxE,GAAG,CACJ,EAAE,CAAC,WAAW,EAAE,CAAC;IAClB,OAAO,QAAQ,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;AAClC,CAAC;AAED,SAAS,cAAc,CAAC,KAAc;IACpC,MAAM,OAAO,GAAG,KAAK,EAAE,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IAC5C,OAAO,OAAO,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC;AAC7D,CAAC;AAaD,SAAS,gBAAgB,CAAC,OAAoB;IAC5C,OAAO;QACL,SAAS,EAAE,OAAO,CAAC,SAAS;QAC5B,QAAQ,EAAE,OAAO,CAAC,QAAQ;QAC1B,GAAG,EAAE,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,YAAY,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS;QACxD,SAAS,EAAE,OAAO,CAAC,SAAS;QAC5B,QAAQ,EAAE,OAAO,CAAC,QAAQ;QAC1B,KAAK,EAAE,cAAc,CAAC,OAAO,CAAC,KAAK,CAAC;KACrC,CAAC;AACJ,CAAC;AAED,SAAS,iBAAiB,CAAC,IAAU,EAAE,SAAmB;IACxD,OAAO,SAAS,KAAK,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,KAAK,SAAS,CAAC;AACvE,CAAC;AAED,SAAS,eAAe,CAAC,IAAU,EAAE,QAA2B;IAC9D,OAAO,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC;AACtD,CAAC;AAED,SAAS,UAAU,CAAC,IAAU,EAAE,GAAY;IAC1C,OAAO,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;AAC9C,CAAC;AAED,SAAS,kBAAkB,CAAC,IAAU,EAAE,KAAc;IACpD,OAAO,KAAK,CAAC,CAAC,CAAC,YAAY,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;AAClD,CAAC;AAED,SAAS,gBAAgB,CAAC,IAAU,EAAE,SAAkB;IACtD,OAAO,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,IAAI,IAAI,CAAC,OAAO,GAAG,SAAS,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;AAC9E,CAAC;AAED,SAAS,eAAe,CAAC,IAAU,EAAE,QAAiB;IACpD,OAAO,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,IAAI,IAAI,CAAC,OAAO,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;AAC5E,CAAC;AAED,MAAM,QAAQ,GAAc;IAC1B,CAAC,IAAI,EAAE,OAAO,EAAE,EAAE,CAAC,iBAAiB,CAAC,IAAI,EAAE,OAAO,CAAC,SAAS,CAAC;IAC7D,CAAC,IAAI,EAAE,OAAO,EAAE,EAAE,CAAC,eAAe,CAAC,IAAI,EAAE,OAAO,CAAC,QAAQ,CAAC;IAC1D,CAAC,IAAI,EAAE,OAAO,EAAE,EAAE,CAAC,UAAU,CAAC,IAAI,EAAE,OAAO,CAAC,GAAG,CAAC;IAChD,CAAC,IAAI,EAAE,OAAO,EAAE,EAAE,CAAC,kBAAkB,CAAC,IAAI,EAAE,OAAO,CAAC,KAAK,CAAC;IAC1D,CAAC,IAAI,EAAE,OAAO,EAAE,EAAE,CAAC,gBAAgB,CAAC,IAAI,EAAE,OAAO,CAAC,SAAS,CAAC;IAC5D,CAAC,IAAI,EAAE,OAAO,EAAE,EAAE,CAAC,eAAe,CAAC,IAAI,EAAE,OAAO,CAAC,QAAQ,CAAC;CAC3D,CAAC;AAEF,SAAS,WAAW,CAAC,IAAU,EAAE,OAA0B;IACzD,KAAK,MAAM,KAAK,IAAI,QAAQ,EAAE,CAAC;QAC7B,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,OAAO,CAAC,EAAE,CAAC;YAC1B,OAAO,KAAK,CAAC;QACf,CAAC;IACH,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,KAAa,EAAE,OAAoB;IAC7D,MAAM,UAAU,GAAG,gBAAgB,CAAC,OAAO,CAAC,CAAC;IAC7C,OAAO,KAAK,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,WAAW,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC,CAAC;AAC/D,CAAC"}
1
+ {"version":3,"file":"storage_filters.js","sourceRoot":"","sources":["../../src/lib/storage_filters.ts"],"names":[],"mappings":"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"}
@@ -1,11 +1,16 @@
1
1
  import type { MatchOutcome } from './resolve.js';
2
2
  import type { Todo } from './types.js';
3
- export type TodoUpdate = Partial<Omit<Todo, 'id' | 'createdAt'>>;
4
- export declare function updateTodoInList(todos: Todo[], id: string, updates: TodoUpdate): Todo | null;
3
+ export interface TodoUpdate {
4
+ title?: string;
5
+ description?: string | undefined;
6
+ completed?: boolean;
7
+ priority?: Todo['priority'];
8
+ dueDate?: string | undefined;
9
+ tags?: string[];
10
+ }
5
11
  export declare function createNotFoundOutcome(id: string): MatchOutcome;
6
12
  export type CompleteTodoOutcome = MatchOutcome | {
7
13
  kind: 'already';
8
14
  todo: Todo;
9
15
  };
10
- export declare function completeTodoInList(todos: Todo[], id: string, completed: boolean): CompleteTodoOutcome;
11
16
  //# sourceMappingURL=storage_mutations.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"storage_mutations.d.ts","sourceRoot":"","sources":["../../src/lib/storage_mutations.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAEjD,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAEvC,MAAM,MAAM,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,GAAG,WAAW,CAAC,CAAC,CAAC;AA0CjE,wBAAgB,gBAAgB,CAC9B,KAAK,EAAE,IAAI,EAAE,EACb,EAAE,EAAE,MAAM,EACV,OAAO,EAAE,UAAU,GAClB,IAAI,GAAG,IAAI,CAYb;AAED,wBAAgB,qBAAqB,CAAC,EAAE,EAAE,MAAM,GAAG,YAAY,CAQ9D;AAED,MAAM,MAAM,mBAAmB,GAC3B,YAAY,GACZ;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,IAAI,EAAE,IAAI,CAAA;CAAE,CAAC;AAEpC,wBAAgB,kBAAkB,CAChC,KAAK,EAAE,IAAI,EAAE,EACb,EAAE,EAAE,MAAM,EACV,SAAS,EAAE,OAAO,GACjB,mBAAmB,CAiBrB"}
1
+ {"version":3,"file":"storage_mutations.d.ts","sourceRoot":"","sources":["../../src/lib/storage_mutations.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AACjD,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAEvC,MAAM,WAAW,UAAU;IACzB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACjC,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,QAAQ,CAAC,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC;IAC5B,OAAO,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC7B,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;CACjB;AAED,wBAAgB,qBAAqB,CAAC,EAAE,EAAE,MAAM,GAAG,YAAY,CAQ9D;AAED,MAAM,MAAM,mBAAmB,GAC3B,YAAY,GACZ;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,IAAI,EAAE,IAAI,CAAA;CAAE,CAAC"}
@@ -1,66 +1,8 @@
1
1
  import { createErrorResponse } from './errors.js';
2
- import { normalizeTags } from './storage_filters.js';
3
- function normalizeUpdateTags(updates) {
4
- const normalizedUpdates = { ...updates };
5
- if (normalizedUpdates.tags) {
6
- normalizedUpdates.tags = normalizeTags(normalizedUpdates.tags);
7
- }
8
- return normalizedUpdates;
9
- }
10
- function resolveCompletionUpdate(currentTodo, updates, now) {
11
- const completed = updates.completed ?? currentTodo.completed;
12
- const completedAt = updates.completedAt ??
13
- (updates.completed !== undefined
14
- ? completed
15
- ? now
16
- : undefined
17
- : currentTodo.completedAt);
18
- return { completed, completedAt };
19
- }
20
- function buildUpdatedTodo(currentTodo, updates) {
21
- const now = new Date().toISOString();
22
- const { completed, completedAt } = resolveCompletionUpdate(currentTodo, updates, now);
23
- return {
24
- ...currentTodo,
25
- ...updates,
26
- completed,
27
- completedAt,
28
- updatedAt: now,
29
- };
30
- }
31
- export function updateTodoInList(todos, id, updates) {
32
- const index = todos.findIndex((todo) => todo.id === id);
33
- if (index === -1)
34
- return null;
35
- const currentTodo = todos[index];
36
- if (!currentTodo)
37
- return null;
38
- const normalizedUpdates = normalizeUpdateTags(updates);
39
- const updatedTodo = buildUpdatedTodo(currentTodo, normalizedUpdates);
40
- todos[index] = updatedTodo;
41
- return updatedTodo;
42
- }
43
2
  export function createNotFoundOutcome(id) {
44
3
  return {
45
4
  kind: 'error',
46
5
  response: createErrorResponse('E_NOT_FOUND', `Todo with ID ${id} not found`),
47
6
  };
48
7
  }
49
- export function completeTodoInList(todos, id, completed) {
50
- const currentTodo = todos.find((todo) => todo.id === id);
51
- if (!currentTodo) {
52
- return createNotFoundOutcome(id);
53
- }
54
- if (currentTodo.completed === completed) {
55
- return { kind: 'already', todo: currentTodo };
56
- }
57
- const updatedTodo = updateTodoInList(todos, id, {
58
- completed,
59
- completedAt: completed ? new Date().toISOString() : undefined,
60
- });
61
- if (!updatedTodo) {
62
- return createNotFoundOutcome(id);
63
- }
64
- return { kind: 'match', todo: updatedTodo };
65
- }
66
8
  //# sourceMappingURL=storage_mutations.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"storage_mutations.js","sourceRoot":"","sources":["../../src/lib/storage_mutations.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"storage_mutations.js","sourceRoot":"","sources":["../../src/lib/storage_mutations.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAalD,MAAM,UAAU,qBAAqB,CAAC,EAAU;IAC9C,OAAO;QACL,IAAI,EAAE,OAAO;QACb,QAAQ,EAAE,mBAAmB,CAC3B,aAAa,EACb,gBAAgB,EAAE,YAAY,CAC/B;KACF,CAAC;AACJ,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"storage_state.d.ts","sourceRoot":"","sources":["../../src/lib/storage_state.ts"],"names":[],"mappings":"AAaA,OAAO,EAAE,KAAK,IAAI,EAAe,MAAM,YAAY,CAAC;AAmGpD,wBAAsB,iBAAiB,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC,CAczD;AA+ED,wBAAgB,UAAU,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAOhE;AAED,wBAAsB,aAAa,IAAI,OAAO,CAAC,IAAI,CAAC,CAEnD;AAED,wBAAsB,YAAY,CAAC,KAAK,EAAE,IAAI,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAG/D"}
1
+ {"version":3,"file":"storage_state.d.ts","sourceRoot":"","sources":["../../src/lib/storage_state.ts"],"names":[],"mappings":"AAaA,OAAO,EAAE,KAAK,IAAI,EAAe,MAAM,YAAY,CAAC;AA4HpD,wBAAsB,iBAAiB,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC,CAoBzD;AA+ED,wBAAgB,UAAU,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAOhE;AAED,wBAAsB,aAAa,IAAI,OAAO,CAAC,IAAI,CAAC,CAEnD;AAED,wBAAsB,YAAY,CAAC,KAAK,EAAE,IAAI,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAS/D"}
@@ -8,6 +8,7 @@ const FILE_TIMEOUT_MS = 5000;
8
8
  const FILE_ENCODING = 'utf-8';
9
9
  const TEMP_DIR_PREFIX = '.tmp-';
10
10
  let writeChain = Promise.resolve();
11
+ let todosCache = null;
11
12
  function withTimeout(promise, timeoutMs, label) {
12
13
  let timer;
13
14
  const timeout = new Promise((_, reject) => {
@@ -59,6 +60,25 @@ function parseTodos(rawJson) {
59
60
  }
60
61
  return parsed.data;
61
62
  }
63
+ function getCachedTodos(path, stats) {
64
+ if (!todosCache)
65
+ return null;
66
+ if (todosCache.path !== path)
67
+ return null;
68
+ if (todosCache.mtimeMs !== stats.mtimeMs)
69
+ return null;
70
+ if (todosCache.size !== stats.size)
71
+ return null;
72
+ return todosCache.todos;
73
+ }
74
+ function setTodosCache(path, stats, todos) {
75
+ todosCache = {
76
+ path,
77
+ mtimeMs: stats.mtimeMs,
78
+ size: stats.size,
79
+ todos,
80
+ };
81
+ }
62
82
  async function statTodoFile(path) {
63
83
  try {
64
84
  const stats = await withTimeout(stat(path), FILE_TIMEOUT_MS, 'stat todo file');
@@ -86,12 +106,19 @@ export async function readTodosFromDisk() {
86
106
  try {
87
107
  const stats = await statTodoFile(path);
88
108
  if (!stats) {
109
+ todosCache = null;
89
110
  return [];
90
111
  }
91
- return await readTodosFile(path);
112
+ const cached = getCachedTodos(path, stats);
113
+ if (cached)
114
+ return cached;
115
+ const todos = await readTodosFile(path);
116
+ setTodosCache(path, stats, todos);
117
+ return todos;
92
118
  }
93
119
  catch (error) {
94
120
  if (isFileNotFound(error)) {
121
+ todosCache = null;
95
122
  return [];
96
123
  }
97
124
  throw error;
@@ -142,7 +169,7 @@ async function writeFileAtomically(path, data) {
142
169
  await withTimeout(rm(tempDir, { recursive: true, force: true }), FILE_TIMEOUT_MS, 'cleanup temp dir');
143
170
  }
144
171
  catch {
145
- void 0;
172
+ // Cleanup failure is non-critical
146
173
  }
147
174
  }
148
175
  }
@@ -157,5 +184,12 @@ export async function waitForWrites() {
157
184
  export async function persistTodos(todos) {
158
185
  const path = getTodoFilePath();
159
186
  await writeFileAtomically(path, JSON.stringify(todos, null, 2));
187
+ const stats = await statTodoFile(path);
188
+ if (stats) {
189
+ setTodosCache(path, stats, todos);
190
+ }
191
+ else {
192
+ todosCache = null;
193
+ }
160
194
  }
161
195
  //# sourceMappingURL=storage_state.js.map