Skip to content

Commit

Permalink
WIP002
Browse files Browse the repository at this point in the history
  • Loading branch information
dakotablair committed Sep 11, 2023
1 parent e94ed78 commit e34aedd
Show file tree
Hide file tree
Showing 10 changed files with 85 additions and 112 deletions.
7 changes: 5 additions & 2 deletions src/common/api/narrativeService.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
/* narrativeService */
import { dynamicService } from './serviceWizardApi';
import { baseApi } from './index';
import { jsonRpcService } from './utils/serviceHelpers';
// import { jsonRpcService } from './utils/serviceHelpers';

const narrativeService = jsonRpcService({
// console.log({ serviceWizardApi }); // eslint-disable-line no-console

const narrativeService = dynamicService({
name: 'NarrativeService',
release: 'release',
});
Expand Down
10 changes: 5 additions & 5 deletions src/common/api/serviceWizardApi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@ import { jsonRpcService } from './utils/serviceHelpers';

const serviceWizard = jsonRpcService({ url: 'services/service_wizard' });

const dynamicService = jsonRpcService;

export { dynamicService };

export interface ServiceStatus {
git_commit_hash: string;
status: string;
Expand Down Expand Up @@ -41,10 +45,6 @@ export const serviceWizardApi = baseApi.injectEndpoints({
}),
});

const setConsumed = () =>
setConsumedService('serviceWizardApi', serviceWizardApi);

setConsumed();
setConsumedService('serviceWizardApi', serviceWizardApi);

export { setConsumed };
export const { getServiceStatus } = serviceWizardApi.endpoints;
67 changes: 67 additions & 0 deletions src/common/api/utils/common.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
/* api/utils/common */
import { FetchBaseQueryError } from '@reduxjs/toolkit/query/react';
/*
JSONRPC Specification details
JSON-RPC 1.0 - https://www.jsonrpc.org/specification_v1
JSON-RPC 1.1 wd - https://jsonrpc.org/historical/json-rpc-1-1-wd.html
JSON-RPC 2.0 - https://www.jsonrpc.org/specification
- id
- 2.0 allows id to be string, number (with no fractional part) or null
- 1.1 allows id to be "any JSON type"
- version
- a string in both JSONRPC 1.1 and 2.0.
*/
// KBase mostly uses strings, or string serializable values, so we can too.
type JsonRpcError = {
version: '1.1';
id: string;
error: {
name: string;
code: number;
message: string;
};
};

export type KBaseBaseQueryError =
| FetchBaseQueryError
| {
status: 'JSONRPC_ERROR';
data: JsonRpcError;
};

export const isJsonRpcError = (obj: unknown): obj is JsonRpcError => {
if (
typeof obj === 'object' &&
obj !== null &&
['version', 'error', 'id'].every((k) => k in obj)
) {
const { version, error } = obj as { version: string; error: unknown };
const versionsSupported = new Set(['1.1', '2.0']);
if (!versionsSupported.has(version)) return false;
if (
typeof error === 'object' &&
error !== null &&
['name', 'code', 'message'].every((k) => k in error)
) {
return true;
}
}
return false;
};

/**
* Type predicate to narrow an unknown error to `FetchBaseQueryError`
*/
export function isFetchBaseQueryError(
error: unknown
): error is FetchBaseQueryError {
return typeof error === 'object' && error !== null && 'status' in error;
}

export const isKBaseBaseQueryError = (
error: unknown
): error is KBaseBaseQueryError => {
const fbq = isFetchBaseQueryError(error);
const condition = fbq && isJsonRpcError(error.data);
return condition;
};
68 changes: 1 addition & 67 deletions src/common/api/utils/kbaseBaseQuery.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@ import {
BaseQueryFn,
FetchArgs,
fetchBaseQuery,
FetchBaseQueryError,
} from '@reduxjs/toolkit/query/react';
import { RootState } from '../../../app/store';
import { serviceWizardApi } from '../serviceWizardApi';
import { KBaseBaseQueryError, isJsonRpcError } from './common';

export interface DynamicService {
name: string;
Expand Down Expand Up @@ -39,72 +39,6 @@ export const isDynamic = (
return (service as StaticService).url === undefined;
};

/*
JSONRPC Specification details
JSON-RPC 1.0 - https://www.jsonrpc.org/specification_v1
JSON-RPC 1.1 wd - https://jsonrpc.org/historical/json-rpc-1-1-wd.html
JSON-RPC 2.0 - https://www.jsonrpc.org/specification
- id
- 2.0 allows id to be string, number (with no fractional part) or null
- 1.1 allows id to be "any JSON type"
- version
- a string in both JSONRPC 1.1 and 2.0.
*/
// KBase mostly uses strings, or string serializable values, so we can too.
type JsonRpcError = {
version: '1.1';
id: string;
error: {
name: string;
code: number;
message: string;
};
};

export const isJsonRpcError = (obj: unknown): obj is JsonRpcError => {
if (
typeof obj === 'object' &&
obj !== null &&
['version', 'error', 'id'].every((k) => k in obj)
) {
const { version, error } = obj as { version: string; error: unknown };
const versionsSupported = new Set(['1.1', '2.0']);
if (!versionsSupported.has(version)) return false;
if (
typeof error === 'object' &&
error !== null &&
['name', 'code', 'message'].every((k) => k in error)
) {
return true;
}
}
return false;
};

export type KBaseBaseQueryError =
| FetchBaseQueryError
| {
status: 'JSONRPC_ERROR';
data: JsonRpcError;
};

/**
* Type predicate to narrow an unknown error to `FetchBaseQueryError`
*/
export function isFetchBaseQueryError(
error: unknown
): error is FetchBaseQueryError {
return typeof error === 'object' && error !== null && 'status' in error;
}

export const isKBaseBaseQueryError = (
error: unknown
): error is KBaseBaseQueryError => {
const fbq = isFetchBaseQueryError(error);
const condition = fbq && isJsonRpcError(error.data);
return condition;
};

// These helpers let us avoid circular dependencies when using an API endpoint within kbaseBaseQuery
const consumedServices: { serviceWizardApi?: typeof serviceWizardApi } = {};
export const setConsumedService = <T extends keyof typeof consumedServices>(
Expand Down
2 changes: 1 addition & 1 deletion src/common/api/utils/parseError.test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { SerializedError } from '@reduxjs/toolkit';
import { FetchBaseQueryError } from '@reduxjs/toolkit/dist/query';
import { KBaseBaseQueryError } from './kbaseBaseQuery';
import { KBaseBaseQueryError } from './common';
import { parseError } from './parseError';

describe('parseError', () => {
Expand Down
2 changes: 1 addition & 1 deletion src/common/api/utils/parseError.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { SerializedError } from '@reduxjs/toolkit';
import { KBaseBaseQueryError } from './kbaseBaseQuery';
import { KBaseBaseQueryError } from './common';

export function parseError(error: KBaseBaseQueryError | SerializedError): {
error: KBaseBaseQueryError | SerializedError;
Expand Down
2 changes: 2 additions & 0 deletions src/features/navigator/NarrativeControl/Copy.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {
import { Input } from '../../../common/components/Input';
import { useAppDispatch } from '../../../common/hooks';
import { TODOAddLoadingState } from '../common';
import { useNarrativeServiceStatus } from '../hooks';
import { copyNarrative } from '../navigatorSlice';
import { ControlProps } from './common';

Expand All @@ -22,6 +23,7 @@ export interface CopyProps extends ControlProps {

export const Copy: FC<CopyProps> = ({ narrativeDoc, modalClose, version }) => {
const dispatch = useAppDispatch();
useNarrativeServiceStatus();
const { formState, getValues, register } = useForm<CopyValues>({
defaultValues: {
narrativeCopyName: `${narrativeDoc.narrative_title} - Copy`,
Expand Down
2 changes: 1 addition & 1 deletion src/features/navigator/NarrativeControl/Delete.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { useNavigate } from 'react-router-dom';
import toast from 'react-hot-toast';
import { Button } from '../../../common/components';
import { useAppDispatch, useAppSelector } from '../../../common/hooks';
import { isKBaseBaseQueryError } from '../../../common/api/utils/kbaseBaseQuery';
import { isKBaseBaseQueryError } from '../../../common/api/utils/common';
import { parseError } from '../../../common/api/utils/parseError';
import { deleteWorkspace } from '../../../common/api/workspaceApi';
import {
Expand Down
3 changes: 1 addition & 2 deletions src/features/navigator/Navigator.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ import {
normalizeVersion,
searchParams,
} from './common';
import { useNarratives, useServices } from './hooks';
import { useNarratives } from './hooks';
import {
loading,
navigatorSelected,
Expand Down Expand Up @@ -210,7 +210,6 @@ const Navigator: FC = () => {
term: search,
username,
});
useServices();
const items = useAppSelector(narrativeDocs);
const narrativeSelected = getNarrativeSelected({ id, obj, verRaw, items });
// hooks that update state
Expand Down
34 changes: 1 addition & 33 deletions src/features/navigator/hooks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,6 @@ import { useEffect, useMemo } from 'react';
import { useAppDispatch, useAppSelector } from '../../common/hooks';
import { getUsers } from '../../common/api/authService';
import { getNarratives, SearchParams } from '../../common/api/searchApi';
import { setConsumed } from '../../common/api/serviceWizardApi';
// import { setConsumedService } from '../../common/api/utils/kbaseBaseQuery';
/*
import {
ServiceStatus,
ServiceWizardParams,
} from '../../common/api/serviceWizardApi';
*/
import { getStatus } from '../../common/api/narrativeService';
import { getwsNarrative } from '../../common/api/workspaceApi';
import { Cell } from '../../common/types/NarrativeDoc';
Expand Down Expand Up @@ -150,31 +142,7 @@ export const useNarratives = (params: getNarrativesParams) => {
}, [dispatch, narrativesPrevious, searchAPIQuery, searchAPIParams, syncd]);
};

export const useServices = () => {
/*
const dispatch = useAppDispatch();
// const serviceState = useAppSelector(services);
const servicesRequired: ServiceWizardParams['getServiceStatus'][] = useMemo(
() => [
{
module_name: 'NarrativeService',
version: 'release',
},
],
[]
);
const servicesQuerys = servicesRequired.map((serviceVersion) =>
getServiceStatus.useQuery(serviceVersion)
);
const servicesAvailable: Record<string, ServiceStatus> = {};
servicesRequired.forEach((serviceVersion, ix) => {
const currQuery = servicesQuerys[ix];
servicesAvailable[serviceVersion.module_name] = data;
//dispatch(setServices(servicesAvailable));
});
setConsumedService('serviceWizardApi', serviceWizardApi);
*/
setConsumed();
export const useNarrativeServiceStatus = () => {
const nsQuery = getStatus.useQuery();
useEffect(() => {
if (nsQuery.isSuccess && nsQuery.data) {
Expand Down

0 comments on commit e34aedd

Please sign in to comment.