@betterinternship/components 2.9.2 → 2.9.4
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.
- package/dist/components/ui/checkbox.js +1 -1
- package/dist/components/ui/checkbox.js.map +1 -1
- package/dist/components/ui/fab.js +9 -9
- package/dist/components/ui/table.js +1 -1
- package/dist/components/ui/table.js.map +1 -1
- package/dist/config.d.ts +6 -6
- package/dist/config.js +9 -9
- package/dist/hooks/useClientProcess.d.ts +69 -69
- package/dist/hooks/useClientProcess.js +255 -255
- package/package.json +1 -1
|
@@ -4,7 +4,7 @@ import { CheckIcon } from 'lucide-react';
|
|
|
4
4
|
import { cn } from '../../utils.js';
|
|
5
5
|
|
|
6
6
|
function Checkbox({ className, ...props }) {
|
|
7
|
-
return (jsx(CheckboxPrimitive.Root, { "data-slot": "checkbox", onClick: (e) => e.stopPropagation(), className: cn('peer border-input dark:bg-input/30 data-[state=checked]:bg-primary data-[state=checked]:text-primary-foreground dark:data-[state=checked]:bg-primary data-[state=checked]:border-primary focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive size-4 shrink-0 cursor-pointer rounded-[4px] border shadow-xs transition-shadow outline-none focus-visible:ring-[3px] disabled:cursor-not-allowed disabled:opacity-50', className), ...props, children: jsx(CheckboxPrimitive.Indicator, { "data-slot": "checkbox-indicator", className: "flex items-center justify-center text-current transition-none", children: jsx(CheckIcon, { className: "size-3.5" }) }) }));
|
|
7
|
+
return (jsx(CheckboxPrimitive.Root, { "data-slot": "checkbox", onClick: (e) => e.stopPropagation(), className: cn('peer border-input dark:bg-input/30 data-[state=checked]:bg-primary data-[state=checked]:text-primary-foreground dark:data-[state=checked]:bg-primary data-[state=checked]:border-primary focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive size-4 shrink-0 cursor-pointer rounded-[4px] border shadow-xs transition-shadow outline-none focus-visible:ring-[3px] disabled:cursor-not-allowed disabled:opacity-50', className), ...props, children: jsx(CheckboxPrimitive.Indicator, { "data-slot": "checkbox-indicator", className: "flex items-center justify-center text-current transition-none", children: jsx(CheckIcon, { className: "size-3.5 stroke-3" }) }) }));
|
|
8
8
|
}
|
|
9
9
|
|
|
10
10
|
export { Checkbox };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"checkbox.js","sources":["../../../src/components/ui/checkbox.tsx"],"sourcesContent":["import * as React from 'react';\nimport * as CheckboxPrimitive from '@radix-ui/react-checkbox';\nimport { CheckIcon } from 'lucide-react';\n\nimport { cn } from '@/utils';\n\nfunction Checkbox({\n className,\n ...props\n}: React.ComponentProps<typeof CheckboxPrimitive.Root>) {\n return (\n <CheckboxPrimitive.Root\n data-slot=\"checkbox\"\n onClick={(e) => e.stopPropagation()}\n className={cn(\n 'peer border-input dark:bg-input/30 data-[state=checked]:bg-primary data-[state=checked]:text-primary-foreground dark:data-[state=checked]:bg-primary data-[state=checked]:border-primary focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive size-4 shrink-0 cursor-pointer rounded-[4px] border shadow-xs transition-shadow outline-none focus-visible:ring-[3px] disabled:cursor-not-allowed disabled:opacity-50',\n className,\n )}\n {...props}\n >\n <CheckboxPrimitive.Indicator\n data-slot=\"checkbox-indicator\"\n className=\"flex items-center justify-center text-current transition-none\"\n >\n <CheckIcon className=\"size-3.5\" />\n </CheckboxPrimitive.Indicator>\n </CheckboxPrimitive.Root>\n );\n}\n\nexport { Checkbox };\n"],"names":["_jsx"],"mappings":";;;;;AAMA,SAAS,QAAQ,CAAC,EAChB,SAAS,EACT,GAAG,KAAK,EAC4C,EAAA;IACpD,QACEA,GAAA,CAAC,iBAAiB,CAAC,IAAI,iBACX,UAAU,EACpB,OAAO,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,eAAe,EAAE,EACnC,SAAS,EAAE,EAAE,CACX,4fAA4f,EAC5f,SAAS,CACV,EAAA,GACG,KAAK,EAAA,QAAA,EAETA,GAAA,CAAC,iBAAiB,CAAC,SAAS,EAAA,EAAA,WAAA,EAChB,oBAAoB,EAC9B,SAAS,EAAC,+DAA+D,EAAA,QAAA,EAEzEA,GAAA,CAAC,SAAS,EAAA,EAAC,SAAS,EAAC,
|
|
1
|
+
{"version":3,"file":"checkbox.js","sources":["../../../src/components/ui/checkbox.tsx"],"sourcesContent":["import * as React from 'react';\nimport * as CheckboxPrimitive from '@radix-ui/react-checkbox';\nimport { CheckIcon } from 'lucide-react';\n\nimport { cn } from '@/utils';\n\nfunction Checkbox({\n className,\n ...props\n}: React.ComponentProps<typeof CheckboxPrimitive.Root>) {\n return (\n <CheckboxPrimitive.Root\n data-slot=\"checkbox\"\n onClick={(e) => e.stopPropagation()}\n className={cn(\n 'peer border-input dark:bg-input/30 data-[state=checked]:bg-primary data-[state=checked]:text-primary-foreground dark:data-[state=checked]:bg-primary data-[state=checked]:border-primary focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive size-4 shrink-0 cursor-pointer rounded-[4px] border shadow-xs transition-shadow outline-none focus-visible:ring-[3px] disabled:cursor-not-allowed disabled:opacity-50',\n className,\n )}\n {...props}\n >\n <CheckboxPrimitive.Indicator\n data-slot=\"checkbox-indicator\"\n className=\"flex items-center justify-center text-current transition-none\"\n >\n <CheckIcon className=\"size-3.5 stroke-3\" />\n </CheckboxPrimitive.Indicator>\n </CheckboxPrimitive.Root>\n );\n}\n\nexport { Checkbox };\n"],"names":["_jsx"],"mappings":";;;;;AAMA,SAAS,QAAQ,CAAC,EAChB,SAAS,EACT,GAAG,KAAK,EAC4C,EAAA;IACpD,QACEA,GAAA,CAAC,iBAAiB,CAAC,IAAI,iBACX,UAAU,EACpB,OAAO,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,eAAe,EAAE,EACnC,SAAS,EAAE,EAAE,CACX,4fAA4f,EAC5f,SAAS,CACV,EAAA,GACG,KAAK,EAAA,QAAA,EAETA,GAAA,CAAC,iBAAiB,CAAC,SAAS,EAAA,EAAA,WAAA,EAChB,oBAAoB,EAC9B,SAAS,EAAC,+DAA+D,EAAA,QAAA,EAEzEA,GAAA,CAAC,SAAS,EAAA,EAAC,SAAS,EAAC,mBAAmB,EAAA,CAAG,EAAA,CACf,EAAA,CACP;AAE7B;;;;"}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { jsx } from 'react/jsx-runtime';
|
|
2
|
-
import { Button } from './button.js';
|
|
3
|
-
|
|
4
|
-
const FloatingActionButton = ({ onClick, children }) => {
|
|
5
|
-
return (jsx(Button, { onClick: onClick, className: "fixed bottom-4 right-4 z-50 rounded-full p-4 shadow-lg bg-primary text-white hover:bg-primary-dark focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-primary", children: children }));
|
|
6
|
-
};
|
|
7
|
-
|
|
8
|
-
export { FloatingActionButton };
|
|
9
|
-
//# sourceMappingURL=fab.js.map
|
|
1
|
+
import { jsx } from 'react/jsx-runtime';
|
|
2
|
+
import { Button } from './button.js';
|
|
3
|
+
|
|
4
|
+
const FloatingActionButton = ({ onClick, children }) => {
|
|
5
|
+
return (jsx(Button, { onClick: onClick, className: "fixed bottom-4 right-4 z-50 rounded-full p-4 shadow-lg bg-primary text-white hover:bg-primary-dark focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-primary", children: children }));
|
|
6
|
+
};
|
|
7
|
+
|
|
8
|
+
export { FloatingActionButton };
|
|
9
|
+
//# sourceMappingURL=fab.js.map
|
|
@@ -2,7 +2,7 @@ import { jsx } from 'react/jsx-runtime';
|
|
|
2
2
|
import { cn } from '../../utils.js';
|
|
3
3
|
|
|
4
4
|
function Table({ className, ...props }) {
|
|
5
|
-
return (jsx("div", { "data-slot": "table-container", className: "relative w-full overflow-x-auto
|
|
5
|
+
return (jsx("div", { "data-slot": "table-container", className: "relative w-full overflow-x-auto", children: jsx("table", { "data-slot": "table", className: cn('w-full caption-bottom text-sm', className), ...props }) }));
|
|
6
6
|
}
|
|
7
7
|
function TableHeader({ className, ...props }) {
|
|
8
8
|
return (jsx("thead", { "data-slot": "table-header", className: cn('[&_tr]:border-b', className), ...props }));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"table.js","sources":["../../../src/components/ui/table.tsx"],"sourcesContent":["import * as React from 'react';\
|
|
1
|
+
{"version":3,"file":"table.js","sources":["../../../src/components/ui/table.tsx"],"sourcesContent":["import * as React from 'react';\n\nimport { cn } from '@/utils';\n\nfunction Table({ className, ...props }: React.ComponentProps<'table'>) {\n return (\n <div\n data-slot=\"table-container\"\n className=\"relative w-full overflow-x-auto\"\n >\n <table\n data-slot=\"table\"\n className={cn('w-full caption-bottom text-sm', className)}\n {...props}\n />\n </div>\n );\n}\n\nfunction TableHeader({ className, ...props }: React.ComponentProps<'thead'>) {\n return (\n <thead\n data-slot=\"table-header\"\n className={cn('[&_tr]:border-b', className)}\n {...props}\n />\n );\n}\n\nfunction TableBody({ className, ...props }: React.ComponentProps<'tbody'>) {\n return (\n <tbody\n data-slot=\"table-body\"\n className={cn('[&_tr:last-child]:border-0', className)}\n {...props}\n />\n );\n}\n\nfunction TableFooter({ className, ...props }: React.ComponentProps<'tfoot'>) {\n return (\n <tfoot\n data-slot=\"table-footer\"\n className={cn(\n 'bg-muted/50 border-t font-medium [&>tr]:last:border-b-0',\n className,\n )}\n {...props}\n />\n );\n}\n\nfunction TableRow({ className, ...props }: React.ComponentProps<'tr'>) {\n return (\n <tr\n data-slot=\"table-row\"\n className={cn(\n 'hover:bg-muted/50 data-[state=selected]:bg-muted border-b transition-colors',\n className,\n )}\n {...props}\n />\n );\n}\n\nfunction TableHead({ className, ...props }: React.ComponentProps<'th'>) {\n return (\n <th\n data-slot=\"table-head\"\n className={cn(\n 'text-foreground h-10 px-2 text-left align-middle font-medium whitespace-nowrap [&:has([role=checkbox])]:pr-0 [&>[role=checkbox]]:translate-y-[2px]',\n className,\n )}\n {...props}\n />\n );\n}\n\nfunction TableCell({ className, ...props }: React.ComponentProps<'td'>) {\n return (\n <td\n data-slot=\"table-cell\"\n className={cn(\n 'p-2 align-middle whitespace-nowrap [&:has([role=checkbox])]:pr-0 [&>[role=checkbox]]:translate-y-[2px]',\n className,\n )}\n {...props}\n />\n );\n}\n\nfunction TableCaption({\n className,\n ...props\n}: React.ComponentProps<'caption'>) {\n return (\n <caption\n data-slot=\"table-caption\"\n className={cn('text-muted-foreground mt-4 text-sm', className)}\n {...props}\n />\n );\n}\n\nexport {\n Table,\n TableHeader,\n TableBody,\n TableFooter,\n TableHead,\n TableRow,\n TableCell,\n TableCaption,\n};\n"],"names":["_jsx"],"mappings":";;;AAIA,SAAS,KAAK,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,EAAiC,EAAA;IACnE,QACEA,GAAA,CAAA,KAAA,EAAA,EAAA,WAAA,EACY,iBAAiB,EAC3B,SAAS,EAAC,iCAAiC,EAAA,QAAA,EAE3CA,GAAA,CAAA,OAAA,EAAA,EAAA,WAAA,EACY,OAAO,EACjB,SAAS,EAAE,EAAE,CAAC,+BAA+B,EAAE,SAAS,CAAC,KACrD,KAAK,EAAA,CACT,EAAA,CACE;AAEV;AAEA,SAAS,WAAW,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,EAAiC,EAAA;AACzE,IAAA,QACEA,GAAA,CAAA,OAAA,EAAA,EAAA,WAAA,EACY,cAAc,EACxB,SAAS,EAAE,EAAE,CAAC,iBAAiB,EAAE,SAAS,CAAC,EAAA,GACvC,KAAK,EAAA,CACT;AAEN;AAEA,SAAS,SAAS,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,EAAiC,EAAA;AACvE,IAAA,QACEA,GAAA,CAAA,OAAA,EAAA,EAAA,WAAA,EACY,YAAY,EACtB,SAAS,EAAE,EAAE,CAAC,4BAA4B,EAAE,SAAS,CAAC,EAAA,GAClD,KAAK,EAAA,CACT;AAEN;AAEA,SAAS,WAAW,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,EAAiC,EAAA;AACzE,IAAA,QACEA,GAAA,CAAA,OAAA,EAAA,EAAA,WAAA,EACY,cAAc,EACxB,SAAS,EAAE,EAAE,CACX,yDAAyD,EACzD,SAAS,CACV,EAAA,GACG,KAAK,EAAA,CACT;AAEN;AAEA,SAAS,QAAQ,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,EAA8B,EAAA;AACnE,IAAA,QACEA,GAAA,CAAA,IAAA,EAAA,EAAA,WAAA,EACY,WAAW,EACrB,SAAS,EAAE,EAAE,CACX,6EAA6E,EAC7E,SAAS,CACV,EAAA,GACG,KAAK,EAAA,CACT;AAEN;AAEA,SAAS,SAAS,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,EAA8B,EAAA;AACpE,IAAA,QACEA,GAAA,CAAA,IAAA,EAAA,EAAA,WAAA,EACY,YAAY,EACtB,SAAS,EAAE,EAAE,CACX,oJAAoJ,EACpJ,SAAS,CACV,EAAA,GACG,KAAK,EAAA,CACT;AAEN;AAEA,SAAS,SAAS,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,EAA8B,EAAA;AACpE,IAAA,QACEA,GAAA,CAAA,IAAA,EAAA,EAAA,WAAA,EACY,YAAY,EACtB,SAAS,EAAE,EAAE,CACX,wGAAwG,EACxG,SAAS,CACV,EAAA,GACG,KAAK,EAAA,CACT;AAEN;AAEA,SAAS,YAAY,CAAC,EACpB,SAAS,EACT,GAAG,KAAK,EACwB,EAAA;AAChC,IAAA,QACEA,GAAA,CAAA,SAAA,EAAA,EAAA,WAAA,EACY,eAAe,EACzB,SAAS,EAAE,EAAE,CAAC,oCAAoC,EAAE,SAAS,CAAC,EAAA,GAC1D,KAAK,EAAA,CACT;AAEN;;;;"}
|
package/dist/config.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
interface PackageConfig {
|
|
2
|
-
orchestratorApi: string;
|
|
3
|
-
}
|
|
4
|
-
export declare let config: PackageConfig;
|
|
5
|
-
export declare const configure: (newConfig: PackageConfig) => void;
|
|
6
|
-
export {};
|
|
1
|
+
interface PackageConfig {
|
|
2
|
+
orchestratorApi: string;
|
|
3
|
+
}
|
|
4
|
+
export declare let config: PackageConfig;
|
|
5
|
+
export declare const configure: (newConfig: PackageConfig) => void;
|
|
6
|
+
export {};
|
package/dist/config.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
let config = {
|
|
2
|
-
orchestratorApi: 'https://orca.betterinternship.com/process',
|
|
3
|
-
};
|
|
4
|
-
const configure = (newConfig) => {
|
|
5
|
-
config = { ...config, ...newConfig };
|
|
6
|
-
};
|
|
7
|
-
|
|
8
|
-
export { config, configure };
|
|
9
|
-
//# sourceMappingURL=config.js.map
|
|
1
|
+
let config = {
|
|
2
|
+
orchestratorApi: 'https://orca.betterinternship.com/process',
|
|
3
|
+
};
|
|
4
|
+
const configure = (newConfig) => {
|
|
5
|
+
config = { ...config, ...newConfig };
|
|
6
|
+
};
|
|
7
|
+
|
|
8
|
+
export { config, configure };
|
|
9
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -1,69 +1,69 @@
|
|
|
1
|
-
interface ClientProcess<T> {
|
|
2
|
-
dto?: ProcessCallbackDto;
|
|
3
|
-
metadata?: ClientProcessMetadata;
|
|
4
|
-
options?: ClientProcessOptions;
|
|
5
|
-
result?: T;
|
|
6
|
-
success?: boolean;
|
|
7
|
-
pending?: boolean;
|
|
8
|
-
error?: string;
|
|
9
|
-
}
|
|
10
|
-
export interface ProcessCallbackDto {
|
|
11
|
-
processId: string;
|
|
12
|
-
processName: string;
|
|
13
|
-
processCallbackUrl: string;
|
|
14
|
-
}
|
|
15
|
-
export interface ClientProcessOptions {
|
|
16
|
-
onLoading?: (processId: string, processName: string) => void;
|
|
17
|
-
onSuccess?: <R>(processId: string, processName: string, result: R) => void;
|
|
18
|
-
onFailure?: (processId: string, processName: string, error?: string) => void;
|
|
19
|
-
}
|
|
20
|
-
export interface ClientProcessMetadata {
|
|
21
|
-
filterKey: string;
|
|
22
|
-
metadata?: Record<string, string>;
|
|
23
|
-
}
|
|
24
|
-
export interface ProcessResponse {
|
|
25
|
-
processId: string;
|
|
26
|
-
processName: string;
|
|
27
|
-
processCallbackUrl: string;
|
|
28
|
-
success: boolean;
|
|
29
|
-
message?: string;
|
|
30
|
-
}
|
|
31
|
-
/**
|
|
32
|
-
* This should be at the root layout.
|
|
33
|
-
*
|
|
34
|
-
* @context
|
|
35
|
-
*/
|
|
36
|
-
export declare const ClientProcessesProvider: ({ children, }: {
|
|
37
|
-
children: React.ReactNode;
|
|
38
|
-
}) => import("react/jsx-runtime").JSX.Element;
|
|
39
|
-
/**
|
|
40
|
-
* A simpler version, where u just pass the async function that returns process data.
|
|
41
|
-
*
|
|
42
|
-
* @param caller
|
|
43
|
-
* @returns
|
|
44
|
-
*/
|
|
45
|
-
export declare function useClientProcess<T, R>({ caller, invalidator, filterKey, onLoading, onSuccess, onFailure, }: {
|
|
46
|
-
caller?: (inputs: T) => Promise<ProcessResponse>;
|
|
47
|
-
invalidator?: (result: R) => boolean;
|
|
48
|
-
filterKey: string;
|
|
49
|
-
onLoading?: (processId: string, processName: string) => void;
|
|
50
|
-
onSuccess?: <R>(processId: string, processName: string, result: R) => void;
|
|
51
|
-
onFailure?: (processId: string, processName: string, error?: string) => void;
|
|
52
|
-
}): {
|
|
53
|
-
run: (inputs: T, metadata?: Record<string, string>) => Promise<{
|
|
54
|
-
id: string;
|
|
55
|
-
success: boolean;
|
|
56
|
-
message: string | undefined;
|
|
57
|
-
} | {
|
|
58
|
-
id: null;
|
|
59
|
-
success: boolean;
|
|
60
|
-
message: string;
|
|
61
|
-
}>;
|
|
62
|
-
get: (id: string) => ClientProcess<unknown> | null;
|
|
63
|
-
getAll: () => ClientProcess<unknown>[];
|
|
64
|
-
getAllPending: () => ClientProcess<unknown>[];
|
|
65
|
-
getAllHandled: () => ClientProcess<unknown>[];
|
|
66
|
-
getAllFailed: () => ClientProcess<unknown>[];
|
|
67
|
-
refreshCache: () => Promise<void>;
|
|
68
|
-
};
|
|
69
|
-
export {};
|
|
1
|
+
interface ClientProcess<T> {
|
|
2
|
+
dto?: ProcessCallbackDto;
|
|
3
|
+
metadata?: ClientProcessMetadata;
|
|
4
|
+
options?: ClientProcessOptions;
|
|
5
|
+
result?: T;
|
|
6
|
+
success?: boolean;
|
|
7
|
+
pending?: boolean;
|
|
8
|
+
error?: string;
|
|
9
|
+
}
|
|
10
|
+
export interface ProcessCallbackDto {
|
|
11
|
+
processId: string;
|
|
12
|
+
processName: string;
|
|
13
|
+
processCallbackUrl: string;
|
|
14
|
+
}
|
|
15
|
+
export interface ClientProcessOptions {
|
|
16
|
+
onLoading?: (processId: string, processName: string) => void;
|
|
17
|
+
onSuccess?: <R>(processId: string, processName: string, result: R) => void;
|
|
18
|
+
onFailure?: (processId: string, processName: string, error?: string) => void;
|
|
19
|
+
}
|
|
20
|
+
export interface ClientProcessMetadata {
|
|
21
|
+
filterKey: string;
|
|
22
|
+
metadata?: Record<string, string>;
|
|
23
|
+
}
|
|
24
|
+
export interface ProcessResponse {
|
|
25
|
+
processId: string;
|
|
26
|
+
processName: string;
|
|
27
|
+
processCallbackUrl: string;
|
|
28
|
+
success: boolean;
|
|
29
|
+
message?: string;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* This should be at the root layout.
|
|
33
|
+
*
|
|
34
|
+
* @context
|
|
35
|
+
*/
|
|
36
|
+
export declare const ClientProcessesProvider: ({ children, }: {
|
|
37
|
+
children: React.ReactNode;
|
|
38
|
+
}) => import("react/jsx-runtime").JSX.Element;
|
|
39
|
+
/**
|
|
40
|
+
* A simpler version, where u just pass the async function that returns process data.
|
|
41
|
+
*
|
|
42
|
+
* @param caller
|
|
43
|
+
* @returns
|
|
44
|
+
*/
|
|
45
|
+
export declare function useClientProcess<T, R>({ caller, invalidator, filterKey, onLoading, onSuccess, onFailure, }: {
|
|
46
|
+
caller?: (inputs: T) => Promise<ProcessResponse>;
|
|
47
|
+
invalidator?: (result: R) => boolean;
|
|
48
|
+
filterKey: string;
|
|
49
|
+
onLoading?: (processId: string, processName: string) => void;
|
|
50
|
+
onSuccess?: <R>(processId: string, processName: string, result: R) => void;
|
|
51
|
+
onFailure?: (processId: string, processName: string, error?: string) => void;
|
|
52
|
+
}): {
|
|
53
|
+
run: (inputs: T, metadata?: Record<string, string>) => Promise<{
|
|
54
|
+
id: string;
|
|
55
|
+
success: boolean;
|
|
56
|
+
message: string | undefined;
|
|
57
|
+
} | {
|
|
58
|
+
id: null;
|
|
59
|
+
success: boolean;
|
|
60
|
+
message: string;
|
|
61
|
+
}>;
|
|
62
|
+
get: (id: string) => ClientProcess<unknown> | null;
|
|
63
|
+
getAll: () => ClientProcess<unknown>[];
|
|
64
|
+
getAllPending: () => ClientProcess<unknown>[];
|
|
65
|
+
getAllHandled: () => ClientProcess<unknown>[];
|
|
66
|
+
getAllFailed: () => ClientProcess<unknown>[];
|
|
67
|
+
refreshCache: () => Promise<void>;
|
|
68
|
+
};
|
|
69
|
+
export {};
|
|
@@ -1,255 +1,255 @@
|
|
|
1
|
-
"use client";
|
|
2
|
-
import { jsx } from 'react/jsx-runtime';
|
|
3
|
-
import { createContext, useRef, useState, useEffect, useContext } from 'react';
|
|
4
|
-
import { useQueryClient, useQueries } from '@tanstack/react-query';
|
|
5
|
-
import { config } from '../config.js';
|
|
6
|
-
|
|
7
|
-
/**
|
|
8
|
-
* The orchestrator service to get the process from.
|
|
9
|
-
*
|
|
10
|
-
* @param processId
|
|
11
|
-
* @returns
|
|
12
|
-
*/
|
|
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
|
-
};
|
|
23
|
-
/**
|
|
24
|
-
* This fetches from the callback endpoint.
|
|
25
|
-
*
|
|
26
|
-
* @param processId
|
|
27
|
-
* @returns
|
|
28
|
-
*/
|
|
29
|
-
const processCallbackResultFetcher = (processId, processName, processCallbackUrl) => fetch(`${processCallbackUrl}`, {
|
|
30
|
-
method: 'POST',
|
|
31
|
-
headers: {
|
|
32
|
-
'Content-Type': 'application/json',
|
|
33
|
-
},
|
|
34
|
-
body: JSON.stringify({
|
|
35
|
-
processId,
|
|
36
|
-
processName,
|
|
37
|
-
}),
|
|
38
|
-
}).then((response) => response.json());
|
|
39
|
-
/**
|
|
40
|
-
* We need a context to keep track of all client processes.
|
|
41
|
-
* This helps us manage the state of the toasts as well.
|
|
42
|
-
*/
|
|
43
|
-
const clientProcessesContext = createContext({});
|
|
44
|
-
/**
|
|
45
|
-
* This should be at the root layout.
|
|
46
|
-
*
|
|
47
|
-
* @context
|
|
48
|
-
*/
|
|
49
|
-
const ClientProcessesProvider = ({ children, }) => {
|
|
50
|
-
const queryClient = useQueryClient();
|
|
51
|
-
const clientProcessAttempts = useRef({});
|
|
52
|
-
const [clientProcessDtos, setClientProcessDtos] = useState({});
|
|
53
|
-
// Populates the state object with cached data on mount
|
|
54
|
-
useEffect(() => {
|
|
55
|
-
setClientProcessDtos((oldData) => {
|
|
56
|
-
if (Object.keys(oldData).length > 0)
|
|
57
|
-
return oldData;
|
|
58
|
-
const cachedClientProcesses = queryClient
|
|
59
|
-
.getQueryCache()
|
|
60
|
-
.findAll({ queryKey: ['.__process'], exact: false });
|
|
61
|
-
const seededClientProcesses = {};
|
|
62
|
-
for (const query of cachedClientProcesses) {
|
|
63
|
-
const processId = query.queryKey[2];
|
|
64
|
-
if (typeof processId !== 'string')
|
|
65
|
-
continue;
|
|
66
|
-
const data = query.state.data;
|
|
67
|
-
if (!data?.dto || !data?.metadata)
|
|
68
|
-
continue;
|
|
69
|
-
seededClientProcesses[processId] = {
|
|
70
|
-
dto: data.dto,
|
|
71
|
-
metadata: data.metadata,
|
|
72
|
-
options: data.options,
|
|
73
|
-
};
|
|
74
|
-
}
|
|
75
|
-
return { ...oldData, ...seededClientProcesses };
|
|
76
|
-
});
|
|
77
|
-
}, [queryClient]);
|
|
78
|
-
// The query for all the processes, pending and sht
|
|
79
|
-
const clientProcesses = useQueries({
|
|
80
|
-
queries: Object.entries(clientProcessDtos).map(([processId, { dto, metadata, options }]) => ({
|
|
81
|
-
staleTime: Infinity,
|
|
82
|
-
gcTime: 3 * 60 * 1000,
|
|
83
|
-
refetchOnWindowFocus: true,
|
|
84
|
-
refetchIntervalInBackground: true,
|
|
85
|
-
refetchOnMount: true,
|
|
86
|
-
refetchOnReconnect: true,
|
|
87
|
-
queryKey: ['.__process', metadata.filterKey, processId],
|
|
88
|
-
queryFn: async () => {
|
|
89
|
-
if (!processId)
|
|
90
|
-
throw new Error('No processId');
|
|
91
|
-
const { process } = await processStatusChecker(processId);
|
|
92
|
-
// Handled! Return the proper response too
|
|
93
|
-
if (process?.status === 'handled') {
|
|
94
|
-
const result = await processCallbackResultFetcher(process.id, process.name, dto.processCallbackUrl);
|
|
95
|
-
// Log and call runner
|
|
96
|
-
console.warn(`Handled ${process.name} (${process.id})!`);
|
|
97
|
-
options?.onSuccess?.(process.id, process.name, result);
|
|
98
|
-
return {
|
|
99
|
-
dto,
|
|
100
|
-
metadata,
|
|
101
|
-
options,
|
|
102
|
-
success: true,
|
|
103
|
-
pending: false,
|
|
104
|
-
result,
|
|
105
|
-
};
|
|
106
|
-
}
|
|
107
|
-
// Pending or failed
|
|
108
|
-
if (process?.status === 'pending') {
|
|
109
|
-
console.log(`Running process ${process.name} (${process.id})...`);
|
|
110
|
-
options?.onLoading?.(process.id, process.name);
|
|
111
|
-
return { dto, metadata, options, pending: true };
|
|
112
|
-
}
|
|
113
|
-
else if (process?.status === 'failed') {
|
|
114
|
-
console.error(`Failed ${process.name} (${process.id}) - ${process.error}.`);
|
|
115
|
-
return {
|
|
116
|
-
dto,
|
|
117
|
-
metadata,
|
|
118
|
-
options,
|
|
119
|
-
success: false,
|
|
120
|
-
pending: false,
|
|
121
|
-
error: process.error,
|
|
122
|
-
};
|
|
123
|
-
}
|
|
124
|
-
// Return null since no response
|
|
125
|
-
return { dto, metadata, options, pending: true };
|
|
126
|
-
},
|
|
127
|
-
// Returns the next interval length to use to wait for fetch
|
|
128
|
-
refetchInterval: (query) => {
|
|
129
|
-
const data = query.state.data;
|
|
130
|
-
if (data?.success !== undefined)
|
|
131
|
-
return false;
|
|
132
|
-
// If not defined, init to 0
|
|
133
|
-
if (!clientProcessAttempts.current[processId])
|
|
134
|
-
clientProcessAttempts.current[processId] = 0;
|
|
135
|
-
const interval = Math.min(500 * 2 ** clientProcessAttempts.current[processId], 10000);
|
|
136
|
-
clientProcessAttempts.current[processId] += 1;
|
|
137
|
-
return interval;
|
|
138
|
-
},
|
|
139
|
-
})),
|
|
140
|
-
});
|
|
141
|
-
/**
|
|
142
|
-
* Registers a new process to handle
|
|
143
|
-
*
|
|
144
|
-
* @param processId
|
|
145
|
-
* @param processCallbackDto
|
|
146
|
-
* @param options
|
|
147
|
-
*/
|
|
148
|
-
const registerProcess = (processId, processCallbackDto, metadata, options) => {
|
|
149
|
-
setClientProcessDtos({
|
|
150
|
-
...clientProcessDtos,
|
|
151
|
-
[processId]: { dto: processCallbackDto, metadata, options },
|
|
152
|
-
});
|
|
153
|
-
};
|
|
154
|
-
/**
|
|
155
|
-
* Retrieves a process
|
|
156
|
-
*
|
|
157
|
-
* @param processId
|
|
158
|
-
* @returns
|
|
159
|
-
*/
|
|
160
|
-
const getProcess = (processId) => {
|
|
161
|
-
const clientProcess = clientProcesses.find((clientProcess) => clientProcess.data?.dto?.processId === processId)?.data ?? null;
|
|
162
|
-
return clientProcess ?? null;
|
|
163
|
-
};
|
|
164
|
-
/**
|
|
165
|
-
* Filters processes by the provided attribute.
|
|
166
|
-
*
|
|
167
|
-
* @param filterKey
|
|
168
|
-
*/
|
|
169
|
-
const filterProcesses = (filterKey) => {
|
|
170
|
-
return clientProcesses
|
|
171
|
-
.filter((clientProcess) => !!clientProcess.data?.dto)
|
|
172
|
-
.map((clientProcess) => clientProcess.data)
|
|
173
|
-
.filter((clientProcessData) => clientProcessData?.metadata.filterKey === filterKey);
|
|
174
|
-
};
|
|
175
|
-
/**
|
|
176
|
-
* Refreshes the cache and invalidates all related processes.
|
|
177
|
-
*/
|
|
178
|
-
const invalidateBasedOnResult = async (filter, invalidator) => {
|
|
179
|
-
await queryClient.invalidateQueries({
|
|
180
|
-
queryKey: ['.__process', filter],
|
|
181
|
-
exact: false,
|
|
182
|
-
});
|
|
183
|
-
const cachedClientProcesses = queryClient
|
|
184
|
-
.getQueryCache()
|
|
185
|
-
.findAll({ queryKey: ['.__process', filter], exact: false });
|
|
186
|
-
for (const query of cachedClientProcesses) {
|
|
187
|
-
const processId = query.queryKey[2];
|
|
188
|
-
if (typeof processId !== 'string')
|
|
189
|
-
continue;
|
|
190
|
-
const data = query.state.data;
|
|
191
|
-
if (!data.result)
|
|
192
|
-
continue;
|
|
193
|
-
// If invalidator says we gotta clear the cache, we clear it
|
|
194
|
-
if (invalidator && invalidator?.(data.result)) {
|
|
195
|
-
queryClient.removeQueries({ queryKey: query.queryKey });
|
|
196
|
-
}
|
|
197
|
-
}
|
|
198
|
-
};
|
|
199
|
-
return (jsx(clientProcessesContext.Provider, { value: {
|
|
200
|
-
registerProcess,
|
|
201
|
-
getProcess,
|
|
202
|
-
filterProcesses,
|
|
203
|
-
invalidateBasedOnResult,
|
|
204
|
-
}, children: children }));
|
|
205
|
-
};
|
|
206
|
-
/**
|
|
207
|
-
* A simpler version, where u just pass the async function that returns process data.
|
|
208
|
-
*
|
|
209
|
-
* @param caller
|
|
210
|
-
* @returns
|
|
211
|
-
*/
|
|
212
|
-
function useClientProcess({ caller, invalidator, filterKey, onLoading, onSuccess, onFailure, }) {
|
|
213
|
-
const clientProcessesApi = useContext(clientProcessesContext);
|
|
214
|
-
// Note that the exposed function doesn't return process ids
|
|
215
|
-
// Client should be oblivious to those
|
|
216
|
-
// Abstraction BABY!
|
|
217
|
-
const wrappedCaller = async (inputs, metadata) => {
|
|
218
|
-
const response = await caller?.(inputs);
|
|
219
|
-
if (response) {
|
|
220
|
-
clientProcessesApi.registerProcess(response.processId, response, { filterKey, metadata }, {
|
|
221
|
-
onLoading,
|
|
222
|
-
onSuccess,
|
|
223
|
-
onFailure,
|
|
224
|
-
});
|
|
225
|
-
return {
|
|
226
|
-
id: response.processId,
|
|
227
|
-
success: response.success,
|
|
228
|
-
message: response.message,
|
|
229
|
-
};
|
|
230
|
-
}
|
|
231
|
-
return {
|
|
232
|
-
id: null,
|
|
233
|
-
success: false,
|
|
234
|
-
message: 'No `caller` specified for useClientProcess().',
|
|
235
|
-
};
|
|
236
|
-
};
|
|
237
|
-
return {
|
|
238
|
-
run: wrappedCaller,
|
|
239
|
-
get: (id) => clientProcessesApi.getProcess(id),
|
|
240
|
-
getAll: () => clientProcessesApi.filterProcesses(filterKey),
|
|
241
|
-
getAllPending: () => clientProcessesApi
|
|
242
|
-
.filterProcesses(filterKey)
|
|
243
|
-
.filter((process) => process.pending),
|
|
244
|
-
getAllHandled: () => clientProcessesApi
|
|
245
|
-
.filterProcesses(filterKey)
|
|
246
|
-
.filter((process) => process.success),
|
|
247
|
-
getAllFailed: () => clientProcessesApi
|
|
248
|
-
.filterProcesses(filterKey)
|
|
249
|
-
.filter((process) => !process.success),
|
|
250
|
-
refreshCache: () => clientProcessesApi.invalidateBasedOnResult(filterKey, invalidator),
|
|
251
|
-
};
|
|
252
|
-
}
|
|
253
|
-
|
|
254
|
-
export { ClientProcessesProvider, useClientProcess };
|
|
255
|
-
//# sourceMappingURL=useClientProcess.js.map
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx } from 'react/jsx-runtime';
|
|
3
|
+
import { createContext, useRef, useState, useEffect, useContext } from 'react';
|
|
4
|
+
import { useQueryClient, useQueries } from '@tanstack/react-query';
|
|
5
|
+
import { config } from '../config.js';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* The orchestrator service to get the process from.
|
|
9
|
+
*
|
|
10
|
+
* @param processId
|
|
11
|
+
* @returns
|
|
12
|
+
*/
|
|
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
|
+
};
|
|
23
|
+
/**
|
|
24
|
+
* This fetches from the callback endpoint.
|
|
25
|
+
*
|
|
26
|
+
* @param processId
|
|
27
|
+
* @returns
|
|
28
|
+
*/
|
|
29
|
+
const processCallbackResultFetcher = (processId, processName, processCallbackUrl) => fetch(`${processCallbackUrl}`, {
|
|
30
|
+
method: 'POST',
|
|
31
|
+
headers: {
|
|
32
|
+
'Content-Type': 'application/json',
|
|
33
|
+
},
|
|
34
|
+
body: JSON.stringify({
|
|
35
|
+
processId,
|
|
36
|
+
processName,
|
|
37
|
+
}),
|
|
38
|
+
}).then((response) => response.json());
|
|
39
|
+
/**
|
|
40
|
+
* We need a context to keep track of all client processes.
|
|
41
|
+
* This helps us manage the state of the toasts as well.
|
|
42
|
+
*/
|
|
43
|
+
const clientProcessesContext = createContext({});
|
|
44
|
+
/**
|
|
45
|
+
* This should be at the root layout.
|
|
46
|
+
*
|
|
47
|
+
* @context
|
|
48
|
+
*/
|
|
49
|
+
const ClientProcessesProvider = ({ children, }) => {
|
|
50
|
+
const queryClient = useQueryClient();
|
|
51
|
+
const clientProcessAttempts = useRef({});
|
|
52
|
+
const [clientProcessDtos, setClientProcessDtos] = useState({});
|
|
53
|
+
// Populates the state object with cached data on mount
|
|
54
|
+
useEffect(() => {
|
|
55
|
+
setClientProcessDtos((oldData) => {
|
|
56
|
+
if (Object.keys(oldData).length > 0)
|
|
57
|
+
return oldData;
|
|
58
|
+
const cachedClientProcesses = queryClient
|
|
59
|
+
.getQueryCache()
|
|
60
|
+
.findAll({ queryKey: ['.__process'], exact: false });
|
|
61
|
+
const seededClientProcesses = {};
|
|
62
|
+
for (const query of cachedClientProcesses) {
|
|
63
|
+
const processId = query.queryKey[2];
|
|
64
|
+
if (typeof processId !== 'string')
|
|
65
|
+
continue;
|
|
66
|
+
const data = query.state.data;
|
|
67
|
+
if (!data?.dto || !data?.metadata)
|
|
68
|
+
continue;
|
|
69
|
+
seededClientProcesses[processId] = {
|
|
70
|
+
dto: data.dto,
|
|
71
|
+
metadata: data.metadata,
|
|
72
|
+
options: data.options,
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
return { ...oldData, ...seededClientProcesses };
|
|
76
|
+
});
|
|
77
|
+
}, [queryClient]);
|
|
78
|
+
// The query for all the processes, pending and sht
|
|
79
|
+
const clientProcesses = useQueries({
|
|
80
|
+
queries: Object.entries(clientProcessDtos).map(([processId, { dto, metadata, options }]) => ({
|
|
81
|
+
staleTime: Infinity,
|
|
82
|
+
gcTime: 3 * 60 * 1000,
|
|
83
|
+
refetchOnWindowFocus: true,
|
|
84
|
+
refetchIntervalInBackground: true,
|
|
85
|
+
refetchOnMount: true,
|
|
86
|
+
refetchOnReconnect: true,
|
|
87
|
+
queryKey: ['.__process', metadata.filterKey, processId],
|
|
88
|
+
queryFn: async () => {
|
|
89
|
+
if (!processId)
|
|
90
|
+
throw new Error('No processId');
|
|
91
|
+
const { process } = await processStatusChecker(processId);
|
|
92
|
+
// Handled! Return the proper response too
|
|
93
|
+
if (process?.status === 'handled') {
|
|
94
|
+
const result = await processCallbackResultFetcher(process.id, process.name, dto.processCallbackUrl);
|
|
95
|
+
// Log and call runner
|
|
96
|
+
console.warn(`Handled ${process.name} (${process.id})!`);
|
|
97
|
+
options?.onSuccess?.(process.id, process.name, result);
|
|
98
|
+
return {
|
|
99
|
+
dto,
|
|
100
|
+
metadata,
|
|
101
|
+
options,
|
|
102
|
+
success: true,
|
|
103
|
+
pending: false,
|
|
104
|
+
result,
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
// Pending or failed
|
|
108
|
+
if (process?.status === 'pending') {
|
|
109
|
+
console.log(`Running process ${process.name} (${process.id})...`);
|
|
110
|
+
options?.onLoading?.(process.id, process.name);
|
|
111
|
+
return { dto, metadata, options, pending: true };
|
|
112
|
+
}
|
|
113
|
+
else if (process?.status === 'failed') {
|
|
114
|
+
console.error(`Failed ${process.name} (${process.id}) - ${process.error}.`);
|
|
115
|
+
return {
|
|
116
|
+
dto,
|
|
117
|
+
metadata,
|
|
118
|
+
options,
|
|
119
|
+
success: false,
|
|
120
|
+
pending: false,
|
|
121
|
+
error: process.error,
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
// Return null since no response
|
|
125
|
+
return { dto, metadata, options, pending: true };
|
|
126
|
+
},
|
|
127
|
+
// Returns the next interval length to use to wait for fetch
|
|
128
|
+
refetchInterval: (query) => {
|
|
129
|
+
const data = query.state.data;
|
|
130
|
+
if (data?.success !== undefined)
|
|
131
|
+
return false;
|
|
132
|
+
// If not defined, init to 0
|
|
133
|
+
if (!clientProcessAttempts.current[processId])
|
|
134
|
+
clientProcessAttempts.current[processId] = 0;
|
|
135
|
+
const interval = Math.min(500 * 2 ** clientProcessAttempts.current[processId], 10000);
|
|
136
|
+
clientProcessAttempts.current[processId] += 1;
|
|
137
|
+
return interval;
|
|
138
|
+
},
|
|
139
|
+
})),
|
|
140
|
+
});
|
|
141
|
+
/**
|
|
142
|
+
* Registers a new process to handle
|
|
143
|
+
*
|
|
144
|
+
* @param processId
|
|
145
|
+
* @param processCallbackDto
|
|
146
|
+
* @param options
|
|
147
|
+
*/
|
|
148
|
+
const registerProcess = (processId, processCallbackDto, metadata, options) => {
|
|
149
|
+
setClientProcessDtos({
|
|
150
|
+
...clientProcessDtos,
|
|
151
|
+
[processId]: { dto: processCallbackDto, metadata, options },
|
|
152
|
+
});
|
|
153
|
+
};
|
|
154
|
+
/**
|
|
155
|
+
* Retrieves a process
|
|
156
|
+
*
|
|
157
|
+
* @param processId
|
|
158
|
+
* @returns
|
|
159
|
+
*/
|
|
160
|
+
const getProcess = (processId) => {
|
|
161
|
+
const clientProcess = clientProcesses.find((clientProcess) => clientProcess.data?.dto?.processId === processId)?.data ?? null;
|
|
162
|
+
return clientProcess ?? null;
|
|
163
|
+
};
|
|
164
|
+
/**
|
|
165
|
+
* Filters processes by the provided attribute.
|
|
166
|
+
*
|
|
167
|
+
* @param filterKey
|
|
168
|
+
*/
|
|
169
|
+
const filterProcesses = (filterKey) => {
|
|
170
|
+
return clientProcesses
|
|
171
|
+
.filter((clientProcess) => !!clientProcess.data?.dto)
|
|
172
|
+
.map((clientProcess) => clientProcess.data)
|
|
173
|
+
.filter((clientProcessData) => clientProcessData?.metadata.filterKey === filterKey);
|
|
174
|
+
};
|
|
175
|
+
/**
|
|
176
|
+
* Refreshes the cache and invalidates all related processes.
|
|
177
|
+
*/
|
|
178
|
+
const invalidateBasedOnResult = async (filter, invalidator) => {
|
|
179
|
+
await queryClient.invalidateQueries({
|
|
180
|
+
queryKey: ['.__process', filter],
|
|
181
|
+
exact: false,
|
|
182
|
+
});
|
|
183
|
+
const cachedClientProcesses = queryClient
|
|
184
|
+
.getQueryCache()
|
|
185
|
+
.findAll({ queryKey: ['.__process', filter], exact: false });
|
|
186
|
+
for (const query of cachedClientProcesses) {
|
|
187
|
+
const processId = query.queryKey[2];
|
|
188
|
+
if (typeof processId !== 'string')
|
|
189
|
+
continue;
|
|
190
|
+
const data = query.state.data;
|
|
191
|
+
if (!data.result)
|
|
192
|
+
continue;
|
|
193
|
+
// If invalidator says we gotta clear the cache, we clear it
|
|
194
|
+
if (invalidator && invalidator?.(data.result)) {
|
|
195
|
+
queryClient.removeQueries({ queryKey: query.queryKey });
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
};
|
|
199
|
+
return (jsx(clientProcessesContext.Provider, { value: {
|
|
200
|
+
registerProcess,
|
|
201
|
+
getProcess,
|
|
202
|
+
filterProcesses,
|
|
203
|
+
invalidateBasedOnResult,
|
|
204
|
+
}, children: children }));
|
|
205
|
+
};
|
|
206
|
+
/**
|
|
207
|
+
* A simpler version, where u just pass the async function that returns process data.
|
|
208
|
+
*
|
|
209
|
+
* @param caller
|
|
210
|
+
* @returns
|
|
211
|
+
*/
|
|
212
|
+
function useClientProcess({ caller, invalidator, filterKey, onLoading, onSuccess, onFailure, }) {
|
|
213
|
+
const clientProcessesApi = useContext(clientProcessesContext);
|
|
214
|
+
// Note that the exposed function doesn't return process ids
|
|
215
|
+
// Client should be oblivious to those
|
|
216
|
+
// Abstraction BABY!
|
|
217
|
+
const wrappedCaller = async (inputs, metadata) => {
|
|
218
|
+
const response = await caller?.(inputs);
|
|
219
|
+
if (response) {
|
|
220
|
+
clientProcessesApi.registerProcess(response.processId, response, { filterKey, metadata }, {
|
|
221
|
+
onLoading,
|
|
222
|
+
onSuccess,
|
|
223
|
+
onFailure,
|
|
224
|
+
});
|
|
225
|
+
return {
|
|
226
|
+
id: response.processId,
|
|
227
|
+
success: response.success,
|
|
228
|
+
message: response.message,
|
|
229
|
+
};
|
|
230
|
+
}
|
|
231
|
+
return {
|
|
232
|
+
id: null,
|
|
233
|
+
success: false,
|
|
234
|
+
message: 'No `caller` specified for useClientProcess().',
|
|
235
|
+
};
|
|
236
|
+
};
|
|
237
|
+
return {
|
|
238
|
+
run: wrappedCaller,
|
|
239
|
+
get: (id) => clientProcessesApi.getProcess(id),
|
|
240
|
+
getAll: () => clientProcessesApi.filterProcesses(filterKey),
|
|
241
|
+
getAllPending: () => clientProcessesApi
|
|
242
|
+
.filterProcesses(filterKey)
|
|
243
|
+
.filter((process) => process.pending),
|
|
244
|
+
getAllHandled: () => clientProcessesApi
|
|
245
|
+
.filterProcesses(filterKey)
|
|
246
|
+
.filter((process) => process.success),
|
|
247
|
+
getAllFailed: () => clientProcessesApi
|
|
248
|
+
.filterProcesses(filterKey)
|
|
249
|
+
.filter((process) => !process.success),
|
|
250
|
+
refreshCache: () => clientProcessesApi.invalidateBasedOnResult(filterKey, invalidator),
|
|
251
|
+
};
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
export { ClientProcessesProvider, useClientProcess };
|
|
255
|
+
//# sourceMappingURL=useClientProcess.js.map
|