@go-avro/avro-js 0.0.66 → 0.0.68

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.
@@ -359,7 +359,8 @@ declare module '../client/QueryClient' {
359
359
  }): UseQueryResult<CheckIn[], StandardError>;
360
360
  useCheckIn(): ReturnType<typeof useMutation<{
361
361
  msg: string;
362
- id: string;
362
+ id: string | null;
363
+ job_id: string | null;
363
364
  }, StandardError, {
364
365
  jobId: string;
365
366
  teamId?: string | null;
@@ -367,16 +368,19 @@ declare module '../client/QueryClient' {
367
368
  useCheckOut(): ReturnType<typeof useMutation<{
368
369
  msg: string;
369
370
  id: string;
371
+ job_id: string | null;
370
372
  }, StandardError, {
371
373
  checkinId: string;
372
374
  }>>;
373
375
  checkInToJob(jobId: string, teamId?: string | null): Promise<{
374
376
  msg: string;
375
- id: string;
377
+ id: string | null;
378
+ job_id: string | null;
376
379
  }>;
377
380
  checkOut(checkinId: string): Promise<{
378
381
  msg: string;
379
382
  id: string;
383
+ job_id: string | null;
380
384
  }>;
381
385
  useImportBillsFromIntuit(): ReturnType<typeof useMutation<{
382
386
  msg: string;
@@ -107,13 +107,20 @@ const SOCKET_EVENT_CONFIG = {
107
107
  entityKey: 'companies',
108
108
  action: 'create',
109
109
  fetchPath: (id) => `/company/${id}`,
110
+ alsoInvalidate: [['/company/list']],
110
111
  },
111
112
  update_company: {
112
113
  entityKey: 'companies',
113
114
  action: 'update',
114
115
  fetchPath: (id) => `/company/${id}`,
116
+ alsoInvalidate: [['companies', 'current'], ['/company/list']],
117
+ },
118
+ delete_company: {
119
+ entityKey: 'companies',
120
+ action: 'delete',
121
+ fetchPath: null,
122
+ alsoInvalidate: [['companies', 'current'], ['/company/list']],
115
123
  },
116
- delete_company: { entityKey: 'companies', action: 'delete', fetchPath: null },
117
124
  // ── Users (no single-entity socket events) ──
118
125
  user_updated: { invalidateKeys: [['users'], ['user']] },
119
126
  update_users: { invalidateKeys: [['users'], ['user']] },
@@ -330,7 +337,18 @@ const SOCKET_EVENT_CONFIG = {
330
337
  },
331
338
  // ── Scheduling ──
332
339
  schedule_complete: {
333
- invalidateKeys: [['routes'], ['jobs'], ['infinite', 'jobs'], ['companies']],
340
+ invalidateKeys: [
341
+ ['routes'],
342
+ ['jobs'],
343
+ ['infinite', 'jobs'],
344
+ ['companies'],
345
+ ['/company/list'],
346
+ ],
347
+ },
348
+ // Terminal failure of a scheduling run: refetch companies so the
349
+ // "scheduling in progress" banner (company.schedule_locked) clears
350
+ scheduling_error: {
351
+ invalidateKeys: [['companies'], ['/company/list']],
334
352
  },
335
353
  // ── Location ──
336
354
  location_update: { invalidateKeys: [['teams']] },
@@ -782,11 +800,11 @@ export class AvroQueryClient {
782
800
  return undefined;
783
801
  }
784
802
  try {
785
- const raw = await queryClient.fetchQuery({
786
- queryKey: [entityKey, id],
787
- queryFn: () => this.get({ path: fetchPath }),
788
- staleTime: 0,
789
- });
803
+ // Direct fetch, not fetchQuery: fetchQuery would return an
804
+ // already-in-flight (older) request for the same entity,
805
+ // losing the newer state when socket events arrive in a
806
+ // burst (e.g. auto-checkout followed by check-in)
807
+ const raw = await this.get({ path: fetchPath });
790
808
  const item = construct ? construct(raw) : raw;
791
809
  queryClient.setQueryData([entityKey, id], item);
792
810
  const matchingQueries = queryClient.getQueryCache().findAll({ predicate });
@@ -1,5 +1,29 @@
1
1
  import { useMutation, useQuery } from '@tanstack/react-query';
2
2
  import { AvroQueryClient } from '../../client/QueryClient';
3
+ import { Job } from '../../types/api/Job';
4
+ /**
5
+ * Refresh the caches a check-in mutation touches. Socket events cover
6
+ * connected clients, but the raw helpers run headless (background
7
+ * location task) where the socket is usually down — sync directly.
8
+ */
9
+ const syncCheckinCaches = async (client, jobId) => {
10
+ const queryClient = client.getQueryClient();
11
+ queryClient.invalidateQueries({ queryKey: ['checkins'] });
12
+ if (!jobId)
13
+ return;
14
+ try {
15
+ await client._syncEntity(queryClient, {
16
+ action: 'update',
17
+ entityKey: 'jobs',
18
+ id: jobId,
19
+ fetchPath: `/job/${jobId}`,
20
+ construct: (d) => new Job(d),
21
+ });
22
+ }
23
+ catch {
24
+ // Cache sync is best-effort; the mutation itself succeeded
25
+ }
26
+ };
3
27
  AvroQueryClient.prototype.useJobCheckins = function (jobId, params) {
4
28
  return useQuery({
5
29
  queryKey: ['checkins', jobId, params?.since ?? 'today'],
@@ -30,17 +54,21 @@ AvroQueryClient.prototype.useCheckOut = function () {
30
54
  });
31
55
  };
32
56
  // Raw helpers, safe outside React (headless background location task)
33
- AvroQueryClient.prototype.checkInToJob = function (jobId, teamId) {
34
- return this.post({
57
+ AvroQueryClient.prototype.checkInToJob = async function (jobId, teamId) {
58
+ const result = await this.post({
35
59
  path: `/job/${jobId}/checkin`,
36
60
  data: JSON.stringify(teamId ? { team_id: teamId } : {}),
37
61
  headers: { 'Content-Type': 'application/json' },
38
62
  });
63
+ await syncCheckinCaches(this, result.job_id ?? jobId);
64
+ return result;
39
65
  };
40
- AvroQueryClient.prototype.checkOut = function (checkinId) {
41
- return this.post({
66
+ AvroQueryClient.prototype.checkOut = async function (checkinId) {
67
+ const result = await this.post({
42
68
  path: `/checkin/${checkinId}/checkout`,
43
69
  data: JSON.stringify({}),
44
70
  headers: { 'Content-Type': 'application/json' },
45
71
  });
72
+ await syncCheckinCaches(this, result.job_id);
73
+ return result;
46
74
  };
@@ -44,7 +44,7 @@ AvroQueryClient.prototype.useGetActiveCompanySessions = function (params = {}) {
44
44
  for (const session of pageSessions) {
45
45
  const isOpen = session.time_ended == null ||
46
46
  session.time_ended <= 0 ||
47
- session.time_ended <= session.time_started;
47
+ session.time_ended < session.time_started;
48
48
  if (isOpen)
49
49
  openSessions.push(session);
50
50
  }
@@ -40,6 +40,7 @@ export interface Company {
40
40
  num_jobs: number;
41
41
  num_routes: number;
42
42
  schedule_locked: boolean;
43
+ schedule_locked_since: number | null;
43
44
  num_teams: number;
44
45
  num_skills: number;
45
46
  bills: Bill[];
@@ -238,8 +238,8 @@ export interface CheckIn {
238
238
  /** Wire shape for per-participant entries on an event update. */
239
239
  export interface EventUserUpdate {
240
240
  user_id: string;
241
- time_started?: number;
242
- time_ended?: number;
241
+ time_started?: number | null;
242
+ time_ended?: number | null;
243
243
  }
244
244
  /** Event update payload: _Event fields, but users use the wire shape. */
245
245
  export type EventUpdatePayload = Partial<Omit<_Event, 'users'>> & {
package/dist/version.d.ts CHANGED
@@ -1 +1 @@
1
- export declare const AVRO_JS_VERSION = "0.0.66";
1
+ export declare const AVRO_JS_VERSION = "0.0.68";
package/dist/version.js CHANGED
@@ -1,3 +1,3 @@
1
1
  // AUTO-GENERATED by scripts/gen-version.js — do not edit by hand.
2
2
  // Regenerated from package.json by the `prebuild` npm hook.
3
- export const AVRO_JS_VERSION = '0.0.66';
3
+ export const AVRO_JS_VERSION = '0.0.68';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@go-avro/avro-js",
3
- "version": "0.0.66",
3
+ "version": "0.0.68",
4
4
  "description": "JS client for Avro backend integration.",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",