@baack-software/baack-ts-tasks 0.0.0-stage → 0.0.1

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 (229) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +158 -2
  3. package/dist/activity.d.ts +20 -0
  4. package/dist/activity.d.ts.map +1 -0
  5. package/dist/activity.js +75 -0
  6. package/dist/activity.js.map +1 -0
  7. package/dist/blockers.d.ts +28 -0
  8. package/dist/blockers.d.ts.map +1 -0
  9. package/dist/blockers.js +134 -0
  10. package/dist/blockers.js.map +1 -0
  11. package/dist/conflicts.d.ts +50 -0
  12. package/dist/conflicts.d.ts.map +1 -0
  13. package/dist/conflicts.js +73 -0
  14. package/dist/conflicts.js.map +1 -0
  15. package/dist/draft.d.ts +45 -0
  16. package/dist/draft.d.ts.map +1 -0
  17. package/dist/draft.js +155 -0
  18. package/dist/draft.js.map +1 -0
  19. package/dist/errors.d.ts +30 -0
  20. package/dist/errors.d.ts.map +1 -0
  21. package/dist/errors.js +37 -0
  22. package/dist/errors.js.map +1 -0
  23. package/dist/index.d.ts +11 -0
  24. package/dist/index.d.ts.map +1 -0
  25. package/dist/index.js +11 -0
  26. package/dist/index.js.map +1 -0
  27. package/dist/react/TaskActivity.d.ts +15 -0
  28. package/dist/react/TaskActivity.d.ts.map +1 -0
  29. package/dist/react/TaskActivity.js +60 -0
  30. package/dist/react/TaskActivity.js.map +1 -0
  31. package/dist/react/TaskBoard.d.ts +38 -0
  32. package/dist/react/TaskBoard.d.ts.map +1 -0
  33. package/dist/react/TaskBoard.js +85 -0
  34. package/dist/react/TaskBoard.js.map +1 -0
  35. package/dist/react/TaskConflicts.d.ts +26 -0
  36. package/dist/react/TaskConflicts.d.ts.map +1 -0
  37. package/dist/react/TaskConflicts.js +87 -0
  38. package/dist/react/TaskConflicts.js.map +1 -0
  39. package/dist/react/TaskCreateForm.d.ts +13 -0
  40. package/dist/react/TaskCreateForm.d.ts.map +1 -0
  41. package/dist/react/TaskCreateForm.js +68 -0
  42. package/dist/react/TaskCreateForm.js.map +1 -0
  43. package/dist/react/TaskEditor.d.ts +33 -0
  44. package/dist/react/TaskEditor.d.ts.map +1 -0
  45. package/dist/react/TaskEditor.js +172 -0
  46. package/dist/react/TaskEditor.js.map +1 -0
  47. package/dist/react/TaskFilters.d.ts +15 -0
  48. package/dist/react/TaskFilters.d.ts.map +1 -0
  49. package/dist/react/TaskFilters.js +48 -0
  50. package/dist/react/TaskFilters.js.map +1 -0
  51. package/dist/react/TaskView.d.ts +30 -0
  52. package/dist/react/TaskView.d.ts.map +1 -0
  53. package/dist/react/TaskView.js +108 -0
  54. package/dist/react/TaskView.js.map +1 -0
  55. package/dist/react/TasksAbout.d.ts +24 -0
  56. package/dist/react/TasksAbout.d.ts.map +1 -0
  57. package/dist/react/TasksAbout.js +82 -0
  58. package/dist/react/TasksAbout.js.map +1 -0
  59. package/dist/react/copy.d.ts +154 -0
  60. package/dist/react/copy.d.ts.map +1 -0
  61. package/dist/react/copy.js +173 -0
  62. package/dist/react/copy.js.map +1 -0
  63. package/dist/react/fields.d.ts +36 -0
  64. package/dist/react/fields.d.ts.map +1 -0
  65. package/dist/react/fields.js +21 -0
  66. package/dist/react/fields.js.map +1 -0
  67. package/dist/react/hooks.d.ts +9 -0
  68. package/dist/react/hooks.d.ts.map +1 -0
  69. package/dist/react/hooks.js +31 -0
  70. package/dist/react/hooks.js.map +1 -0
  71. package/dist/react/index.d.ts +13 -0
  72. package/dist/react/index.d.ts.map +1 -0
  73. package/dist/react/index.js +13 -0
  74. package/dist/react/index.js.map +1 -0
  75. package/dist/react/parts.d.ts +55 -0
  76. package/dist/react/parts.d.ts.map +1 -0
  77. package/dist/react/parts.js +92 -0
  78. package/dist/react/parts.js.map +1 -0
  79. package/dist/react/ui/alert.d.ts +11 -0
  80. package/dist/react/ui/alert.d.ts.map +1 -0
  81. package/dist/react/ui/alert.js +29 -0
  82. package/dist/react/ui/alert.js.map +1 -0
  83. package/dist/react/ui/avatar.d.ts +12 -0
  84. package/dist/react/ui/avatar.d.ts.map +1 -0
  85. package/dist/react/ui/avatar.js +24 -0
  86. package/dist/react/ui/avatar.js.map +1 -0
  87. package/dist/react/ui/badge.d.ts +10 -0
  88. package/dist/react/ui/badge.d.ts.map +1 -0
  89. package/dist/react/ui/badge.js +26 -0
  90. package/dist/react/ui/badge.js.map +1 -0
  91. package/dist/react/ui/button.d.ts +11 -0
  92. package/dist/react/ui/button.d.ts.map +1 -0
  93. package/dist/react/ui/button.js +37 -0
  94. package/dist/react/ui/button.js.map +1 -0
  95. package/dist/react/ui/card.d.ts +12 -0
  96. package/dist/react/ui/card.d.ts.map +1 -0
  97. package/dist/react/ui/card.js +26 -0
  98. package/dist/react/ui/card.js.map +1 -0
  99. package/dist/react/ui/input.d.ts +4 -0
  100. package/dist/react/ui/input.d.ts.map +1 -0
  101. package/dist/react/ui/input.js +8 -0
  102. package/dist/react/ui/input.js.map +1 -0
  103. package/dist/react/ui/label.d.ts +5 -0
  104. package/dist/react/ui/label.d.ts.map +1 -0
  105. package/dist/react/ui/label.js +10 -0
  106. package/dist/react/ui/label.js.map +1 -0
  107. package/dist/react/ui/radio-group.d.ts +6 -0
  108. package/dist/react/ui/radio-group.d.ts.map +1 -0
  109. package/dist/react/ui/radio-group.js +12 -0
  110. package/dist/react/ui/radio-group.js.map +1 -0
  111. package/dist/react/ui/select.d.ts +16 -0
  112. package/dist/react/ui/select.d.ts.map +1 -0
  113. package/dist/react/ui/select.js +37 -0
  114. package/dist/react/ui/select.js.map +1 -0
  115. package/dist/react/ui/separator.d.ts +5 -0
  116. package/dist/react/ui/separator.d.ts.map +1 -0
  117. package/dist/react/ui/separator.js +10 -0
  118. package/dist/react/ui/separator.js.map +1 -0
  119. package/dist/react/ui/sheet.d.ts +15 -0
  120. package/dist/react/ui/sheet.d.ts.map +1 -0
  121. package/dist/react/ui/sheet.js +38 -0
  122. package/dist/react/ui/sheet.js.map +1 -0
  123. package/dist/react/ui/skeleton.d.ts +3 -0
  124. package/dist/react/ui/skeleton.d.ts.map +1 -0
  125. package/dist/react/ui/skeleton.js +7 -0
  126. package/dist/react/ui/skeleton.js.map +1 -0
  127. package/dist/react/ui/table.d.ts +11 -0
  128. package/dist/react/ui/table.d.ts.map +1 -0
  129. package/dist/react/ui/table.js +29 -0
  130. package/dist/react/ui/table.js.map +1 -0
  131. package/dist/react/ui/tabs.d.ts +12 -0
  132. package/dist/react/ui/tabs.d.ts.map +1 -0
  133. package/dist/react/ui/tabs.js +31 -0
  134. package/dist/react/ui/tabs.js.map +1 -0
  135. package/dist/react/ui/textarea.d.ts +4 -0
  136. package/dist/react/ui/textarea.d.ts.map +1 -0
  137. package/dist/react/ui/textarea.js +8 -0
  138. package/dist/react/ui/textarea.js.map +1 -0
  139. package/dist/react/ui/toggle-group.d.ts +11 -0
  140. package/dist/react/ui/toggle-group.d.ts.map +1 -0
  141. package/dist/react/ui/toggle-group.js +25 -0
  142. package/dist/react/ui/toggle-group.js.map +1 -0
  143. package/dist/react/ui/toggle.d.ts +10 -0
  144. package/dist/react/ui/toggle.d.ts.map +1 -0
  145. package/dist/react/ui/toggle.js +27 -0
  146. package/dist/react/ui/toggle.js.map +1 -0
  147. package/dist/refs.d.ts +16 -0
  148. package/dist/refs.d.ts.map +1 -0
  149. package/dist/refs.js +43 -0
  150. package/dist/refs.js.map +1 -0
  151. package/dist/server/index.d.ts +4 -0
  152. package/dist/server/index.d.ts.map +1 -0
  153. package/dist/server/index.js +4 -0
  154. package/dist/server/index.js.map +1 -0
  155. package/dist/server/recipes.d.ts +39 -0
  156. package/dist/server/recipes.d.ts.map +1 -0
  157. package/dist/server/recipes.js +81 -0
  158. package/dist/server/recipes.js.map +1 -0
  159. package/dist/server/webhooks.d.ts +135 -0
  160. package/dist/server/webhooks.d.ts.map +1 -0
  161. package/dist/server/webhooks.js +243 -0
  162. package/dist/server/webhooks.js.map +1 -0
  163. package/dist/store.d.ts +124 -0
  164. package/dist/store.d.ts.map +1 -0
  165. package/dist/store.js +443 -0
  166. package/dist/store.js.map +1 -0
  167. package/dist/task-client.d.ts +137 -0
  168. package/dist/task-client.d.ts.map +1 -0
  169. package/dist/task-client.js +271 -0
  170. package/dist/task-client.js.map +1 -0
  171. package/dist/tasks.d.ts +84 -0
  172. package/dist/tasks.d.ts.map +1 -0
  173. package/dist/tasks.js +208 -0
  174. package/dist/tasks.js.map +1 -0
  175. package/dist/time.d.ts +15 -0
  176. package/dist/time.d.ts.map +1 -0
  177. package/dist/time.js +34 -0
  178. package/dist/time.js.map +1 -0
  179. package/dist/types.d.ts +74 -0
  180. package/dist/types.d.ts.map +1 -0
  181. package/dist/types.js +9 -0
  182. package/dist/types.js.map +1 -0
  183. package/package.json +101 -4
  184. package/src/activity.ts +86 -0
  185. package/src/blockers.ts +134 -0
  186. package/src/conflicts.ts +115 -0
  187. package/src/draft.ts +162 -0
  188. package/src/errors.ts +40 -0
  189. package/src/index.ts +10 -0
  190. package/src/react/TaskActivity.tsx +187 -0
  191. package/src/react/TaskBoard.tsx +264 -0
  192. package/src/react/TaskConflicts.tsx +217 -0
  193. package/src/react/TaskCreateForm.tsx +165 -0
  194. package/src/react/TaskEditor.tsx +485 -0
  195. package/src/react/TaskFilters.tsx +122 -0
  196. package/src/react/TaskView.tsx +291 -0
  197. package/src/react/TasksAbout.tsx +226 -0
  198. package/src/react/copy.tsx +253 -0
  199. package/src/react/fields.tsx +104 -0
  200. package/src/react/hooks.ts +41 -0
  201. package/src/react/index.ts +12 -0
  202. package/src/react/parts.tsx +176 -0
  203. package/src/react/ui/README.md +6 -0
  204. package/src/react/ui/alert.tsx +75 -0
  205. package/src/react/ui/avatar.tsx +109 -0
  206. package/src/react/ui/badge.tsx +48 -0
  207. package/src/react/ui/button.tsx +66 -0
  208. package/src/react/ui/card.tsx +102 -0
  209. package/src/react/ui/input.tsx +18 -0
  210. package/src/react/ui/label.tsx +23 -0
  211. package/src/react/ui/radio-group.tsx +41 -0
  212. package/src/react/ui/select.tsx +189 -0
  213. package/src/react/ui/separator.tsx +27 -0
  214. package/src/react/ui/sheet.tsx +145 -0
  215. package/src/react/ui/skeleton.tsx +13 -0
  216. package/src/react/ui/table.tsx +113 -0
  217. package/src/react/ui/tabs.tsx +89 -0
  218. package/src/react/ui/textarea.tsx +17 -0
  219. package/src/react/ui/toggle-group.tsx +89 -0
  220. package/src/react/ui/toggle.tsx +44 -0
  221. package/src/refs.ts +49 -0
  222. package/src/server/index.ts +3 -0
  223. package/src/server/recipes.ts +107 -0
  224. package/src/server/webhooks.ts +369 -0
  225. package/src/store.ts +538 -0
  226. package/src/task-client.ts +373 -0
  227. package/src/tasks.ts +263 -0
  228. package/src/time.ts +35 -0
  229. package/src/types.ts +101 -0
package/dist/store.js ADDED
@@ -0,0 +1,443 @@
1
+ import { isBaackApiError, } from '@baack-software/baack-ts-client';
2
+ import { openBlockers as openBlockersOf } from "./blockers.js";
3
+ import { applyChanges } from "./draft.js";
4
+ import { TaskConflictError } from "./errors.js";
5
+ import { ref, urnOf, withRef, withoutRef } from "./refs.js";
6
+ import { filterTasks, groupTasks, } from "./tasks.js";
7
+ const EMPTY = {
8
+ status: 'idle',
9
+ tasks: [],
10
+ byUrn: new Map(),
11
+ identities: new Map(),
12
+ projects: new Map(),
13
+ workflows: new Map(),
14
+ saving: new Set(),
15
+ logs: new Map(),
16
+ changedElsewhere: new Map(),
17
+ };
18
+ /**
19
+ * Holds a company's tasks for a UI: loads them, applies changes straight away and rolls them back if the server
20
+ * refuses, and notifies subscribers. `subscribe` and `getState` fit React's `useSyncExternalStore`.
21
+ *
22
+ * ```ts
23
+ * const store = new TaskStore(tasks, { owner: companyUrn, actor: me });
24
+ * store.subscribe(() => render(selectTasks(store.getState(), { assignee: [me], open: true }, byUrgency)));
25
+ * await store.load();
26
+ * await store.setStatus(urn, 'COMPLETED');
27
+ * ```
28
+ */
29
+ export class TaskStore {
30
+ client;
31
+ options;
32
+ #state = EMPTY;
33
+ #listeners = new Set();
34
+ /** Tasks as the server last returned them. */
35
+ #confirmed = new Map();
36
+ #order = [];
37
+ #pending = new Map();
38
+ #nextPatch = 0;
39
+ #timers = new Set();
40
+ #loading;
41
+ constructor(client, options) {
42
+ this.client = client;
43
+ this.options = options;
44
+ }
45
+ getState = () => this.#state;
46
+ subscribe = (listener) => {
47
+ this.#listeners.add(listener);
48
+ return () => this.#listeners.delete(listener);
49
+ };
50
+ /** The task as the reader should see it. */
51
+ get(task) {
52
+ return this.#state.byUrn.get(urnOf(task));
53
+ }
54
+ /** Stops pending work and drops subscribers. */
55
+ dispose() {
56
+ this.#loading?.abort();
57
+ this.#timers.forEach(clearTimeout);
58
+ this.#timers.clear();
59
+ this.#listeners.clear();
60
+ }
61
+ // ==========================================
62
+ // LOADING
63
+ // ==========================================
64
+ /** Loads (or reloads) every task. A load already running is cancelled. Pending changes stay applied. */
65
+ async load() {
66
+ this.#loading?.abort();
67
+ const controller = new AbortController();
68
+ this.#loading = controller;
69
+ this.#publish({ status: 'loading' });
70
+ try {
71
+ const [listing, workflows] = await Promise.all([
72
+ this.client.list({
73
+ owner: this.options.owner,
74
+ includeRelated: this.options.includeRelated ?? true,
75
+ signal: controller.signal,
76
+ }),
77
+ Promise.all((this.options.workflows ?? []).map((workflow) => this.client.getWorkflow(workflow).catch(() => undefined))),
78
+ ]);
79
+ if (controller.signal.aborted)
80
+ return;
81
+ this.#confirmed.clear();
82
+ for (const task of listing.tasks)
83
+ this.#confirmed.set(task.urn, task);
84
+ this.#order = listing.tasks.map((task) => task.urn);
85
+ this.#publish({
86
+ status: 'ready',
87
+ error: undefined,
88
+ identities: new Map(listing.identities.map((item) => [item.urn, item])),
89
+ projects: new Map(listing.projects.map((item) => [item.urn, item])),
90
+ workflows: new Map(workflows.filter((w) => w !== undefined).map((workflow) => [workflow.urn, workflow])),
91
+ });
92
+ }
93
+ catch (error) {
94
+ if (controller.signal.aborted)
95
+ return;
96
+ this.#publish({ status: 'error', error });
97
+ throw error;
98
+ }
99
+ finally {
100
+ if (this.#loading === controller)
101
+ this.#loading = undefined;
102
+ }
103
+ }
104
+ /** Reads one task again. Removes it when it no longer exists. */
105
+ async reload(task) {
106
+ const urn = urnOf(task);
107
+ try {
108
+ const fresh = await this.client.get(urn);
109
+ this.#confirm(fresh);
110
+ this.#publish();
111
+ return fresh;
112
+ }
113
+ catch (error) {
114
+ if (isBaackApiError(error) && error.isNotFound) {
115
+ this.#forget(urn);
116
+ this.#publish();
117
+ return undefined;
118
+ }
119
+ throw error;
120
+ }
121
+ }
122
+ // ==========================================
123
+ // CHANGES
124
+ // ==========================================
125
+ async create(input, options = {}) {
126
+ const created = await this.client.create({ owner: this.options.owner, ...input }, this.#changeOptions(options));
127
+ this.#confirm(created, true);
128
+ this.#publish();
129
+ this.#settle([created.urn]);
130
+ return created;
131
+ }
132
+ /**
133
+ * Shows `changes` at once and sends them. On success the server's task replaces the shown one; on failure the
134
+ * change is rolled back and the error rethrown.
135
+ *
136
+ * The change is checked against the task as shown when it was made. If someone else changed one of the same fields
137
+ * since, it throws `TaskConflictError`, saves nothing and shows the task as it is now; resolve the conflict with
138
+ * `resolveConflicts` and update again. Other fields they changed are kept and listed in `changedElsewhere`.
139
+ */
140
+ async update(task, changes, options = {}) {
141
+ const urn = urnOf(task);
142
+ const before = this.get(urn);
143
+ const id = this.#addPatch(urn, { changes });
144
+ try {
145
+ const result = (await this.client.update(before ?? urn, changes, {
146
+ ...this.#changeOptions(options),
147
+ base: before,
148
+ onChangedElsewhere: (fields) => this.#noteChangedElsewhere(urn, fields),
149
+ }));
150
+ const saved = result ?? (await this.client.get(urn));
151
+ this.#confirm(saved);
152
+ this.#removePatch(urn, id);
153
+ this.#settle([urn, ...changedBlockers(before, changes)]);
154
+ return saved;
155
+ }
156
+ catch (error) {
157
+ if (error instanceof TaskConflictError)
158
+ this.#confirm(error.current);
159
+ this.#removePatch(urn, id);
160
+ throw error;
161
+ }
162
+ }
163
+ /** Clears the note of fields someone else changed on the task. */
164
+ dismissChangedElsewhere(task) {
165
+ const urn = urnOf(task);
166
+ if (!this.#state.changedElsewhere.has(urn))
167
+ return;
168
+ const changedElsewhere = new Map(this.#state.changedElsewhere);
169
+ changedElsewhere.delete(urn);
170
+ this.#publish({ changedElsewhere });
171
+ }
172
+ async delete(task) {
173
+ const urn = urnOf(task);
174
+ const id = this.#addPatch(urn, { deleted: true });
175
+ try {
176
+ await this.client.delete(urn);
177
+ const blockers = changedBlockers(this.#confirmed.get(urn), { blockedBy: [], blocking: [] });
178
+ this.#forget(urn);
179
+ this.#removePatch(urn, id);
180
+ this.#settle(blockers);
181
+ }
182
+ catch (error) {
183
+ this.#removePatch(urn, id);
184
+ throw error;
185
+ }
186
+ }
187
+ setStatus(task, status, options) {
188
+ return this.update(task, { status }, options);
189
+ }
190
+ setPriority(task, priority, options) {
191
+ return this.update(task, { priority }, options);
192
+ }
193
+ assign(task, assignee, options) {
194
+ return this.update(task, { assignee: assignee === null ? null : ref(assignee) }, options);
195
+ }
196
+ setDue(task, dueTimestamp, options) {
197
+ return this.update(task, { dueTimestamp }, options);
198
+ }
199
+ setProject(task, project, options) {
200
+ return this.update(task, { project: project === null ? null : ref(project) }, options);
201
+ }
202
+ setWorkflowStage(task, stage, options) {
203
+ return this.update(task, { workflowStage: stage === null ? null : ref(stage) }, options);
204
+ }
205
+ addBlocker(task, blocker, options) {
206
+ return this.addTo(task, 'blockedBy', blocker, options);
207
+ }
208
+ removeBlocker(task, blocker, options) {
209
+ return this.removeFrom(task, 'blockedBy', blocker, options);
210
+ }
211
+ /** Adds a reference to one of the task's lists, building on pending changes. */
212
+ addTo(task, field, value, options) {
213
+ return this.update(task, { [field]: withRef(this.#require(task)[field], value) }, options);
214
+ }
215
+ /** Removes a reference from one of the task's lists, building on pending changes. */
216
+ removeFrom(task, field, value, options) {
217
+ return this.update(task, { [field]: withoutRef(this.#require(task)[field], value) }, options);
218
+ }
219
+ // ==========================================
220
+ // ACTIVITY LOG
221
+ // ==========================================
222
+ /** Loads the newest page of the task's log, replacing what was loaded. */
223
+ async loadLogs(task) {
224
+ const urn = urnOf(task);
225
+ this.#setLogs(urn, { ...this.#logState(urn), status: 'loading' });
226
+ try {
227
+ const page = await this.client.logs(urn);
228
+ this.#setLogs(urn, { status: 'ready', logs: page.logs, ...afterOf(page.pagination) });
229
+ }
230
+ catch (error) {
231
+ this.#setLogs(urn, { ...this.#logState(urn), status: 'error', error });
232
+ throw error;
233
+ }
234
+ }
235
+ /** Loads the next older page of the task's log, if there is one. */
236
+ async loadMoreLogs(task) {
237
+ const urn = urnOf(task);
238
+ const current = this.#logState(urn);
239
+ if (current.after === undefined)
240
+ return;
241
+ this.#setLogs(urn, { ...current, status: 'loading' });
242
+ try {
243
+ const page = await this.client.logs(urn, { after: current.after });
244
+ this.#setLogs(urn, {
245
+ status: 'ready',
246
+ logs: mergeLogs(current.logs, page.logs),
247
+ ...afterOf(page.pagination),
248
+ });
249
+ }
250
+ catch (error) {
251
+ this.#setLogs(urn, { ...current, status: 'error', error });
252
+ throw error;
253
+ }
254
+ }
255
+ /** Adds a comment and shows it at the top of the task's log. */
256
+ async comment(task, text, options = {}) {
257
+ const urn = urnOf(task);
258
+ const actor = options.actor ?? this.options.actor;
259
+ const log = await this.client.comment(urn, text, {
260
+ ...(actor === undefined ? {} : { actor }),
261
+ ...(options.replyTo === undefined ? {} : { replyTo: options.replyTo }),
262
+ });
263
+ const current = this.#state.logs.get(urn);
264
+ if (current)
265
+ this.#setLogs(urn, { ...current, logs: mergeLogs([log], current.logs) });
266
+ this.#settle([urn]);
267
+ return log;
268
+ }
269
+ // ==========================================
270
+ // INTERNALS
271
+ // ==========================================
272
+ #changeOptions(options) {
273
+ const actor = options.actor ?? this.options.actor;
274
+ return actor === undefined ? {} : { actor };
275
+ }
276
+ #require(task) {
277
+ const found = this.get(task);
278
+ if (!found)
279
+ throw new Error(`Task ${urnOf(task)} is not in the store`);
280
+ return found;
281
+ }
282
+ #confirm(task, first = false) {
283
+ this.#confirmed.set(task.urn, task);
284
+ if (!this.#order.includes(task.urn))
285
+ this.#order = first ? [task.urn, ...this.#order] : [...this.#order, task.urn];
286
+ }
287
+ #forget(urn) {
288
+ this.#confirmed.delete(urn);
289
+ this.#order = this.#order.filter((candidate) => candidate !== urn);
290
+ if (this.#state.logs.has(urn)) {
291
+ const logs = new Map(this.#state.logs);
292
+ logs.delete(urn);
293
+ this.#state = { ...this.#state, logs };
294
+ }
295
+ }
296
+ #addPatch(urn, patch) {
297
+ const id = this.#nextPatch++;
298
+ this.#pending.set(urn, [...(this.#pending.get(urn) ?? []), { id, ...patch }]);
299
+ this.#publish();
300
+ return id;
301
+ }
302
+ #removePatch(urn, id) {
303
+ const remaining = (this.#pending.get(urn) ?? []).filter((patch) => patch.id !== id);
304
+ if (remaining.length > 0)
305
+ this.#pending.set(urn, remaining);
306
+ else
307
+ this.#pending.delete(urn);
308
+ this.#publish();
309
+ }
310
+ #noteChangedElsewhere(urn, fields) {
311
+ const noted = new Set([...(this.#state.changedElsewhere.get(urn) ?? []), ...fields]);
312
+ this.#state = { ...this.#state, changedElsewhere: new Map(this.#state.changedElsewhere).set(urn, [...noted]) };
313
+ }
314
+ #logState(urn) {
315
+ return this.#state.logs.get(urn) ?? { status: 'idle', logs: [] };
316
+ }
317
+ #setLogs(urn, state) {
318
+ this.#publish({ logs: new Map(this.#state.logs).set(urn, state) });
319
+ }
320
+ /** Reads the given tasks (and their loaded logs) again once the server has had time to settle. */
321
+ #settle(urns) {
322
+ const settleMs = this.options.settleMs ?? 500;
323
+ if (settleMs <= 0)
324
+ return;
325
+ const timer = setTimeout(() => {
326
+ this.#timers.delete(timer);
327
+ for (const urn of new Set(urns)) {
328
+ if (!this.#confirmed.has(urn))
329
+ continue;
330
+ this.reload(urn).catch(() => undefined);
331
+ if (this.#state.logs.get(urn)?.status === 'ready')
332
+ this.#refreshLogs(urn).catch(() => undefined);
333
+ }
334
+ }, settleMs);
335
+ this.#timers.add(timer);
336
+ }
337
+ /** Reads the newest page of a log and merges it in, keeping older pages already loaded. */
338
+ async #refreshLogs(urn) {
339
+ const page = await this.client.logs(urn);
340
+ const current = this.#logState(urn);
341
+ this.#setLogs(urn, { ...current, logs: mergeLogs(page.logs, current.logs) });
342
+ }
343
+ #publish(changes = {}) {
344
+ const tasks = [];
345
+ const byUrn = new Map();
346
+ const saving = new Set();
347
+ for (const urn of this.#order) {
348
+ let task = this.#confirmed.get(urn);
349
+ const patches = this.#pending.get(urn) ?? [];
350
+ if (patches.length > 0)
351
+ saving.add(urn);
352
+ for (const patch of patches) {
353
+ if (!task)
354
+ break;
355
+ task = 'deleted' in patch ? undefined : this.#withNames(applyChanges(task, patch.changes));
356
+ }
357
+ if (task) {
358
+ tasks.push(task);
359
+ byUrn.set(urn, task);
360
+ }
361
+ }
362
+ for (const urn of this.#pending.keys())
363
+ saving.add(urn);
364
+ this.#state = { ...this.#state, ...changes, tasks, byUrn, saving };
365
+ this.#listeners.forEach((listener) => listener());
366
+ }
367
+ /** Fills in names for an assignee or project set by URN, from the identities and projects loaded. */
368
+ #withNames(task) {
369
+ const result = { ...task };
370
+ const assignee = task.assignee && this.#state.identities.get(task.assignee.urn);
371
+ if (task.assignee && assignee && task.assignee.name == null) {
372
+ result.assignee = { ...task.assignee, name: assignee.name ?? null };
373
+ }
374
+ const project = task.project && this.#state.projects.get(task.project.urn);
375
+ if (task.project && project && task.project.name == null) {
376
+ result.project = { ...task.project, name: project.name ?? '' };
377
+ }
378
+ return result;
379
+ }
380
+ }
381
+ // ==========================================
382
+ // SELECTORS
383
+ // ==========================================
384
+ /** Tasks matching `filter`, sorted when a comparator is given. */
385
+ export function selectTasks(state, filter = {}, sort) {
386
+ const tasks = filterTasks(state.tasks, filter);
387
+ return sort ? tasks.sort(sort) : tasks;
388
+ }
389
+ /** Tasks matching `filter`, grouped for a board, each group sorted when a comparator is given. */
390
+ export function selectGroups(state, by, filter = {}, sort) {
391
+ const groups = groupTasks(filterTasks(state.tasks, filter), by);
392
+ if (sort)
393
+ groups.forEach((group) => group.sort(sort));
394
+ return groups;
395
+ }
396
+ /** The display name of an identity, project, task or workflow stage, falling back to the end of its URN. */
397
+ export function selectName(state, item) {
398
+ const urn = urnOf(item);
399
+ return (state.identities.get(urn)?.name ??
400
+ state.projects.get(urn)?.name ??
401
+ state.byUrn.get(urn)?.title ??
402
+ stageName(state.workflows.values(), urn) ??
403
+ (typeof item === 'object' && 'name' in item && typeof item.name === 'string' ? item.name : undefined) ??
404
+ urn.slice(-6));
405
+ }
406
+ /** The name of a stage in one of `workflows`. */
407
+ function stageName(workflows, urn) {
408
+ for (const workflow of workflows) {
409
+ const stage = workflow.stages?.find((s) => s.urn === urn);
410
+ if (stage)
411
+ return stage.name;
412
+ }
413
+ return undefined;
414
+ }
415
+ /** The URNs of the open tasks blocking `task`, by the store's tasks. */
416
+ export function selectOpenBlockers(state, task) {
417
+ return openBlockersOf(task, (urn) => state.byUrn.get(urn));
418
+ }
419
+ function changedBlockers(before, changes) {
420
+ const urns = [];
421
+ for (const field of ['blockedBy', 'blocking']) {
422
+ const after = changes[field];
423
+ if (after === undefined)
424
+ continue;
425
+ const old = new Set((before?.[field] ?? []).map(urnOf));
426
+ const next = new Set(after.map(urnOf));
427
+ for (const urn of old)
428
+ if (!next.has(urn))
429
+ urns.push(urn);
430
+ for (const urn of next)
431
+ if (!old.has(urn))
432
+ urns.push(urn);
433
+ }
434
+ return urns;
435
+ }
436
+ function mergeLogs(newer, older) {
437
+ const seen = new Set(newer.map((log) => log.urn));
438
+ return [...newer, ...older.filter((log) => !seen.has(log.urn))];
439
+ }
440
+ function afterOf(pagination) {
441
+ return pagination?.isMorePages && pagination.after ? { after: pagination.after } : {};
442
+ }
443
+ //# sourceMappingURL=store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"store.js","sourceRoot":"","sources":["../src/store.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,137 @@
1
+ import { type BaackClient, type IncludeScope, type SearchItem, type Task, type TaskLog, type TaskPriority, type TaskStatus, type Workflow } from '@baack-software/baack-ts-client';
2
+ import { type DraftInput } from './draft.ts';
3
+ import { type TaskField } from './conflicts.ts';
4
+ import { type RefLike, type TaskDraft, type TaskInput, type TaskListField, type TaskLogPage } from './types.ts';
5
+ /** Options for a change: who made it, for the activity log. */
6
+ export interface ChangeOptions {
7
+ /** The identity the change is attributed to in the activity log. It does not assign the task. */
8
+ actor?: RefLike;
9
+ }
10
+ export interface UpdateOptions extends ChangeOptions {
11
+ /**
12
+ * The task as the person saw it when they made the change, usually the copy the editor shows. When given, the update
13
+ * is checked against it: if someone else changed a field this update also changes, it throws `TaskConflictError`
14
+ * and saves nothing; list changes are applied as additions and removals to the lists as they are now.
15
+ */
16
+ base?: Task | undefined;
17
+ /** Told which fields someone else changed since `base` that this update leaves as they are. */
18
+ onChangedElsewhere?: ((fields: (TaskField | TaskListField)[], current: Task) => void) | undefined;
19
+ }
20
+ export interface CommentOptions {
21
+ /** The identity making the comment. */
22
+ actor?: RefLike;
23
+ /** The log entry this comment replies to. */
24
+ replyTo?: RefLike;
25
+ }
26
+ export interface PollOptions {
27
+ /** First wait between reads of a running search. Default 250 ms. */
28
+ intervalMs?: number;
29
+ /** Longest wait between reads; waits grow by half each time up to this. Default 2000 ms. */
30
+ maxIntervalMs?: number;
31
+ /** Give up with `TaskSearchTimeoutError` after this long. Default 30000 ms. */
32
+ timeoutMs?: number;
33
+ }
34
+ export interface ListOptions {
35
+ /** The company whose tasks to list. */
36
+ owner: RefLike;
37
+ /**
38
+ * Also return the identities and projects the reader can see, for assignee and project pickers and names.
39
+ * Default true. Turn off for readers without access to them.
40
+ */
41
+ includeRelated?: boolean;
42
+ /** How many tasks to read at once. Default 6. */
43
+ concurrency?: number;
44
+ poll?: PollOptions;
45
+ /** Stops polling and reading. A request already sent still completes. */
46
+ signal?: AbortSignal;
47
+ }
48
+ export interface TaskListing {
49
+ /** The tasks, in the search's order. Tasks deleted between the search and the read are left out. */
50
+ tasks: Task[];
51
+ /** Identities seen by the search, with their names. Empty when `includeRelated` is false. */
52
+ identities: SearchItem[];
53
+ /** Projects seen by the search, with their names. Empty when `includeRelated` is false. */
54
+ projects: SearchItem[];
55
+ }
56
+ /**
57
+ * Typed access to Baack tasks and their activity logs, on top of a `BaackClient` that holds the base URL and
58
+ * credentials.
59
+ *
60
+ * ```ts
61
+ * const tasks = new TaskClient(new BaackClient({ baseUrl: 'https://api.baack.co', credentials: 'include' }));
62
+ * const { tasks: all } = await tasks.list({ owner: companyUrn });
63
+ * await tasks.setStatus(all[0], 'IN_PROGRESS', { actor: me });
64
+ * ```
65
+ */
66
+ export declare class TaskClient {
67
+ #private;
68
+ readonly client: BaackClient;
69
+ constructor(client: BaackClient);
70
+ get(task: RefLike): Promise<Task>;
71
+ /** Reads a workflow: its name and its stages, which tasks move through. */
72
+ getWorkflow(workflow: RefLike): Promise<Workflow>;
73
+ /**
74
+ * Creates a task. Accepts a full `TaskDraft`, or the owner and title plus any other fields, which `draft` fills in.
75
+ * Throws `TaskValidationError` before sending when the task breaks the API's rules.
76
+ */
77
+ create(input: TaskDraft | DraftInput, options?: ChangeOptions): Promise<Task>;
78
+ /**
79
+ * Changes the task. The API stores the task as an update sends it, clearing optional fields left out, so this reads
80
+ * the task, applies `changes` and sends it whole (see `updateBody`). Lists are sent whole and the server applies the
81
+ * difference. Updates to the same task from this client run one at a time, so each builds on the last.
82
+ *
83
+ * `changes` can be a function of the task as just read, for changes built from its current state, such as adding
84
+ * to a list.
85
+ *
86
+ * Throws `TaskValidationError` before sending when the changes break the API's rules. Returns the task as the
87
+ * server has it after the change.
88
+ *
89
+ * The `BaackClient`'s `failureGuard` applies: retrying a failed update before its backoff has passed fails at once
90
+ * with the same error, sending nothing.
91
+ */
92
+ update(task: RefLike, changes: TaskInput | ((current: Task) => TaskInput), options?: UpdateOptions): Promise<Task>;
93
+ delete(task: RefLike): Promise<void>;
94
+ setStatus(task: RefLike, status: TaskStatus, options?: ChangeOptions): Promise<Task>;
95
+ setPriority(task: RefLike, priority: TaskPriority, options?: ChangeOptions): Promise<Task>;
96
+ /** Assigns the task to `assignee`, or unassigns it with `null`. */
97
+ assign(task: RefLike, assignee: RefLike | null, options?: ChangeOptions): Promise<Task>;
98
+ /** Sets the due date (a Baack timestamp, see `toTimestamp`), or removes it with `null`. */
99
+ setDue(task: RefLike, dueTimestamp: string | null, options?: ChangeOptions): Promise<Task>;
100
+ /** Moves the task into `project`, or out of its project with `null`. */
101
+ setProject(task: RefLike, project: RefLike | null, options?: ChangeOptions): Promise<Task>;
102
+ /** Moves the task to a workflow stage, or out of its stage with `null`. */
103
+ setWorkflowStage(task: RefLike, stage: RefLike | null, options?: ChangeOptions): Promise<Task>;
104
+ /** Marks `blocker` as blocking `task`. */
105
+ addBlocker(task: RefLike, blocker: RefLike, options?: ChangeOptions): Promise<Task>;
106
+ removeBlocker(task: RefLike, blocker: RefLike, options?: ChangeOptions): Promise<Task>;
107
+ /** Adds a reference to one of the task's lists, as the server has the list when the update is sent. */
108
+ addTo(task: RefLike, field: TaskListField, value: RefLike, options?: ChangeOptions): Promise<Task>;
109
+ /** Removes a reference from one of the task's lists, as the server has the list when the update is sent. */
110
+ removeFrom(task: RefLike, field: TaskListField, value: RefLike, options?: ChangeOptions): Promise<Task>;
111
+ /** One page of the task's activity log, newest first. Pass `pagination.after` from a page to read the next. */
112
+ logs(task: RefLike, options?: {
113
+ after?: string;
114
+ }): Promise<TaskLogPage>;
115
+ /** The task's activity log across pages, newest first, stopping after `limit` entries when given. */
116
+ allLogs(task: RefLike, options?: {
117
+ limit?: number;
118
+ }): Promise<TaskLog[]>;
119
+ /** Adds a comment to the task's activity log. */
120
+ comment(task: RefLike, comment: string, options?: CommentOptions): Promise<TaskLog>;
121
+ /**
122
+ * Lists a company's tasks. Runs a search, waits for its full result, follows its pages, then
123
+ * reads each task (search results don't carry the task itself yet).
124
+ */
125
+ list(options: ListOptions): Promise<TaskListing>;
126
+ /**
127
+ * Runs a search and returns every item once the result is full, across pages. Exposed for callers that want other
128
+ * scopes alongside tasks.
129
+ */
130
+ search(query: {
131
+ owner: RefLike;
132
+ scopes: IncludeScope[];
133
+ }, options?: PollOptions & {
134
+ signal?: AbortSignal;
135
+ }): Promise<SearchItem[]>;
136
+ }
137
+ //# sourceMappingURL=task-client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"task-client.d.ts","sourceRoot":"","sources":["../src/task-client.ts"],"names":[],"mappings":"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"}