Compare commits

..

2 Commits

Author SHA1 Message Date
muzam1l
04e2274dbf some refactoring 2022-04-06 14:42:39 +05:30
muzam1l
842b8a5226 Set debug stream default account from transaction account 2022-04-04 21:29:08 +05:30
6 changed files with 1429 additions and 402 deletions

View File

@@ -2,7 +2,6 @@ NEXTAUTH_URL=https://example.com
GITHUB_SECRET=""
GITHUB_ID=""
NEXT_PUBLIC_COMPILE_API_ENDPOINT="http://localhost:9000/api/build"
NEXT_PUBLIC_COMPILE_API_BASE_URL="http://localhost:9000"
NEXT_PUBLIC_LANGUAGE_SERVER_API_ENDPOINT="ws://localhost:9000/language-server/c"
NEXT_PUBLIC_TESTNET_URL="hooks-testnet-v2.xrpl-labs.com"
NEXT_PUBLIC_DEBUG_STREAM_URL="hooks-testnet-v2-debugstream.xrpl-labs.com"

View File

@@ -10,7 +10,7 @@ interface ISelect<T = string> {
value: T;
}
const streamState = proxy({
export const streamState = proxy({
selectedAccount: null as ISelect | null,
logs: [] as ILog[],
socket: undefined as WebSocket | undefined,

View File

@@ -1,356 +0,0 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import type { languages } from '../../fillers/monaco-editor-core';
export const conf: languages.LanguageConfiguration = {
comments: {
lineComment: '//',
blockComment: ['/*', '*/']
},
brackets: [
['{', '}'],
['[', ']'],
['(', ')']
],
autoClosingPairs: [
{ open: '[', close: ']' },
{ open: '{', close: '}' },
{ open: '(', close: ')' },
{ open: "'", close: "'", notIn: ['string', 'comment'] },
{ open: '"', close: '"', notIn: ['string'] }
],
surroundingPairs: [
{ open: '{', close: '}' },
{ open: '[', close: ']' },
{ open: '(', close: ')' },
{ open: '"', close: '"' },
{ open: "'", close: "'" }
],
folding: {
markers: {
start: new RegExp('^\\s*#pragma\\s+region\\b'),
end: new RegExp('^\\s*#pragma\\s+endregion\\b')
}
}
};
export const language = <languages.IMonarchLanguage>{
defaultToken: '',
tokenPostfix: '.c',
brackets: [
{ token: 'delimiter.curly', open: '{', close: '}' },
{ token: 'delimiter.parenthesis', open: '(', close: ')' },
{ token: 'delimiter.square', open: '[', close: ']' },
{ token: 'delimiter.angle', open: '<', close: '>' }
],
keywords: [
'abstract',
'amp',
'array',
'asm',
'auto',
'break',
'case',
'char',
'const',
'continue',
'default',
'do',
'double',
'dynamic_cast',
'else',
'enum',
'extern',
'float',
'for',
'goto',
'if',
'inline',
'int',
'long',
'register',
'restrict',
'return',
'short',
'signed',
'sizeof',
'static',
'struct',
'switch',
'typedef',
'union',
'unsigned',
'void',
'volatile',
'wchar_t',
'where',
'while',
'__abstract', // reserved word with two underscores
'__alignof',
'__asm',
'__assume',
'__based',
'__box',
'__builtin_alignof',
'__cdecl',
'__clrcall',
'__declspec',
'__delegate',
'__event',
'__except',
'__fastcall',
'__finally',
'__forceinline',
'__gc',
'__hook',
'__identifier',
'__if_exists',
'__if_not_exists',
'__inline',
'__int128',
'__int16',
'__int32',
'__int64',
'__int8',
'__interface',
'__leave',
'__m128',
'__m128d',
'__m128i',
'__m256',
'__m256d',
'__m256i',
'__m64',
'__multiple_inheritance',
'__newslot',
'__nogc',
'__noop',
'__nounwind',
'__novtordisp',
'__pascal',
'__pin',
'__pragma',
'__property',
'__ptr32',
'__ptr64',
'__raise',
'__restrict',
'__resume',
'__sealed',
'__single_inheritance',
'__stdcall',
'__super',
'__thiscall',
'__try',
'__try_cast',
'__typeof',
'__unaligned',
'__unhook',
'__uuidof',
'__value',
'__virtual_inheritance',
'__w64',
'__wchar_t'
],
operators: [
'=',
'>',
'<',
'!',
'~',
'?',
':',
'==',
'<=',
'>=',
'!=',
'&&',
'||',
'++',
'--',
'+',
'-',
'*',
'/',
'&',
'|',
'^',
'%',
'<<',
'>>',
'+=',
'-=',
'*=',
'/=',
'&=',
'|=',
'^=',
'%=',
'<<=',
'>>='
],
// we include these common regular expressions
symbols: /[=><!~?:&|+\-*\/\^%]+/,
escapes: /\\(?:[abfnrtv\\"']|x[0-9A-Fa-f]{1,4}|u[0-9A-Fa-f]{4}|U[0-9A-Fa-f]{8})/,
integersuffix: /([uU](ll|LL|l|L)|(ll|LL|l|L)?[uU]?)/,
floatsuffix: /[fFlL]?/,
encoding: /u|u8|U|L/,
// The main tokenizer for our languages
tokenizer: {
root: [
// C++ 11 Raw String
[/@encoding?R\"(?:([^ ()\\\t]*))\(/, { token: 'string.raw.begin', next: '@raw.$1' }],
// identifiers and keywords
[
/[a-zA-Z_]\w*/,
{
cases: {
'@keywords': { token: 'keyword.$0' },
'@default': 'identifier'
}
}
],
// The preprocessor checks must be before whitespace as they check /^\s*#/ which
// otherwise fails to match later after other whitespace has been removed.
// Inclusion
[/^\s*#\s*include/, { token: 'keyword.directive.include', next: '@include' }],
// Preprocessor directive
[/^\s*#\s*\w+/, 'keyword.directive'],
// whitespace
{ include: '@whitespace' },
// [[ attributes ]].
[/\[\s*\[/, { token: 'annotation', next: '@annotation' }],
// delimiters and operators
[/[{}()\[\]]/, '@brackets'],
[/[<>](?!@symbols)/, '@brackets'],
[
/@symbols/,
{
cases: {
'@operators': 'delimiter',
'@default': ''
}
}
],
// numbers
[/\d*\d+[eE]([\-+]?\d+)?(@floatsuffix)/, 'number.float'],
[/\d*\.\d+([eE][\-+]?\d+)?(@floatsuffix)/, 'number.float'],
[/0[xX][0-9a-fA-F']*[0-9a-fA-F](@integersuffix)/, 'number.hex'],
[/0[0-7']*[0-7](@integersuffix)/, 'number.octal'],
[/0[bB][0-1']*[0-1](@integersuffix)/, 'number.binary'],
[/\d[\d']*\d(@integersuffix)/, 'number'],
[/\d(@integersuffix)/, 'number'],
// delimiter: after number because of .\d floats
[/[;,.]/, 'delimiter'],
// strings
[/"([^"\\]|\\.)*$/, 'string.invalid'], // non-teminated string
[/"/, 'string', '@string'],
// characters
[/'[^\\']'/, 'string'],
[/(')(@escapes)(')/, ['string', 'string.escape', 'string']],
[/'/, 'string.invalid']
],
whitespace: [
[/[ \t\r\n]+/, ''],
[/\/\*\*(?!\/)/, 'comment.doc', '@doccomment'],
[/\/\*/, 'comment', '@comment'],
[/\/\/.*\\$/, 'comment', '@linecomment'],
[/\/\/.*$/, 'comment']
],
comment: [
[/[^\/*]+/, 'comment'],
[/\*\//, 'comment', '@pop'],
[/[\/*]/, 'comment']
],
//For use with continuous line comments
linecomment: [
[/.*[^\\]$/, 'comment', '@pop'],
[/[^]+/, 'comment']
],
//Identical copy of comment above, except for the addition of .doc
doccomment: [
[/[^\/*]+/, 'comment.doc'],
[/\*\//, 'comment.doc', '@pop'],
[/[\/*]/, 'comment.doc']
],
string: [
[/[^\\"]+/, 'string'],
[/@escapes/, 'string.escape'],
[/\\./, 'string.escape.invalid'],
[/"/, 'string', '@pop']
],
raw: [
[
/(.*)(\))(?:([^ ()\\\t"]*))(\")/,
{
cases: {
'$3==$S2': [
'string.raw',
'string.raw.end',
'string.raw.end',
{ token: 'string.raw.end', next: '@pop' }
],
'@default': ['string.raw', 'string.raw', 'string.raw', 'string.raw']
}
}
],
[/.*/, 'string.raw']
],
annotation: [
{ include: '@whitespace' },
[/[a-zA-Z0-9_]+/, 'annotation'],
[/[,:]/, 'delimiter'],
[/[()]/, '@brackets'],
[/\]\s*\]/, { token: 'annotation', next: '@pop' }]
],
include: [
[
/(\s*)(<)([^<>]*)(>)/,
[
'',
'keyword.directive.include.begin',
'string.include.identifier',
{ token: 'keyword.directive.include.end', next: '@pop' }
]
],
[
/(\s*)(")([^"]*)(")/,
[
'',
'keyword.directive.include.begin',
'string.include.identifier',
{ token: 'keyword.directive.include.end', next: '@pop' }
]
]
]
}
};

View File

@@ -18,6 +18,7 @@ import transactionsData from "../../content/transactions.json";
import state from "../../state";
import { sendTransaction } from "../../state/actions";
import { getSplit, saveSplit } from "../../state/actions/persistSplits";
import { streamState } from "../../components/DebugStream";
const DebugStream = dynamic(() => import("../../components/DebugStream"), {
ssr: false,
@@ -37,6 +38,11 @@ type TxFields = Omit<
>;
type OtherFields = (keyof Omit<TxFields, "Destination">)[];
interface AccountOption {
label: string;
value: string;
}
interface Props {
header?: string;
}
@@ -44,7 +50,7 @@ interface Props {
const Transaction: FC<Props> = ({ header, ...props }) => {
const snap = useSnapshot(state);
const transactionsOptions = transactionsData.map((tx) => ({
const transactionsOptions = transactionsData.map(tx => ({
value: tx.TransactionType,
label: tx.TransactionType,
}));
@@ -52,23 +58,24 @@ const Transaction: FC<Props> = ({ header, ...props }) => {
typeof transactionsOptions[0] | null
>(null);
const accountOptions = snap.accounts.map((acc) => ({
const accountOptions: AccountOption[] = snap.accounts.map(acc => ({
label: acc.name,
value: acc.address,
}));
const [selectedAccount, setSelectedAccount] = useState<
typeof accountOptions[0] | null
>(null);
const destAccountOptions = snap.accounts
.map((acc) => ({
const [selectedAccount, setSelectedAccount] = useState<AccountOption | null>(
null
);
const destAccountOptions: AccountOption[] = snap.accounts
.map(acc => ({
label: acc.name,
value: acc.address,
}))
.filter((acc) => acc.value !== selectedAccount?.value);
const [selectedDestAccount, setSelectedDestAccount] = useState<
typeof destAccountOptions[0] | null
>(null);
.filter(acc => acc.value !== selectedAccount?.value);
const [selectedDestAccount, setSelectedDestAccount] =
useState<AccountOption | null>(null);
const [txIsLoading, setTxIsLoading] = useState(false);
const [txIsDisabled, setTxIsDisabled] = useState(false);
@@ -77,7 +84,7 @@ const Transaction: FC<Props> = ({ header, ...props }) => {
useEffect(() => {
const transactionType = selectedTransaction?.value;
const account = snap.accounts.find(
(acc) => acc.address === selectedAccount?.value
acc => acc.address === selectedAccount?.value
);
if (!account || !transactionType || txIsLoading) {
setTxIsDisabled(true);
@@ -88,7 +95,7 @@ const Transaction: FC<Props> = ({ header, ...props }) => {
useEffect(() => {
let _txFields: TxFields | undefined = transactionsData.find(
(tx) => tx.TransactionType === selectedTransaction?.value
tx => tx.TransactionType === selectedTransaction?.value
);
if (!_txFields) return setTxFields({});
_txFields = { ..._txFields } as TxFields;
@@ -105,7 +112,7 @@ const Transaction: FC<Props> = ({ header, ...props }) => {
const submitTest = useCallback(async () => {
const account = snap.accounts.find(
(acc) => acc.address === selectedAccount?.value
acc => acc.address === selectedAccount?.value
);
const TransactionType = selectedTransaction?.value;
if (!account || !TransactionType || txIsDisabled) return;
@@ -116,7 +123,7 @@ const Transaction: FC<Props> = ({ header, ...props }) => {
let options = { ...txFields };
options.Destination = selectedDestAccount?.value;
(Object.keys(options) as (keyof TxFields)[]).forEach((field) => {
(Object.keys(options) as (keyof TxFields)[]).forEach(field => {
let _value = options[field];
// convert currency
if (typeof _value === "object" && _value.type === "currency") {
@@ -182,9 +189,14 @@ const Transaction: FC<Props> = ({ header, ...props }) => {
setTxIsLoading(false);
}, []);
const handleSetAccount = (acc: AccountOption) => {
setSelectedAccount(acc);
streamState.selectedAccount = acc;
};
const usualFields = ["TransactionType", "Amount", "Account", "Destination"];
const otherFields = Object.keys(txFields).filter(
(k) => !usualFields.includes(k)
k => !usualFields.includes(k)
) as OtherFields;
return (
<Box css={{ position: "relative", height: "calc(100% - 28px)" }} {...props}>
@@ -217,7 +229,7 @@ const Transaction: FC<Props> = ({ header, ...props }) => {
hideSelectedOptions
css={{ width: "70%" }}
value={selectedTransaction}
onChange={(tt) => setSelectedTransaction(tt as any)}
onChange={(tt: any) => setSelectedTransaction(tt)}
/>
</Flex>
<Flex
@@ -239,7 +251,7 @@ const Transaction: FC<Props> = ({ header, ...props }) => {
css={{ width: "70%" }}
options={accountOptions}
value={selectedAccount}
onChange={(acc) => setSelectedAccount(acc as any)}
onChange={(acc: any) => handleSetAccount(acc)} // TODO make react-select have correct types for acc
/>
</Flex>
{txFields.Amount !== undefined && (
@@ -258,7 +270,7 @@ const Transaction: FC<Props> = ({ header, ...props }) => {
</Text>
<Input
value={txFields.Amount.value}
onChange={(e) =>
onChange={e =>
setTxFields({
...txFields,
Amount: { type: "currency", value: e.target.value },
@@ -289,11 +301,11 @@ const Transaction: FC<Props> = ({ header, ...props }) => {
options={destAccountOptions}
value={selectedDestAccount}
isClearable
onChange={(acc) => setSelectedDestAccount(acc as any)}
onChange={(acc: any) => setSelectedDestAccount(acc)}
/>
</Flex>
)}
{otherFields.map((field) => {
{otherFields.map(field => {
let _value = txFields[field];
let value = typeof _value === "object" ? _value.value : _value;
value =
@@ -319,7 +331,7 @@ const Transaction: FC<Props> = ({ header, ...props }) => {
</Text>
<Input
value={value}
onChange={(e) =>
onChange={e =>
setTxFields({
...txFields,
[field]:
@@ -376,7 +388,7 @@ const Test = () => {
gutterSize={4}
gutterAlign="center"
style={{ height: "calc(100vh - 60px)" }}
onDragEnd={(e) => saveSplit("testVertical", e)}
onDragEnd={e => saveSplit("testVertical", e)}
>
<Flex
row
@@ -398,21 +410,19 @@ const Test = () => {
width: "100%",
height: "100%",
}}
onDragEnd={(e) => saveSplit("testHorizontal", e)}
onDragEnd={e => saveSplit("testHorizontal", e)}
>
<Box css={{ width: "55%", px: "$2" }}>
<Tabs
keepAllAlive
forceDefaultExtension
defaultExtension=".json"
onCreateNewTab={(name) =>
setTabHeaders(tabHeaders.concat(name))
}
onCloseTab={(index) =>
onCreateNewTab={name => setTabHeaders(tabHeaders.concat(name))}
onCloseTab={index =>
setTabHeaders(tabHeaders.filter((_, idx) => idx !== index))
}
>
{tabHeaders.map((header) => (
{tabHeaders.map(header => (
<Tab key={header} header={header}>
<Transaction header={header} />
</Tab>

View File

@@ -2,6 +2,8 @@ import { Octokit } from "@octokit/core";
import Router from "next/router";
import state from '../index';
import { templateFileIds } from '../constants';
import { hookapiH, hookmacroH, sfcodesH } from '../constants/headerTemplates';
const octokit = new Octokit();
@@ -18,29 +20,18 @@ export const fetchFiles = (gistId: string) => {
octokit
.request("GET /gists/{gist_id}", { gist_id: gistId })
.then(async res => {
.then(res => {
if (!Object.values(templateFileIds).includes(gistId)) {
return res
}
// in case of templates, fetch header file(s) and append to res
let resHeaderJson;
try {
const resHeader = await fetch(`${process.env.NEXT_PUBLIC_COMPILE_API_BASE_URL}/api/header-files`);
if (resHeader.ok) {
resHeaderJson = await resHeader.json();
}
} catch (err) {
console.log(err)
}
const files = {
...res.data.files,
'hookapi.h': res.data.files?.['hookapi.h'] || { filename: 'hookapi.h', content: resHeaderJson.hookapi, language: 'C' },
'hookmacro.h': res.data.files?.['hookmacro.h'] || { filename: 'hookmacro.h', content: resHeaderJson.hookmacro, language: 'C' },
'sfcodes.h': res.data.files?.['sfcodes.h'] || { filename: 'sfcodes.h', content: resHeaderJson.sfcodes, language: 'C' },
'hookapi.h': res.data.files?.['hookapi.h'] || { filename: 'hookapi.h', content: hookapiH, language: 'C' },
'hookmacro.h': res.data.files?.['hookmacro.h'] || { filename: 'hookmacro.h', content: hookmacroH, language: 'C' },
'sfcodes.h': res.data.files?.['sfcodes.h'] || { filename: 'sfcodes.h', content: sfcodesH, language: 'C' },
};
res.data.files = files;
return res;
// If you want to load templates from GIST instad, uncomment the code below and comment the code above.
// return octokit.request("GET /gists/{gist_id}", { gist_id: templateFileIds.headers }).then(({ data: { files: headerFiles } }) => {

File diff suppressed because it is too large Load Diff