@betterinternship/components 1.5.3 → 1.5.5

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.
@@ -4,9 +4,10 @@ export interface ProcessCallbackDto {
4
4
  processCallbackUrl: string;
5
5
  }
6
6
  export interface ClientProcessOptions {
7
- loadingMessage?: string;
8
- successMessage?: string;
9
- failureMessage?: string;
7
+ filter?: string;
8
+ onLoading?: (processId: string, processName: string) => void;
9
+ onSuccess?: <R>(processId: string, processName: string, result: R) => void;
10
+ onFailure?: (processId: string, processName: string, error?: string) => void;
10
11
  }
11
12
  export interface ProcessResponse {
12
13
  processId: string;
@@ -20,7 +21,7 @@ export interface ProcessResponse {
20
21
  *
21
22
  * @context
22
23
  */
23
- export declare const ClientProcessesProvider: ({ children }: {
24
+ export declare const ClientProcessesProvider: ({ children, }: {
24
25
  children: React.ReactNode;
25
26
  }) => import("react/jsx-runtime").JSX.Element;
26
27
  /**
@@ -29,11 +30,12 @@ export declare const ClientProcessesProvider: ({ children }: {
29
30
  * @param caller
30
31
  * @returns
31
32
  */
32
- export declare function useClientProcess<T, R>({ caller, loadingMessage, successMessage, failureMessage, }: {
33
+ export declare function useClientProcess<T>({ caller, filterKey, onLoading, onSuccess, onFailure, }: {
33
34
  caller: (inputs: T) => Promise<ProcessResponse>;
34
- loadingMessage?: string;
35
- successMessage?: string;
36
- failureMessage?: string;
35
+ filterKey: string;
36
+ onLoading?: (processId: string, processName: string) => void;
37
+ onSuccess?: <R>(processId: string, processName: string, result: R) => void;
38
+ onFailure?: (processId: string, processName: string, error?: string) => void;
37
39
  }): {
38
40
  run: (inputs: T) => Promise<{
39
41
  id: string;
@@ -46,4 +48,10 @@ export declare function useClientProcess<T, R>({ caller, loadingMessage, success
46
48
  result?: unknown;
47
49
  success: boolean;
48
50
  } | null;
51
+ getAll: () => {
52
+ id: string;
53
+ name: string;
54
+ result?: unknown;
55
+ success: boolean;
56
+ }[];
49
57
  };
@@ -3,7 +3,6 @@ import { j as jsxRuntimeExports } from '../_virtual/jsx-runtime.js';
3
3
  import { createContext, useState, useRef, useContext } from 'react';
4
4
  import { useQueries } from '@tanstack/react-query';
5
5
  import { config } from '../config.js';
6
- import { toast } from 'sonner';
7
6
 
8
7
  /**
9
8
  * The orchestrator service to get the process from.
@@ -12,9 +11,9 @@ import { toast } from 'sonner';
12
11
  * @returns
13
12
  */
14
13
  const processStatusChecker = (processId) => fetch(`${config.orchestratorApi}/${encodeURIComponent(processId)}`, {
15
- method: "GET",
14
+ method: 'GET',
16
15
  headers: {
17
- "Content-Type": "application/json",
16
+ 'Content-Type': 'application/json',
18
17
  },
19
18
  }).then((response) => response.json());
20
19
  /**
@@ -24,14 +23,14 @@ const processStatusChecker = (processId) => fetch(`${config.orchestratorApi}/${e
24
23
  * @returns
25
24
  */
26
25
  const processCallbackResultFetcher = (processId, processName, processCallbackUrl) => fetch(`${processCallbackUrl}`, {
27
- method: "POST",
26
+ method: 'POST',
28
27
  headers: {
29
- "Content-Type": "application/json",
28
+ 'Content-Type': 'application/json',
30
29
  },
31
30
  body: JSON.stringify({
32
31
  processId,
33
32
  processName,
34
- })
33
+ }),
35
34
  }).then((response) => response.json());
36
35
  /**
37
36
  * We need a context to keep track of all client processes.
@@ -43,40 +42,37 @@ const clientProcessesContext = createContext({});
43
42
  *
44
43
  * @context
45
44
  */
46
- const ClientProcessesProvider = ({ children }) => {
45
+ const ClientProcessesProvider = ({ children, }) => {
47
46
  const [clientProcessDtos, setClientProcessDtos] = useState({});
48
47
  const clientProcessAttempts = useRef({});
49
- const clientProcesses = useQueries({ queries: Object.entries(clientProcessDtos).map(([processId, { dto, options }]) => ({
48
+ const clientProcesses = useQueries({
49
+ queries: Object.entries(clientProcessDtos).map(([processId, { dto, options }]) => ({
50
50
  queryKey: ['__process', processId],
51
51
  queryFn: async () => {
52
52
  if (!processId)
53
- throw new Error("No processId");
53
+ throw new Error('No processId');
54
54
  const { process } = await processStatusChecker(processId);
55
55
  // Handled! Return the proper response too
56
- if (process.status === "handled") {
56
+ if (process.status === 'handled') {
57
57
  const result = await processCallbackResultFetcher(process.id, process.name, dto.processCallbackUrl);
58
- console.warn(process.name, options?.successMessage ?? "Success!");
59
- toast.success(options?.successMessage ?? "Success!", {
60
- id: process.id
61
- });
62
- setTimeout(() => toast.dismiss(process.id), 1500);
63
- return { id: process.id, name: process.name, success: true, result };
58
+ // Log and call runner
59
+ console.warn(`Handled ${process.name} (${process.id})!`);
60
+ options?.onSuccess?.(process.id, process.name, result);
61
+ return {
62
+ id: process.id,
63
+ name: process.name,
64
+ success: true,
65
+ result,
66
+ };
64
67
  }
65
68
  // Pending or failed
66
- if (process.status === "pending") {
67
- console.log(process.name, options?.loadingMessage ?? "Loading...");
68
- toast.loading(options?.loadingMessage ?? "Loading...", {
69
- id: process.id,
70
- duration: Infinity,
71
- });
69
+ if (process.status === 'pending') {
70
+ console.log(`Running process ${process.name} (${process.id})...`);
71
+ options?.onLoading?.(process.id, process.name);
72
72
  return null;
73
73
  }
74
- else if (process.status === "failed") {
75
- console.error(process.name, options?.failureMessage ?? "Something went wrong.");
76
- toast.error(options?.failureMessage ?? "Something went wrong.", {
77
- id: process.id
78
- });
79
- setTimeout(() => toast.dismiss(process.id), 1500);
74
+ else if (process.status === 'failed') {
75
+ console.error(`Failed ${process.name} (${process.id}) - ${process.error}.`);
80
76
  return { id: process.id, name: process.name, success: false };
81
77
  }
82
78
  // Return null since no response
@@ -94,7 +90,7 @@ const ClientProcessesProvider = ({ children }) => {
94
90
  clientProcessAttempts.current[processId] += 1;
95
91
  return interval;
96
92
  },
97
- }))
93
+ })),
98
94
  });
99
95
  /**
100
96
  * Registers a new process to handle
@@ -104,7 +100,10 @@ const ClientProcessesProvider = ({ children }) => {
104
100
  * @param options
105
101
  */
106
102
  const registerProcess = (processId, processCallbackDto, options) => {
107
- setClientProcessDtos({ ...clientProcessDtos, [processId]: { dto: processCallbackDto, options } });
103
+ setClientProcessDtos({
104
+ ...clientProcessDtos,
105
+ [processId]: { dto: processCallbackDto, options },
106
+ });
108
107
  };
109
108
  /**
110
109
  * Retrieves a process
@@ -112,12 +111,25 @@ const ClientProcessesProvider = ({ children }) => {
112
111
  * @param processId
113
112
  * @returns
114
113
  */
115
- const getProcess = (processId) => {
116
- return clientProcesses.find(clientProcess => clientProcess.data?.id === processId)?.data ?? null;
114
+ const getProcess = (processId, options = {}) => {
115
+ return (clientProcesses.find((clientProcess) => clientProcess.data?.id === processId)?.data ?? null);
116
+ };
117
+ /**
118
+ * Filters processes by the provided attribute.
119
+ *
120
+ * @param filter
121
+ */
122
+ const filterProcesses = (filter) => {
123
+ return clientProcesses
124
+ .filter((clientProcess) => clientProcess.data?.id &&
125
+ clientProcessDtos[clientProcess.data.id].options?.filter === filter)
126
+ .map((clientProcess) => clientProcess.data)
127
+ .filter((clientProcess) => !!clientProcess);
117
128
  };
118
129
  return (jsxRuntimeExports.jsx(clientProcessesContext.Provider, { value: {
119
130
  registerProcess,
120
- getProcess
131
+ getProcess,
132
+ filterProcesses,
121
133
  }, children: children }));
122
134
  };
123
135
  /**
@@ -126,7 +138,7 @@ const ClientProcessesProvider = ({ children }) => {
126
138
  * @param caller
127
139
  * @returns
128
140
  */
129
- function useClientProcess({ caller, loadingMessage, successMessage, failureMessage, }) {
141
+ function useClientProcess({ caller, filterKey, onLoading, onSuccess, onFailure, }) {
130
142
  const clientProcessesApi = useContext(clientProcessesContext);
131
143
  // Note that the exposed function doesn't return process ids
132
144
  // Client should be oblivious to those
@@ -134,9 +146,9 @@ function useClientProcess({ caller, loadingMessage, successMessage, failureMessa
134
146
  const wrappedCaller = async (inputs) => {
135
147
  const response = await caller(inputs);
136
148
  clientProcessesApi.registerProcess(response.processId, response, {
137
- loadingMessage,
138
- successMessage,
139
- failureMessage
149
+ onLoading,
150
+ onSuccess,
151
+ onFailure,
140
152
  });
141
153
  return {
142
154
  id: response.processId,
@@ -146,7 +158,8 @@ function useClientProcess({ caller, loadingMessage, successMessage, failureMessa
146
158
  };
147
159
  return {
148
160
  run: wrappedCaller,
149
- get: (id) => clientProcessesApi.getProcess(id)
161
+ get: (id) => clientProcessesApi.getProcess(id),
162
+ getAll: () => clientProcessesApi.filterProcesses(filterKey),
150
163
  };
151
164
  }
152
165
 
@@ -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 } from \"@tanstack/react-query\";\r\nimport { config } from \"../config\";\r\nimport { toast } from \"sonner\"\r\n\r\ntype ProcessStatus = \"pending\" | \"handled\" | \"failed\";\r\n\r\ninterface Process<T> {\r\n\tid: string;\r\n\tname: string;\r\n status: ProcessStatus;\r\n result?: T;\r\n error?: string;\r\n\ttimestamp: 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 loadingMessage?: string;\r\n successMessage?: string;\r\n failureMessage?: 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 processId identifies the process instance.\r\n * The processName identifies the type of process.\r\n * The processCallbackUrl tells the hook what route to ask the result for.\r\n * \r\n * * Note to self and devs: we use a callback system to keep the return values of the processes safe. \r\n * * The job of the callback route is to filter the output of the process.\r\n */\r\ninterface UseAsyncProcessOptions {\r\n processId?: string; \r\n processName?: string;\r\n processCallbackUrl?: string;\r\n baseInterval?: number;\r\n maxInterval?: number;\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) => fetch(`${config.orchestratorApi}/${encodeURIComponent(processId)}`, {\r\n\tmethod: \"GET\",\r\n\theaders: {\r\n\t\t\"Content-Type\": \"application/json\",\r\n\t},\r\n}).then((response) => response.json()) as unknown as Promise<{ process: Omit<Process<T>, 'result'> }>;\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,>(processId: string, processName: string, processCallbackUrl?: string) => fetch(`${processCallbackUrl}`, {\r\n\tmethod: \"POST\",\r\n\theaders: {\r\n\t\t\"Content-Type\": \"application/json\",\r\n\t},\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: (processId: string, dto: ProcessCallbackDto, options?: ClientProcessOptions) => void;\r\n getProcess: (processId: string) => { id: string, name: string, result?: unknown, success: boolean } | null;\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>({} as ClientProcesses);\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 [clientProcessDtos, setClientProcessDtos] = \r\n useState<Record<string, { dto: ProcessCallbackDto, options?: ClientProcessOptions }>>({});\r\n const clientProcessAttempts = useRef<Record<string, number>>({});\r\n const clientProcesses = useQueries({ queries: Object.entries(clientProcessDtos).map(\r\n ([processId, { dto, options }]) => (\r\n {\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(process.id, process.name, dto.processCallbackUrl)\r\n console.warn(process.name, options?.successMessage ?? \"Success!\");\r\n toast.success(options?.successMessage ?? \"Success!\", { \r\n id: process.id\r\n })\r\n setTimeout(() => toast.dismiss(process.id), 1500)\r\n return { id: process.id, name: process.name, success: true, result };\r\n }\r\n\r\n // Pending or failed\r\n if (process.status === \"pending\") {\r\n console.log(process.name, options?.loadingMessage ?? \"Loading...\");\r\n toast.loading(options?.loadingMessage ?? \"Loading...\", {\r\n id: process.id,\r\n duration: Infinity,\r\n })\r\n return null;\r\n } else if (process.status === \"failed\") {\r\n console.error(process.name, options?.failureMessage ?? \"Something went wrong.\");\r\n toast.error(options?.failureMessage ?? \"Something went wrong.\", { \r\n id: process.id \r\n })\r\n setTimeout(() => toast.dismiss(process.id), 1500)\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 null;\r\n },\r\n\r\n // Returns the next interval length to use to wait for fetch\r\n refetchInterval: (query: Query) => {\r\n const data = query.state.data;\r\n if (data !== null)\r\n 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 options?: ClientProcessOptions\r\n ) => {\r\n setClientProcessDtos({ ...clientProcessDtos, [processId]: { dto: processCallbackDto, options } })\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 = (processId: string) => {\r\n return clientProcesses.find(clientProcess => clientProcess.data?.id === processId)?.data ?? null\r\n }\r\n\r\n return (\r\n <clientProcessesContext.Provider value={{\r\n registerProcess,\r\n getProcess\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>({ \r\n caller,\r\n loadingMessage,\r\n successMessage,\r\n failureMessage,\r\n}: {\r\n caller: (inputs: T) => Promise<ProcessResponse>;\r\n loadingMessage?: string \r\n successMessage?: string\r\n failureMessage?: string\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 (inputs: T) => {\r\n const response = await caller(inputs);\r\n clientProcessesApi.registerProcess(response.processId, response, { \r\n loadingMessage, \r\n successMessage, \r\n failureMessage \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 }\r\n}"],"names":[],"mappings":";;;;;;;AAsDA;;;;;AAKG;AACH;AACC;AACA;AACC;AACA;AACD;AAED;;;;;AAKG;AACH;AACC;AACA;AACC;AACA;AACA;;;;AAID;AAOD;;;AAGG;AACH;AAEA;;;;AAIG;;;AAID;AACA;AAGM;;AAEE;AAAgB;;;AAIhB;AACE;AACA;;;AAGC;AACD;AACA;;;AAIF;AACE;;;AAGE;AACD;AACD;;AACK;AACL;;;AAGC;AACD;AACA;;;AAIF;;;AAIF;AACE;;AAEE;;AAGF;AACE;AAEF;AAKA;AACA;;AAEH;AAEJ;AAED;;;;;;AAMG;;AAMD;AACF;AAEA;;;;;AAKG;AACH;;AAEA;AAEA;;;;AAQF;AAEA;;;;;AAKG;AACG;AAWJ;;;;AAKA;AACE;;;;;AAKC;;;;;;AAOH;;AAGE;;;AAGJ;;"}
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 } 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\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 filter?: 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\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 options?: ClientProcessOptions,\r\n ) => void;\r\n getProcess: (\r\n processId: string,\r\n ) => { id: string; name: string; result?: unknown; success: boolean } | null;\r\n filterProcesses: (\r\n filter: string,\r\n ) => { id: string; name: string; result?: unknown; success: boolean }[];\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 = ({\r\n children,\r\n}: {\r\n children: React.ReactNode;\r\n}) => {\r\n const [clientProcessDtos, setClientProcessDtos] = useState<\r\n Record<string, { dto: ProcessCallbackDto; options?: ClientProcessOptions }>\r\n >({});\r\n const clientProcessAttempts = useRef<Record<string, number>>({});\r\n const clientProcesses = useQueries({\r\n queries: Object.entries(clientProcessDtos).map(\r\n ([processId, { dto, options }]) => ({\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 null;\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 null;\r\n },\r\n\r\n // Returns the next interval length to use to wait for fetch\r\n refetchInterval: (query: Query) => {\r\n const data = query.state.data;\r\n if (data !== null) 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 options?: ClientProcessOptions,\r\n ) => {\r\n setClientProcessDtos({\r\n ...clientProcessDtos,\r\n [processId]: { dto: processCallbackDto, 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 = (processId: string, options: { filter?: string } = {}) => {\r\n return (\r\n clientProcesses.find(\r\n (clientProcess) => clientProcess.data?.id === processId,\r\n )?.data ?? null\r\n );\r\n };\r\n\r\n /**\r\n * Filters processes by the provided attribute.\r\n *\r\n * @param filter\r\n */\r\n const filterProcesses = (filter: string) => {\r\n return clientProcesses\r\n .filter(\r\n (clientProcess) =>\r\n clientProcess.data?.id &&\r\n clientProcessDtos[clientProcess.data.id].options?.filter === filter,\r\n )\r\n .map((clientProcess) => clientProcess.data)\r\n .filter((clientProcess) => !!clientProcess);\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 }}\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 (inputs: T) => {\r\n const response = await caller(inputs);\r\n clientProcessesApi.registerProcess(response.processId, response, {\r\n onLoading,\r\n onSuccess,\r\n onFailure,\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 };\r\n}"],"names":[],"mappings":";;;;;;AAsCA;;;;;AAKG;AACH;AAEI;AACA;AACE;AACD;AACF;AAIH;;;;;AAKG;AACH;AAMI;AACA;AACE;AACD;AACD;;;;AAID;AAgBH;;;AAGG;AACH;AAIA;;;;AAIG;;;AASD;;;AAIM;;AAEE;AAAgB;;;AAIhB;AACE;;AAOA;AACA;;;;AAKE;;;;;AAMJ;AACE;AACA;AACA;;AACK;AACL;AAGA;;;AAIF;;;AAIF;AACE;;AACmB;;AAGnB;AACE;AAEF;AAKA;AACA;;AAEH;AAEJ;AAED;;;;;;AAMG;;AAMD;AACE;;AAED;AACH;AAEA;;;;;AAKG;;;AAOH;AAEA;;;;AAIG;AACH;AACE;;AAIM;;;AAIR;AAEA;;;;;AAWF;AAEA;;;;;AAKG;AACG;AAaJ;;;;AAKA;AACE;;;;;AAKC;;;;;;AAOH;;AAGE;;;;AAIJ;;"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@betterinternship/components",
3
- "version": "1.5.3",
3
+ "version": "1.5.5",
4
4
  "main": "dist/index.esm.js",
5
5
  "module": "dist/index.esm.js",
6
6
  "types": "dist/index.d.ts",
@@ -74,6 +74,13 @@
74
74
  }
75
75
  },
76
76
  "devDependencies": {
77
+ "@eslint/eslintrc": "^3.2.0",
78
+ "@eslint/js": "^9.18.0",
79
+ "eslint": "^9.18.0",
80
+ "eslint-config-prettier": "^10.0.1",
81
+ "eslint-plugin-prettier": "^5.2.2",
82
+ "prettier": "^3.4.2",
83
+ "typescript-eslint": "^8.20.0",
77
84
  "@radix-ui/react-accordion": "^1.2.11",
78
85
  "@radix-ui/react-alert-dialog": "^1.1.15",
79
86
  "@radix-ui/react-aspect-ratio": "^1.1.1",