parent
6b2731bf48
commit
73758de7ac
@ -4,6 +4,7 @@
|
||||
|
||||
import { ApiPromise } from '@polkadot/api';
|
||||
import { KeyringInstance } from '@polkadot/keyring/types';
|
||||
import { ApiProps } from '@polkadot/react-api/types';
|
||||
import { AppProps as Props } from '@polkadot/react-components/types';
|
||||
import { Log, LogType, Snippet } from './types';
|
||||
|
||||
@ -30,24 +31,49 @@ interface Injected {
|
||||
error: (...args: any[]) => void;
|
||||
log: (...args: any[]) => void;
|
||||
};
|
||||
global: null;
|
||||
hashing: typeof hashing;
|
||||
keyring: KeyringInstance | null;
|
||||
localStorage: null;
|
||||
location: null;
|
||||
setIsRunning: (isRunning: boolean) => void;
|
||||
types: typeof types;
|
||||
util: typeof util;
|
||||
window: null;
|
||||
[name: string]: any;
|
||||
}
|
||||
|
||||
const ALLOWED_GLOBALS = ['atob', 'btoa'];
|
||||
const snippets: Snippet[] = JSON.parse(JSON.stringify(allSnippets));
|
||||
let hasSnippetWrappers = false;
|
||||
|
||||
function setupInjected ({ api, isDevelopment }: ApiProps, setIsRunning: (isRunning: boolean) => void, hookConsole: (type: LogType, args: any[]) => void): Injected {
|
||||
const nullObject = Object
|
||||
.keys(window)
|
||||
.filter((key): boolean => !key.includes('-') && !ALLOWED_GLOBALS.includes(key))
|
||||
.reduce((result: Record<string, null>, key): Record<string, null> => {
|
||||
result[key] = null;
|
||||
|
||||
return result;
|
||||
}, { global: null, window: null });
|
||||
|
||||
return {
|
||||
...nullObject,
|
||||
api: api.clone(),
|
||||
console: {
|
||||
error: (...args: any[]): void => hookConsole('error', args),
|
||||
log: (...args: any[]): void => hookConsole('log', args)
|
||||
},
|
||||
hashing,
|
||||
keyring: isDevelopment
|
||||
? uiKeyring.keyring
|
||||
: null,
|
||||
setIsRunning,
|
||||
types,
|
||||
util
|
||||
};
|
||||
}
|
||||
|
||||
// FIXME This... ladies & gentlemen, is a mess that should be untangled
|
||||
function Playground ({ className }: Props): React.ReactElement<Props> {
|
||||
const { t } = useTranslation();
|
||||
const { api, isDevelopment } = useApi();
|
||||
const apiProps = useApi();
|
||||
const injectedRef = useRef<Injected | null>(null);
|
||||
const [code, setCode] = useState('');
|
||||
const [isCustomExample, setIsCustomExample] = useState(false);
|
||||
@ -62,7 +88,7 @@ function Playground ({ className }: Props): React.ReactElement<Props> {
|
||||
// add snippets if not already available (global)
|
||||
if (!hasSnippetWrappers) {
|
||||
snippets.forEach((snippet): void => {
|
||||
snippet.code = `${makeWrapper(isDevelopment)}${snippet.code}`;
|
||||
snippet.code = `${makeWrapper(apiProps.isDevelopment)}${snippet.code}`;
|
||||
});
|
||||
|
||||
hasSnippetWrappers = true;
|
||||
@ -103,24 +129,7 @@ function Playground ({ className }: Props): React.ReactElement<Props> {
|
||||
setIsRunning(true);
|
||||
_clearConsole();
|
||||
|
||||
injectedRef.current = {
|
||||
api: api.clone(),
|
||||
console: {
|
||||
error: (...args: any[]): void => _hookConsole('error', args),
|
||||
log: (...args: any[]): void => _hookConsole('log', args)
|
||||
},
|
||||
global: null,
|
||||
hashing,
|
||||
keyring: isDevelopment
|
||||
? uiKeyring.keyring
|
||||
: null,
|
||||
location: null,
|
||||
localStorage: null,
|
||||
setIsRunning,
|
||||
types,
|
||||
util,
|
||||
window: null
|
||||
};
|
||||
injectedRef.current = setupInjected(apiProps, setIsRunning, _hookConsole);
|
||||
|
||||
await injectedRef.current.api.isReady;
|
||||
|
||||
@ -128,7 +137,7 @@ function Playground ({ className }: Props): React.ReactElement<Props> {
|
||||
// squash into a single line so exceptions (with line numbers) maps to the
|
||||
// same line/origin as we have in the editor view
|
||||
// TODO: Make the console.error here actually return the full stack
|
||||
const exec = `(async ({${Object.keys(injectedRef.current).join(',')}}) => { try { ${code} \n } catch (error) { console.error(error); setIsRunning(false); } })(injected);`;
|
||||
const exec = `(async ({${Object.keys(injectedRef.current).sort().join(',')}}) => { try { ${code} \n } catch (error) { console.error(error); setIsRunning(false); } })(injected);`;
|
||||
|
||||
// eslint-disable-next-line no-new-func
|
||||
new Function('injected', exec).bind({}, injectedRef.current)();
|
||||
|
||||
Loading…
Reference in New Issue
Block a user