Resolve hook problems.
Fixed logging.
This commit is contained in:
parent
bc177cc1a1
commit
38efa6a030
@ -9,6 +9,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|
||||||
|
- [x] Fixed hook that causes 100x rerendering.
|
||||||
|
- [x] Logging.
|
||||||
|
- [x] Error handling.
|
||||||
- [x] Table sorting.
|
- [x] Table sorting.
|
||||||
- [x] Version check.
|
- [x] Version check.
|
||||||
- [x] Fix JsonTree (yarn link).
|
- [x] Fix JsonTree (yarn link).
|
||||||
@ -23,9 +26,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||||||
- [x] Monorepo for client/server.
|
- [x] Monorepo for client/server.
|
||||||
- [x] Basic React/Apollo component.
|
- [x] Basic React/Apollo component.
|
||||||
|
|
||||||
## Tasks
|
### Next
|
||||||
|
|
||||||
### POC
|
|
||||||
|
|
||||||
- [ ] Webpack and dynamic config
|
- [ ] Webpack and dynamic config
|
||||||
- [ ] Complete WNS functionality
|
- [ ] Complete WNS functionality
|
||||||
@ -38,8 +39,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||||||
- [ ] Signal
|
- [ ] Signal
|
||||||
- [ ] Metadata
|
- [ ] Metadata
|
||||||
|
|
||||||
### Next
|
|
||||||
|
|
||||||
- [ ] https://github.com/standard/standardx (JSX)
|
- [ ] https://github.com/standard/standardx (JSX)
|
||||||
- [ ] Client/server API abstraction (error handler, etc.)
|
- [ ] Client/server API abstraction (error handler, etc.)
|
||||||
- [ ] Port dashboard API calls (resolve config first).
|
- [ ] Port dashboard API calls (resolve config first).
|
||||||
|
@ -30,8 +30,9 @@
|
|||||||
"@apollo/react-components": "^3.1.5",
|
"@apollo/react-components": "^3.1.5",
|
||||||
"@apollo/react-hooks": "^3.1.5",
|
"@apollo/react-hooks": "^3.1.5",
|
||||||
"@babel/runtime": "^7.8.7",
|
"@babel/runtime": "^7.8.7",
|
||||||
|
"@dxos/debug": "^1.0.0-beta.20",
|
||||||
"@dxos/gem-core": "^1.0.0-beta.11",
|
"@dxos/gem-core": "^1.0.0-beta.11",
|
||||||
"@dxos/react-ux": "^1.0.0-beta.20",
|
"@dxos/react-ux": "^1.0.0-beta.37",
|
||||||
"@material-ui/core": "^4.10.0",
|
"@material-ui/core": "^4.10.0",
|
||||||
"@material-ui/icons": "^4.9.1",
|
"@material-ui/icons": "^4.9.1",
|
||||||
"@material-ui/lab": "^4.0.0-alpha.54",
|
"@material-ui/lab": "^4.0.0-alpha.54",
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
// Copyright 2020 DxOS.org
|
// Copyright 2020 DxOS.org
|
||||||
//
|
//
|
||||||
|
|
||||||
import React from 'react';
|
import React, { useEffect, useState } from 'react';
|
||||||
import { makeStyles } from '@material-ui/core/styles';
|
import { makeStyles } from '@material-ui/core/styles';
|
||||||
import Alert from '@material-ui/lab/Alert';
|
import Alert from '@material-ui/lab/Alert';
|
||||||
import AlertTitle from '@material-ui/lab/AlertTitle';
|
import AlertTitle from '@material-ui/lab/AlertTitle';
|
||||||
@ -10,30 +10,37 @@ import Snackbar from '@material-ui/core/Snackbar';
|
|||||||
|
|
||||||
const useStyles = makeStyles(() => ({
|
const useStyles = makeStyles(() => ({
|
||||||
root: {
|
root: {
|
||||||
marginBottom: 60
|
marginBottom: 48
|
||||||
|
},
|
||||||
|
|
||||||
|
alert: {
|
||||||
|
minWidth: 400
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
|
|
||||||
const Error = ({ message, ...rest }) => {
|
const Error = ({ error, ...rest }) => {
|
||||||
const classes = useStyles();
|
const classes = useStyles();
|
||||||
if (!message) {
|
const [message, setMessage] = useState(error);
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
const messages = Array.isArray(message) ? message : [message];
|
useEffect(() => {
|
||||||
|
setMessage(error ? error.message || String(error) : null);
|
||||||
|
}, [error]);
|
||||||
|
|
||||||
|
const handleClose = () => {
|
||||||
|
setMessage(null);
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Snackbar
|
<Snackbar
|
||||||
className={classes.root}
|
classes={{ root: classes.root }}
|
||||||
open={Boolean(message)}
|
open={Boolean(message)}
|
||||||
anchorOrigin={{ vertical: 'bottom', horizontal: 'center' }}
|
anchorOrigin={{ vertical: 'bottom', horizontal: 'center' }}
|
||||||
TransitionProps={{ exit: false }}
|
TransitionProps={{ exit: false }}
|
||||||
|
autoHideDuration={1000}
|
||||||
>
|
>
|
||||||
<Alert severity="error" {...rest}>
|
<Alert classes={{ root: classes.alert }} severity="error" {...rest} onClose={handleClose}>
|
||||||
<AlertTitle>Error</AlertTitle>
|
<AlertTitle>Error</AlertTitle>
|
||||||
{messages.map((message, i) => (
|
<div>{message}</div>
|
||||||
<div key={i}>{message}</div>
|
|
||||||
))}
|
|
||||||
</Alert>
|
</Alert>
|
||||||
</Snackbar>
|
</Snackbar>
|
||||||
);
|
);
|
||||||
|
@ -4,31 +4,28 @@
|
|||||||
|
|
||||||
import clsx from 'clsx';
|
import clsx from 'clsx';
|
||||||
import moment from 'moment';
|
import moment from 'moment';
|
||||||
import React, { Fragment } from 'react';
|
import React from 'react';
|
||||||
import { makeStyles } from '@material-ui/core/styles';
|
import { makeStyles } from '@material-ui/core/styles';
|
||||||
|
|
||||||
const useStyles = makeStyles(theme => ({
|
const useStyles = makeStyles(theme => ({
|
||||||
root: {
|
root: {
|
||||||
display: 'flex',
|
display: 'flex',
|
||||||
flex: 1,
|
flex: 1,
|
||||||
flexDirection: 'column',
|
|
||||||
overflow: 'hidden'
|
overflow: 'hidden'
|
||||||
},
|
},
|
||||||
|
|
||||||
container: {
|
log: {
|
||||||
display: 'flex',
|
display: 'flex',
|
||||||
// Pin to bottom (render in time order).
|
// Pin to bottom (render in time order).
|
||||||
flexDirection: 'column-reverse',
|
flexDirection: 'column-reverse',
|
||||||
flex: 1,
|
overflow: 'scroll',
|
||||||
overflowX: 'scroll',
|
|
||||||
overflowY: 'scroll'
|
|
||||||
},
|
|
||||||
|
|
||||||
log: {
|
|
||||||
padding: theme.spacing(1),
|
padding: theme.spacing(1),
|
||||||
fontSize: 16,
|
|
||||||
fontFamily: 'monospace',
|
'& div': {
|
||||||
whiteSpace: 'nowrap'
|
fontSize: 16,
|
||||||
|
fontFamily: 'monospace',
|
||||||
|
whiteSpace: 'nowrap'
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
level: {
|
level: {
|
||||||
@ -50,7 +47,7 @@ const useStyles = makeStyles(theme => ({
|
|||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
|
|
||||||
const Log = ({ log = [], onClear }) => {
|
const Log = ({ log = [] }) => {
|
||||||
const classes = useStyles();
|
const classes = useStyles();
|
||||||
|
|
||||||
const levels = {
|
const levels = {
|
||||||
@ -91,11 +88,11 @@ const Log = ({ log = [], onClear }) => {
|
|||||||
const pkg = levels[level] ? '' : `[${level}]: `;
|
const pkg = levels[level] ? '' : `[${level}]: `;
|
||||||
|
|
||||||
message = (
|
message = (
|
||||||
<Fragment>
|
<>
|
||||||
<span className={classes.ts}>{datetime}</span>
|
<span className={classes.ts}>{datetime}</span>
|
||||||
<span className={clsx(classes.level, className)}>{label || level}</span>
|
<span className={clsx(classes.level, className)}>{label || level}</span>
|
||||||
<span>{pkg}{text}</span>
|
<span>{pkg}{text}</span>
|
||||||
</Fragment>
|
</>
|
||||||
);
|
);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@ -111,10 +108,8 @@ const Log = ({ log = [], onClear }) => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={classes.root}>
|
<div className={classes.root}>
|
||||||
<div className={classes.container}>
|
<div className={classes.log}>
|
||||||
<div className={classes.log}>
|
{log.map((line, i) => <Line key={i} message={line} />)}
|
||||||
{log.reverse().map((line, i) => <Line key={i} message={line} />)}
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
// Copyright 2020 DxOS.org.org
|
// Copyright 2020 DxOS.org.org
|
||||||
//
|
//
|
||||||
|
|
||||||
import React, { Fragment } from 'react';
|
import React from 'react';
|
||||||
import Link from '@material-ui/core/Link';
|
import Link from '@material-ui/core/Link';
|
||||||
|
|
||||||
import { getServiceUrl } from '../util/config';
|
import { getServiceUrl } from '../util/config';
|
||||||
@ -14,7 +14,6 @@ import { getServiceUrl } from '../util/config';
|
|||||||
* @param {string} pkg
|
* @param {string} pkg
|
||||||
*/
|
*/
|
||||||
const PackageLink = ({ config, type, pkg }) => {
|
const PackageLink = ({ config, type, pkg }) => {
|
||||||
|
|
||||||
// TODO(burdon): Pass in expected arg types.
|
// TODO(burdon): Pass in expected arg types.
|
||||||
if (typeof pkg === 'string') {
|
if (typeof pkg === 'string') {
|
||||||
const ipfsUrl = getServiceUrl(config, 'ipfs.gateway', { path: `${pkg}` });
|
const ipfsUrl = getServiceUrl(config, 'ipfs.gateway', { path: `${pkg}` });
|
||||||
@ -25,28 +24,26 @@ const PackageLink = ({ config, type, pkg }) => {
|
|||||||
switch (type) {
|
switch (type) {
|
||||||
case 'wrn:bot': {
|
case 'wrn:bot': {
|
||||||
const packageLinks = [];
|
const packageLinks = [];
|
||||||
Object.keys(pkg).forEach(platform => {
|
Object.keys(pkg).forEach((platform, i) => {
|
||||||
Object.keys(pkg[platform]).forEach(arch => {
|
Object.keys(pkg[platform]).forEach(arch => {
|
||||||
const cid = pkg[platform][arch];
|
const cid = pkg[platform][arch];
|
||||||
const ipfsUrl = getServiceUrl(config, 'ipfs.gateway', { path: `${cid}` });
|
const ipfsUrl = getServiceUrl(config, 'ipfs.gateway', { path: `${cid}` });
|
||||||
|
|
||||||
packageLinks.push(
|
packageLinks.push(
|
||||||
<Fragment>
|
<Link
|
||||||
<Link
|
key={`${cid}`}
|
||||||
key={cid}
|
href={ipfsUrl}
|
||||||
href={ipfsUrl}
|
title={cid}
|
||||||
title={cid}
|
target="ipfs"
|
||||||
target="ipfs"
|
>
|
||||||
>
|
{platform}/{arch}: {cid}
|
||||||
{platform}/{arch}: {cid}
|
</Link>
|
||||||
</Link>
|
|
||||||
</Fragment>
|
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Fragment>{packageLinks}</Fragment>
|
<>{packageLinks}</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -7,7 +7,7 @@ import defaultsDeep from 'lodash.defaultsdeep';
|
|||||||
|
|
||||||
import ErrorBoundary from '../components/ErrorBoundary';
|
import ErrorBoundary from '../components/ErrorBoundary';
|
||||||
|
|
||||||
import { ConsoleContext, statusReducer, SET_STATUS } from '../hooks';
|
import { ConsoleContext, statusReducer, STATUS, SET_STATUS } from '../hooks';
|
||||||
|
|
||||||
const defaultState = {};
|
const defaultState = {};
|
||||||
|
|
||||||
@ -18,8 +18,7 @@ const defaultState = {};
|
|||||||
* @param {string} action
|
* @param {string} action
|
||||||
*/
|
*/
|
||||||
const appReducer = (state, action) => ({
|
const appReducer = (state, action) => ({
|
||||||
// TODO(burdon): Key shouldn't be same as action type.
|
[STATUS]: statusReducer(state[STATUS], action)
|
||||||
[SET_STATUS]: statusReducer(state[SET_STATUS], action)
|
|
||||||
});
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -36,8 +35,6 @@ const appReducer = (state, action) => ({
|
|||||||
const ConsoleContextProvider = ({ children, config, modules, initialState = {}, errorHandler }) => {
|
const ConsoleContextProvider = ({ children, config, modules, initialState = {}, errorHandler }) => {
|
||||||
const [state, dispatch] = useReducer(appReducer, defaultsDeep({}, initialState, defaultState));
|
const [state, dispatch] = useReducer(appReducer, defaultsDeep({}, initialState, defaultState));
|
||||||
|
|
||||||
const { errors: { exceptions = [] } = {} } = state[SET_STATUS] || {};
|
|
||||||
|
|
||||||
// Bind the error handler.
|
// Bind the error handler.
|
||||||
if (errorHandler) {
|
if (errorHandler) {
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@ -45,7 +42,7 @@ const ConsoleContextProvider = ({ children, config, modules, initialState = {},
|
|||||||
dispatch({
|
dispatch({
|
||||||
type: SET_STATUS,
|
type: SET_STATUS,
|
||||||
payload: {
|
payload: {
|
||||||
exceptions: [error, ...exceptions]
|
error
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -9,6 +9,8 @@ import { ApolloProvider } from '@apollo/react-hooks';
|
|||||||
import { ThemeProvider } from '@material-ui/core/styles';
|
import { ThemeProvider } from '@material-ui/core/styles';
|
||||||
import CssBaseline from '@material-ui/core/CssBaseline';
|
import CssBaseline from '@material-ui/core/CssBaseline';
|
||||||
|
|
||||||
|
import { ErrorHandler } from '@dxos/debug';
|
||||||
|
|
||||||
import config from '../../config.yml';
|
import config from '../../config.yml';
|
||||||
import { build } from '../../version.json';
|
import { build } from '../../version.json';
|
||||||
|
|
||||||
@ -33,13 +35,16 @@ Object.assign(config, { build });
|
|||||||
|
|
||||||
debug.enable(config.system.debug);
|
debug.enable(config.system.debug);
|
||||||
|
|
||||||
|
// Global error handler.
|
||||||
|
const errorHandler = new ErrorHandler();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Root application.
|
* Root application.
|
||||||
*/
|
*/
|
||||||
const Main = () => {
|
const Main = () => {
|
||||||
return (
|
return (
|
||||||
<ApolloProvider client={clientFactory(config)}>
|
<ApolloProvider client={clientFactory(config)}>
|
||||||
<ConsoleContextProvider config={config} modules={modules}>
|
<ConsoleContextProvider config={config} modules={modules} errorHandler={errorHandler}>
|
||||||
<ThemeProvider theme={createTheme(config.app.theme)}>
|
<ThemeProvider theme={createTheme(config.app.theme)}>
|
||||||
<CssBaseline />
|
<CssBaseline />
|
||||||
<HashRouter>
|
<HashRouter>
|
||||||
|
@ -18,6 +18,8 @@ import red from '@material-ui/core/colors/red';
|
|||||||
|
|
||||||
import { ConsoleContext, useStatusReducer } from '../hooks';
|
import { ConsoleContext, useStatusReducer } from '../hooks';
|
||||||
|
|
||||||
|
import Error from '../components/Error';
|
||||||
|
|
||||||
import VersionCheck from './VersionCheck';
|
import VersionCheck from './VersionCheck';
|
||||||
|
|
||||||
const useStyles = makeStyles((theme) => ({
|
const useStyles = makeStyles((theme) => ({
|
||||||
@ -30,17 +32,15 @@ const useStyles = makeStyles((theme) => ({
|
|||||||
color: grey[400]
|
color: grey[400]
|
||||||
},
|
},
|
||||||
left: {
|
left: {
|
||||||
|
display: 'flex',
|
||||||
width: 160
|
width: 160
|
||||||
},
|
},
|
||||||
right: {
|
right: {
|
||||||
|
display: 'flex',
|
||||||
width: 160,
|
width: 160,
|
||||||
textAlign: 'right'
|
justifyContent: 'flex-end'
|
||||||
},
|
},
|
||||||
center: {
|
center: {
|
||||||
flex: 1,
|
|
||||||
textAlign: 'center'
|
|
||||||
},
|
|
||||||
info: {
|
|
||||||
display: 'flex',
|
display: 'flex',
|
||||||
fontFamily: 'monospace',
|
fontFamily: 'monospace',
|
||||||
fontSize: 'large',
|
fontSize: 'large',
|
||||||
@ -90,7 +90,7 @@ const StatusBar = () => {
|
|||||||
const StatusIcon = ({ error }) => {
|
const StatusIcon = ({ error }) => {
|
||||||
if (error) {
|
if (error) {
|
||||||
return (
|
return (
|
||||||
<ErrorIcon className={clsx(classes.icon, classes.error)} title={String(error)} />
|
<ErrorIcon className={clsx(classes.icon, classes.error)} />
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
return (
|
return (
|
||||||
@ -100,24 +100,28 @@ const StatusBar = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Toolbar className={classes.root}>
|
<>
|
||||||
<div className={classes.left}>
|
<Toolbar className={classes.root}>
|
||||||
<Link className={classes.link} href={config.app.website} rel="noreferrer" target="_blank">
|
<div className={classes.left}>
|
||||||
<PublicIcon />
|
<Link className={classes.link} href={config.app.website} rel="noreferrer" target="_blank">
|
||||||
</Link>
|
<PublicIcon />
|
||||||
</div>
|
</Link>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div className={classes.info}>
|
<div className={classes.center}>
|
||||||
<div>{name} ({version})</div>
|
<div>{name} ({version})</div>
|
||||||
<div>{moment(buildDate).format('L')}</div>
|
<div>{moment(buildDate).format('L')}</div>
|
||||||
<VersionCheck />
|
<VersionCheck />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className={classes.right}>
|
<div className={classes.right}>
|
||||||
<LoadingIcon className={clsx(classes.icon, isLoading && classes.loading)} />
|
<LoadingIcon className={clsx(classes.icon, isLoading && classes.loading)} />
|
||||||
<StatusIcon error={error} />
|
<StatusIcon error={error} />
|
||||||
</div>
|
</div>
|
||||||
</Toolbar>
|
</Toolbar>
|
||||||
|
|
||||||
|
<Error error={error} />
|
||||||
|
</>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -20,8 +20,8 @@ import WNSLog from './WNSLog';
|
|||||||
import WNSRecords, { WNSRecordType } from './WNSRecords';
|
import WNSRecords, { WNSRecordType } from './WNSRecords';
|
||||||
import WNSStatus from './WNSStatus';
|
import WNSStatus from './WNSStatus';
|
||||||
|
|
||||||
const TAB_RECORDS = 'explorer';
|
const TAB_RECORDS = 'records';
|
||||||
const TAB_STATUS = 'records';
|
const TAB_STATUS = 'status';
|
||||||
const TAB_LOG = 'log';
|
const TAB_LOG = 'log';
|
||||||
|
|
||||||
const useStyles = makeStyles(() => ({
|
const useStyles = makeStyles(() => ({
|
||||||
|
@ -2,20 +2,21 @@
|
|||||||
// Copyright 2019 DxOS
|
// Copyright 2019 DxOS
|
||||||
//
|
//
|
||||||
|
|
||||||
import { useContext } from 'react';
|
import { useContext, useEffect } from 'react';
|
||||||
|
|
||||||
import { ConsoleContext } from './context';
|
import { ConsoleContext } from './context';
|
||||||
|
|
||||||
export const SET_STATUS = 'errors';
|
export const STATUS = 'xxx';
|
||||||
|
export const SET_STATUS = 'set.status';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
* Dispatcher for app status.
|
||||||
*/
|
*/
|
||||||
export const useStatusReducer = () => {
|
export const useStatusReducer = () => {
|
||||||
const { state, dispatch } = useContext(ConsoleContext);
|
const { state, dispatch } = useContext(ConsoleContext);
|
||||||
|
|
||||||
return [
|
return [
|
||||||
state[SET_STATUS] || {},
|
state[STATUS] || {},
|
||||||
value => dispatch({ type: SET_STATUS, payload: value || { exceptions: [] } })
|
value => dispatch({ type: SET_STATUS, payload: value || { exceptions: [] } })
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
@ -26,13 +27,15 @@ export const useStatusReducer = () => {
|
|||||||
export const useQueryStatusReducer = ({ loading, error, data }) => {
|
export const useQueryStatusReducer = ({ loading, error, data }) => {
|
||||||
const [, setStatus] = useStatusReducer();
|
const [, setStatus] = useStatusReducer();
|
||||||
|
|
||||||
if (loading) {
|
useEffect(() => {
|
||||||
setTimeout(() => setStatus({ loading }));
|
if (loading) {
|
||||||
}
|
setTimeout(() => setStatus({ loading }));
|
||||||
|
}
|
||||||
|
|
||||||
if (error) {
|
if (error) {
|
||||||
setTimeout(() => setStatus({ error }));
|
setTimeout(() => setStatus({ error }));
|
||||||
}
|
}
|
||||||
|
}, [loading, error]);
|
||||||
|
|
||||||
return data;
|
return data;
|
||||||
};
|
};
|
||||||
|
@ -12,6 +12,8 @@ const log = debug('dxos:console:client:resolvers');
|
|||||||
|
|
||||||
const timestamp = () => new Date().toUTCString();
|
const timestamp = () => new Date().toUTCString();
|
||||||
|
|
||||||
|
const MAX_LOG_LENGTH = 200;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Resolvers
|
* Resolvers
|
||||||
* https://www.apollographql.com/docs/tutorial/local-state/#local-resolvers
|
* https://www.apollographql.com/docs/tutorial/local-state/#local-resolvers
|
||||||
@ -21,6 +23,11 @@ export const createResolvers = config => {
|
|||||||
const endpoint = getServiceUrl(config, 'wns.server', { absolute: true });
|
const endpoint = getServiceUrl(config, 'wns.server', { absolute: true });
|
||||||
const registry = new Registry(endpoint);
|
const registry = new Registry(endpoint);
|
||||||
|
|
||||||
|
// TODO(burdon): Errors swallowed!
|
||||||
|
|
||||||
|
// Oldest to latest.
|
||||||
|
let cachedLog = [];
|
||||||
|
|
||||||
return {
|
return {
|
||||||
Query: {
|
Query: {
|
||||||
wns_status: async () => {
|
wns_status: async () => {
|
||||||
@ -52,13 +59,29 @@ export const createResolvers = config => {
|
|||||||
wns_log: async () => {
|
wns_log: async () => {
|
||||||
log('WNS log...');
|
log('WNS log...');
|
||||||
|
|
||||||
// TODO(burdon): Cache and merge previous state.
|
|
||||||
const data = await registry.getLogs();
|
const data = await registry.getLogs();
|
||||||
|
|
||||||
|
// TODO(burdon): Bug returns blank line at end.
|
||||||
|
const filtered = data.map(line => line).filter(Boolean);
|
||||||
|
|
||||||
|
// Cache and merge previous state.
|
||||||
|
let i = filtered.findIndex(line => line === cachedLog[cachedLog.length - 1]);
|
||||||
|
if (i === -1) {
|
||||||
|
cachedLog = filtered;
|
||||||
|
} else {
|
||||||
|
i++;
|
||||||
|
for (; i < filtered.length - 1; i++) {
|
||||||
|
cachedLog.push(filtered[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Trim.
|
||||||
|
cachedLog.splice(0, cachedLog.length - MAX_LOG_LENGTH);
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
__typename: 'JSONLog',
|
__typename: 'JSONLog',
|
||||||
timestamp: timestamp(),
|
timestamp: timestamp(),
|
||||||
log: data
|
log: [...cachedLog].reverse()
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"build": {
|
"build": {
|
||||||
"name": "@dxos/console-client",
|
"name": "@dxos/console-client",
|
||||||
"buildDate": "2020-05-26T17:38:45.688Z",
|
"buildDate": "2020-05-27T01:16:27.565Z",
|
||||||
"version": "1.0.0-beta.0"
|
"version": "1.0.0-beta.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -15,6 +15,10 @@ const timestamp = () => new Date().toUTCString();
|
|||||||
* @param config
|
* @param config
|
||||||
*/
|
*/
|
||||||
export const createResolvers = config => ({
|
export const createResolvers = config => ({
|
||||||
|
|
||||||
|
// TODO(burdon): Auth mutations.
|
||||||
|
// https://www.apollographql.com/docs/apollo-server/data/errors/#codes
|
||||||
|
|
||||||
Mutation: {
|
Mutation: {
|
||||||
//
|
//
|
||||||
// WNS
|
// WNS
|
||||||
|
20
yarn.lock
20
yarn.lock
@ -1179,6 +1179,13 @@
|
|||||||
dependencies:
|
dependencies:
|
||||||
debug "^4.1.1"
|
debug "^4.1.1"
|
||||||
|
|
||||||
|
"@dxos/debug@^1.0.0-beta.37":
|
||||||
|
version "1.0.0-beta.37"
|
||||||
|
resolved "https://registry.yarnpkg.com/@dxos/debug/-/debug-1.0.0-beta.37.tgz#0fc3a1d9d0b2616c5c22da6fcea7c369610ec282"
|
||||||
|
integrity sha512-65jOaqMrjv1Comepqq2U0k9olpAiKtk6pVEnhZHb+FutPMnjIkA+TPedNfTpxWQEs3MpG0IVyj64JugGl2KhQA==
|
||||||
|
dependencies:
|
||||||
|
debug "^4.1.1"
|
||||||
|
|
||||||
"@dxos/gem-core@^1.0.0-beta.11":
|
"@dxos/gem-core@^1.0.0-beta.11":
|
||||||
version "1.0.0-beta.11"
|
version "1.0.0-beta.11"
|
||||||
resolved "https://registry.yarnpkg.com/@dxos/gem-core/-/gem-core-1.0.0-beta.11.tgz#b4b8e82b3cfe7a9dd06fac8596ccf04fa8028e21"
|
resolved "https://registry.yarnpkg.com/@dxos/gem-core/-/gem-core-1.0.0-beta.11.tgz#b4b8e82b3cfe7a9dd06fac8596ccf04fa8028e21"
|
||||||
@ -1194,17 +1201,16 @@
|
|||||||
react-dom "^16.13.1"
|
react-dom "^16.13.1"
|
||||||
react-resize-aware "^3.0.0"
|
react-resize-aware "^3.0.0"
|
||||||
|
|
||||||
"@dxos/react-ux@^1.0.0-beta.20":
|
"@dxos/react-ux@^1.0.0-beta.37":
|
||||||
version "1.0.0-beta.20"
|
version "1.0.0-beta.37"
|
||||||
resolved "https://registry.yarnpkg.com/@dxos/react-ux/-/react-ux-1.0.0-beta.20.tgz#0f0801ae2ddb9089428034cc4b466ee98206a180"
|
resolved "https://registry.yarnpkg.com/@dxos/react-ux/-/react-ux-1.0.0-beta.37.tgz#4a6003ce52f0afa156e0af457162d2d14695f153"
|
||||||
integrity sha512-larSB5cNCbyvP55/qan9uzioGXrcbtvrmy+fBRx7eLlsFs/eTgD/zrNMSVtq5mvMAn/oKKCOX1wipxm4gK6fdA==
|
integrity sha512-QuRIAc4xY57uHRqRnXwGZEW5VD6NVmpIQWRB1T2XsmRdyIzwWDHgK6pBzd7zeNQI/6nqzHr0fkeRY0Lsqou8Cw==
|
||||||
dependencies:
|
dependencies:
|
||||||
"@dxos/crypto" "^1.0.0-beta.1"
|
"@dxos/crypto" "^1.0.0-beta.1"
|
||||||
"@dxos/debug" "^1.0.0-beta.20"
|
"@dxos/debug" "^1.0.0-beta.37"
|
||||||
"@material-ui/core" "^4.9.0"
|
"@material-ui/core" "^4.9.0"
|
||||||
"@material-ui/icons" "^4.5.1"
|
"@material-ui/icons" "^4.5.1"
|
||||||
"@material-ui/lab" "^4.0.0-alpha.42"
|
"@material-ui/lab" "^4.0.0-alpha.42"
|
||||||
"@material-ui/styles" "^4.9.0"
|
|
||||||
clsx "^1.0.4"
|
clsx "^1.0.4"
|
||||||
lodash.isplainobject "^4.0.6"
|
lodash.isplainobject "^4.0.6"
|
||||||
uuid "^3.3.3"
|
uuid "^3.3.3"
|
||||||
@ -2189,7 +2195,7 @@
|
|||||||
prop-types "^15.7.2"
|
prop-types "^15.7.2"
|
||||||
react-is "^16.8.0"
|
react-is "^16.8.0"
|
||||||
|
|
||||||
"@material-ui/styles@^4.10.0", "@material-ui/styles@^4.9.0":
|
"@material-ui/styles@^4.10.0":
|
||||||
version "4.10.0"
|
version "4.10.0"
|
||||||
resolved "https://registry.yarnpkg.com/@material-ui/styles/-/styles-4.10.0.tgz#2406dc23aa358217aa8cc772e6237bd7f0544071"
|
resolved "https://registry.yarnpkg.com/@material-ui/styles/-/styles-4.10.0.tgz#2406dc23aa358217aa8cc772e6237bd7f0544071"
|
||||||
integrity sha512-XPwiVTpd3rlnbfrgtEJ1eJJdFCXZkHxy8TrdieaTvwxNYj42VnnCyFzxYeNW9Lhj4V1oD8YtQ6S5Gie7bZDf7Q==
|
integrity sha512-XPwiVTpd3rlnbfrgtEJ1eJJdFCXZkHxy8TrdieaTvwxNYj42VnnCyFzxYeNW9Lhj4V1oD8YtQ6S5Gie7bZDf7Q==
|
||||||
|
Loading…
Reference in New Issue
Block a user