@everysk/apps-sdk 0.2.0 → 0.3.0-beta-20261016180126
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/README.md +298 -12
- package/dist/EveryskApp.d.ts +34 -2
- package/dist/EveryskApp.d.ts.map +1 -1
- package/dist/EveryskApp.js +35 -2
- package/dist/EveryskApp.js.map +1 -1
- package/dist/agGrid/handleRowsScrollEnd.d.ts +53 -0
- package/dist/agGrid/handleRowsScrollEnd.d.ts.map +1 -0
- package/dist/agGrid/handleRowsScrollEnd.js +47 -0
- package/dist/agGrid/handleRowsScrollEnd.js.map +1 -0
- package/dist/agGrid/index.d.ts +2 -0
- package/dist/agGrid/index.d.ts.map +1 -1
- package/dist/agGrid/index.js +2 -1
- package/dist/api/datastore.d.ts +10 -8
- package/dist/api/datastore.d.ts.map +1 -1
- package/dist/api/datastore.js +24 -55
- package/dist/api/datastore.js.map +1 -1
- package/dist/api/entityQuery.d.ts +46 -41
- package/dist/api/entityQuery.d.ts.map +1 -1
- package/dist/api/entityQuery.js +55 -14
- package/dist/api/entityQuery.js.map +1 -1
- package/dist/api/file.d.ts +26 -9
- package/dist/api/file.d.ts.map +1 -1
- package/dist/api/file.js +45 -55
- package/dist/api/file.js.map +1 -1
- package/dist/api/portfolio.d.ts +11 -8
- package/dist/api/portfolio.d.ts.map +1 -1
- package/dist/api/portfolio.js +24 -55
- package/dist/api/portfolio.js.map +1 -1
- package/dist/api/profile.d.ts +3 -2
- package/dist/api/profile.d.ts.map +1 -1
- package/dist/api/profile.js +4 -9
- package/dist/api/profile.js.map +1 -1
- package/dist/api/request.d.ts +106 -0
- package/dist/api/request.d.ts.map +1 -0
- package/dist/api/request.js +132 -0
- package/dist/api/request.js.map +1 -0
- package/dist/api/websocketsConfig.d.ts +7 -2
- package/dist/api/websocketsConfig.d.ts.map +1 -1
- package/dist/api/websocketsConfig.js +2 -10
- package/dist/api/websocketsConfig.js.map +1 -1
- package/dist/api/workflow.d.ts +84 -89
- package/dist/api/workflow.d.ts.map +1 -1
- package/dist/api/workflow.js +121 -208
- package/dist/api/workflow.js.map +1 -1
- package/dist/api/workspace.d.ts +18 -8
- package/dist/api/workspace.d.ts.map +1 -1
- package/dist/api/workspace.js +21 -26
- package/dist/api/workspace.js.map +1 -1
- package/dist/components/ui/Footer/index.d.ts.map +1 -1
- package/dist/components/ui/Footer/index.js.map +1 -1
- package/dist/components/ui/GlobalLoading/index.d.ts.map +1 -1
- package/dist/components/ui/GlobalLoading/index.js.map +1 -1
- package/dist/components/ui/PageContainer/index.d.ts +1 -1
- package/dist/components/ui/PageContainer/index.d.ts.map +1 -1
- package/dist/components/ui/PageContainer/index.js.map +1 -1
- package/dist/components/ui/Toolbar/index.d.ts +40 -3
- package/dist/components/ui/Toolbar/index.d.ts.map +1 -1
- package/dist/components/ui/Toolbar/index.js +42 -15
- package/dist/components/ui/Toolbar/index.js.map +1 -1
- package/dist/contexts/appAlertContext/provider.js.map +1 -1
- package/dist/contexts/appAlertContext/types.d.ts.map +1 -1
- package/dist/contexts/appConfigContext/index.d.ts.map +1 -1
- package/dist/contexts/appConfigContext/index.js.map +1 -1
- package/dist/contexts/appConfigContext/provider.d.ts.map +1 -1
- package/dist/contexts/appConfigContext/provider.js.map +1 -1
- package/dist/contexts/webSocketContext/handler.d.ts +3 -2
- package/dist/contexts/webSocketContext/handler.d.ts.map +1 -1
- package/dist/contexts/webSocketContext/handler.js.map +1 -1
- package/dist/contexts/webSocketContext/hooks/useWebSocket/index.d.ts +1 -1
- package/dist/contexts/webSocketContext/hooks/useWebSocket/index.js +1 -1
- package/dist/contexts/webSocketContext/hooks/useWebSocket/index.js.map +1 -1
- package/dist/contexts/webSocketContext/provider.d.ts +6 -3
- package/dist/contexts/webSocketContext/provider.d.ts.map +1 -1
- package/dist/contexts/webSocketContext/provider.js +42 -7
- package/dist/contexts/webSocketContext/provider.js.map +1 -1
- package/dist/contexts/webSocketContext/types.d.ts +7 -5
- package/dist/contexts/webSocketContext/types.d.ts.map +1 -1
- package/dist/file/index.d.ts +2 -0
- package/dist/file/index.d.ts.map +1 -1
- package/dist/hooks/datastore/useDatastoreMutations.d.ts +4 -4
- package/dist/hooks/datastore/useDatastoreMutations.d.ts.map +1 -1
- package/dist/hooks/datastore/useDatastoreMutations.js +17 -55
- package/dist/hooks/datastore/useDatastoreMutations.js.map +1 -1
- package/dist/hooks/datastore/useFetchDatastore.d.ts +30 -41
- package/dist/hooks/datastore/useFetchDatastore.d.ts.map +1 -1
- package/dist/hooks/datastore/useFetchDatastore.js +25 -59
- package/dist/hooks/datastore/useFetchDatastore.js.map +1 -1
- package/dist/hooks/datastore/useFetchDatastores.d.ts +47 -52
- package/dist/hooks/datastore/useFetchDatastores.d.ts.map +1 -1
- package/dist/hooks/datastore/useFetchDatastores.js +55 -70
- package/dist/hooks/datastore/useFetchDatastores.js.map +1 -1
- package/dist/hooks/file/fileData.d.ts +17 -0
- package/dist/hooks/file/fileData.d.ts.map +1 -0
- package/dist/hooks/file/fileData.js +10 -0
- package/dist/hooks/file/fileData.js.map +1 -0
- package/dist/hooks/file/useFetchFile.d.ts +38 -58
- package/dist/hooks/file/useFetchFile.d.ts.map +1 -1
- package/dist/hooks/file/useFetchFile.js +26 -66
- package/dist/hooks/file/useFetchFile.js.map +1 -1
- package/dist/hooks/file/useFetchFiles.d.ts +18 -52
- package/dist/hooks/file/useFetchFiles.d.ts.map +1 -1
- package/dist/hooks/file/useFetchFiles.js +53 -69
- package/dist/hooks/file/useFetchFiles.js.map +1 -1
- package/dist/hooks/file/useFileMutations.d.ts +9 -8
- package/dist/hooks/file/useFileMutations.d.ts.map +1 -1
- package/dist/hooks/file/useFileMutations.js +23 -60
- package/dist/hooks/file/useFileMutations.js.map +1 -1
- package/dist/hooks/portfolio/useFetchPortfolio.d.ts +16 -50
- package/dist/hooks/portfolio/useFetchPortfolio.d.ts.map +1 -1
- package/dist/hooks/portfolio/useFetchPortfolio.js +15 -63
- package/dist/hooks/portfolio/useFetchPortfolio.js.map +1 -1
- package/dist/hooks/portfolio/useFetchPortfolios.d.ts +13 -52
- package/dist/hooks/portfolio/useFetchPortfolios.d.ts.map +1 -1
- package/dist/hooks/portfolio/useFetchPortfolios.js +29 -71
- package/dist/hooks/portfolio/useFetchPortfolios.js.map +1 -1
- package/dist/hooks/portfolio/usePortfolioMutations.d.ts +8 -8
- package/dist/hooks/portfolio/usePortfolioMutations.d.ts.map +1 -1
- package/dist/hooks/portfolio/usePortfolioMutations.js +20 -58
- package/dist/hooks/portfolio/usePortfolioMutations.js.map +1 -1
- package/dist/hooks/profile/useFetchProfile.d.ts +18 -44
- package/dist/hooks/profile/useFetchProfile.d.ts.map +1 -1
- package/dist/hooks/profile/useFetchProfile.js +16 -48
- package/dist/hooks/profile/useFetchProfile.js.map +1 -1
- package/dist/hooks/useAxios.js.map +1 -1
- package/dist/hooks/useEntityInfiniteQuery.d.ts +88 -0
- package/dist/hooks/useEntityInfiniteQuery.d.ts.map +1 -0
- package/dist/hooks/useEntityInfiniteQuery.js +111 -0
- package/dist/hooks/useEntityInfiniteQuery.js.map +1 -0
- package/dist/hooks/useEntityMutation.d.ts +47 -0
- package/dist/hooks/useEntityMutation.d.ts.map +1 -0
- package/dist/hooks/useEntityMutation.js +58 -0
- package/dist/hooks/useEntityMutation.js.map +1 -0
- package/dist/hooks/useEntityQuery.d.ts +68 -0
- package/dist/hooks/useEntityQuery.d.ts.map +1 -0
- package/dist/hooks/useEntityQuery.js +75 -0
- package/dist/hooks/useEntityQuery.js.map +1 -0
- package/dist/hooks/workflow/useFetchWorkerExecution.d.ts +17 -34
- package/dist/hooks/workflow/useFetchWorkerExecution.d.ts.map +1 -1
- package/dist/hooks/workflow/useFetchWorkerExecution.js +16 -46
- package/dist/hooks/workflow/useFetchWorkerExecution.js.map +1 -1
- package/dist/hooks/workflow/useFetchWorkerExecutions.d.ts +179 -41
- package/dist/hooks/workflow/useFetchWorkerExecutions.d.ts.map +1 -1
- package/dist/hooks/workflow/useFetchWorkerExecutions.js +29 -62
- package/dist/hooks/workflow/useFetchWorkerExecutions.js.map +1 -1
- package/dist/hooks/workflow/useFetchWorkflow.d.ts +16 -35
- package/dist/hooks/workflow/useFetchWorkflow.d.ts.map +1 -1
- package/dist/hooks/workflow/useFetchWorkflow.js +15 -48
- package/dist/hooks/workflow/useFetchWorkflow.js.map +1 -1
- package/dist/hooks/workflow/useFetchWorkflowExecution.d.ts +17 -34
- package/dist/hooks/workflow/useFetchWorkflowExecution.d.ts.map +1 -1
- package/dist/hooks/workflow/useFetchWorkflowExecution.js +16 -46
- package/dist/hooks/workflow/useFetchWorkflowExecution.js.map +1 -1
- package/dist/hooks/workflow/useFetchWorkflowExecutions.d.ts +22 -36
- package/dist/hooks/workflow/useFetchWorkflowExecutions.d.ts.map +1 -1
- package/dist/hooks/workflow/useFetchWorkflowExecutions.js +43 -56
- package/dist/hooks/workflow/useFetchWorkflowExecutions.js.map +1 -1
- package/dist/hooks/workflow/useFetchWorkflows.d.ts +20 -37
- package/dist/hooks/workflow/useFetchWorkflows.d.ts.map +1 -1
- package/dist/hooks/workflow/useFetchWorkflows.js +32 -47
- package/dist/hooks/workflow/useFetchWorkflows.js.map +1 -1
- package/dist/hooks/workflow/useRunWorkflow.d.ts +21 -16
- package/dist/hooks/workflow/useRunWorkflow.d.ts.map +1 -1
- package/dist/hooks/workflow/useRunWorkflow.js +66 -29
- package/dist/hooks/workflow/useRunWorkflow.js.map +1 -1
- package/dist/hooks/workflow/useTriggerWorkflow.d.ts +20 -0
- package/dist/hooks/workflow/useTriggerWorkflow.d.ts.map +1 -0
- package/dist/hooks/workflow/useTriggerWorkflow.js +32 -0
- package/dist/hooks/workflow/useTriggerWorkflow.js.map +1 -0
- package/dist/hooks/workspace/useFetchWorkspace.d.ts +19 -34
- package/dist/hooks/workspace/useFetchWorkspace.d.ts.map +1 -1
- package/dist/hooks/workspace/useFetchWorkspace.js +16 -46
- package/dist/hooks/workspace/useFetchWorkspace.js.map +1 -1
- package/dist/hooks/workspace/useFetchWorkspaces.d.ts +17 -37
- package/dist/hooks/workspace/useFetchWorkspaces.d.ts.map +1 -1
- package/dist/hooks/workspace/useFetchWorkspaces.js +25 -47
- package/dist/hooks/workspace/useFetchWorkspaces.js.map +1 -1
- package/dist/index.d.ts +13 -10
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +13 -11
- package/dist/lib/abort.d.ts +58 -0
- package/dist/lib/abort.d.ts.map +1 -0
- package/dist/lib/abort.js +112 -0
- package/dist/lib/abort.js.map +1 -0
- package/dist/lib/datastoreTable.d.ts +59 -54
- package/dist/lib/datastoreTable.d.ts.map +1 -1
- package/dist/lib/datastoreTable.js +58 -62
- package/dist/lib/datastoreTable.js.map +1 -1
- package/dist/lib/file.d.ts +34 -0
- package/dist/lib/file.d.ts.map +1 -0
- package/dist/lib/file.js +63 -0
- package/dist/lib/file.js.map +1 -0
- package/dist/lib/queryClient.d.ts.map +1 -1
- package/dist/lib/queryClient.js.map +1 -1
- package/dist/lib/workflowRun.d.ts +91 -0
- package/dist/lib/workflowRun.d.ts.map +1 -0
- package/dist/lib/workflowRun.js +224 -0
- package/dist/lib/workflowRun.js.map +1 -0
- package/dist/socket/index.d.ts +1 -3
- package/dist/socket/index.d.ts.map +1 -1
- package/dist/socket/index.js +3 -5
- package/dist/test/mocks/index.d.ts +1 -1
- package/dist/test/mocks/index.d.ts.map +1 -1
- package/dist/test/renderWithProviders.d.ts +2 -2
- package/dist/test/renderWithProviders.d.ts.map +1 -1
- package/dist/test/renderWithProviders.js.map +1 -1
- package/dist/test/setup.js.map +1 -1
- package/dist/theme/index.d.ts +1 -1
- package/dist/theme/index.d.ts.map +1 -1
- package/dist/theme/overrides/index.d.ts +4 -2
- package/dist/theme/overrides/index.d.ts.map +1 -1
- package/dist/theme/overrides/index.js +5 -3
- package/dist/theme/overrides/index.js.map +1 -1
- package/dist/theme/overrides/muiButton.d.ts +2 -2
- package/dist/theme/overrides/muiButton.js.map +1 -1
- package/dist/theme/overrides/muiCssBaseline.d.ts.map +1 -1
- package/dist/theme/overrides/muiCssBaseline.js.map +1 -1
- package/dist/theme/overrides/muiDatePicker.js.map +1 -1
- package/dist/theme/overrides/muiFormControl.js.map +1 -1
- package/dist/theme/overrides/muiIconButton.d.ts +2 -2
- package/dist/theme/overrides/muiIconButton.js.map +1 -1
- package/dist/theme/overrides/muiSelect.d.ts.map +1 -1
- package/dist/theme/overrides/muiSelect.js.map +1 -1
- package/dist/theme/overrides/muiSvgIcon.d.ts.map +1 -1
- package/dist/theme/overrides/muiSvgIcon.js.map +1 -1
- package/dist/theme/overrides/muiTextField.js.map +1 -1
- package/dist/theme/overrides/muiToggleButton.d.ts +2 -2
- package/dist/theme/overrides/muiToggleButton.js.map +1 -1
- package/dist/theme/overrides/muiToggleButtonGroup.d.ts +2 -2
- package/dist/theme/overrides/muiToggleButtonGroup.js.map +1 -1
- package/dist/theme/themes/DefaultDark.js +2 -2
- package/dist/theme/themes/DefaultDark.js.map +1 -1
- package/dist/theme/themes/DefaultLight.js +2 -2
- package/dist/theme/themes/DefaultLight.js.map +1 -1
- package/dist/theme/themes/EveryskDark.js +2 -2
- package/dist/theme/themes/EveryskDark.js.map +1 -1
- package/dist/theme/themes/EveryskLight.js +2 -2
- package/dist/theme/themes/EveryskLight.js.map +1 -1
- package/dist/theme/themes/MidnightEmber.js +2 -2
- package/dist/theme/themes/MidnightEmber.js.map +1 -1
- package/dist/types/anyRecord.d.ts.map +1 -1
- package/dist/types/datastore.d.ts +35 -5
- package/dist/types/datastore.d.ts.map +1 -1
- package/dist/types/datastoreDataFormat.d.ts +13 -0
- package/dist/types/datastoreDataFormat.d.ts.map +1 -0
- package/dist/types/entityQuery.d.ts +86 -16
- package/dist/types/entityQuery.d.ts.map +1 -1
- package/dist/types/file.d.ts +7 -3
- package/dist/types/file.d.ts.map +1 -1
- package/dist/types/portfolio.d.ts +1 -3
- package/dist/types/portfolio.d.ts.map +1 -1
- package/dist/types/profile.d.ts +0 -10
- package/dist/types/profile.d.ts.map +1 -1
- package/dist/types/workflow.d.ts +35 -6
- package/dist/types/workflow.d.ts.map +1 -1
- package/dist/types/workspace.d.ts +1 -2
- package/dist/types/workspace.d.ts.map +1 -1
- package/dist/ui/index.d.ts +1 -1
- package/dist/ui/index.d.ts.map +1 -1
- package/dist/workflow/index.d.ts +2 -0
- package/dist/workflow/index.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/EveryskApp.tsx +53 -2
- package/src/agGrid/handleRowsScrollEnd.ts +71 -0
- package/src/agGrid/index.ts +5 -1
- package/src/api/datastore.ts +79 -107
- package/src/api/entityQuery.ts +86 -17
- package/src/api/file.ts +110 -103
- package/src/api/portfolio.ts +82 -125
- package/src/api/profile.ts +25 -18
- package/src/api/request.ts +168 -0
- package/src/api/websocketsConfig.ts +11 -19
- package/src/api/workflow.ts +232 -334
- package/src/api/workspace.ts +43 -43
- package/src/components/ui/Footer/index.tsx +8 -7
- package/src/components/ui/GlobalLoading/index.tsx +13 -3
- package/src/components/ui/PageContainer/index.tsx +9 -2
- package/src/components/ui/Toolbar/index.tsx +105 -30
- package/src/contexts/appAlertContext/provider.tsx +1 -1
- package/src/contexts/appAlertContext/types.ts +3 -3
- package/src/contexts/appConfigContext/index.tsx +1 -1
- package/src/contexts/appConfigContext/provider.tsx +1 -5
- package/src/contexts/webSocketContext/handler.ts +8 -2
- package/src/contexts/webSocketContext/hooks/useWebSocket/index.ts +1 -1
- package/src/contexts/webSocketContext/provider.tsx +64 -14
- package/src/contexts/webSocketContext/types.ts +7 -6
- package/src/file/index.ts +2 -0
- package/src/hooks/datastore/useDatastoreMutations.ts +19 -60
- package/src/hooks/datastore/useFetchDatastore.ts +45 -73
- package/src/hooks/datastore/useFetchDatastores.ts +106 -131
- package/src/hooks/file/fileData.ts +19 -0
- package/src/hooks/file/useFetchFile.ts +41 -76
- package/src/hooks/file/useFetchFiles.ts +92 -87
- package/src/hooks/file/useFileMutations.ts +23 -73
- package/src/hooks/portfolio/useFetchPortfolio.ts +26 -78
- package/src/hooks/portfolio/useFetchPortfolios.ts +50 -93
- package/src/hooks/portfolio/usePortfolioMutations.ts +22 -72
- package/src/hooks/profile/useFetchProfile.ts +24 -65
- package/src/hooks/useAxios.ts +5 -5
- package/src/hooks/useEntityInfiniteQuery.ts +193 -0
- package/src/hooks/useEntityMutation.ts +70 -0
- package/src/hooks/useEntityQuery.ts +117 -0
- package/src/hooks/workflow/useFetchWorkerExecution.ts +27 -56
- package/src/hooks/workflow/useFetchWorkerExecutions.ts +54 -79
- package/src/hooks/workflow/useFetchWorkflow.ts +24 -58
- package/src/hooks/workflow/useFetchWorkflowExecution.ts +27 -57
- package/src/hooks/workflow/useFetchWorkflowExecutions.ts +64 -73
- package/src/hooks/workflow/useFetchWorkflows.ts +48 -64
- package/src/hooks/workflow/useRunWorkflow.ts +82 -36
- package/src/hooks/workflow/useTriggerWorkflow.ts +36 -0
- package/src/hooks/workspace/useFetchWorkspace.ts +25 -58
- package/src/hooks/workspace/useFetchWorkspaces.ts +38 -69
- package/src/index.ts +34 -19
- package/src/lib/abort.ts +131 -0
- package/src/lib/datastoreTable.ts +127 -74
- package/src/lib/file.ts +67 -0
- package/src/lib/queryClient.ts +11 -13
- package/src/lib/workflowRun.ts +329 -0
- package/src/socket/index.ts +1 -3
- package/src/test/mocks/index.ts +1 -5
- package/src/test/renderWithProviders.tsx +8 -3
- package/src/test/setup.ts +16 -16
- package/src/theme/index.ts +1 -1
- package/src/theme/overrides/index.ts +5 -3
- package/src/theme/overrides/muiButton.ts +3 -3
- package/src/theme/overrides/muiCssBaseline.ts +11 -12
- package/src/theme/overrides/muiDatePicker.ts +2 -2
- package/src/theme/overrides/muiFormControl.ts +2 -2
- package/src/theme/overrides/muiIconButton.ts +3 -3
- package/src/theme/overrides/muiSelect.ts +2 -2
- package/src/theme/overrides/muiSvgIcon.ts +2 -2
- package/src/theme/overrides/muiTextField.ts +1 -1
- package/src/theme/overrides/muiToggleButton.ts +4 -4
- package/src/theme/overrides/muiToggleButtonGroup.ts +4 -4
- package/src/theme/themes/DefaultDark.ts +2 -2
- package/src/theme/themes/DefaultLight.ts +2 -2
- package/src/theme/themes/EveryskDark.ts +2 -2
- package/src/theme/themes/EveryskLight.ts +2 -2
- package/src/theme/themes/MidnightEmber.ts +15 -15
- package/src/types/anyRecord.ts +2 -2
- package/src/types/datastore.ts +56 -22
- package/src/types/datastoreDataFormat.ts +12 -0
- package/src/types/entityQuery.ts +122 -38
- package/src/types/file.ts +8 -6
- package/src/types/portfolio.ts +70 -74
- package/src/types/profile.ts +0 -11
- package/src/types/workflow.ts +38 -9
- package/src/types/workspace.ts +2 -4
- package/src/ui/index.ts +1 -1
- package/src/workflow/index.ts +5 -0
package/src/lib/queryClient.ts
CHANGED
|
@@ -8,22 +8,20 @@ async function throwIfResNotOk(res: Response) {
|
|
|
8
8
|
}
|
|
9
9
|
|
|
10
10
|
type UnauthorizedBehavior = "returnNull" | "throw";
|
|
11
|
-
export const getQueryFn: <T>(options: {
|
|
12
|
-
on401: UnauthorizedBehavior;
|
|
13
|
-
}) => QueryFunction<T> =
|
|
11
|
+
export const getQueryFn: <T>(options: { on401: UnauthorizedBehavior }) => QueryFunction<T> =
|
|
14
12
|
({ on401: unauthorizedBehavior }) =>
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
13
|
+
async ({ queryKey }) => {
|
|
14
|
+
const res = await fetch(queryKey.join("/") as string, {
|
|
15
|
+
credentials: "include",
|
|
16
|
+
});
|
|
19
17
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
18
|
+
if (unauthorizedBehavior === "returnNull" && res.status === 401) {
|
|
19
|
+
return null;
|
|
20
|
+
}
|
|
23
21
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
22
|
+
await throwIfResNotOk(res);
|
|
23
|
+
return await res.json();
|
|
24
|
+
};
|
|
27
25
|
|
|
28
26
|
/**
|
|
29
27
|
* createQueryClient
|
|
@@ -0,0 +1,329 @@
|
|
|
1
|
+
import { isRetryableFailure } from "@/api/request";
|
|
2
|
+
import { isTerminalRunStatus } from "@/api/workflow";
|
|
3
|
+
import { abortable, createDeadline, unlessAborted } from "@/lib/abort";
|
|
4
|
+
import type { WebSocketNotification, WebSocketStatus } from "@/contexts/webSocketContext/types";
|
|
5
|
+
import type { WorkflowExecution } from "@/types/workflow";
|
|
6
|
+
|
|
7
|
+
/** The alert a run hook shows when its failure carries no message of its own. */
|
|
8
|
+
export const RUN_FAILED_MESSAGE = "Unable to run the workflow. Please try again.";
|
|
9
|
+
|
|
10
|
+
/** The events the backend sends when a run's Ender finishes. */
|
|
11
|
+
const RUN_END_EVENTS: readonly string[] = [
|
|
12
|
+
"WORKFLOW_EXECUTION_COMPLETED",
|
|
13
|
+
"WORKFLOW_EXECUTION_FAILED",
|
|
14
|
+
];
|
|
15
|
+
|
|
16
|
+
const isRunEndEvent = (event: WebSocketNotification) => RUN_END_EVENTS.includes(event.event_type);
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* The error a run ends with when its caller stopped it — the screen went away, or the app's own
|
|
20
|
+
* signal — with that signal's reason as the cause. One class for both phases, the wait and the
|
|
21
|
+
* result read, so a caller can tell a stop from a failure with `instanceof` rather than by its
|
|
22
|
+
* message.
|
|
23
|
+
*/
|
|
24
|
+
export class WorkflowRunAbortedError extends Error {
|
|
25
|
+
constructor(reason: unknown) {
|
|
26
|
+
super("Waiting for the workflow run was aborted", { cause: reason });
|
|
27
|
+
this.name = "WorkflowRunAbortedError";
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/** The longest delay `setTimeout` honours; it fires a longer one after 1 ms. */
|
|
32
|
+
const MAX_TIMER_DELAY_MS = 2 ** 31 - 1;
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Throws when a wait option is not a positive number a timer can wait: zero or NaN would read
|
|
36
|
+
* back to back, and above `MAX_TIMER_DELAY_MS` the timer fires at once.
|
|
37
|
+
*/
|
|
38
|
+
const requireTimerDelays = (options: Record<string, number>) => {
|
|
39
|
+
for (const [name, value] of Object.entries(options)) {
|
|
40
|
+
if (!(value > 0 && value <= MAX_TIMER_DELAY_MS)) {
|
|
41
|
+
throw new Error(
|
|
42
|
+
`[apps-sdk] runWorkflowToEnd: ${name} must be a positive number of milliseconds up to ${MAX_TIMER_DELAY_MS}, got ${value}`,
|
|
43
|
+
);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
export type WorkflowWaitOptions = {
|
|
49
|
+
/**
|
|
50
|
+
* How long the run may go without any event before the execution is read anyway, in
|
|
51
|
+
* milliseconds. Defaults to a minute. It covers a lost event, and a long worker, which sends
|
|
52
|
+
* nothing while it runs.
|
|
53
|
+
*/
|
|
54
|
+
silenceMs?: number;
|
|
55
|
+
/** How long to wait for the run to end before giving up, in milliseconds. Defaults to 5 minutes. */
|
|
56
|
+
timeoutMs?: number;
|
|
57
|
+
/**
|
|
58
|
+
* The first gap between reads after the end event, while the run still reads RUNNING, in
|
|
59
|
+
* milliseconds. It doubles each time it passes without a new event, up to `silenceMs`.
|
|
60
|
+
* Defaults to 1 second.
|
|
61
|
+
*/
|
|
62
|
+
confirmIntervalMs?: number;
|
|
63
|
+
/**
|
|
64
|
+
* How long the socket may stay in `error` before the run is given up on as unfollowable, in
|
|
65
|
+
* milliseconds. Defaults to 30 seconds: socket.io keeps retrying after a failed reconnect, on
|
|
66
|
+
* a backoff that alone can reach about 7.5 seconds between attempts.
|
|
67
|
+
*/
|
|
68
|
+
unavailableAfterMs?: number;
|
|
69
|
+
/** Stops waiting. `useRunWorkflow` also stops when its screen unmounts. */
|
|
70
|
+
signal?: AbortSignal;
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
export type RunWorkflowToEndParams = WorkflowWaitOptions & {
|
|
74
|
+
/** Starts the run (`POST /workflows/:id/run`) and returns the execution it created. */
|
|
75
|
+
startRun: () => Promise<WorkflowExecution>;
|
|
76
|
+
/**
|
|
77
|
+
* Reads the execution; its `run_status` is what says the run ended, and how. Pass `signal` to
|
|
78
|
+
* the request, so a timeout or an abort cancels a read in flight.
|
|
79
|
+
*/
|
|
80
|
+
getExecution: (workflowExecutionId: string, signal: AbortSignal) => Promise<WorkflowExecution>;
|
|
81
|
+
/** The websocket context's `subscribe`. */
|
|
82
|
+
subscribeToEvents: (listener: (event: WebSocketNotification) => void) => () => void;
|
|
83
|
+
/**
|
|
84
|
+
* The websocket context's `subscribeStatus`, which tells a new listener the current status at
|
|
85
|
+
* once: that is how the wait learns the status it begins in.
|
|
86
|
+
*/
|
|
87
|
+
subscribeToStatus: (listener: (status: WebSocketStatus) => void) => () => void;
|
|
88
|
+
};
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* What wakes the wait up: an event of the run (`progress`, or `end` for the Ender's), the socket
|
|
92
|
+
* coming back (`reconnect`) or going (`unavailable`), or nothing at all for `silenceMs` (`silence`).
|
|
93
|
+
*/
|
|
94
|
+
type Trigger = "progress" | "end" | "reconnect" | "unavailable" | "silence";
|
|
95
|
+
|
|
96
|
+
/** The triggers kept for later while the loop is busy reading, highest first. */
|
|
97
|
+
const PENDING_PRIORITY: Trigger[] = ["unavailable", "end", "reconnect"];
|
|
98
|
+
|
|
99
|
+
const socketUnavailableError = () =>
|
|
100
|
+
new Error(
|
|
101
|
+
"Real-time notifications are unavailable, so the end of the workflow run cannot be followed. " +
|
|
102
|
+
"The run itself may still be going on on the server.",
|
|
103
|
+
);
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* The triggers, handed by the socket listeners to the wait loop one at a time, so the loop reads
|
|
107
|
+
* as a sequence while the listeners stay callbacks.
|
|
108
|
+
*
|
|
109
|
+
* Only one trigger is kept for later while the loop is busy reading, the highest in
|
|
110
|
+
* `PENDING_PRIORITY`; `progress` only restarts the silence, which matters only while the loop
|
|
111
|
+
* waits. `unavailable` outranks everything, since it ends the wait; `end` outranks `reconnect`,
|
|
112
|
+
* since both lead to a read and the end's read is the one that keeps going.
|
|
113
|
+
*/
|
|
114
|
+
const createTriggerQueue = (signal: AbortSignal) => {
|
|
115
|
+
let pending: Trigger | null = null;
|
|
116
|
+
let wake: ((trigger: Trigger) => void) | null = null;
|
|
117
|
+
const outranks = (trigger: Trigger) =>
|
|
118
|
+
PENDING_PRIORITY.includes(trigger) &&
|
|
119
|
+
(!pending || PENDING_PRIORITY.indexOf(trigger) < PENDING_PRIORITY.indexOf(pending));
|
|
120
|
+
|
|
121
|
+
return {
|
|
122
|
+
push(trigger: Trigger) {
|
|
123
|
+
if (wake) return wake(trigger);
|
|
124
|
+
if (outranks(trigger)) pending = trigger;
|
|
125
|
+
},
|
|
126
|
+
/** The next trigger, or `silence` when none comes within `silenceMs`. */
|
|
127
|
+
next(silenceMs: number): Promise<Trigger> {
|
|
128
|
+
if (pending) {
|
|
129
|
+
const trigger = pending;
|
|
130
|
+
pending = null;
|
|
131
|
+
return Promise.resolve(trigger);
|
|
132
|
+
}
|
|
133
|
+
return abortable<Trigger>(signal, (resolve) => {
|
|
134
|
+
const silenceTimer = setTimeout(() => resolve("silence"), silenceMs);
|
|
135
|
+
wake = resolve;
|
|
136
|
+
return () => {
|
|
137
|
+
clearTimeout(silenceTimer);
|
|
138
|
+
wake = null;
|
|
139
|
+
};
|
|
140
|
+
});
|
|
141
|
+
},
|
|
142
|
+
};
|
|
143
|
+
};
|
|
144
|
+
|
|
145
|
+
/**
|
|
146
|
+
* Hands `onEvent` the events of one execution. Listening starts at once, and events are kept
|
|
147
|
+
* until `follow` names the execution: a quick run can end before `POST /run` answers. After that,
|
|
148
|
+
* only that execution's events pass — the channel carries every run of the account.
|
|
149
|
+
*/
|
|
150
|
+
const listenToRun = (
|
|
151
|
+
subscribeToEvents: RunWorkflowToEndParams["subscribeToEvents"],
|
|
152
|
+
onEvent: (event: WebSocketNotification) => void,
|
|
153
|
+
) => {
|
|
154
|
+
let workflowExecutionId: string | null = null;
|
|
155
|
+
const buffered: WebSocketNotification[] = [];
|
|
156
|
+
const isFollowed = (event: WebSocketNotification) =>
|
|
157
|
+
event.workflow_execution_id === workflowExecutionId;
|
|
158
|
+
|
|
159
|
+
const stop = subscribeToEvents((event) => {
|
|
160
|
+
if (!workflowExecutionId) buffered.push(event);
|
|
161
|
+
else if (isFollowed(event)) onEvent(event);
|
|
162
|
+
});
|
|
163
|
+
|
|
164
|
+
return {
|
|
165
|
+
follow(id: string) {
|
|
166
|
+
workflowExecutionId = id;
|
|
167
|
+
buffered.splice(0).filter(isFollowed).forEach(onEvent);
|
|
168
|
+
},
|
|
169
|
+
stop,
|
|
170
|
+
};
|
|
171
|
+
};
|
|
172
|
+
|
|
173
|
+
/**
|
|
174
|
+
* Follows the socket's status for the wait, starting from the one the subscription reports at
|
|
175
|
+
* once. It reports the socket coming back (`connected` after any other status) and going: an
|
|
176
|
+
* `error` that lasts `unavailableAfterMs` without a reconnect, counted from the first one, since
|
|
177
|
+
* `connecting` in between only means socket.io is retrying. `isConnected` is false from any other
|
|
178
|
+
* status until the next `connected`; the run is not started before then.
|
|
179
|
+
*/
|
|
180
|
+
const watchSocket = (
|
|
181
|
+
subscribeToStatus: RunWorkflowToEndParams["subscribeToStatus"],
|
|
182
|
+
{
|
|
183
|
+
unavailableAfterMs,
|
|
184
|
+
onReconnect,
|
|
185
|
+
onUnavailable,
|
|
186
|
+
}: { unavailableAfterMs: number; onReconnect: () => void; onUnavailable: () => void },
|
|
187
|
+
) => {
|
|
188
|
+
let connected = true;
|
|
189
|
+
let graceTimer: ReturnType<typeof setTimeout> | undefined;
|
|
190
|
+
const endGrace = () => {
|
|
191
|
+
clearTimeout(graceTimer);
|
|
192
|
+
graceTimer = undefined;
|
|
193
|
+
};
|
|
194
|
+
|
|
195
|
+
const stopListening = subscribeToStatus((status) => {
|
|
196
|
+
if (status === "error" && graceTimer === undefined)
|
|
197
|
+
graceTimer = setTimeout(onUnavailable, unavailableAfterMs);
|
|
198
|
+
if (status !== "connected") {
|
|
199
|
+
connected = false;
|
|
200
|
+
return;
|
|
201
|
+
}
|
|
202
|
+
endGrace();
|
|
203
|
+
if (!connected) {
|
|
204
|
+
connected = true;
|
|
205
|
+
onReconnect();
|
|
206
|
+
}
|
|
207
|
+
});
|
|
208
|
+
|
|
209
|
+
return {
|
|
210
|
+
isConnected: () => connected,
|
|
211
|
+
stop() {
|
|
212
|
+
endGrace();
|
|
213
|
+
stopListening();
|
|
214
|
+
},
|
|
215
|
+
};
|
|
216
|
+
};
|
|
217
|
+
|
|
218
|
+
/**
|
|
219
|
+
* runWorkflowToEnd
|
|
220
|
+
*
|
|
221
|
+
* Starts a workflow run and waits for it to end, listening to the websocket rather than polling;
|
|
222
|
+
* the end itself is read from the API. Resolves with the ended execution, whatever its
|
|
223
|
+
* `run_status` — deciding what counts as success is the caller's.
|
|
224
|
+
*
|
|
225
|
+
* The websocket says *when* to read, never *what* happened. The backend publishes a
|
|
226
|
+
* `WORKER_EXECUTION_*` event per worker and a `WORKFLOW_EXECUTION_COMPLETED|FAILED` one when the
|
|
227
|
+
* Ender finishes, all on the account's channel. That end event goes out before `run_status` is
|
|
228
|
+
* written, and its `COMPLETED` is the Ender's status, not the run's: so it triggers a read, and
|
|
229
|
+
* then more on a short, doubling delay (`confirmIntervalMs`, capped at `silenceMs`) until the run
|
|
230
|
+
* reads ended — no later event would trigger one.
|
|
231
|
+
*
|
|
232
|
+
* Delivery is at most once, with no replay, and the server cuts every socket about once an hour.
|
|
233
|
+
* So the execution is also read after `silenceMs` without any event of the run, and as soon as
|
|
234
|
+
* the socket reconnects. A read that fails in a way that may pass (no response, a 5XX, a 429) does
|
|
235
|
+
* not end the wait — the next trigger reads again — and the last such failure is the cause if the
|
|
236
|
+
* wait times out, until a read succeeds. Any other failure ends it at once: a 4XX, or anything
|
|
237
|
+
* that is not a request failure, such as a body that is not the expected JSON.
|
|
238
|
+
*
|
|
239
|
+
* The run's end cannot be followed without the socket, so a socket in `error` for
|
|
240
|
+
* `unavailableAfterMs` — its config failed, or the server dropped it — fails the wait. The run is
|
|
241
|
+
* held back until the socket is connected, so it is never started unfollowable, and nothing it
|
|
242
|
+
* publishes goes out before the wait is listening.
|
|
243
|
+
*
|
|
244
|
+
* A timeout or an abort stops everything at once through one signal: the wait, the pause between
|
|
245
|
+
* reads, and the read in flight, whose request is cancelled. The start request is abandoned
|
|
246
|
+
* rather than cancelled — `startRun` takes no signal — so the run may still begin on the server.
|
|
247
|
+
*
|
|
248
|
+
* @param params - The start and read calls, the websocket subscriptions and the wait options.
|
|
249
|
+
* @returns The execution, once its `run_status` is terminal.
|
|
250
|
+
* @throws {Error} If a wait option is not a positive number, the run cannot be started or has no
|
|
251
|
+
* execution id, a read fails for good, the socket stays unavailable for `unavailableAfterMs`, or
|
|
252
|
+
* the wait times out or is aborted (`WorkflowRunAbortedError`, with the signal's reason as the cause).
|
|
253
|
+
*/
|
|
254
|
+
export const runWorkflowToEnd = async ({
|
|
255
|
+
startRun,
|
|
256
|
+
getExecution,
|
|
257
|
+
subscribeToEvents,
|
|
258
|
+
subscribeToStatus,
|
|
259
|
+
silenceMs = 60_000,
|
|
260
|
+
timeoutMs = 5 * 60_000,
|
|
261
|
+
confirmIntervalMs = 1_000,
|
|
262
|
+
unavailableAfterMs = 30_000,
|
|
263
|
+
signal,
|
|
264
|
+
}: RunWorkflowToEndParams): Promise<WorkflowExecution> => {
|
|
265
|
+
requireTimerDelays({ silenceMs, timeoutMs, confirmIntervalMs, unavailableAfterMs });
|
|
266
|
+
|
|
267
|
+
let lastError: unknown;
|
|
268
|
+
const deadline = createDeadline({
|
|
269
|
+
timeoutMs,
|
|
270
|
+
signal,
|
|
271
|
+
timeoutError: () =>
|
|
272
|
+
new Error("Timed out while waiting for the workflow run to end", { cause: lastError }),
|
|
273
|
+
abortError: () => new WorkflowRunAbortedError(signal?.reason),
|
|
274
|
+
});
|
|
275
|
+
const waitSignal = deadline.signal;
|
|
276
|
+
|
|
277
|
+
const triggers = createTriggerQueue(waitSignal);
|
|
278
|
+
const runEvents = listenToRun(subscribeToEvents, (event) =>
|
|
279
|
+
triggers.push(isRunEndEvent(event) ? "end" : "progress"),
|
|
280
|
+
);
|
|
281
|
+
const connection = watchSocket(subscribeToStatus, {
|
|
282
|
+
unavailableAfterMs,
|
|
283
|
+
onReconnect: () => triggers.push("reconnect"),
|
|
284
|
+
onUnavailable: () => triggers.push("unavailable"),
|
|
285
|
+
});
|
|
286
|
+
|
|
287
|
+
/** Reads the execution once; `null` while the run has not ended. */
|
|
288
|
+
const readIfEnded = async (id: string) => {
|
|
289
|
+
try {
|
|
290
|
+
const execution = await unlessAborted(getExecution(id, waitSignal), waitSignal);
|
|
291
|
+
lastError = undefined;
|
|
292
|
+
return isTerminalRunStatus(execution.run_status) ? execution : null;
|
|
293
|
+
} catch (error) {
|
|
294
|
+
if (waitSignal.aborted) throw waitSignal.reason;
|
|
295
|
+
if (!isRetryableFailure(error)) throw error;
|
|
296
|
+
lastError = error;
|
|
297
|
+
return null;
|
|
298
|
+
}
|
|
299
|
+
};
|
|
300
|
+
|
|
301
|
+
try {
|
|
302
|
+
if (waitSignal.aborted) throw waitSignal.reason;
|
|
303
|
+
while (!connection.isConnected()) {
|
|
304
|
+
if ((await triggers.next(silenceMs)) === "unavailable") throw socketUnavailableError();
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
const id = (await unlessAborted(startRun(), waitSignal))?.id;
|
|
308
|
+
if (!id) throw new Error("Workflow run did not return an execution id");
|
|
309
|
+
runEvents.follow(id);
|
|
310
|
+
|
|
311
|
+
let confirmDelay: number | undefined;
|
|
312
|
+
for (;;) {
|
|
313
|
+
const trigger = await triggers.next(confirmDelay ?? silenceMs);
|
|
314
|
+
if (trigger === "unavailable") throw socketUnavailableError();
|
|
315
|
+
if (trigger === "progress") continue;
|
|
316
|
+
|
|
317
|
+
if (trigger === "end") confirmDelay = confirmIntervalMs;
|
|
318
|
+
else if (trigger === "silence" && confirmDelay !== undefined)
|
|
319
|
+
confirmDelay = Math.min(confirmDelay * 2, silenceMs);
|
|
320
|
+
|
|
321
|
+
const ended = await readIfEnded(id);
|
|
322
|
+
if (ended) return ended;
|
|
323
|
+
}
|
|
324
|
+
} finally {
|
|
325
|
+
deadline.dispose();
|
|
326
|
+
runEvents.stop();
|
|
327
|
+
connection.stop();
|
|
328
|
+
}
|
|
329
|
+
};
|
package/src/socket/index.ts
CHANGED
|
@@ -11,9 +11,7 @@
|
|
|
11
11
|
export * from "@/contexts/webSocketContext";
|
|
12
12
|
export * from "@/contexts/webSocketContext/provider";
|
|
13
13
|
export * from "@/contexts/webSocketContext/types";
|
|
14
|
-
export
|
|
15
|
-
export * from "@/contexts/webSocketContext/handler";
|
|
14
|
+
export { APP_NOTIFICATION_EVENT_TYPE } from "@/contexts/webSocketContext/constants";
|
|
16
15
|
export * from "@/contexts/webSocketContext/hooks/useWebSocket";
|
|
17
16
|
export * from "@/contexts/webSocketContext/hooks/useWebSocketSubscription";
|
|
18
17
|
export * from "@/contexts/webSocketContext/hooks/useAppNotificationSubscription";
|
|
19
|
-
export * from "@/api/websocketsConfig";
|
package/src/test/mocks/index.ts
CHANGED
|
@@ -8,11 +8,7 @@
|
|
|
8
8
|
// break every suite in an app that never installed them.
|
|
9
9
|
|
|
10
10
|
export { agGridReactMock } from "./agGridReact";
|
|
11
|
-
export {
|
|
12
|
-
agGridEnterpriseMock,
|
|
13
|
-
getAgGridLicenseKey,
|
|
14
|
-
resetAgGridLicense,
|
|
15
|
-
} from "./agGridEnterprise";
|
|
11
|
+
export { agGridEnterpriseMock, getAgGridLicenseKey, resetAgGridLicense } from "./agGridEnterprise";
|
|
16
12
|
export {
|
|
17
13
|
socketIoClientMock,
|
|
18
14
|
createMockSocket,
|
|
@@ -9,7 +9,7 @@ import {
|
|
|
9
9
|
import userEvent from "@testing-library/user-event";
|
|
10
10
|
import { QueryClient } from "@tanstack/react-query";
|
|
11
11
|
|
|
12
|
-
import { EveryskApp, type
|
|
12
|
+
import { EveryskApp, type ProviderEntry } from "@/EveryskApp";
|
|
13
13
|
import type { AnyRecord } from "@/types/anyRecord";
|
|
14
14
|
|
|
15
15
|
/**
|
|
@@ -39,14 +39,19 @@ export function createTestQueryClient(): QueryClient {
|
|
|
39
39
|
type ProviderOptions = {
|
|
40
40
|
queryClient?: QueryClient;
|
|
41
41
|
/** Extra providers, mounted inside the core tree and around the subject. */
|
|
42
|
-
providers?:
|
|
42
|
+
providers?: ProviderEntry[];
|
|
43
43
|
/** Injected instead of `window.APP_ID`, so a test needs no page globals. */
|
|
44
44
|
appId?: string | null;
|
|
45
45
|
/** Injected instead of `window.APP_CONFIG`. */
|
|
46
46
|
appEnvironmentVar?: AnyRecord;
|
|
47
47
|
};
|
|
48
48
|
|
|
49
|
-
const buildWrapper = ({
|
|
49
|
+
const buildWrapper = ({
|
|
50
|
+
queryClient,
|
|
51
|
+
providers,
|
|
52
|
+
appId,
|
|
53
|
+
appEnvironmentVar,
|
|
54
|
+
}: ProviderOptions & {
|
|
50
55
|
queryClient: QueryClient;
|
|
51
56
|
}) =>
|
|
52
57
|
function Wrapper({ children }: { children?: React.ReactNode }) {
|
package/src/test/setup.ts
CHANGED
|
@@ -5,31 +5,31 @@ import "@testing-library/jest-dom/vitest";
|
|
|
5
5
|
|
|
6
6
|
// Unmount React trees and clear the jsdom document between tests so they stay isolated.
|
|
7
7
|
afterEach(() => {
|
|
8
|
-
|
|
8
|
+
cleanup();
|
|
9
9
|
});
|
|
10
10
|
|
|
11
11
|
// jsdom does not implement matchMedia; MUI's `useMediaQuery` needs it. The theme no longer
|
|
12
12
|
// reads it — it is pinned to the brand dark theme — but responsive components still do.
|
|
13
13
|
if (!window.matchMedia) {
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
14
|
+
window.matchMedia = vi.fn().mockImplementation((query: string) => ({
|
|
15
|
+
matches: false,
|
|
16
|
+
media: query,
|
|
17
|
+
onchange: null,
|
|
18
|
+
addListener: vi.fn(),
|
|
19
|
+
removeListener: vi.fn(),
|
|
20
|
+
addEventListener: vi.fn(),
|
|
21
|
+
removeEventListener: vi.fn(),
|
|
22
|
+
dispatchEvent: vi.fn(),
|
|
23
|
+
}));
|
|
24
24
|
}
|
|
25
25
|
|
|
26
26
|
// jsdom does not implement ResizeObserver; several MUI components observe their container.
|
|
27
27
|
if (!globalThis.ResizeObserver) {
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
28
|
+
globalThis.ResizeObserver = class {
|
|
29
|
+
observe(): void {}
|
|
30
|
+
unobserve(): void {}
|
|
31
|
+
disconnect(): void {}
|
|
32
|
+
};
|
|
33
33
|
}
|
|
34
34
|
|
|
35
35
|
// The template stubbed `BroadcastChannel` here, which jsdom does not implement. Nothing in
|
package/src/theme/index.ts
CHANGED
|
@@ -12,4 +12,4 @@ export { EveryskDarkTheme } from "./themes/EveryskDark";
|
|
|
12
12
|
export { DefaultLightTheme } from "./themes/DefaultLight";
|
|
13
13
|
export { DefaultDarkTheme } from "./themes/DefaultDark";
|
|
14
14
|
export { MidnightEmberTheme } from "./themes/MidnightEmber";
|
|
15
|
-
export {
|
|
15
|
+
export { componentOverrides } from "./overrides";
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { Components, Theme } from "@mui/material/styles";
|
|
2
2
|
|
|
3
|
-
import type {
|
|
3
|
+
import type {} from "@mui/x-date-pickers/themeAugmentation";
|
|
4
4
|
|
|
5
5
|
import { MuiCssBaseline } from "./muiCssBaseline";
|
|
6
6
|
import { MuiDatePicker } from "./muiDatePicker";
|
|
@@ -15,9 +15,11 @@ import { MuiButton } from "./muiButton";
|
|
|
15
15
|
|
|
16
16
|
/**
|
|
17
17
|
* Shared MUI component overrides applied by every theme (light, dark and branded).
|
|
18
|
-
* They read `theme.palette.mode`, so the same set works for any palette.
|
|
18
|
+
* They read `theme.palette.mode`, so the same set works for any palette. Public as
|
|
19
|
+
* `componentOverrides` for an app that builds its own theme; `components` alone, at the root of
|
|
20
|
+
* the package, did not say whose components.
|
|
19
21
|
*/
|
|
20
|
-
export const
|
|
22
|
+
export const componentOverrides: Components<Omit<Theme, "components">> = {
|
|
21
23
|
MuiCssBaseline,
|
|
22
24
|
MuiDatePicker,
|
|
23
25
|
MuiTextField,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import type { Components, Theme } from
|
|
1
|
+
import type { Components, Theme } from "@mui/material/styles";
|
|
2
2
|
|
|
3
|
-
export const MuiButton: Components<Theme>[
|
|
3
|
+
export const MuiButton: Components<Theme>["MuiButton"] = {
|
|
4
4
|
defaultProps: {
|
|
5
|
-
size:
|
|
5
|
+
size: "small",
|
|
6
6
|
},
|
|
7
7
|
};
|
|
@@ -9,27 +9,26 @@ export const MuiCssBaseline = {
|
|
|
9
9
|
},
|
|
10
10
|
"*::-webkit-scrollbar-thumb": {
|
|
11
11
|
borderRadius: 10,
|
|
12
|
-
backgroundColor:
|
|
13
|
-
|
|
12
|
+
backgroundColor: "#959595",
|
|
14
13
|
},
|
|
15
14
|
"*::-webkit-scrollbar-thumb:hover ": {
|
|
16
|
-
backgroundColor:
|
|
15
|
+
backgroundColor: "#959595",
|
|
17
16
|
},
|
|
18
17
|
"*:hover::-webkit-scrollbar-thumb": {
|
|
19
|
-
backgroundColor:
|
|
18
|
+
backgroundColor: "#959595",
|
|
20
19
|
},
|
|
21
20
|
|
|
22
21
|
"*::-webkit-scrollbar-thumb:active": {
|
|
23
|
-
backgroundColor: theme.palette.primary.main
|
|
22
|
+
backgroundColor: theme.palette.primary.main,
|
|
24
23
|
},
|
|
25
24
|
|
|
26
25
|
"*::-moz-selection": {
|
|
27
|
-
color:
|
|
28
|
-
backgroundColor: theme.palette.primary.main
|
|
26
|
+
color: theme.palette.mode === "dark" ? colors.common.black : colors.common.white,
|
|
27
|
+
backgroundColor: theme.palette.primary.main,
|
|
29
28
|
},
|
|
30
29
|
"*::selection": {
|
|
31
|
-
color:
|
|
32
|
-
backgroundColor: theme.palette.primary.main
|
|
33
|
-
}
|
|
34
|
-
})
|
|
35
|
-
}
|
|
30
|
+
color: theme.palette.mode === "dark" ? colors.common.black : colors.common.white,
|
|
31
|
+
backgroundColor: theme.palette.primary.main,
|
|
32
|
+
},
|
|
33
|
+
}),
|
|
34
|
+
};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import type { Components, Theme } from
|
|
1
|
+
import type { Components, Theme } from "@mui/material/styles";
|
|
2
2
|
|
|
3
|
-
export const MuiIconButton: Components<Theme>[
|
|
3
|
+
export const MuiIconButton: Components<Theme>["MuiIconButton"] = {
|
|
4
4
|
defaultProps: {
|
|
5
|
-
size:
|
|
5
|
+
size: "small",
|
|
6
6
|
},
|
|
7
7
|
};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import type { Components, Theme } from
|
|
1
|
+
import type { Components, Theme } from "@mui/material/styles";
|
|
2
2
|
|
|
3
|
-
export const MuiToggleButton: Components<Theme>[
|
|
3
|
+
export const MuiToggleButton: Components<Theme>["MuiToggleButton"] = {
|
|
4
4
|
defaultProps: {
|
|
5
|
-
size:
|
|
5
|
+
size: "small",
|
|
6
6
|
},
|
|
7
|
-
};
|
|
7
|
+
};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import type { Components, Theme } from
|
|
1
|
+
import type { Components, Theme } from "@mui/material/styles";
|
|
2
2
|
|
|
3
|
-
export const MuiToggleButtonGroup: Components<Theme>[
|
|
3
|
+
export const MuiToggleButtonGroup: Components<Theme>["MuiToggleButtonGroup"] = {
|
|
4
4
|
defaultProps: {
|
|
5
|
-
size:
|
|
5
|
+
size: "small",
|
|
6
6
|
},
|
|
7
|
-
};
|
|
7
|
+
};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { createTheme, type Theme } from "@mui/material/styles";
|
|
2
2
|
|
|
3
|
-
import {
|
|
3
|
+
import { componentOverrides } from "@/theme/overrides";
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* Neutral dark theme. Uses MUI's default palette (no brand color) plus the
|
|
@@ -10,5 +10,5 @@ export const DefaultDarkTheme: Theme = createTheme({
|
|
|
10
10
|
palette: {
|
|
11
11
|
mode: "dark",
|
|
12
12
|
},
|
|
13
|
-
components,
|
|
13
|
+
components: componentOverrides,
|
|
14
14
|
});
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { createTheme, type Theme } from "@mui/material/styles";
|
|
2
2
|
|
|
3
|
-
import {
|
|
3
|
+
import { componentOverrides } from "@/theme/overrides";
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* Neutral light theme. Uses MUI's default palette (no brand color) plus the
|
|
@@ -10,5 +10,5 @@ export const DefaultLightTheme: Theme = createTheme({
|
|
|
10
10
|
palette: {
|
|
11
11
|
mode: "light",
|
|
12
12
|
},
|
|
13
|
-
components,
|
|
13
|
+
components: componentOverrides,
|
|
14
14
|
});
|