@go-avro/avro-js 0.0.2-beta.134 → 0.0.2-beta.136

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,8 +17,11 @@ export class LocalStorage {
17
17
  this.key = 'cache_data';
18
18
  }
19
19
  async get(key) {
20
- const item = localStorage.getItem(this.key);
21
- return item ? JSON.parse(item) : null;
20
+ const item = JSON.parse(localStorage.getItem(this.key) ?? 'null');
21
+ if (typeof item !== 'object' || item === null) {
22
+ return null;
23
+ }
24
+ return item ? key ? item[key] ?? null : item : null;
22
25
  }
23
26
  async set(data) {
24
27
  const current = await this.get() || {};
@@ -0,0 +1,14 @@
1
+ import React, { ReactNode } from "react";
2
+ import { QueryClient } from "@tanstack/react-query";
3
+ import { AvroQueryClient, AvroQueryClientConfig } from "./QueryClient";
4
+ import { AuthManager } from "../auth/AuthManager";
5
+ export interface AvroQueryClientProviderProps {
6
+ baseUrl: string;
7
+ authManager: AuthManager;
8
+ queryClient?: QueryClient;
9
+ configOverrides?: Partial<AvroQueryClientConfig>;
10
+ children: ReactNode;
11
+ }
12
+ export declare const AvroQueryClientProvider: ({ baseUrl, authManager, configOverrides, children, }: AvroQueryClientProviderProps) => React.JSX.Element;
13
+ export declare const useAvroQueryClient: () => AvroQueryClient;
14
+ export default AvroQueryClientProvider;
@@ -0,0 +1,32 @@
1
+ import React, { createContext, useContext, useMemo, useEffect } from "react";
2
+ import { AvroQueryClient } from "./QueryClient";
3
+ const AvroQueryClientContext = createContext(null);
4
+ export const AvroQueryClientProvider = ({ baseUrl, authManager, configOverrides, children, }) => {
5
+ const client = useMemo(() => {
6
+ const cfg = {
7
+ baseUrl,
8
+ authManager,
9
+ ...(configOverrides || {}),
10
+ };
11
+ return new AvroQueryClient(cfg);
12
+ }, [baseUrl, authManager, configOverrides]);
13
+ useEffect(() => {
14
+ return () => {
15
+ try {
16
+ client.socket?.disconnect();
17
+ }
18
+ catch (e) {
19
+ // ignore
20
+ }
21
+ };
22
+ }, [client]);
23
+ return (React.createElement(AvroQueryClientContext.Provider, { value: client }, children));
24
+ };
25
+ export const useAvroQueryClient = () => {
26
+ const ctx = useContext(AvroQueryClientContext);
27
+ if (!ctx) {
28
+ throw new Error("useAvroQueryClient must be used within <AvroQueryClientProvider>");
29
+ }
30
+ return ctx;
31
+ };
32
+ export default AvroQueryClientProvider;
@@ -1,7 +1,7 @@
1
1
  import { Socket } from 'socket.io-client';
2
2
  import { InfiniteData, QueryClient, UseInfiniteQueryResult, useMutation, UseQueryResult } from '@tanstack/react-query';
3
3
  import { AuthManager } from '../auth/AuthManager';
4
- import { _Event, ApiInfo, Avro, Bill, Break, Chat, Company, FinancialInsightData, Job, EventInsightData, LoginResponse, Message, Plan, Route, ServiceMonth, Session, Team, User, UserCompanyAssociation, Skill } from '../types/api';
4
+ import { _Event, ApiInfo, Avro, Bill, Break, Chat, Company, FinancialInsightData, Job, EventInsightData, LoginResponse, Message, Plan, Route, ServiceMonth, Session, Team, User, UserCompanyAssociation, Skill, Group } from '../types/api';
5
5
  import { Tokens } from '../types/auth';
6
6
  import { CancelToken, RetryStrategy } from '../types/client';
7
7
  import { StandardError } from '../types/error';
@@ -9,7 +9,6 @@ import { CacheData } from '../types/cache';
9
9
  export interface AvroQueryClientConfig {
10
10
  baseUrl: string;
11
11
  authManager: AuthManager;
12
- queryClient: QueryClient;
13
12
  maxRetries?: number;
14
13
  retryStrategy?: RetryStrategy;
15
14
  timeout?: number;
@@ -87,6 +86,13 @@ declare module '../client/QueryClient' {
87
86
  query?: string;
88
87
  paid?: boolean;
89
88
  }): UseInfiniteQueryResult<InfiniteData<Bill[], unknown>, StandardError>;
89
+ useGetGroups(body: {
90
+ amt?: number;
91
+ known_ids?: string[];
92
+ unknown_ids?: string[];
93
+ query?: string;
94
+ offset?: number;
95
+ }, total: number, onProgress?: (fraction: number) => void): UseQueryResult<Group[], StandardError>;
90
96
  useGetPlans(code: string): UseQueryResult<Plan[], StandardError>;
91
97
  useGetCompanies(options?: {}): UseQueryResult<Company[], StandardError>;
92
98
  useGetAnalytics(): UseQueryResult<any, StandardError>;
@@ -109,6 +115,11 @@ declare module '../client/QueryClient' {
109
115
  useGetUserSessions(): UseQueryResult<Session[], StandardError>;
110
116
  useGetAvro(): UseQueryResult<Avro, StandardError>;
111
117
  useSearchUsers(searchUsername: string): UseQueryResult<User[], StandardError>;
118
+ useCreateGroup(): ReturnType<typeof useMutation<{
119
+ id: string;
120
+ }, StandardError, {
121
+ groupData: Partial<Group>;
122
+ }>>;
112
123
  useCreateSkill(): ReturnType<typeof useMutation<{
113
124
  id: string;
114
125
  }, StandardError, {
@@ -186,6 +197,12 @@ declare module '../client/QueryClient' {
186
197
  sessionId: string;
187
198
  updates: Partial<Session>;
188
199
  }>>;
200
+ useUpdateGroup(): ReturnType<typeof useMutation<{
201
+ msg: string;
202
+ }, StandardError, {
203
+ groupId: string;
204
+ groupData: Partial<Group>;
205
+ }>>;
189
206
  useUpdateJob(): ReturnType<typeof useMutation<{
190
207
  msg: string;
191
208
  }, StandardError, {
@@ -258,6 +275,11 @@ declare module '../client/QueryClient' {
258
275
  }, StandardError, {
259
276
  userId: string;
260
277
  }>>;
278
+ useDeleteGroup(): ReturnType<typeof useMutation<{
279
+ msg: string;
280
+ }, StandardError, {
281
+ groupId: string;
282
+ }>>;
261
283
  useDeleteEvent(): ReturnType<typeof useMutation<{
262
284
  msg: string;
263
285
  }, StandardError, {
@@ -414,6 +436,13 @@ export declare class AvroQueryClient {
414
436
  query?: string;
415
437
  offset?: number;
416
438
  }, cancelToken?: CancelToken, headers?: Record<string, string>): Promise<any>;
439
+ fetchGroups(body?: {
440
+ amt?: number;
441
+ known_ids?: string[];
442
+ unknown_ids?: string[];
443
+ query?: string;
444
+ offset?: number;
445
+ }, cancelToken?: CancelToken, headers?: Record<string, string>): Promise<any>;
417
446
  fetchSkills(body?: {
418
447
  amt?: number;
419
448
  known_ids?: string[];
@@ -1,5 +1,5 @@
1
1
  import io from 'socket.io-client';
2
- import { useMutation } from '@tanstack/react-query';
2
+ import { useMutation, useQueryClient } from '@tanstack/react-query';
3
3
  import { LoginResponse } from '../types/api';
4
4
  import { StandardError } from '../types/error';
5
5
  export class AvroQueryClient {
@@ -12,7 +12,6 @@ export class AvroQueryClient {
12
12
  this.config = {
13
13
  baseUrl: config.baseUrl,
14
14
  authManager: config.authManager,
15
- queryClient: config.queryClient,
16
15
  maxRetries: config.maxRetries ?? 3,
17
16
  retryStrategy: config.retryStrategy ?? 'fixed',
18
17
  timeout: config.timeout ?? 0,
@@ -233,7 +232,7 @@ export class AvroQueryClient {
233
232
  return this.config.authManager.isAuthenticated();
234
233
  }
235
234
  getQueryClient() {
236
- return this.config.queryClient;
235
+ return useQueryClient();
237
236
  }
238
237
  useLogout() {
239
238
  const queryClient = this.getQueryClient();
@@ -409,6 +408,25 @@ export class AvroQueryClient {
409
408
  throw new StandardError(500, 'Failed to fetch teams');
410
409
  });
411
410
  }
411
+ fetchGroups(body = {}, cancelToken, headers = {}) {
412
+ if (!this.companyId || this.companyId.trim() === '') {
413
+ throw new StandardError(400, 'Company ID is required');
414
+ }
415
+ return this._fetch('POST', `/company/${this.companyId}/groups`, JSON.stringify(body), cancelToken, {
416
+ ...headers,
417
+ 'Content-Type': 'application/json',
418
+ })
419
+ .then(response => {
420
+ if (!response || !Array.isArray(response)) {
421
+ throw new StandardError(400, 'Invalid groups response');
422
+ }
423
+ return response;
424
+ })
425
+ .catch(err => {
426
+ console.error('Failed to fetch groups:', err);
427
+ throw new StandardError(500, 'Failed to fetch groups');
428
+ });
429
+ }
412
430
  fetchSkills(body = {}, cancelToken, headers = {}) {
413
431
  if (!this.companyId || this.companyId.trim() === '') {
414
432
  throw new StandardError(400, 'Company ID is required');
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,130 @@
1
+ import { useMutation, useQuery } from "@tanstack/react-query";
2
+ import { AvroQueryClient } from "../../client/QueryClient";
3
+ AvroQueryClient.prototype.useGetGroups = function (body, total, onProgress) {
4
+ return useQuery({
5
+ queryKey: ['groups', this.companyId, body.amt ?? 50, body.query ?? "", total ?? "all"],
6
+ queryFn: async () => {
7
+ if (typeof total !== "number") {
8
+ return this.fetchGroups({ ...body, offset: 0 });
9
+ }
10
+ onProgress?.(0);
11
+ const pageCount = body.amt ? Math.ceil(total / body.amt) + 1 : 1;
12
+ let completed = 0;
13
+ const promises = Array.from({ length: pageCount }, (_, i) => this.fetchGroups({
14
+ ...body,
15
+ offset: i * (body.amt ?? 1),
16
+ }));
17
+ const trackedPromises = promises.map((promise) => promise.then((result) => {
18
+ completed++;
19
+ const fraction = completed / pageCount;
20
+ onProgress?.(fraction);
21
+ return result;
22
+ }));
23
+ const pages = await Promise.all(trackedPromises);
24
+ const groups = pages.flat();
25
+ return groups;
26
+ },
27
+ });
28
+ };
29
+ AvroQueryClient.prototype.useCreateGroup = function () {
30
+ const queryClient = this.getQueryClient();
31
+ return useMutation({
32
+ mutationFn: async ({ groupData }) => {
33
+ return this.post(`/company/${this.companyId}/group`, JSON.stringify(groupData), undefined, { "Content-Type": "application/json" });
34
+ },
35
+ onSettled: () => {
36
+ queryClient.invalidateQueries({ queryKey: ['company'] });
37
+ queryClient.invalidateQueries({ queryKey: ['groups'] });
38
+ },
39
+ });
40
+ };
41
+ AvroQueryClient.prototype.useUpdateGroup = function () {
42
+ const queryClient = this.getQueryClient();
43
+ return useMutation({
44
+ mutationFn: async ({ groupId, groupData }) => {
45
+ return this.put(`/group/${groupId}`, JSON.stringify(groupData), undefined, { "Content-Type": "application/json" });
46
+ },
47
+ onMutate: async ({ groupId, groupData }) => {
48
+ await queryClient.cancelQueries({ queryKey: ['groups'] });
49
+ await queryClient.cancelQueries({ queryKey: ['group', groupId] });
50
+ const previousGroups = queryClient.getQueryData(['groups']);
51
+ const previousGroup = queryClient.getQueryData(['group', groupId]);
52
+ queryClient.setQueryData(['group', groupId], (oldData) => {
53
+ if (!oldData)
54
+ return oldData;
55
+ return { ...oldData, ...groupData };
56
+ });
57
+ queryClient.setQueriesData({ queryKey: ['groups'] }, (oldData) => {
58
+ if (!oldData)
59
+ return oldData;
60
+ if (oldData.pages) {
61
+ const updatedPages = oldData.pages.map((page) => page.map((group) => group.id === groupId ? { ...group, ...groupData } : group));
62
+ return { ...oldData, pages: updatedPages };
63
+ }
64
+ if (Array.isArray(oldData)) {
65
+ return oldData.map((group) => group.id === groupId ? { ...group, ...groupData } : group);
66
+ }
67
+ return oldData;
68
+ });
69
+ return { previousGroups, previousGroup };
70
+ },
71
+ onError: (_err, variables, context) => {
72
+ const { groupId } = variables;
73
+ if (context?.previousGroups) {
74
+ queryClient.setQueryData(['groups'], context.previousGroups);
75
+ }
76
+ if (context?.previousGroup) {
77
+ queryClient.setQueryData(['group', groupId], context.previousGroup);
78
+ }
79
+ },
80
+ onSettled: (_data, _error, variables) => {
81
+ const { groupId } = variables;
82
+ queryClient.invalidateQueries({ queryKey: ['groups'] });
83
+ queryClient.invalidateQueries({ queryKey: ['group', groupId] });
84
+ queryClient.invalidateQueries({ queryKey: ['company'] });
85
+ },
86
+ });
87
+ };
88
+ AvroQueryClient.prototype.useDeleteGroup = function () {
89
+ const queryClient = this.getQueryClient();
90
+ return useMutation({
91
+ mutationFn: async ({ groupId, }) => {
92
+ return this.delete(`/group/${groupId}`);
93
+ },
94
+ onMutate: async ({ groupId }) => {
95
+ await queryClient.cancelQueries({ queryKey: ['groups'] });
96
+ await queryClient.cancelQueries({ queryKey: ['group', groupId] });
97
+ const previousGroups = queryClient.getQueryData(['groups']);
98
+ const previousGroup = queryClient.getQueryData(['group', groupId]);
99
+ queryClient.setQueryData(['group', groupId], undefined);
100
+ queryClient.setQueriesData({ queryKey: ['groups'] }, (oldData) => {
101
+ if (!oldData)
102
+ return oldData;
103
+ if (oldData.pages) {
104
+ const updatedPages = oldData.pages.map((page) => page.filter((group) => group.id !== groupId));
105
+ return { ...oldData, pages: updatedPages };
106
+ }
107
+ if (Array.isArray(oldData)) {
108
+ return oldData.filter((group) => group.id !== groupId);
109
+ }
110
+ return oldData;
111
+ });
112
+ return { previousGroups, previousGroup };
113
+ },
114
+ onError: (_err, variables, context) => {
115
+ const { groupId } = variables;
116
+ if (context?.previousGroups) {
117
+ queryClient.setQueryData(['groups'], context.previousGroups);
118
+ }
119
+ if (context?.previousGroup) {
120
+ queryClient.setQueryData(['group', groupId], context.previousGroup);
121
+ }
122
+ },
123
+ onSettled: (_data, _error, variables) => {
124
+ const { groupId } = variables;
125
+ queryClient.invalidateQueries({ queryKey: ['groups'] });
126
+ queryClient.invalidateQueries({ queryKey: ['group', groupId] });
127
+ queryClient.invalidateQueries({ queryKey: ['company'] });
128
+ },
129
+ });
130
+ };
package/dist/index.d.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  export { AvroQueryClientConfig, AvroQueryClient } from './client/QueryClient';
2
+ export { AvroQueryClientProvider } from './client/AvroQueryClientProvider';
2
3
  export { AuthManager } from './auth/AuthManager';
3
4
  export { MemoryStorage, LocalStorage } from './auth/storage';
4
5
  import './client/core/xhr';
@@ -19,6 +20,7 @@ import './client/hooks/plans';
19
20
  import './client/hooks/analytics';
20
21
  import './client/hooks/avro';
21
22
  import './client/hooks/teams';
23
+ import './client/hooks/groups';
22
24
  import './client/hooks/skills';
23
25
  export * from './types/api';
24
26
  export * from './types/auth';
package/dist/index.js CHANGED
@@ -1,4 +1,5 @@
1
1
  export { AvroQueryClient } from './client/QueryClient';
2
+ export { AvroQueryClientProvider } from './client/AvroQueryClientProvider';
2
3
  export { AuthManager } from './auth/AuthManager';
3
4
  export { MemoryStorage, LocalStorage } from './auth/storage';
4
5
  import './client/core/xhr';
@@ -19,6 +20,7 @@ import './client/hooks/plans';
19
20
  import './client/hooks/analytics';
20
21
  import './client/hooks/avro';
21
22
  import './client/hooks/teams';
23
+ import './client/hooks/groups';
22
24
  import './client/hooks/skills';
23
25
  export * from './types/api';
24
26
  export * from './types/auth';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@go-avro/avro-js",
3
- "version": "0.0.2-beta.134",
3
+ "version": "0.0.2-beta.136",
4
4
  "description": "JS client for Avro backend integration.",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",