@crimson-education/sdk 0.2.3 → 0.2.5

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/README.md CHANGED
@@ -116,11 +116,13 @@ const page = await client.missions.listPaginated("student-uid", undefined, {
116
116
  涉及接口:
117
117
 
118
118
  - `GET /roadmap/action-items`
119
+ - `GET /roadmap/action-items/creators`
119
120
  - `POST /roadmap/action-items`
120
121
  - `PUT /roadmap/action-items/:id`
121
122
  - `DELETE /roadmap/action-items/:id`
122
123
  - `POST /roadmap/action-items/:actionItemId/resources`
123
124
  - `POST /roadmap/upload`
125
+ - `GET /roadmap/download`
124
126
 
125
127
  主要方法:
126
128
 
@@ -138,6 +140,10 @@ const page = await client.missions.listPaginated("student-uid", undefined, {
138
140
  - 当 **同时提供** `roadmapId` 且提供 `start/limit` 时:返回 `PaginatedResult<Task>`
139
141
  - `listPaginated(roadmapId, userId, filters?, pagination?)`
140
142
  - 始终返回 `PaginatedResult<Task>`(内部复用 `list`)
143
+ - `getCreators(roadmapId)`
144
+ - 获取指定 roadmap 下所有任务的创建者列表
145
+ - `getDownloadUrl(key)`
146
+ - 获取 S3 资源的预签名下载 URL
141
147
  - `create(data: Partial<Task>)`
142
148
  - 支持两种模式:
143
149
  - Mission 关联任务:提供 `roadmapMissionId`(或 `missionId`)
@@ -203,6 +209,8 @@ SDK 会将后端返回的 action item 做归一化,保证至少返回以下核
203
209
  涉及接口:
204
210
 
205
211
  - `GET /roadmap/library/missions`
212
+ - `POST /roadmap/library/missions`
213
+ - `PUT /roadmap/library/missions/:missionId`
206
214
  - `GET /roadmap/library/tasks`
207
215
  - `POST /roadmap/library/missions/copy`
208
216
  - `POST /roadmap/library/missions/assign-bulk`
@@ -213,6 +221,8 @@ SDK 会将后端返回的 action item 做归一化,保证至少返回以下核
213
221
  主要方法:
214
222
 
215
223
  - `listTemplateMissions(filters?: TemplateMissionFilters): Promise<PaginatedResult<TemplateMission>>`
224
+ - `createTemplateMission(input: TemplateMissionCreateInput): Promise<TemplateMission>`
225
+ - `updateTemplateMission(id: string, raw: TemplateMission, update: TemplateMissionUpdateInput): Promise<TemplateMission>`
216
226
  - `listTemplateTasks(filters?: TemplateTaskFilters): Promise<PaginatedResult<TemplateTask>>`
217
227
  - `copyTemplateMission(input: CopyTemplateMissionInput): Promise<TemplateMission[]>`
218
228
  - `assignBulkMission(input: AssignBulkMissionInput[]): Promise<{ code: number; msg?: string }>`
@@ -314,9 +324,16 @@ Props:
314
324
  - `useTasks(missionId, enabled)`:拉取某 mission 的 tasks
315
325
  - `useTasksInfinite(roadmapId, userId, filters?, options?)`:分页拉取 tasks
316
326
  - `useRoadmapContext(userId, enabled)`:拉取 roadmap context
327
+ - `useTaskCreators(roadmapId, enabled)`:获取任务创建者列表
317
328
  - CRUD mutation:
318
329
  - `useCreateMission/useUpdateMission/useDeleteMission`
319
330
  - `useCreateTask/useUpdateTask/useDeleteTask`
331
+ - `useCreateTemplateMission/useUpdateTemplateMission`
332
+ - `useGetDownloadUrl`:获取文件下载地址
333
+ - 模板库相关:
334
+ - `useTemplateMissions/useTemplateMissionsInfinite`
335
+ - `useTemplateTasks/useTemplateTasksInfinite`
336
+ - `useTemplateMissionDetail(missionId)`
320
337
 
321
338
  ---
322
339
 
@@ -39,6 +39,17 @@ export interface CreateFromPredefinedInput {
39
39
  missionId: string;
40
40
  predefinedTaskIds: string[];
41
41
  }
42
+ export interface TemplateMissionCreateInput {
43
+ title: string;
44
+ description: string;
45
+ category: string;
46
+ subcategory: string;
47
+ tasks: {
48
+ id?: string | null;
49
+ description: string;
50
+ content: string;
51
+ }[];
52
+ }
42
53
  export declare class MissionLibraryApi {
43
54
  private client;
44
55
  constructor(client: CrimsonClient);
@@ -46,6 +57,14 @@ export declare class MissionLibraryApi {
46
57
  * List template missions with pagination
47
58
  */
48
59
  listTemplateMissions(filters?: TemplateMissionFilters): Promise<PaginatedResult<TemplateMission>>;
60
+ /**
61
+ * Create a new template mission
62
+ */
63
+ createTemplateMission(input: TemplateMissionCreateInput): Promise<TemplateMission>;
64
+ /**
65
+ * Delete a template mission
66
+ */
67
+ deleteTemplateMission(id: string): Promise<void>;
49
68
  /**
50
69
  * List template tasks with pagination
51
70
  */
@@ -49,6 +49,27 @@ class MissionLibraryApi {
49
49
  return this.client.fetch(path);
50
50
  });
51
51
  }
52
+ /**
53
+ * Create a new template mission
54
+ */
55
+ createTemplateMission(input) {
56
+ return __awaiter(this, void 0, void 0, function* () {
57
+ return this.client.fetch("/roadmap/library/missions", {
58
+ method: "POST",
59
+ body: JSON.stringify(Object.assign(Object.assign({}, input), { type: "custom" })),
60
+ });
61
+ });
62
+ }
63
+ /**
64
+ * Delete a template mission
65
+ */
66
+ deleteTemplateMission(id) {
67
+ return __awaiter(this, void 0, void 0, function* () {
68
+ return this.client.fetch(`/roadmap/library/missions/${id}`, {
69
+ method: "DELETE",
70
+ });
71
+ });
72
+ }
52
73
  /**
53
74
  * List template tasks with pagination
54
75
  */
@@ -1,5 +1,5 @@
1
1
  import type { CrimsonClient } from "./client";
2
- import type { Task, PaginationParams, PaginatedResult, ActionItemResource, AddResourceInput, UploadUrlResponse, UpdateTaskResourceInput } from "./types";
2
+ import type { Task, PaginationParams, PaginatedResult, ActionItemResource, AddResourceInput, UploadUrlResponse, DownloadUrlResponse, UpdateTaskResourceInput, User } from "./types";
3
3
  export type TaskOrderBy = "priority" | "dueDate" | "missionTitle" | "createdAt" | "description";
4
4
  export interface TaskFilters extends PaginationParams {
5
5
  status?: string[];
@@ -28,6 +28,10 @@ export declare class TasksApi {
28
28
  * List tasks with pagination (requires roadmapId, always returns paginated result)
29
29
  */
30
30
  listPaginated(roadmapId: string, userId: string, filters?: Omit<TaskFilters, "start" | "limit">, pagination?: PaginationParams): Promise<PaginatedResult<Task>>;
31
+ /**
32
+ * Get all creators of tasks in a roadmap
33
+ */
34
+ getCreators(roadmapId: string): Promise<User[]>;
31
35
  /**
32
36
  * Create a new task/action item
33
37
  *
@@ -53,6 +57,24 @@ export declare class TasksApi {
53
57
  createStandalone(roadmapId: string, data: Omit<Partial<Task>, "roadmapMissionId" | "missionId">): Promise<Task>;
54
58
  update(id: string, data: Partial<Task>): Promise<Task>;
55
59
  delete(id: string): Promise<void>;
60
+ /**
61
+ * Bulk delete tasks
62
+ * @param ids - Array of task IDs to delete
63
+ */
64
+ bulkDelete(ids: string[]): Promise<{
65
+ deleted: string[];
66
+ }>;
67
+ /**
68
+ * Bulk update tasks
69
+ * @param ids - Array of task IDs to update
70
+ * @param data - Update data (dueDate, status)
71
+ */
72
+ bulkUpdate(ids: string[], data: {
73
+ dueDate?: string | null;
74
+ status?: string;
75
+ }): Promise<{
76
+ updated: any[];
77
+ }>;
56
78
  /**
57
79
  * Add resources to an action item
58
80
  * @param actionItemId - The ID of the action item
@@ -92,6 +114,13 @@ export declare class TasksApi {
92
114
  * await tasks.updateResources(taskId, [{ title: "Document", type: "Upload", url }]);
93
115
  */
94
116
  getUploadUrl(filename: string, contentType: string): Promise<UploadUrlResponse>;
117
+ /**
118
+ * Get a presigned URL for downloading a file from S3
119
+ *
120
+ * @param key - The S3 object key
121
+ * @returns Promise with url (presigned download URL)
122
+ */
123
+ getDownloadUrl(key: string): Promise<DownloadUrlResponse>;
95
124
  /**
96
125
  * Upload a file and get the S3 URL
97
126
  *
@@ -149,6 +149,12 @@ class TasksApi {
149
149
  var _a, _b;
150
150
  return this.list({ roadmapId, userId }, Object.assign(Object.assign({}, filters), { start: (_a = pagination === null || pagination === void 0 ? void 0 : pagination.start) !== null && _a !== void 0 ? _a : 0, limit: (_b = pagination === null || pagination === void 0 ? void 0 : pagination.limit) !== null && _b !== void 0 ? _b : 20 }));
151
151
  }
152
+ /**
153
+ * Get all creators of tasks in a roadmap
154
+ */
155
+ getCreators(roadmapId) {
156
+ return this.client.fetch(`/roadmap/action-items/creators?roadmapId=${roadmapId}`);
157
+ }
152
158
  /**
153
159
  * Create a new task/action item
154
160
  *
@@ -194,6 +200,27 @@ class TasksApi {
194
200
  method: "DELETE",
195
201
  });
196
202
  }
203
+ /**
204
+ * Bulk delete tasks
205
+ * @param ids - Array of task IDs to delete
206
+ */
207
+ bulkDelete(ids) {
208
+ return this.client.fetch("/roadmap/action-items/bulk-delete", {
209
+ method: "POST",
210
+ body: JSON.stringify({ ids }),
211
+ });
212
+ }
213
+ /**
214
+ * Bulk update tasks
215
+ * @param ids - Array of task IDs to update
216
+ * @param data - Update data (dueDate, status)
217
+ */
218
+ bulkUpdate(ids, data) {
219
+ return this.client.fetch("/roadmap/action-items/bulk-update", {
220
+ method: "POST",
221
+ body: JSON.stringify({ ids, data }),
222
+ });
223
+ }
197
224
  /**
198
225
  * Add resources to an action item
199
226
  * @param actionItemId - The ID of the action item
@@ -246,6 +273,17 @@ class TasksApi {
246
273
  body: JSON.stringify({ filename, contentType }),
247
274
  });
248
275
  }
276
+ /**
277
+ * Get a presigned URL for downloading a file from S3
278
+ *
279
+ * @param key - The S3 object key
280
+ * @returns Promise with url (presigned download URL)
281
+ */
282
+ getDownloadUrl(key) {
283
+ return this.client.fetch(`/roadmap/download?key=${encodeURIComponent(key)}`, {
284
+ method: "GET",
285
+ });
286
+ }
249
287
  /**
250
288
  * Upload a file and get the S3 URL
251
289
  *
@@ -297,6 +297,10 @@ export interface UploadUrlResponse {
297
297
  /** S3 bucket name */
298
298
  bucket: string;
299
299
  }
300
+ export interface DownloadUrlResponse {
301
+ /** Presigned URL for downloading the file */
302
+ url: string;
303
+ }
300
304
  export interface UpdateTaskResourceInput {
301
305
  /** Resource ID - include to update existing, omit to create new */
302
306
  id?: string;
@@ -2,9 +2,9 @@ export { useAuthState } from "./useAuthState";
2
2
  export { useOAuth, useOAuthCallback } from "./useOAuth";
3
3
  export type { UseOAuthResult } from "./useOAuth";
4
4
  export { useMissions, useMissionsInfinite, useCreateMission, useUpdateMission, useDeleteMission, missionKeys, } from "./useMissions";
5
- export { useTasks, useAllUserTasks, useTasksByRoadmapId, useTasksInfinite, useCreateTask, useUpdateTask, useDeleteTask, taskKeys, } from "./useTasks";
5
+ export { useTasks, useAllUserTasks, useTasksByRoadmapId, useTasksInfinite, useCreateTask, useUpdateTask, useDeleteTask, useBulkDeleteTasks, useBulkUpdateTasks, taskKeys, useGetDownloadUrl, useTaskCreators } from "./useTasks";
6
6
  export { useUsers, useUser, userKeys } from "./useUsers";
7
7
  export { useCurrentUserRoles, useMyStudents, accountKeys } from "./useAccount";
8
8
  export { useRoadmapContext } from "./useRoadmapContext";
9
- export { useTemplateMissions, useTemplateMissionsInfinite, useTemplateTasks, useTemplateTasksInfinite, useTemplateMissionDetail, useUpdateTemplateMission, useCopyTemplateMission, useAssignBulkMission, useAssignBulkTask, useCreateFromPredefinedTasks, missionLibraryKeys, } from "./useMissionLibrary";
9
+ export { useTemplateMissions, useTemplateMissionsInfinite, useTemplateTasks, useTemplateTasksInfinite, useTemplateMissionDetail, useUpdateTemplateMission, useCopyTemplateMission, useAssignBulkMission, useAssignBulkTask, useCreateFromPredefinedTasks, missionLibraryKeys, useCreateTemplateMission, useDeleteTemplateMission, } from "./useMissionLibrary";
10
10
  export { useStudentProfile, useStudentPrefilledInfo, studentProfileKeys, } from "./useStudentProfile";
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.studentProfileKeys = exports.useStudentPrefilledInfo = exports.useStudentProfile = exports.missionLibraryKeys = exports.useCreateFromPredefinedTasks = exports.useAssignBulkTask = exports.useAssignBulkMission = exports.useCopyTemplateMission = exports.useUpdateTemplateMission = exports.useTemplateMissionDetail = exports.useTemplateTasksInfinite = exports.useTemplateTasks = exports.useTemplateMissionsInfinite = exports.useTemplateMissions = exports.useRoadmapContext = exports.accountKeys = exports.useMyStudents = exports.useCurrentUserRoles = exports.userKeys = exports.useUser = exports.useUsers = exports.taskKeys = exports.useDeleteTask = exports.useUpdateTask = exports.useCreateTask = exports.useTasksInfinite = exports.useTasksByRoadmapId = exports.useAllUserTasks = exports.useTasks = exports.missionKeys = exports.useDeleteMission = exports.useUpdateMission = exports.useCreateMission = exports.useMissionsInfinite = exports.useMissions = exports.useOAuthCallback = exports.useOAuth = exports.useAuthState = void 0;
3
+ exports.studentProfileKeys = exports.useStudentPrefilledInfo = exports.useStudentProfile = exports.useDeleteTemplateMission = exports.useCreateTemplateMission = exports.missionLibraryKeys = exports.useCreateFromPredefinedTasks = exports.useAssignBulkTask = exports.useAssignBulkMission = exports.useCopyTemplateMission = exports.useUpdateTemplateMission = exports.useTemplateMissionDetail = exports.useTemplateTasksInfinite = exports.useTemplateTasks = exports.useTemplateMissionsInfinite = exports.useTemplateMissions = exports.useRoadmapContext = exports.accountKeys = exports.useMyStudents = exports.useCurrentUserRoles = exports.userKeys = exports.useUser = exports.useUsers = exports.useTaskCreators = exports.useGetDownloadUrl = exports.taskKeys = exports.useBulkUpdateTasks = exports.useBulkDeleteTasks = exports.useDeleteTask = exports.useUpdateTask = exports.useCreateTask = exports.useTasksInfinite = exports.useTasksByRoadmapId = exports.useAllUserTasks = exports.useTasks = exports.missionKeys = exports.useDeleteMission = exports.useUpdateMission = exports.useCreateMission = exports.useMissionsInfinite = exports.useMissions = exports.useOAuthCallback = exports.useOAuth = exports.useAuthState = void 0;
4
4
  var useAuthState_1 = require("./useAuthState");
5
5
  Object.defineProperty(exports, "useAuthState", { enumerable: true, get: function () { return useAuthState_1.useAuthState; } });
6
6
  var useOAuth_1 = require("./useOAuth");
@@ -21,7 +21,11 @@ Object.defineProperty(exports, "useTasksInfinite", { enumerable: true, get: func
21
21
  Object.defineProperty(exports, "useCreateTask", { enumerable: true, get: function () { return useTasks_1.useCreateTask; } });
22
22
  Object.defineProperty(exports, "useUpdateTask", { enumerable: true, get: function () { return useTasks_1.useUpdateTask; } });
23
23
  Object.defineProperty(exports, "useDeleteTask", { enumerable: true, get: function () { return useTasks_1.useDeleteTask; } });
24
+ Object.defineProperty(exports, "useBulkDeleteTasks", { enumerable: true, get: function () { return useTasks_1.useBulkDeleteTasks; } });
25
+ Object.defineProperty(exports, "useBulkUpdateTasks", { enumerable: true, get: function () { return useTasks_1.useBulkUpdateTasks; } });
24
26
  Object.defineProperty(exports, "taskKeys", { enumerable: true, get: function () { return useTasks_1.taskKeys; } });
27
+ Object.defineProperty(exports, "useGetDownloadUrl", { enumerable: true, get: function () { return useTasks_1.useGetDownloadUrl; } });
28
+ Object.defineProperty(exports, "useTaskCreators", { enumerable: true, get: function () { return useTasks_1.useTaskCreators; } });
25
29
  var useUsers_1 = require("./useUsers");
26
30
  Object.defineProperty(exports, "useUsers", { enumerable: true, get: function () { return useUsers_1.useUsers; } });
27
31
  Object.defineProperty(exports, "useUser", { enumerable: true, get: function () { return useUsers_1.useUser; } });
@@ -44,6 +48,8 @@ Object.defineProperty(exports, "useAssignBulkMission", { enumerable: true, get:
44
48
  Object.defineProperty(exports, "useAssignBulkTask", { enumerable: true, get: function () { return useMissionLibrary_1.useAssignBulkTask; } });
45
49
  Object.defineProperty(exports, "useCreateFromPredefinedTasks", { enumerable: true, get: function () { return useMissionLibrary_1.useCreateFromPredefinedTasks; } });
46
50
  Object.defineProperty(exports, "missionLibraryKeys", { enumerable: true, get: function () { return useMissionLibrary_1.missionLibraryKeys; } });
51
+ Object.defineProperty(exports, "useCreateTemplateMission", { enumerable: true, get: function () { return useMissionLibrary_1.useCreateTemplateMission; } });
52
+ Object.defineProperty(exports, "useDeleteTemplateMission", { enumerable: true, get: function () { return useMissionLibrary_1.useDeleteTemplateMission; } });
47
53
  var useStudentProfile_1 = require("./useStudentProfile");
48
54
  Object.defineProperty(exports, "useStudentProfile", { enumerable: true, get: function () { return useStudentProfile_1.useStudentProfile; } });
49
55
  Object.defineProperty(exports, "useStudentPrefilledInfo", { enumerable: true, get: function () { return useStudentProfile_1.useStudentPrefilledInfo; } });
@@ -1,5 +1,5 @@
1
1
  import type { TemplateMission, TemplateTask, MissionDetail, AssignBulkMissionInput, AssignBulkTaskInput } from "../../core/types";
2
- import type { TemplateMissionFilters, TemplateTaskFilters, CopyTemplateMissionInput, CreateFromPredefinedInput, TemplateMissionUpdateInput } from "../../core/missionLibrary";
2
+ import type { TemplateMissionFilters, TemplateTaskFilters, CopyTemplateMissionInput, CreateFromPredefinedInput, TemplateMissionUpdateInput, TemplateMissionCreateInput } from "../../core/missionLibrary";
3
3
  export declare const missionLibraryKeys: {
4
4
  all: readonly ["missionLibrary"];
5
5
  missions: (filters?: TemplateMissionFilters) => readonly ["missionLibrary", "missions", TemplateMissionFilters | undefined];
@@ -24,6 +24,8 @@ export declare function useUpdateTemplateMission(): import("@tanstack/react-quer
24
24
  raw: TemplateMission;
25
25
  update: TemplateMissionUpdateInput;
26
26
  }, unknown>;
27
+ export declare function useCreateTemplateMission(): import("@tanstack/react-query").UseMutationResult<TemplateMission, Error, TemplateMissionCreateInput, unknown>;
28
+ export declare function useDeleteTemplateMission(): import("@tanstack/react-query").UseMutationResult<void, Error, string, unknown>;
27
29
  export declare function useCopyTemplateMission(): import("@tanstack/react-query").UseMutationResult<TemplateMission[], Error, CopyTemplateMissionInput, unknown>;
28
30
  export declare function useAssignBulkMission(): import("@tanstack/react-query").UseMutationResult<{
29
31
  code: number;
@@ -17,6 +17,8 @@ exports.useTemplateTasks = useTemplateTasks;
17
17
  exports.useTemplateTasksInfinite = useTemplateTasksInfinite;
18
18
  exports.useTemplateMissionDetail = useTemplateMissionDetail;
19
19
  exports.useUpdateTemplateMission = useUpdateTemplateMission;
20
+ exports.useCreateTemplateMission = useCreateTemplateMission;
21
+ exports.useDeleteTemplateMission = useDeleteTemplateMission;
20
22
  exports.useCopyTemplateMission = useCopyTemplateMission;
21
23
  exports.useAssignBulkMission = useAssignBulkMission;
22
24
  exports.useAssignBulkTask = useAssignBulkTask;
@@ -121,6 +123,35 @@ function useUpdateTemplateMission() {
121
123
  },
122
124
  });
123
125
  }
126
+ function useCreateTemplateMission() {
127
+ const client = (0, provider_1.useCrimsonClient)();
128
+ const queryClient = (0, react_query_1.useQueryClient)();
129
+ return (0, react_query_1.useMutation)({
130
+ mutationFn: (input) => client.library.createTemplateMission(input),
131
+ onSuccess: () => {
132
+ queryClient.invalidateQueries({
133
+ queryKey: exports.missionLibraryKeys.missionsInfinite({
134
+ groups: ["custom"],
135
+ }),
136
+ });
137
+ },
138
+ });
139
+ }
140
+ function useDeleteTemplateMission() {
141
+ const client = (0, provider_1.useCrimsonClient)();
142
+ const queryClient = (0, react_query_1.useQueryClient)();
143
+ return (0, react_query_1.useMutation)({
144
+ mutationFn: (id) => client.library.deleteTemplateMission(id),
145
+ onSuccess: () => {
146
+ queryClient.invalidateQueries({
147
+ queryKey: exports.missionLibraryKeys.missionsInfinite(),
148
+ });
149
+ queryClient.invalidateQueries({
150
+ queryKey: exports.missionLibraryKeys.missions(),
151
+ });
152
+ },
153
+ });
154
+ }
124
155
  function useCopyTemplateMission() {
125
156
  const client = (0, provider_1.useCrimsonClient)();
126
157
  const queryClient = (0, react_query_1.useQueryClient)();
@@ -1,3 +1,4 @@
1
+ import { InfiniteData } from "@tanstack/react-query";
1
2
  import type { Mission, PaginatedResult } from "../../core/types";
2
3
  import type { MissionFilters } from "../../core/missions";
3
4
  export declare const missionKeys: {
@@ -15,10 +16,19 @@ export declare function useMissions(userId: string | null, enabled: boolean): im
15
16
  export declare function useMissionsInfinite(userId: string | null, filters?: Omit<MissionFilters, "start" | "limit">, options?: {
16
17
  enabled?: boolean;
17
18
  pageSize?: number;
18
- }): import("@tanstack/react-query").UseInfiniteQueryResult<import("@tanstack/react-query").InfiniteData<PaginatedResult<Mission>, unknown>, Error>;
19
- export declare function useCreateMission(): import("@tanstack/react-query").UseMutationResult<Mission, Error, Partial<Mission>, unknown>;
20
- export declare function useUpdateMission(): import("@tanstack/react-query").UseMutationResult<Mission, Error, {
19
+ }): import("@tanstack/react-query").UseInfiniteQueryResult<InfiniteData<PaginatedResult<Mission>, unknown>, Error>;
20
+ export interface OptimisticOptions {
21
+ optimistic?: boolean;
22
+ }
23
+ export declare function useCreateMission(options?: OptimisticOptions): import("@tanstack/react-query").UseMutationResult<Mission, Error, Partial<Mission>, {
24
+ previousMissions: Mission[] | undefined;
25
+ } | undefined>;
26
+ export declare function useUpdateMission(options?: OptimisticOptions): import("@tanstack/react-query").UseMutationResult<Mission, Error, {
21
27
  id: string;
22
28
  data: Partial<Mission>;
23
- }, unknown>;
24
- export declare function useDeleteMission(): import("@tanstack/react-query").UseMutationResult<void, Error, string, unknown>;
29
+ }, {
30
+ previousMissionsMap: Map<string, unknown>;
31
+ } | undefined>;
32
+ export declare function useDeleteMission(options?: OptimisticOptions): import("@tanstack/react-query").UseMutationResult<void, Error, string, {
33
+ previousMissionsMap: Map<string, unknown>;
34
+ } | undefined>;
@@ -72,32 +72,127 @@ function useMissionsInfinite(userId, filters, options) {
72
72
  enabled: !!userId && enabled,
73
73
  });
74
74
  }
75
- function useCreateMission() {
75
+ function useCreateMission(options) {
76
+ var _a;
76
77
  const client = (0, provider_1.useCrimsonClient)();
77
78
  const queryClient = (0, react_query_1.useQueryClient)();
79
+ const optimistic = (_a = options === null || options === void 0 ? void 0 : options.optimistic) !== null && _a !== void 0 ? _a : true;
78
80
  return (0, react_query_1.useMutation)({
79
81
  mutationFn: (data) => client.missions.create(data),
80
- onSuccess: () => {
82
+ onMutate: (newMission) => __awaiter(this, void 0, void 0, function* () {
83
+ if (!optimistic || !newMission.userId)
84
+ return;
85
+ const queryKey = exports.missionKeys.list(newMission.userId);
86
+ yield queryClient.cancelQueries({ queryKey });
87
+ const previousMissions = queryClient.getQueryData(queryKey);
88
+ if (previousMissions) {
89
+ const optimisticMission = Object.assign({ id: `temp-${Date.now()}`, title: "New Mission", status: "PLANNED", category: "General", roadmapId: "" }, newMission);
90
+ queryClient.setQueryData(queryKey, (old) => {
91
+ return old ? [...old, optimisticMission] : [optimisticMission];
92
+ });
93
+ }
94
+ return { previousMissions };
95
+ }),
96
+ onError: (err, newMission, context) => {
97
+ if (!optimistic || !(context === null || context === void 0 ? void 0 : context.previousMissions) || !newMission.userId)
98
+ return;
99
+ queryClient.setQueryData(exports.missionKeys.list(newMission.userId), context.previousMissions);
100
+ },
101
+ onSettled: () => {
81
102
  queryClient.invalidateQueries({ queryKey: exports.missionKeys.all });
82
103
  },
83
104
  });
84
105
  }
85
- function useUpdateMission() {
106
+ function useUpdateMission(options) {
107
+ var _a;
86
108
  const client = (0, provider_1.useCrimsonClient)();
87
109
  const queryClient = (0, react_query_1.useQueryClient)();
110
+ const optimistic = (_a = options === null || options === void 0 ? void 0 : options.optimistic) !== null && _a !== void 0 ? _a : true;
88
111
  return (0, react_query_1.useMutation)({
89
112
  mutationFn: ({ id, data }) => client.missions.update(id, data),
90
- onSuccess: () => {
113
+ onMutate: (_a) => __awaiter(this, [_a], void 0, function* ({ id, data }) {
114
+ if (!optimistic)
115
+ return;
116
+ yield queryClient.cancelQueries({ queryKey: exports.missionKeys.all });
117
+ const previousMissionsMap = new Map();
118
+ queryClient
119
+ .getQueriesData({ queryKey: exports.missionKeys.all })
120
+ .forEach(([key, old]) => {
121
+ previousMissionsMap.set(JSON.stringify(key), old);
122
+ if (!old)
123
+ return;
124
+ // Handle Infinite Query Support
125
+ if (typeof old === "object" &&
126
+ "pages" in old &&
127
+ Array.isArray(old.pages)) {
128
+ queryClient.setQueryData(key, (oldData) => {
129
+ if (!oldData)
130
+ return oldData;
131
+ return Object.assign(Object.assign({}, oldData), { pages: oldData.pages.map((page) => (Object.assign(Object.assign({}, page), { data: page.data.map((mission) => mission.id === id ? Object.assign(Object.assign({}, mission), data) : mission) }))) });
132
+ });
133
+ }
134
+ // Handle Standard List Support
135
+ else if (Array.isArray(old)) {
136
+ queryClient.setQueryData(key, (oldData) => oldData === null || oldData === void 0 ? void 0 : oldData.map((mission) => mission.id === id ? Object.assign(Object.assign({}, mission), data) : mission));
137
+ }
138
+ });
139
+ return { previousMissionsMap };
140
+ }),
141
+ onError: (err, { id }, context) => {
142
+ if (!optimistic || !(context === null || context === void 0 ? void 0 : context.previousMissionsMap))
143
+ return;
144
+ context.previousMissionsMap.forEach((old, keyStr) => {
145
+ queryClient.setQueryData(JSON.parse(keyStr), old);
146
+ });
147
+ },
148
+ onSettled: () => {
91
149
  queryClient.invalidateQueries({ queryKey: exports.missionKeys.all });
92
150
  },
93
151
  });
94
152
  }
95
- function useDeleteMission() {
153
+ function useDeleteMission(options) {
154
+ var _a;
96
155
  const client = (0, provider_1.useCrimsonClient)();
97
156
  const queryClient = (0, react_query_1.useQueryClient)();
157
+ const optimistic = (_a = options === null || options === void 0 ? void 0 : options.optimistic) !== null && _a !== void 0 ? _a : true;
98
158
  return (0, react_query_1.useMutation)({
99
159
  mutationFn: (id) => client.missions.delete(id),
100
- onSuccess: () => {
160
+ onMutate: (id) => __awaiter(this, void 0, void 0, function* () {
161
+ if (!optimistic)
162
+ return;
163
+ yield queryClient.cancelQueries({ queryKey: exports.missionKeys.all });
164
+ const previousMissionsMap = new Map();
165
+ queryClient
166
+ .getQueriesData({ queryKey: exports.missionKeys.all })
167
+ .forEach(([key, old]) => {
168
+ previousMissionsMap.set(JSON.stringify(key), old);
169
+ if (!old)
170
+ return;
171
+ // Handle Infinite Query Support
172
+ if (typeof old === "object" &&
173
+ "pages" in old &&
174
+ Array.isArray(old.pages)) {
175
+ queryClient.setQueryData(key, (oldData) => {
176
+ if (!oldData)
177
+ return oldData;
178
+ return Object.assign(Object.assign({}, oldData), { pages: oldData.pages.map((page) => (Object.assign(Object.assign({}, page), { data: page.data.filter((mission) => mission.id !== id) }))) });
179
+ });
180
+ }
181
+ // Handle Standard List Support
182
+ else if (Array.isArray(old)) {
183
+ queryClient.setQueryData(key, (oldData) => oldData === null || oldData === void 0 ? void 0 : oldData.filter((mission) => mission.id !== id));
184
+ }
185
+ });
186
+ return { previousMissionsMap };
187
+ }),
188
+ onError: (err, id, context) => {
189
+ if (!optimistic || !(context === null || context === void 0 ? void 0 : context.previousMissionsMap))
190
+ return;
191
+ context.previousMissionsMap.forEach((old, keyStr) => {
192
+ queryClient.setQueryData(JSON.parse(keyStr), old);
193
+ });
194
+ },
195
+ onSettled: () => {
101
196
  queryClient.invalidateQueries({ queryKey: exports.missionKeys.all });
102
197
  },
103
198
  });
@@ -1,4 +1,5 @@
1
- import type { Task, PaginatedResult } from "../../core/types";
1
+ import { InfiniteData } from "@tanstack/react-query";
2
+ import type { Task, PaginatedResult, User } from "../../core/types";
2
3
  import type { TaskFilters } from "../../core/tasks";
3
4
  export declare const taskKeys: {
4
5
  all: readonly ["tasks"];
@@ -7,8 +8,10 @@ export declare const taskKeys: {
7
8
  infinite: (roadmapId: string, userId: string, filters?: Omit<TaskFilters, "start" | "limit">) => readonly ["tasks", "infinite", string, string, Omit<TaskFilters, "start" | "limit"> | undefined];
8
9
  details: () => readonly ["tasks", "detail"];
9
10
  detail: (id: string) => readonly ["tasks", "detail", string];
11
+ creators: (roadmapId: string) => readonly ["tasks", "creators", string];
10
12
  };
11
13
  export declare function useTasks(missionId: string | null, enabled: boolean): import("@tanstack/react-query").UseQueryResult<Task[], Error>;
14
+ export declare function useTaskCreators(roadmapId: string | null, enabled?: boolean): import("@tanstack/react-query").UseQueryResult<User[], Error>;
12
15
  export declare function useAllUserTasks(missionLinkIds: string[], enabled: boolean): import("@tanstack/react-query").UseQueryResult<Task[], Error>;
13
16
  export declare function useTasksByRoadmapId(roadmapId: string | null, userId: string | null, enabled: boolean): import("@tanstack/react-query").UseQueryResult<Task[], Error>;
14
17
  /**
@@ -17,10 +20,36 @@ export declare function useTasksByRoadmapId(roadmapId: string | null, userId: st
17
20
  export declare function useTasksInfinite(roadmapId: string | null, userId: string | null, filters?: Omit<TaskFilters, "start" | "limit">, options?: {
18
21
  enabled?: boolean;
19
22
  pageSize?: number;
20
- }): import("@tanstack/react-query").UseInfiniteQueryResult<import("@tanstack/react-query").InfiniteData<PaginatedResult<Task>, unknown>, Error>;
21
- export declare function useCreateTask(): import("@tanstack/react-query").UseMutationResult<Task, Error, Partial<Task>, unknown>;
22
- export declare function useUpdateTask(): import("@tanstack/react-query").UseMutationResult<Task, Error, {
23
+ }): import("@tanstack/react-query").UseInfiniteQueryResult<InfiniteData<PaginatedResult<Task>, unknown>, Error>;
24
+ export interface OptimisticOptions {
25
+ optimistic?: boolean;
26
+ }
27
+ export declare function useCreateTask(options?: OptimisticOptions): import("@tanstack/react-query").UseMutationResult<Task, Error, Partial<Task>, {
28
+ previousTasks: Task[] | undefined;
29
+ } | undefined>;
30
+ export declare function useUpdateTask(options?: OptimisticOptions): import("@tanstack/react-query").UseMutationResult<Task, Error, {
23
31
  id: string;
24
32
  data: Partial<Task>;
25
- }, unknown>;
26
- export declare function useDeleteTask(): import("@tanstack/react-query").UseMutationResult<void, Error, string, unknown>;
33
+ }, {
34
+ previousTasksMap: Map<string, unknown>;
35
+ } | undefined>;
36
+ export declare function useDeleteTask(options?: OptimisticOptions): import("@tanstack/react-query").UseMutationResult<void, Error, string, {
37
+ previousTasksMap: Map<string, unknown>;
38
+ } | undefined>;
39
+ export declare function useBulkDeleteTasks(options?: OptimisticOptions): import("@tanstack/react-query").UseMutationResult<{
40
+ deleted: string[];
41
+ }, Error, string[], {
42
+ previousTasksMap: Map<string, unknown>;
43
+ } | undefined>;
44
+ export declare function useBulkUpdateTasks(options?: OptimisticOptions): import("@tanstack/react-query").UseMutationResult<{
45
+ updated: any[];
46
+ }, Error, {
47
+ ids: string[];
48
+ data: {
49
+ dueDate?: string | null;
50
+ status?: string;
51
+ };
52
+ }, {
53
+ previousTasksMap: Map<string, unknown>;
54
+ } | undefined>;
55
+ export declare function useGetDownloadUrl(): import("@tanstack/react-query").UseMutationResult<import("../../core/types").DownloadUrlResponse, Error, string, unknown>;
@@ -12,12 +12,16 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
12
12
  Object.defineProperty(exports, "__esModule", { value: true });
13
13
  exports.taskKeys = void 0;
14
14
  exports.useTasks = useTasks;
15
+ exports.useTaskCreators = useTaskCreators;
15
16
  exports.useAllUserTasks = useAllUserTasks;
16
17
  exports.useTasksByRoadmapId = useTasksByRoadmapId;
17
18
  exports.useTasksInfinite = useTasksInfinite;
18
19
  exports.useCreateTask = useCreateTask;
19
20
  exports.useUpdateTask = useUpdateTask;
20
21
  exports.useDeleteTask = useDeleteTask;
22
+ exports.useBulkDeleteTasks = useBulkDeleteTasks;
23
+ exports.useBulkUpdateTasks = useBulkUpdateTasks;
24
+ exports.useGetDownloadUrl = useGetDownloadUrl;
21
25
  const react_query_1 = require("@tanstack/react-query");
22
26
  const provider_1 = require("../provider");
23
27
  // Query keys
@@ -28,6 +32,7 @@ exports.taskKeys = {
28
32
  infinite: (roadmapId, userId, filters) => [...exports.taskKeys.all, "infinite", roadmapId, userId, filters],
29
33
  details: () => [...exports.taskKeys.all, "detail"],
30
34
  detail: (id) => [...exports.taskKeys.details(), id],
35
+ creators: (roadmapId) => [...exports.taskKeys.all, "creators", roadmapId],
31
36
  };
32
37
  function useTasks(missionId, enabled) {
33
38
  const client = (0, provider_1.useCrimsonClient)();
@@ -43,6 +48,19 @@ function useTasks(missionId, enabled) {
43
48
  enabled: !!missionId && enabled,
44
49
  });
45
50
  }
51
+ function useTaskCreators(roadmapId, enabled = true) {
52
+ const client = (0, provider_1.useCrimsonClient)();
53
+ return (0, react_query_1.useQuery)({
54
+ queryKey: exports.taskKeys.creators(roadmapId || ""),
55
+ queryFn: () => __awaiter(this, void 0, void 0, function* () {
56
+ if (!roadmapId) {
57
+ return [];
58
+ }
59
+ return client.tasks.getCreators(roadmapId);
60
+ }),
61
+ enabled: !!roadmapId && enabled,
62
+ });
63
+ }
46
64
  function useAllUserTasks(missionLinkIds, enabled) {
47
65
  const client = (0, provider_1.useCrimsonClient)();
48
66
  return (0, react_query_1.useQuery)({
@@ -105,33 +123,229 @@ function useTasksInfinite(roadmapId, userId, filters, options) {
105
123
  enabled: !!roadmapId && !!userId && enabled,
106
124
  });
107
125
  }
108
- function useCreateTask() {
126
+ function useCreateTask(options) {
127
+ var _a;
109
128
  const client = (0, provider_1.useCrimsonClient)();
110
129
  const queryClient = (0, react_query_1.useQueryClient)();
130
+ const optimistic = (_a = options === null || options === void 0 ? void 0 : options.optimistic) !== null && _a !== void 0 ? _a : true;
111
131
  return (0, react_query_1.useMutation)({
112
132
  mutationFn: (data) => client.tasks.create(data),
113
- onSuccess: () => {
133
+ onMutate: (newTask) => __awaiter(this, void 0, void 0, function* () {
134
+ if (!optimistic || !newTask.missionId)
135
+ return;
136
+ const queryKey = exports.taskKeys.list(newTask.missionId);
137
+ yield queryClient.cancelQueries({ queryKey });
138
+ const previousTasks = queryClient.getQueryData(queryKey);
139
+ if (previousTasks) {
140
+ const optimisticTask = Object.assign({ id: `temp-${Date.now()}`, name: "New Task", status: "PLANNED", date: new Date().toISOString(), roadmapMissionId: "", userId: "" }, newTask);
141
+ queryClient.setQueryData(queryKey, (old) => {
142
+ return old ? [...old, optimisticTask] : [optimisticTask];
143
+ });
144
+ }
145
+ return { previousTasks };
146
+ }),
147
+ onError: (err, newTodo, context) => {
148
+ if (!optimistic || !(context === null || context === void 0 ? void 0 : context.previousTasks) || !newTodo.missionId)
149
+ return;
150
+ queryClient.setQueryData(exports.taskKeys.list(newTodo.missionId), context.previousTasks);
151
+ },
152
+ onSettled: () => {
114
153
  queryClient.invalidateQueries({ queryKey: exports.taskKeys.all });
115
154
  },
116
155
  });
117
156
  }
118
- function useUpdateTask() {
157
+ function useUpdateTask(options) {
158
+ var _a;
119
159
  const client = (0, provider_1.useCrimsonClient)();
120
160
  const queryClient = (0, react_query_1.useQueryClient)();
161
+ const optimistic = (_a = options === null || options === void 0 ? void 0 : options.optimistic) !== null && _a !== void 0 ? _a : true;
121
162
  return (0, react_query_1.useMutation)({
122
163
  mutationFn: ({ id, data }) => client.tasks.update(id, data),
123
- onSuccess: () => {
164
+ onMutate: (_a) => __awaiter(this, [_a], void 0, function* ({ id, data }) {
165
+ if (!optimistic)
166
+ return;
167
+ yield queryClient.cancelQueries({ queryKey: exports.taskKeys.all });
168
+ const previousTasksMap = new Map();
169
+ // Update basic list and infinite queries
170
+ queryClient
171
+ .getQueriesData({ queryKey: exports.taskKeys.all })
172
+ .forEach(([key, old]) => {
173
+ previousTasksMap.set(JSON.stringify(key), old);
174
+ if (!old)
175
+ return;
176
+ // Handle Infinite Query Support
177
+ if (typeof old === "object" &&
178
+ "pages" in old &&
179
+ Array.isArray(old.pages)) {
180
+ queryClient.setQueryData(key, (oldData) => {
181
+ if (!oldData)
182
+ return oldData;
183
+ return Object.assign(Object.assign({}, oldData), { pages: oldData.pages.map((page) => (Object.assign(Object.assign({}, page), { data: page.data.map((task) => task.id === id ? Object.assign(Object.assign({}, task), data) : task) }))) });
184
+ });
185
+ }
186
+ // Handle Standard List Support
187
+ else if (Array.isArray(old)) {
188
+ queryClient.setQueryData(key, (oldData) => oldData === null || oldData === void 0 ? void 0 : oldData.map((task) => task.id === id ? Object.assign(Object.assign({}, task), data) : task));
189
+ }
190
+ });
191
+ return { previousTasksMap };
192
+ }),
193
+ onError: (err, { id }, context) => {
194
+ if (!optimistic || !(context === null || context === void 0 ? void 0 : context.previousTasksMap))
195
+ return;
196
+ context.previousTasksMap.forEach((old, keyStr) => {
197
+ queryClient.setQueryData(JSON.parse(keyStr), old);
198
+ });
199
+ },
200
+ onSettled: () => {
124
201
  queryClient.invalidateQueries({ queryKey: exports.taskKeys.all });
125
202
  },
126
203
  });
127
204
  }
128
- function useDeleteTask() {
205
+ function useDeleteTask(options) {
206
+ var _a;
129
207
  const client = (0, provider_1.useCrimsonClient)();
130
208
  const queryClient = (0, react_query_1.useQueryClient)();
209
+ const optimistic = (_a = options === null || options === void 0 ? void 0 : options.optimistic) !== null && _a !== void 0 ? _a : true;
131
210
  return (0, react_query_1.useMutation)({
132
211
  mutationFn: (id) => client.tasks.delete(id),
133
- onSuccess: () => {
212
+ onMutate: (id) => __awaiter(this, void 0, void 0, function* () {
213
+ if (!optimistic)
214
+ return;
215
+ yield queryClient.cancelQueries({ queryKey: exports.taskKeys.all });
216
+ const previousTasksMap = new Map();
217
+ queryClient
218
+ .getQueriesData({ queryKey: exports.taskKeys.all })
219
+ .forEach(([key, old]) => {
220
+ previousTasksMap.set(JSON.stringify(key), old);
221
+ if (!old)
222
+ return;
223
+ // Handle Infinite Query Support
224
+ if (typeof old === "object" &&
225
+ "pages" in old &&
226
+ Array.isArray(old.pages)) {
227
+ queryClient.setQueryData(key, (oldData) => {
228
+ if (!oldData)
229
+ return oldData;
230
+ return Object.assign(Object.assign({}, oldData), { pages: oldData.pages.map((page) => (Object.assign(Object.assign({}, page), { data: page.data.filter((task) => task.id !== id) }))) });
231
+ });
232
+ }
233
+ // Handle Standard List Support
234
+ else if (Array.isArray(old)) {
235
+ queryClient.setQueryData(key, (oldData) => oldData === null || oldData === void 0 ? void 0 : oldData.filter((task) => task.id !== id));
236
+ }
237
+ });
238
+ return { previousTasksMap };
239
+ }),
240
+ onError: (err, id, context) => {
241
+ if (!optimistic || !(context === null || context === void 0 ? void 0 : context.previousTasksMap))
242
+ return;
243
+ context.previousTasksMap.forEach((old, keyStr) => {
244
+ queryClient.setQueryData(JSON.parse(keyStr), old);
245
+ });
246
+ },
247
+ onSettled: () => {
134
248
  queryClient.invalidateQueries({ queryKey: exports.taskKeys.all });
135
249
  },
136
250
  });
137
251
  }
252
+ function useBulkDeleteTasks(options) {
253
+ var _a;
254
+ const client = (0, provider_1.useCrimsonClient)();
255
+ const queryClient = (0, react_query_1.useQueryClient)();
256
+ const optimistic = (_a = options === null || options === void 0 ? void 0 : options.optimistic) !== null && _a !== void 0 ? _a : true;
257
+ return (0, react_query_1.useMutation)({
258
+ mutationFn: (ids) => client.tasks.bulkDelete(ids),
259
+ onMutate: (ids) => __awaiter(this, void 0, void 0, function* () {
260
+ if (!optimistic)
261
+ return;
262
+ yield queryClient.cancelQueries({ queryKey: exports.taskKeys.all });
263
+ const previousTasksMap = new Map();
264
+ queryClient
265
+ .getQueriesData({ queryKey: exports.taskKeys.all })
266
+ .forEach(([key, old]) => {
267
+ previousTasksMap.set(JSON.stringify(key), old);
268
+ if (!old)
269
+ return;
270
+ // Handle Infinite Query Support
271
+ if (typeof old === "object" &&
272
+ "pages" in old &&
273
+ Array.isArray(old.pages)) {
274
+ queryClient.setQueryData(key, (oldData) => {
275
+ if (!oldData)
276
+ return oldData;
277
+ return Object.assign(Object.assign({}, oldData), { pages: oldData.pages.map((page) => (Object.assign(Object.assign({}, page), { data: page.data.filter((task) => !ids.includes(task.id)) }))) });
278
+ });
279
+ }
280
+ // Handle Standard List Support
281
+ else if (Array.isArray(old)) {
282
+ queryClient.setQueryData(key, (oldData) => oldData === null || oldData === void 0 ? void 0 : oldData.filter((task) => !ids.includes(task.id)));
283
+ }
284
+ });
285
+ return { previousTasksMap };
286
+ }),
287
+ onError: (err, ids, context) => {
288
+ if (!optimistic || !(context === null || context === void 0 ? void 0 : context.previousTasksMap))
289
+ return;
290
+ context.previousTasksMap.forEach((old, keyStr) => {
291
+ queryClient.setQueryData(JSON.parse(keyStr), old);
292
+ });
293
+ },
294
+ onSettled: () => {
295
+ queryClient.invalidateQueries({ queryKey: exports.taskKeys.all });
296
+ },
297
+ });
298
+ }
299
+ function useBulkUpdateTasks(options) {
300
+ var _a;
301
+ const client = (0, provider_1.useCrimsonClient)();
302
+ const queryClient = (0, react_query_1.useQueryClient)();
303
+ const optimistic = (_a = options === null || options === void 0 ? void 0 : options.optimistic) !== null && _a !== void 0 ? _a : true;
304
+ return (0, react_query_1.useMutation)({
305
+ mutationFn: ({ ids, data, }) => client.tasks.bulkUpdate(ids, data),
306
+ onMutate: (_a) => __awaiter(this, [_a], void 0, function* ({ ids, data }) {
307
+ if (!optimistic)
308
+ return;
309
+ yield queryClient.cancelQueries({ queryKey: exports.taskKeys.all });
310
+ const previousTasksMap = new Map();
311
+ queryClient
312
+ .getQueriesData({ queryKey: exports.taskKeys.all })
313
+ .forEach(([key, old]) => {
314
+ previousTasksMap.set(JSON.stringify(key), old);
315
+ if (!old)
316
+ return;
317
+ // Handle Infinite Query Support
318
+ if (typeof old === "object" &&
319
+ "pages" in old &&
320
+ Array.isArray(old.pages)) {
321
+ queryClient.setQueryData(key, (oldData) => {
322
+ if (!oldData)
323
+ return oldData;
324
+ return Object.assign(Object.assign({}, oldData), { pages: oldData.pages.map((page) => (Object.assign(Object.assign({}, page), { data: page.data.map((task) => ids.includes(task.id) ? Object.assign(Object.assign({}, task), data) : task) }))) });
325
+ });
326
+ }
327
+ // Handle Standard List Support
328
+ else if (Array.isArray(old)) {
329
+ queryClient.setQueryData(key, (oldData) => oldData === null || oldData === void 0 ? void 0 : oldData.map((task) => ids.includes(task.id) ? Object.assign(Object.assign({}, task), data) : task));
330
+ }
331
+ });
332
+ return { previousTasksMap };
333
+ }),
334
+ onError: (err, variables, context) => {
335
+ if (!optimistic || !(context === null || context === void 0 ? void 0 : context.previousTasksMap))
336
+ return;
337
+ context.previousTasksMap.forEach((old, keyStr) => {
338
+ queryClient.setQueryData(JSON.parse(keyStr), old);
339
+ });
340
+ },
341
+ onSettled: () => {
342
+ queryClient.invalidateQueries({ queryKey: exports.taskKeys.all });
343
+ },
344
+ });
345
+ }
346
+ function useGetDownloadUrl() {
347
+ const client = (0, provider_1.useCrimsonClient)();
348
+ return (0, react_query_1.useMutation)({
349
+ mutationFn: (key) => client.tasks.getDownloadUrl(key),
350
+ });
351
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@crimson-education/sdk",
3
- "version": "0.2.3",
3
+ "version": "0.2.5",
4
4
  "description": "Crimson SDK for accessing Crimson App APIs",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.js",