@go-avro/avro-js 0.0.39 → 0.0.42

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.
@@ -17,7 +17,10 @@ export const AvroQueryClientProvider = ({ baseUrl, authManager, queryClient, con
17
17
  return () => {
18
18
  try {
19
19
  client.teardownSocketInvalidation();
20
- client.socket?.disconnect();
20
+ // Socket is NOT disconnected here. Its lifecycle is managed by the
21
+ // AvroQueryClient constructor and token refresh callbacks.
22
+ // Disconnecting here breaks React StrictMode — the constructor's
23
+ // async connect flow has already completed, so the socket stays dead.
21
24
  }
22
25
  catch (e) {
23
26
  // ignore
@@ -1,7 +1,7 @@
1
1
  import io from "socket.io-client";
2
2
  import { useMutation, useQueryClient, } from "@tanstack/react-query";
3
3
  import { v4 as uuidv4 } from "uuid";
4
- import { Job, LoginResponse, } from "../types/api";
4
+ import { _Event, Job, LoginResponse, Route, } from "../types/api";
5
5
  import { AuthState } from "../types/auth";
6
6
  import { StandardError } from "../types/error";
7
7
  function isBulkEvent(c) {
@@ -53,11 +53,13 @@ const SOCKET_EVENT_CONFIG = {
53
53
  entityKey: "routes",
54
54
  action: "create",
55
55
  fetchPath: (id) => `/route/${id}`,
56
+ construct: (d) => new Route(d),
56
57
  },
57
58
  update_route: {
58
59
  entityKey: "routes",
59
60
  action: "update",
60
61
  fetchPath: (id) => `/route/${id}`,
62
+ construct: (d) => new Route(d),
61
63
  },
62
64
  delete_route: { entityKey: "routes", action: "delete", fetchPath: null },
63
65
  // ── Events (also refetch parent job — overdueness, last_event, etc.) ──
@@ -65,6 +67,7 @@ const SOCKET_EVENT_CONFIG = {
65
67
  entityKey: "events",
66
68
  action: "create",
67
69
  fetchPath: (id) => `/event/${id}`,
70
+ construct: (d) => new _Event(d),
68
71
  relatedRefetch: [
69
72
  {
70
73
  entityKey: "jobs",
@@ -78,6 +81,7 @@ const SOCKET_EVENT_CONFIG = {
78
81
  entityKey: "events",
79
82
  action: "update",
80
83
  fetchPath: (id) => `/event/${id}`,
84
+ construct: (d) => new _Event(d),
81
85
  relatedRefetch: [
82
86
  {
83
87
  entityKey: "jobs",
@@ -324,6 +328,7 @@ export class AvroQueryClient {
324
328
  if (isBulkEvent(config)) {
325
329
  // ── Bulk: invalidate all specified keys ──────────────
326
330
  const handler = () => {
331
+ console.log(`[socket-debug] bulk event: ${event}`, config.invalidateKeys);
327
332
  for (const key of config.invalidateKeys) {
328
333
  queryClient.invalidateQueries({ queryKey: key });
329
334
  }
@@ -335,9 +340,11 @@ export class AvroQueryClient {
335
340
  // ── Targeted: surgical cache update ──────────────────
336
341
  const { entityKey, action, fetchPath, idField, alsoInvalidate, relatedRefetch, } = config;
337
342
  const handler = async (data) => {
343
+ console.log(`[socket-debug] targeted event: ${event}`, data);
338
344
  const id = data?.[idField ?? "id"];
339
345
  // No id → old backend or malformed payload → full invalidation
340
346
  if (!id || typeof id !== "string") {
347
+ console.log(`[socket-debug] no id found, falling back to full invalidation for ${entityKey}`);
341
348
  invalidateEntity(entityKey);
342
349
  alsoInvalidate?.forEach((k) => queryClient.invalidateQueries({ queryKey: k }));
343
350
  return;
@@ -375,8 +382,13 @@ export class AvroQueryClient {
375
382
  }
376
383
  // Auto join/leave company room
377
384
  const joinCompanyRoom = () => {
385
+ console.log(`[socket-debug] joinCompanyRoom called, companyId=${this.companyId}, connected=${this.socket.connected}`);
378
386
  if (this.companyId) {
379
387
  this.socket.emit("join_company", { company_id: this.companyId });
388
+ console.log(`[socket-debug] emitted join_company for ${this.companyId}`);
389
+ }
390
+ else {
391
+ console.warn(`[socket-debug] joinCompanyRoom skipped — companyId is undefined`);
380
392
  }
381
393
  };
382
394
  this.socket.on("connect", joinCompanyRoom);
@@ -385,6 +397,7 @@ export class AvroQueryClient {
385
397
  if (this.socket.connected && this.companyId) {
386
398
  joinCompanyRoom();
387
399
  }
400
+ console.log(`[socket-debug] setupSocketInvalidation complete, socket.connected=${this.socket.connected}, companyId=${this.companyId}`);
388
401
  this._socketInvalidationCleanup = () => {
389
402
  for (const { event, handler } of handlers) {
390
403
  this.socket.off(event, handler);
@@ -567,12 +580,17 @@ export class AvroQueryClient {
567
580
  setCompanyId(companyId) {
568
581
  const previousId = this.companyId;
569
582
  this.companyId = companyId;
583
+ console.log(`[socket-debug] setCompanyId called: ${companyId}, socket.connected=${this.socket.connected}, prev=${previousId}`);
570
584
  // If the socket is already connected, leave the old room and join the new one.
571
585
  if (this.socket.connected) {
572
586
  if (previousId && previousId !== companyId) {
573
587
  this.socket.emit("leave_company", { company_id: previousId });
574
588
  }
575
589
  this.socket.emit("join_company", { company_id: companyId });
590
+ console.log(`[socket-debug] setCompanyId emitted join_company for ${companyId}`);
591
+ }
592
+ else {
593
+ console.warn(`[socket-debug] setCompanyId: socket not connected, will join on next connect`);
576
594
  }
577
595
  return this.config.authManager.setCompanyId(companyId);
578
596
  }
@@ -627,6 +645,7 @@ export class AvroQueryClient {
627
645
  */
628
646
  async _syncEntity(queryClient, params) {
629
647
  const { action, entityKey, id, fetchPath, construct } = params;
648
+ console.log(`[socket-debug] _syncEntity: action=${action}, entity=${entityKey}, id=${id}, fetchPath=${fetchPath}`);
630
649
  const predicate = (q) => matchesEntityKey(q, entityKey);
631
650
  const invalidate = () => queryClient.invalidateQueries({ predicate });
632
651
  // ─── DELETE ─────────────────────────────────────────
@@ -660,6 +679,7 @@ export class AvroQueryClient {
660
679
  staleTime: 0,
661
680
  });
662
681
  const item = construct ? construct(raw) : raw;
682
+ console.log(`[socket-debug] _syncEntity fetched ${entityKey}/${id}:`, item);
663
683
  queryClient.setQueryData([entityKey, id], item);
664
684
  if (action === "create") {
665
685
  queryClient.setQueriesData({ predicate, type: "active" }, (old) => {
@@ -698,9 +718,11 @@ export class AvroQueryClient {
698
718
  return old;
699
719
  });
700
720
  }
721
+ console.log(`[socket-debug] _syncEntity completed ${action} for ${entityKey}/${id}`);
701
722
  return item;
702
723
  }
703
- catch {
724
+ catch (err) {
725
+ console.error(`[socket-debug] _syncEntity fetch FAILED for ${entityKey}/${id}:`, err);
704
726
  invalidate();
705
727
  return undefined;
706
728
  }
@@ -32,14 +32,17 @@ AvroQueryClient.prototype.useGetCurrentCompany = function () {
32
32
  queryKey: ["companies", "current"],
33
33
  queryFn: async () => {
34
34
  if (!this.companyId) {
35
- this.companyId = await this.config.authManager.getCompanyId();
35
+ const storedId = await this.config.authManager.getCompanyId();
36
+ if (storedId) {
37
+ await this.setCompanyId(storedId);
38
+ }
36
39
  }
37
40
  if (!this.companyId) {
38
41
  const companyList = await this.get({
39
42
  path: `/company/list`,
40
43
  });
41
44
  if (companyList.length > 0) {
42
- this.companyId = companyList[0].id;
45
+ await this.setCompanyId(companyList[0].id);
43
46
  }
44
47
  else {
45
48
  throw new Error("No company ID set and no companies available");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@go-avro/avro-js",
3
- "version": "0.0.39",
3
+ "version": "0.0.42",
4
4
  "description": "JS client for Avro backend integration.",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",