@betterinternship/components 1.5.13 → 1.5.15

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.
@@ -44,7 +44,7 @@ export declare const ClientProcessesProvider: ({ children }: {
44
44
  * @returns
45
45
  */
46
46
  export declare function useClientProcess<T>({ caller, filterKey, onLoading, onSuccess, onFailure, }: {
47
- caller: (inputs: T) => Promise<ProcessResponse>;
47
+ caller?: (inputs: T) => Promise<ProcessResponse>;
48
48
  filterKey: string;
49
49
  onLoading?: (processId: string, processName: string) => void;
50
50
  onSuccess?: <R>(processId: string, processName: string, result: R) => void;
@@ -54,9 +54,16 @@ export declare function useClientProcess<T>({ caller, filterKey, onLoading, onSu
54
54
  id: string;
55
55
  success: boolean;
56
56
  message: string | undefined;
57
+ } | {
58
+ id: null;
59
+ success: boolean;
60
+ message: string;
57
61
  }>;
58
62
  get: (id: string) => ClientProcess<unknown> | null;
59
63
  getAll: () => ClientProcess<unknown>[];
64
+ getAllPending: () => ClientProcess<unknown>[];
65
+ getAllHandled: () => ClientProcess<unknown>[];
66
+ getAllFailed: () => ClientProcess<unknown>[];
60
67
  cp: UseQueryResult[];
61
68
  };
62
69
  export {};
@@ -10,12 +10,16 @@ import { config } from '../config.js';
10
10
  * @param processId
11
11
  * @returns
12
12
  */
13
- const processStatusChecker = (processId) => fetch(`${config.orchestratorApi}/${encodeURIComponent(processId)}`, {
14
- method: 'GET',
15
- headers: {
16
- 'Content-Type': 'application/json',
17
- },
18
- }).then((response) => response.json());
13
+ const processStatusChecker = (processId) => {
14
+ if (!processId)
15
+ return { process: null };
16
+ return fetch(`${config.orchestratorApi}/${encodeURIComponent(processId)}`, {
17
+ method: 'GET',
18
+ headers: {
19
+ 'Content-Type': 'application/json',
20
+ },
21
+ }).then((response) => response.json());
22
+ };
19
23
  /**
20
24
  * This fetches from the callback endpoint.
21
25
  *
@@ -48,13 +52,14 @@ const ClientProcessesProvider = ({ children }) => {
48
52
  const clientProcesses = useQueries({
49
53
  queries: Object.entries(clientProcessDtos).map(([processId, { dto, options }]) => ({
50
54
  staleTime: Infinity,
55
+ gcTime: Infinity,
51
56
  queryKey: ['.__process', processId],
52
57
  queryFn: async () => {
53
58
  if (!processId)
54
59
  throw new Error('No processId');
55
60
  const { process } = await processStatusChecker(processId);
56
61
  // Handled! Return the proper response too
57
- if (process.status === 'handled') {
62
+ if (process?.status === 'handled') {
58
63
  const result = await processCallbackResultFetcher(process.id, process.name, dto.processCallbackUrl);
59
64
  // Log and call runner
60
65
  console.warn(`Handled ${process.name} (${process.id})!`);
@@ -67,17 +72,17 @@ const ClientProcessesProvider = ({ children }) => {
67
72
  };
68
73
  }
69
74
  // Pending or failed
70
- if (process.status === 'pending') {
75
+ if (process?.status === 'pending') {
71
76
  console.log(`Running process ${process.name} (${process.id})...`);
72
77
  options?.onLoading?.(process.id, process.name);
73
78
  return { id: process.id, name: process.name, pending: true };
74
79
  }
75
- else if (process.status === 'failed') {
80
+ else if (process?.status === 'failed') {
76
81
  console.error(`Failed ${process.name} (${process.id}) - ${process.error}.`);
77
82
  return { id: process.id, name: process.name, success: false };
78
83
  }
79
84
  // Return null since no response
80
- return { id: process.id, name: process.name, pending: true };
85
+ return { id: process?.id, name: process?.name, pending: true };
81
86
  },
82
87
  // Returns the next interval length to use to wait for fetch
83
88
  refetchInterval: (query) => {
@@ -114,11 +119,12 @@ const ClientProcessesProvider = ({ children }) => {
114
119
  */
115
120
  const getProcess = (processId) => {
116
121
  const clientProcess = clientProcesses.find((clientProcess) => clientProcess.data?.id === processId)?.data ?? null;
117
- return (clientProcess &&
118
- {
122
+ return clientProcess?.id
123
+ ? {
119
124
  ...clientProcess,
120
125
  metadata: clientProcessDtos[clientProcess.id].metadata,
121
- });
126
+ }
127
+ : null;
122
128
  };
123
129
  /**
124
130
  * Filters processes by the provided attribute.
@@ -153,22 +159,38 @@ function useClientProcess({ caller, filterKey, onLoading, onSuccess, onFailure,
153
159
  // Client should be oblivious to those
154
160
  // Abstraction BABY!
155
161
  const wrappedCaller = async (inputs, metadata) => {
156
- const response = await caller(inputs);
157
- clientProcessesApi.registerProcess(response.processId, response, { filterKey, metadata }, {
158
- onLoading,
159
- onSuccess,
160
- onFailure,
161
- });
162
+ const response = await caller?.(inputs);
163
+ if (response) {
164
+ clientProcessesApi.registerProcess(response.processId, response, { filterKey, metadata }, {
165
+ onLoading,
166
+ onSuccess,
167
+ onFailure,
168
+ });
169
+ return {
170
+ id: response.processId,
171
+ success: response.success,
172
+ message: response.message,
173
+ };
174
+ }
162
175
  return {
163
- id: response.processId,
164
- success: response.success,
165
- message: response.message,
176
+ id: null,
177
+ success: false,
178
+ message: 'No `caller` specified for useClientProcess().',
166
179
  };
167
180
  };
168
181
  return {
169
182
  run: wrappedCaller,
170
183
  get: (id) => clientProcessesApi.getProcess(id),
171
184
  getAll: () => clientProcessesApi.filterProcesses(filterKey),
185
+ getAllPending: () => clientProcessesApi
186
+ .filterProcesses(filterKey)
187
+ .filter((process) => process.pending),
188
+ getAllHandled: () => clientProcessesApi
189
+ .filterProcesses(filterKey)
190
+ .filter((process) => process.success),
191
+ getAllFailed: () => clientProcessesApi
192
+ .filterProcesses(filterKey)
193
+ .filter((process) => !process.success),
172
194
  cp: clientProcessesApi.cp,
173
195
  };
174
196
  }
@@ -1 +1 @@
1
- {"version":3,"file":"useClientProcess.js","sources":["../../src/hooks/useClientProcess.tsx"],"sourcesContent":["'use client';\r\n\r\nimport { useState, useRef, createContext, useContext } from 'react';\r\nimport { Query, useQueries, UseQueryResult } from '@tanstack/react-query';\r\nimport { config } from '../config';\r\n\r\ntype ProcessStatus = 'pending' | 'handled' | 'failed';\r\n\r\ninterface Process<T> {\r\n id: string;\r\n name: string;\r\n status: ProcessStatus;\r\n result?: T;\r\n error?: string;\r\n timestamp: string;\r\n}\r\n\r\ninterface ClientProcess<T> {\r\n id: string;\r\n name: string;\r\n result?: T;\r\n metadata?: ClientProcessMetadata;\r\n success?: boolean;\r\n pending?: boolean;\r\n error?: string;\r\n}\r\n\r\nexport interface ProcessCallbackDto {\r\n processId: string;\r\n processName: string;\r\n processCallbackUrl: string;\r\n}\r\n\r\nexport interface ClientProcessOptions {\r\n onLoading?: (processId: string, processName: string) => void;\r\n onSuccess?: <R>(processId: string, processName: string, result: R) => void;\r\n onFailure?: (processId: string, processName: string, error?: string) => void;\r\n}\r\n\r\nexport interface ClientProcessMetadata {\r\n filterKey: string;\r\n metadata?: Record<string, string>;\r\n}\r\n\r\nexport interface ProcessResponse {\r\n processId: string;\r\n processName: string;\r\n processCallbackUrl: string;\r\n success: boolean;\r\n message?: string;\r\n}\r\n\r\n/**\r\n * The orchestrator service to get the process from.\r\n *\r\n * @param processId\r\n * @returns\r\n */\r\nconst processStatusChecker = <T,>(processId: string) =>\r\n fetch(`${config.orchestratorApi}/${encodeURIComponent(processId)}`, {\r\n method: 'GET',\r\n headers: {\r\n 'Content-Type': 'application/json',\r\n },\r\n }).then((response) => response.json()) as unknown as Promise<{\r\n process: Omit<Process<T>, 'result'>;\r\n }>;\r\n\r\n/**\r\n * This fetches from the callback endpoint.\r\n *\r\n * @param processId\r\n * @returns\r\n */\r\nconst processCallbackResultFetcher = <T,>(\r\n processId: string,\r\n processName: string,\r\n processCallbackUrl?: string,\r\n) =>\r\n fetch(`${processCallbackUrl}`, {\r\n method: 'POST',\r\n headers: {\r\n 'Content-Type': 'application/json',\r\n },\r\n body: JSON.stringify({\r\n processId,\r\n processName,\r\n }),\r\n }).then((response) => response.json()) as unknown as Promise<T>;\r\n\r\ninterface ClientProcesses {\r\n registerProcess: (\r\n processId: string,\r\n dto: ProcessCallbackDto,\r\n metadata: ClientProcessMetadata,\r\n options?: ClientProcessOptions,\r\n ) => void;\r\n getProcess: <T>(processId: string) => ClientProcess<T> | null;\r\n filterProcesses: <T>(filter: string) => ClientProcess<T>[];\r\n cp: UseQueryResult[];\r\n}\r\n\r\n/**\r\n * We need a context to keep track of all client processes.\r\n * This helps us manage the state of the toasts as well.\r\n */\r\nconst clientProcessesContext = createContext<ClientProcesses>(\r\n {} as ClientProcesses,\r\n);\r\n\r\n/**\r\n * This should be at the root layout.\r\n *\r\n * @context\r\n */\r\nexport const ClientProcessesProvider = ({ children }: { children: React.ReactNode }) => {\r\n const clientProcessAttempts = useRef<Record<string, number>>({});\r\n const [clientProcessDtos, setClientProcessDtos] = useState<\r\n Record<\r\n string,\r\n {\r\n dto: ProcessCallbackDto;\r\n metadata: ClientProcessMetadata;\r\n options?: ClientProcessOptions;\r\n }\r\n >\r\n >({});\r\n\r\n const clientProcesses = useQueries({\r\n queries: Object.entries(clientProcessDtos).map(\r\n ([processId, { dto, options }]) => ({\r\n staleTime: Infinity,\r\n queryKey: ['.__process', processId],\r\n queryFn: async () => {\r\n if (!processId) throw new Error('No processId');\r\n const { process } = await processStatusChecker(processId);\r\n\r\n // Handled! Return the proper response too\r\n if (process.status === 'handled') {\r\n const result = await processCallbackResultFetcher(\r\n process.id,\r\n process.name,\r\n dto.processCallbackUrl,\r\n );\r\n\r\n // Log and call runner\r\n console.warn(`Handled ${process.name} (${process.id})!`);\r\n options?.onSuccess?.(process.id, process.name, result);\r\n\r\n return {\r\n id: process.id,\r\n name: process.name,\r\n success: true,\r\n result,\r\n };\r\n }\r\n\r\n // Pending or failed\r\n if (process.status === 'pending') {\r\n console.log(`Running process ${process.name} (${process.id})...`);\r\n options?.onLoading?.(process.id, process.name);\r\n return { id: process.id, name: process.name, pending: true };\r\n } else if (process.status === 'failed') {\r\n console.error(\r\n `Failed ${process.name} (${process.id}) - ${process.error}.`,\r\n );\r\n return { id: process.id, name: process.name, success: false };\r\n }\r\n\r\n // Return null since no response\r\n return { id: process.id, name: process.name, pending: true };\r\n },\r\n\r\n // Returns the next interval length to use to wait for fetch\r\n refetchInterval: <T,>(query: Query) => {\r\n const data = query.state.data as ClientProcess<T>;\r\n if (data?.success !== undefined) return false;\r\n\r\n // If not defined, init to 0\r\n if (!clientProcessAttempts.current[processId])\r\n clientProcessAttempts.current[processId] = 0;\r\n\r\n const interval = Math.min(\r\n 500 * 2 ** clientProcessAttempts.current[processId],\r\n 10000,\r\n );\r\n\r\n clientProcessAttempts.current[processId] += 1;\r\n return interval;\r\n },\r\n }),\r\n ),\r\n });\r\n\r\n /**\r\n * Registers a new process to handle\r\n *\r\n * @param processId\r\n * @param processCallbackDto\r\n * @param options\r\n */\r\n const registerProcess = (\r\n processId: string,\r\n processCallbackDto: ProcessCallbackDto,\r\n metadata: ClientProcessMetadata,\r\n options?: ClientProcessOptions,\r\n ) => {\r\n setClientProcessDtos({\r\n ...clientProcessDtos,\r\n [processId]: { dto: processCallbackDto, metadata, options },\r\n });\r\n };\r\n\r\n /**\r\n * Retrieves a process\r\n *\r\n * @param processId\r\n * @returns\r\n */\r\n const getProcess = <T,>(processId: string) => {\r\n const clientProcess =\r\n clientProcesses.find(\r\n (clientProcess) => clientProcess.data?.id === processId,\r\n )?.data ?? null;\r\n\r\n return (\r\n clientProcess &&\r\n ({\r\n ...clientProcess,\r\n metadata: clientProcessDtos[clientProcess.id].metadata,\r\n } as ClientProcess<T>)\r\n );\r\n };\r\n\r\n /**\r\n * Filters processes by the provided attribute.\r\n *\r\n * @param filterKey\r\n */\r\n const filterProcesses = <T,>(filterKey: string) => {\r\n return clientProcesses\r\n .filter(\r\n (clientProcess) => !!clientProcess.data && !!clientProcess.data.id,\r\n )\r\n .map((clientProcess) => ({\r\n ...clientProcess.data!,\r\n metadata: clientProcessDtos[clientProcess.data!.id].metadata,\r\n }))\r\n .filter(\r\n (clientProcessData) =>\r\n clientProcessData.metadata.filterKey === filterKey,\r\n ) as ClientProcess<T>[];\r\n };\r\n\r\n return (\r\n <clientProcessesContext.Provider\r\n value={{\r\n registerProcess,\r\n getProcess,\r\n filterProcesses,\r\n cp: clientProcesses,\r\n }}\r\n >\r\n {children}\r\n </clientProcessesContext.Provider>\r\n );\r\n};;;;\r\n\r\n/**\r\n * A simpler version, where u just pass the async function that returns process data.\r\n *\r\n * @param caller\r\n * @returns\r\n */\r\nexport function useClientProcess<T>({\r\n caller,\r\n filterKey,\r\n onLoading,\r\n onSuccess,\r\n onFailure,\r\n}: {\r\n caller: (inputs: T) => Promise<ProcessResponse>;\r\n filterKey: string;\r\n onLoading?: (processId: string, processName: string) => void;\r\n onSuccess?: <R>(processId: string, processName: string, result: R) => void;\r\n onFailure?: (processId: string, processName: string, error?: string) => void;\r\n}) {\r\n const clientProcessesApi = useContext(clientProcessesContext);\r\n\r\n // Note that the exposed function doesn't return process ids\r\n // Client should be oblivious to those\r\n // Abstraction BABY!\r\n const wrappedCaller = async (\r\n inputs: T,\r\n metadata?: Record<string, string>,\r\n ) => {\r\n const response = await caller(inputs);\r\n clientProcessesApi.registerProcess(\r\n response.processId,\r\n response,\r\n { filterKey, metadata },\r\n {\r\n onLoading,\r\n onSuccess,\r\n onFailure,\r\n },\r\n );\r\n\r\n return {\r\n id: response.processId,\r\n success: response.success,\r\n message: response.message,\r\n };\r\n };\r\n\r\n return {\r\n run: wrappedCaller,\r\n get: (id: string) => clientProcessesApi.getProcess(id),\r\n getAll: () => clientProcessesApi.filterProcesses(filterKey),\r\n cp: clientProcessesApi.cp,\r\n };\r\n}"],"names":[],"mappings":";;;;;;AAoDA;;;;;AAKG;AACH;AAEI;AACA;AACE;AACD;AACF;AAIH;;;;;AAKG;AACH;AAMI;AACA;AACE;AACD;AACD;;;;AAID;AAcH;;;AAGG;AACH;AAIA;;;;AAIG;;AAED;;;;AAeM;AACA;;AAEE;AAAgB;;;AAIhB;AACE;;AAOA;AACA;;;;AAKE;;;;;AAMJ;AACE;AACA;AACA;;AACK;AACL;AAGA;;;AAIF;;;AAIF;AACE;AACA;AAAiC;;AAGjC;AACE;AAEF;AAKA;AACA;;AAEH;AAEJ;AAED;;;;;;AAMG;;AAOD;AACE;;AAED;AACH;AAEA;;;;;AAKG;AACH;;AAME;AAEG;AACC;;AAEoB;AAE1B;AAEA;;;;AAIG;AACH;AACE;AACG;AAGA;;;AAGA;AACA;AAIL;AAEA;;;;AAMM;;AAMR;AAEA;;;;;AAKG;AACG;AAaJ;;;;;AASE;AACA;;;;AAQG;;;;;;AAQL;;AAGE;;;;;AAKJ;;"}
1
+ {"version":3,"file":"useClientProcess.js","sources":["../../src/hooks/useClientProcess.tsx"],"sourcesContent":["'use client';\r\n\r\nimport { useState, useRef, createContext, useContext } from 'react';\r\nimport { Query, useQueries, UseQueryResult } from '@tanstack/react-query';\r\nimport { config } from '../config';\r\n\r\ntype ProcessStatus = 'pending' | 'handled' | 'failed';\r\n\r\ninterface Process<T> {\r\n id: string;\r\n name: string;\r\n status: ProcessStatus;\r\n result?: T;\r\n error?: string;\r\n timestamp: string;\r\n}\r\n\r\ninterface ClientProcess<T> {\r\n id: string;\r\n name: string;\r\n result?: T;\r\n metadata?: ClientProcessMetadata;\r\n success?: boolean;\r\n pending?: boolean;\r\n error?: string;\r\n}\r\n\r\nexport interface ProcessCallbackDto {\r\n processId: string;\r\n processName: string;\r\n processCallbackUrl: string;\r\n}\r\n\r\nexport interface ClientProcessOptions {\r\n onLoading?: (processId: string, processName: string) => void;\r\n onSuccess?: <R>(processId: string, processName: string, result: R) => void;\r\n onFailure?: (processId: string, processName: string, error?: string) => void;\r\n}\r\n\r\nexport interface ClientProcessMetadata {\r\n filterKey: string;\r\n metadata?: Record<string, string>;\r\n}\r\n\r\nexport interface ProcessResponse {\r\n processId: string;\r\n processName: string;\r\n processCallbackUrl: string;\r\n success: boolean;\r\n message?: string;\r\n}\r\n\r\n/**\r\n * The orchestrator service to get the process from.\r\n *\r\n * @param processId\r\n * @returns\r\n */\r\nconst processStatusChecker = <T,>(processId: string) => {\r\n if (!processId) return { process: null };\r\n return fetch(`${config.orchestratorApi}/${encodeURIComponent(processId)}`, {\r\n method: 'GET',\r\n headers: {\r\n 'Content-Type': 'application/json',\r\n },\r\n }).then((response) => response.json()) as unknown as Promise<{\r\n process: Omit<Process<T>, 'result'>;\r\n }>;\r\n};\r\n\r\n/**\r\n * This fetches from the callback endpoint.\r\n *\r\n * @param processId\r\n * @returns\r\n */\r\nconst processCallbackResultFetcher = <T,>(\r\n processId: string,\r\n processName: string,\r\n processCallbackUrl?: string,\r\n) =>\r\n fetch(`${processCallbackUrl}`, {\r\n method: 'POST',\r\n headers: {\r\n 'Content-Type': 'application/json',\r\n },\r\n body: JSON.stringify({\r\n processId,\r\n processName,\r\n }),\r\n }).then((response) => response.json()) as unknown as Promise<T>;\r\n\r\ninterface ClientProcesses {\r\n registerProcess: (\r\n processId: string,\r\n dto: ProcessCallbackDto,\r\n metadata: ClientProcessMetadata,\r\n options?: ClientProcessOptions,\r\n ) => void;\r\n getProcess: <T>(processId: string) => ClientProcess<T> | null;\r\n filterProcesses: <T>(filter: string) => ClientProcess<T>[];\r\n cp: UseQueryResult[];\r\n}\r\n\r\n/**\r\n * We need a context to keep track of all client processes.\r\n * This helps us manage the state of the toasts as well.\r\n */\r\nconst clientProcessesContext = createContext<ClientProcesses>(\r\n {} as ClientProcesses,\r\n);\r\n\r\n/**\r\n * This should be at the root layout.\r\n *\r\n * @context\r\n */\r\nexport const ClientProcessesProvider = ({ children }: { children: React.ReactNode }) => {\r\n const clientProcessAttempts = useRef<Record<string, number>>({});\r\n const [clientProcessDtos, setClientProcessDtos] = useState<\r\n Record<\r\n string,\r\n {\r\n dto: ProcessCallbackDto;\r\n metadata: ClientProcessMetadata;\r\n options?: ClientProcessOptions;\r\n }\r\n >\r\n >({});\r\n\r\n const clientProcesses = useQueries({\r\n queries: Object.entries(clientProcessDtos).map(\r\n ([processId, { dto, options }]) => ({\r\n staleTime: Infinity,\r\n gcTime: Infinity,\r\n queryKey: ['.__process', processId],\r\n queryFn: async () => {\r\n if (!processId) throw new Error('No processId');\r\n const { process } = await processStatusChecker(processId);\r\n\r\n // Handled! Return the proper response too\r\n if (process?.status === 'handled') {\r\n const result = await processCallbackResultFetcher(\r\n process.id,\r\n process.name,\r\n dto.processCallbackUrl,\r\n );\r\n\r\n // Log and call runner\r\n console.warn(`Handled ${process.name} (${process.id})!`);\r\n options?.onSuccess?.(process.id, process.name, result);\r\n\r\n return {\r\n id: process.id,\r\n name: process.name,\r\n success: true,\r\n result,\r\n };\r\n }\r\n\r\n // Pending or failed\r\n if (process?.status === 'pending') {\r\n console.log(`Running process ${process.name} (${process.id})...`);\r\n options?.onLoading?.(process.id, process.name);\r\n return { id: process.id, name: process.name, pending: true };\r\n } else if (process?.status === 'failed') {\r\n console.error(\r\n `Failed ${process.name} (${process.id}) - ${process.error}.`,\r\n );\r\n return { id: process.id, name: process.name, success: false };\r\n }\r\n\r\n // Return null since no response\r\n return { id: process?.id, name: process?.name, pending: true };\r\n },\r\n\r\n // Returns the next interval length to use to wait for fetch\r\n refetchInterval: <T,>(query: Query) => {\r\n const data = query.state.data as ClientProcess<T>;\r\n if (data?.success !== undefined) return false;\r\n\r\n // If not defined, init to 0\r\n if (!clientProcessAttempts.current[processId])\r\n clientProcessAttempts.current[processId] = 0;\r\n\r\n const interval = Math.min(\r\n 500 * 2 ** clientProcessAttempts.current[processId],\r\n 10000,\r\n );\r\n\r\n clientProcessAttempts.current[processId] += 1;\r\n return interval;\r\n },\r\n }),\r\n ),\r\n });\r\n\r\n /**\r\n * Registers a new process to handle\r\n *\r\n * @param processId\r\n * @param processCallbackDto\r\n * @param options\r\n */\r\n const registerProcess = (\r\n processId: string,\r\n processCallbackDto: ProcessCallbackDto,\r\n metadata: ClientProcessMetadata,\r\n options?: ClientProcessOptions,\r\n ) => {\r\n setClientProcessDtos({\r\n ...clientProcessDtos,\r\n [processId]: { dto: processCallbackDto, metadata, options },\r\n });\r\n };\r\n\r\n /**\r\n * Retrieves a process\r\n *\r\n * @param processId\r\n * @returns\r\n */\r\n const getProcess = <T,>(processId: string) => {\r\n const clientProcess =\r\n clientProcesses.find(\r\n (clientProcess) => clientProcess.data?.id === processId,\r\n )?.data ?? null;\r\n\r\n return clientProcess?.id\r\n ? ({\r\n ...clientProcess,\r\n metadata: clientProcessDtos[clientProcess.id].metadata,\r\n } as ClientProcess<T>)\r\n : null;\r\n };\r\n\r\n /**\r\n * Filters processes by the provided attribute.\r\n *\r\n * @param filterKey\r\n */\r\n const filterProcesses = <T,>(filterKey: string) => {\r\n return clientProcesses\r\n .filter(\r\n (clientProcess) => !!clientProcess.data && !!clientProcess.data.id,\r\n )\r\n .map((clientProcess) => ({\r\n ...clientProcess.data!,\r\n metadata: clientProcessDtos[clientProcess.data!.id!].metadata,\r\n }))\r\n .filter(\r\n (clientProcessData) =>\r\n clientProcessData.metadata.filterKey === filterKey,\r\n ) as ClientProcess<T>[];\r\n };\r\n\r\n return (\r\n <clientProcessesContext.Provider\r\n value={{\r\n registerProcess,\r\n getProcess,\r\n filterProcesses,\r\n cp: clientProcesses,\r\n }}\r\n >\r\n {children}\r\n </clientProcessesContext.Provider>\r\n );\r\n}\r\n\r\n/**\r\n * A simpler version, where u just pass the async function that returns process data.\r\n *\r\n * @param caller\r\n * @returns\r\n */\r\nexport function useClientProcess<T>({\r\n caller,\r\n filterKey,\r\n onLoading,\r\n onSuccess,\r\n onFailure,\r\n}: {\r\n caller?: (inputs: T) => Promise<ProcessResponse>;\r\n filterKey: string;\r\n onLoading?: (processId: string, processName: string) => void;\r\n onSuccess?: <R>(processId: string, processName: string, result: R) => void;\r\n onFailure?: (processId: string, processName: string, error?: string) => void;\r\n}) {\r\n const clientProcessesApi = useContext(clientProcessesContext);\r\n\r\n // Note that the exposed function doesn't return process ids\r\n // Client should be oblivious to those\r\n // Abstraction BABY!\r\n const wrappedCaller = async (\r\n inputs: T,\r\n metadata?: Record<string, string>,\r\n ) => {\r\n const response = await caller?.(inputs);\r\n if (response) {\r\n clientProcessesApi.registerProcess(\r\n response.processId,\r\n response,\r\n { filterKey, metadata },\r\n {\r\n onLoading,\r\n onSuccess,\r\n onFailure,\r\n },\r\n );\r\n\r\n return {\r\n id: response.processId,\r\n success: response.success,\r\n message: response.message,\r\n };\r\n }\r\n\r\n return {\r\n id: null,\r\n success: false,\r\n message: 'No `caller` specified for useClientProcess().',\r\n };\r\n };\r\n\r\n return {\r\n run: wrappedCaller,\r\n get: (id: string) => clientProcessesApi.getProcess(id),\r\n getAll: () => clientProcessesApi.filterProcesses(filterKey),\r\n getAllPending: () =>\r\n clientProcessesApi\r\n .filterProcesses(filterKey)\r\n .filter((process) => process.pending),\r\n getAllHandled: () =>\r\n clientProcessesApi\r\n .filterProcesses(filterKey)\r\n .filter((process) => process.success),\r\n getAllFailed: () =>\r\n clientProcessesApi\r\n .filterProcesses(filterKey)\r\n .filter((process) => !process.success),\r\n cp: clientProcessesApi.cp,\r\n };\r\n}"],"names":[],"mappings":";;;;;;AAoDA;;;;;AAKG;AACH;AACE;AAAgB;AAChB;AACE;AACA;AACE;AACD;AACF;AAGH;AAEA;;;;;AAKG;AACH;AAMI;AACA;AACE;AACD;AACD;;;;AAID;AAcH;;;AAGG;AACH;AAIA;;;;AAIG;;AAED;;;;AAeM;AACA;AACA;;AAEE;AAAgB;;;AAIhB;AACE;;AAOA;AACA;;;;AAKE;;;;;AAMJ;AACE;AACA;AACA;;AACK;AACL;AAGA;;;AAIF;;;AAIF;AACE;AACA;AAAiC;;AAGjC;AACE;AAEF;AAKA;AACA;;AAEH;AAEJ;AAED;;;;;;AAMG;;AAOD;AACE;;AAED;AACH;AAEA;;;;;AAKG;AACH;;;AAOI;AACI;;AAEoB;;AAE5B;AAEA;;;;AAIG;AACH;AACE;AACG;AAGA;;;AAGA;AACA;AAIL;AAEA;;;;AAMM;;AAMR;AAEA;;;;;AAKG;AACG;AAaJ;;;;;;;AAWI;;;;AAQG;;;;;;;;AAWH;AACA;AACA;;AAEJ;;AAGE;;;AAGA;;;AAIA;;;AAIA;;;;;AAMJ;;"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@betterinternship/components",
3
- "version": "1.5.13",
3
+ "version": "1.5.15",
4
4
  "main": "dist/index.esm.js",
5
5
  "module": "dist/index.esm.js",
6
6
  "types": "dist/index.d.ts",