@go-avro/avro-js 0.0.34 → 0.0.36
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.
|
@@ -216,6 +216,7 @@ export class AvroQueryClient {
|
|
|
216
216
|
return;
|
|
217
217
|
}
|
|
218
218
|
const entityPredicate = (q) => matchesEntityKey(q, entityKey);
|
|
219
|
+
let fetchedItem;
|
|
219
220
|
switch (action) {
|
|
220
221
|
// ─── CREATE ─────────────────────────────────
|
|
221
222
|
case 'create': {
|
|
@@ -226,6 +227,7 @@ export class AvroQueryClient {
|
|
|
226
227
|
queryFn: () => client.get({ path: fetchPath(id) }),
|
|
227
228
|
staleTime: 0,
|
|
228
229
|
});
|
|
230
|
+
fetchedItem = item;
|
|
229
231
|
queryClient.setQueriesData({ predicate: entityPredicate, type: 'active' }, (old) => {
|
|
230
232
|
if (!old)
|
|
231
233
|
return old;
|
|
@@ -270,6 +272,7 @@ export class AvroQueryClient {
|
|
|
270
272
|
queryFn: () => client.get({ path: fetchPath(id) }),
|
|
271
273
|
staleTime: 0,
|
|
272
274
|
});
|
|
275
|
+
fetchedItem = item;
|
|
273
276
|
// Patch it into every active list / infinite-query cache
|
|
274
277
|
queryClient.setQueriesData({ predicate: entityPredicate, type: 'active' }, (old) => {
|
|
275
278
|
if (!old)
|
|
@@ -323,7 +326,7 @@ export class AvroQueryClient {
|
|
|
323
326
|
// Refetch & patch related entities (e.g. event → parent job)
|
|
324
327
|
if (relatedRefetch) {
|
|
325
328
|
for (const related of relatedRefetch) {
|
|
326
|
-
const relatedId = data?.[related.idField];
|
|
329
|
+
const relatedId = data?.[related.idField] ?? fetchedItem?.[related.idField];
|
|
327
330
|
if (!relatedId || typeof relatedId !== 'string')
|
|
328
331
|
continue;
|
|
329
332
|
try {
|
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
import { useInfiniteQuery, useQuery, useMutation } from '@tanstack/react-query';
|
|
2
2
|
import { AvroQueryClient } from '../../client/QueryClient';
|
|
3
|
-
import { _Event, LineItemStatus } from '../../types/api';
|
|
3
|
+
import { _Event, Job, LineItemStatus } from '../../types/api';
|
|
4
|
+
/** Predicate that matches all 'jobs' queries (list and individual, but NOT 'infinite'). */
|
|
5
|
+
const isJobsQuery = (q) => q.queryKey[0] === 'jobs';
|
|
6
|
+
/** Predicate that matches all 'events' queries (list and individual). */
|
|
7
|
+
const isEventsQuery = (q) => q.queryKey[0] === 'events';
|
|
4
8
|
AvroQueryClient.prototype.useGetEvents = function (body) {
|
|
5
9
|
const queryClient = this.getQueryClient();
|
|
6
10
|
const result = useInfiniteQuery({
|
|
@@ -54,70 +58,67 @@ AvroQueryClient.prototype.useCreateEvent = function () {
|
|
|
54
58
|
},
|
|
55
59
|
onMutate: async ({ eventData }) => {
|
|
56
60
|
await queryClient.cancelQueries({ queryKey: ['events'] });
|
|
57
|
-
const previousEvents = queryClient.getQueryData(['events']);
|
|
58
61
|
const previousJob = queryClient.getQueryData(['jobs', eventData.job_id]);
|
|
59
|
-
const previousJobs = queryClient.getQueryData(['jobs']);
|
|
60
62
|
const optimisticEvent = new _Event({
|
|
61
63
|
...eventData,
|
|
62
64
|
id: Math.random().toString(36).substring(2, 11),
|
|
63
65
|
company_id: this.companyId,
|
|
64
66
|
});
|
|
65
67
|
if (previousJob) {
|
|
66
|
-
const updatedJob = {
|
|
68
|
+
const updatedJob = new Job({
|
|
67
69
|
...previousJob,
|
|
68
70
|
current_event: optimisticEvent,
|
|
69
71
|
last_completed_event: (optimisticEvent.time_ended ?? -1) > -1 ? optimisticEvent : previousJob.last_completed_event,
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
|
|
72
|
+
tasks: previousJob.tasks.map((task) => {
|
|
73
|
+
if (eventData.tasks?.includes(task.id ?? "")) {
|
|
74
|
+
return {
|
|
75
|
+
...task,
|
|
76
|
+
current_event: optimisticEvent,
|
|
77
|
+
last_completed_event: (optimisticEvent.time_ended ?? -1) > -1 ? optimisticEvent : task.last_completed_event,
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
return task;
|
|
81
|
+
}),
|
|
82
|
+
});
|
|
83
|
+
// Update individual job cache AND every active jobs list/query
|
|
84
|
+
queryClient.setQueriesData({ predicate: isJobsQuery, type: 'active' }, (old) => {
|
|
85
|
+
if (!old)
|
|
86
|
+
return old;
|
|
87
|
+
if (Array.isArray(old))
|
|
88
|
+
return old.map((j) => j?.id === updatedJob.id ? updatedJob : j);
|
|
89
|
+
if (old?.id === updatedJob.id)
|
|
90
|
+
return updatedJob;
|
|
91
|
+
return old;
|
|
80
92
|
});
|
|
81
|
-
const updatedJobs = previousJobs?.map((job) => job.id === updatedJob.id ? updatedJob : job);
|
|
82
|
-
queryClient.setQueryData(['jobs', previousJob.id], updatedJob);
|
|
83
|
-
queryClient.setQueryData(['jobs'], updatedJobs);
|
|
84
93
|
}
|
|
85
|
-
|
|
94
|
+
// Add optimistic event to all active events queries
|
|
95
|
+
queryClient.setQueriesData({ predicate: isEventsQuery, type: 'active' }, (oldData) => {
|
|
86
96
|
if (!oldData)
|
|
87
|
-
return
|
|
97
|
+
return oldData;
|
|
88
98
|
if (oldData.pages) {
|
|
89
99
|
const firstPage = oldData.pages[0] || [];
|
|
90
100
|
return {
|
|
91
101
|
...oldData,
|
|
92
102
|
pages: [
|
|
93
|
-
[
|
|
94
|
-
optimisticEvent,
|
|
95
|
-
...firstPage,
|
|
96
|
-
],
|
|
103
|
+
[optimisticEvent, ...firstPage],
|
|
97
104
|
...oldData.pages.slice(1),
|
|
98
105
|
],
|
|
99
106
|
};
|
|
100
107
|
}
|
|
101
108
|
if (Array.isArray(oldData)) {
|
|
102
|
-
return [
|
|
103
|
-
optimisticEvent,
|
|
104
|
-
...oldData,
|
|
105
|
-
];
|
|
109
|
+
return [optimisticEvent, ...oldData];
|
|
106
110
|
}
|
|
107
111
|
return oldData;
|
|
108
112
|
});
|
|
109
|
-
return {
|
|
113
|
+
return { previousJob };
|
|
110
114
|
},
|
|
111
115
|
onError: (err, variables, context) => {
|
|
112
|
-
|
|
113
|
-
queryClient.setQueryData(['events'], context.previousEvents);
|
|
114
|
-
}
|
|
116
|
+
// Restore individual job; invalidate lists to refetch clean state
|
|
115
117
|
if (context?.previousJob) {
|
|
116
118
|
queryClient.setQueryData(['jobs', context.previousJob.id], context.previousJob);
|
|
117
119
|
}
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
}
|
|
120
|
+
queryClient.invalidateQueries({ predicate: isJobsQuery });
|
|
121
|
+
queryClient.invalidateQueries({ predicate: isEventsQuery });
|
|
121
122
|
},
|
|
122
123
|
});
|
|
123
124
|
};
|
|
@@ -134,30 +135,52 @@ AvroQueryClient.prototype.useUpdateEvent = function () {
|
|
|
134
135
|
onMutate: async ({ eventId, updates }) => {
|
|
135
136
|
await queryClient.cancelQueries({ queryKey: ['events', eventId] });
|
|
136
137
|
await queryClient.cancelQueries({ queryKey: ['events'] });
|
|
137
|
-
|
|
138
|
-
|
|
138
|
+
// Try individual cache first; fall back to scanning all active events queries
|
|
139
|
+
let previousEvent = queryClient.getQueryData(['events', eventId]);
|
|
140
|
+
if (!previousEvent) {
|
|
141
|
+
const allEventsData = queryClient.getQueriesData({ predicate: isEventsQuery });
|
|
142
|
+
outer: for (const [, data] of allEventsData) {
|
|
143
|
+
const pages = data?.pages ?? (Array.isArray(data) ? [data] : undefined);
|
|
144
|
+
if (pages) {
|
|
145
|
+
for (const page of pages) {
|
|
146
|
+
const found = page.find((e) => e.id === eventId);
|
|
147
|
+
if (found) {
|
|
148
|
+
previousEvent = found;
|
|
149
|
+
break outer;
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
}
|
|
139
155
|
const previousJob = queryClient.getQueryData(['jobs', previousEvent?.job_id]);
|
|
140
|
-
const previousJobs = queryClient.getQueryData(['jobs']);
|
|
141
156
|
if (previousJob) {
|
|
142
|
-
const
|
|
157
|
+
const isEnding = (updates.time_ended ?? -1) > -1;
|
|
158
|
+
const mergedEvent = previousEvent ? new _Event({ ...previousEvent, ...updates }) : null;
|
|
159
|
+
const updatedJob = new Job({
|
|
143
160
|
...previousJob,
|
|
144
|
-
current_event:
|
|
145
|
-
last_completed_event:
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
|
|
161
|
+
current_event: isEnding ? null : (mergedEvent ?? previousJob.current_event),
|
|
162
|
+
last_completed_event: isEnding && mergedEvent ? mergedEvent : previousJob.last_completed_event,
|
|
163
|
+
tasks: previousJob.tasks.map((task) => {
|
|
164
|
+
if (updates.tasks?.includes(task.id ?? "")) {
|
|
165
|
+
return {
|
|
166
|
+
...task,
|
|
167
|
+
current_event: isEnding ? null : (previousEvent ? { ...previousEvent, ...updates } : task.current_event),
|
|
168
|
+
last_completed_event: isEnding ? (previousEvent ? { ...previousEvent, ...updates } : task.last_completed_event) : task.last_completed_event,
|
|
169
|
+
overdue_time: isEnding ? -(task.frequency ?? 0) - (task.delay ?? 0) : task.overdue_time,
|
|
170
|
+
};
|
|
171
|
+
}
|
|
172
|
+
return task;
|
|
173
|
+
}),
|
|
174
|
+
});
|
|
175
|
+
queryClient.setQueriesData({ predicate: isJobsQuery, type: 'active' }, (old) => {
|
|
176
|
+
if (!old)
|
|
177
|
+
return old;
|
|
178
|
+
if (Array.isArray(old))
|
|
179
|
+
return old.map((j) => j?.id === updatedJob.id ? updatedJob : j);
|
|
180
|
+
if (old?.id === updatedJob.id)
|
|
181
|
+
return updatedJob;
|
|
182
|
+
return old;
|
|
157
183
|
});
|
|
158
|
-
const updatedJobs = previousJobs?.map((job) => job.id === updatedJob.id ? updatedJob : job);
|
|
159
|
-
queryClient.setQueryData(['jobs', previousJob.id], updatedJob);
|
|
160
|
-
queryClient.setQueryData(['jobs'], updatedJobs);
|
|
161
184
|
}
|
|
162
185
|
queryClient.setQueryData(['events', eventId], (oldData) => oldData ? { ...oldData, ...updates } : undefined);
|
|
163
186
|
queryClient.setQueriesData({ queryKey: ['events'] }, (oldData) => {
|
|
@@ -172,22 +195,18 @@ AvroQueryClient.prototype.useUpdateEvent = function () {
|
|
|
172
195
|
}
|
|
173
196
|
return oldData;
|
|
174
197
|
});
|
|
175
|
-
return { previousEvent,
|
|
198
|
+
return { previousEvent, previousJob };
|
|
176
199
|
},
|
|
177
200
|
onError: (_err, variables, context) => {
|
|
178
201
|
const { eventId } = variables;
|
|
179
202
|
if (context?.previousEvent) {
|
|
180
203
|
queryClient.setQueryData(['events', eventId], context.previousEvent);
|
|
181
204
|
}
|
|
182
|
-
if (context?.previousEvents) {
|
|
183
|
-
queryClient.setQueryData(['events'], context.previousEvents);
|
|
184
|
-
}
|
|
185
205
|
if (context?.previousJob) {
|
|
186
206
|
queryClient.setQueryData(['jobs', context.previousJob.id], context.previousJob);
|
|
187
207
|
}
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
}
|
|
208
|
+
queryClient.invalidateQueries({ predicate: isJobsQuery });
|
|
209
|
+
queryClient.invalidateQueries({ predicate: isEventsQuery });
|
|
191
210
|
},
|
|
192
211
|
});
|
|
193
212
|
};
|