vega-frontend-monorepo/libs/environment/src/hooks/use-config.tsx
botond afeb772702
Feat/718 integrate node validation (#741)
* feat: add node swicther

* chore: remove hook form from node switcher

* feat: generate apollo types and add tests

* fix: format

* fix: types

* fix: remove redundant wrapper

* fix: layout styles

* fix: add controlled value to radio group

* fix: flaky node hook test

* feat: add custom input for node and more tests

* feat: wip refactor config hook to run on init

* fix: dont open node switcher on init

* fix: lint

* fix: lint

* fix: cache key error

* fix: format

* fix: lint

* feat: validate connected node on init WIP

* chore: refactor useconfig and usenodes

* fix: revert custom node branch changes

* feat: fix config loading errors and custom node handling

* feat: add test for nodes init

* fix: env error states

* fix: add more tests

* fix: format

* fix: lint and format

* fix: mock type in test

* fix: clean up queries

* fix: node block heights

* fix: make git variables optional

* fix: dialog width on lg screens

* feat: improve mobile looks

* fix: format

* fix: remove commented out styles

* fix: use node data url instead of key

* fix: clean up node switcher dialog props

* fix: add missing title and subtitle for dialog

* fix: show confiug load errors
2022-07-15 12:00:57 +01:00

99 lines
2.8 KiB
TypeScript

import { useState, useEffect } from 'react';
import { LocalStorage } from '@vegaprotocol/react-helpers';
import { ErrorType } from '../types';
import type { Environment, Configuration, Networks } from '../types';
import { validateConfiguration } from '../utils/validate-configuration';
export const LOCAL_STORAGE_NETWORK_KEY = 'vegaNetworkConfig';
export type EnvironmentWithOptionalUrl = Partial<Environment> &
Omit<Environment, 'VEGA_URL'>;
const compileHosts = (hosts: string[], envUrl?: string) => {
if (envUrl && !hosts.includes(envUrl)) {
return [...hosts, envUrl];
}
return hosts;
};
const getCacheKey = (env: Networks) => `${LOCAL_STORAGE_NETWORK_KEY}-${env}`;
const getCachedConfig = (env: Networks) => {
const cacheKey = getCacheKey(env);
const value = LocalStorage.getItem(cacheKey);
if (value) {
try {
const config = JSON.parse(value) as Configuration;
const hasError = validateConfiguration(config);
if (hasError) {
throw new Error('Invalid configuration found in the storage.');
}
return config;
} catch (err) {
LocalStorage.removeItem(cacheKey);
console.warn(
'Malformed data found for network configuration. Removed cached configuration, continuing...'
);
}
}
return undefined;
};
export const useConfig = (
environment: EnvironmentWithOptionalUrl,
onError: (errorType: ErrorType) => void
) => {
const [loading, setLoading] = useState(false);
const [config, setConfig] = useState<Configuration | undefined>(
getCachedConfig(environment.VEGA_ENV)
);
useEffect(() => {
let isMounted = true;
(async () => {
if (!config && environment.VEGA_CONFIG_URL) {
isMounted && setLoading(true);
try {
const response = await fetch(environment.VEGA_CONFIG_URL);
const configData: Configuration = await response.json();
if (validateConfiguration(configData)) {
onError(ErrorType.CONFIG_VALIDATION_ERROR);
isMounted && setLoading(false);
return;
}
const hosts = compileHosts(configData.hosts, environment.VEGA_URL);
isMounted && setConfig({ hosts });
LocalStorage.setItem(
getCacheKey(environment.VEGA_ENV),
JSON.stringify({ hosts })
);
isMounted && setLoading(false);
} catch (err) {
if (isMounted) {
setLoading(false);
setConfig({ hosts: [] });
}
onError(ErrorType.CONFIG_LOAD_ERROR);
}
}
})();
return () => {
isMounted = false;
};
// load config only once per runtime
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [environment.VEGA_CONFIG_URL, !!config, onError, setLoading]);
return {
loading,
config,
};
};