Compare commits

...

18 Commits

Author SHA1 Message Date
muzam1l
513db7bf09 Update asc. 2023-03-31 14:22:33 +05:30
muzam1l
969fd0f63c Merge branch 'main' into feat/ts-support. 2023-03-31 14:20:04 +05:30
muzam1l
bd1a0c9836 Remove some logs. 2023-02-21 16:30:01 +05:30
muzam1l
ba95eb5be2 Merge branch 'main' into feat/ts-support 2023-02-20 19:52:33 +05:30
muzam1l
6911bcc0f3 Upgrade to official @eqlabs/assemblyscript. 2023-02-20 19:33:54 +05:30
muzam1l
a6055feb1f update asc (top level return) 2023-02-03 15:26:24 +05:30
muzam1l
31a185f49f Enable top level api. 2023-02-02 17:44:15 +05:30
muzam1l
d693458421 fix wat state not updating. 2023-02-01 21:58:25 +05:30
muzam1l
692bbeb9b2 minor fixes. 2023-02-01 04:27:10 +05:30
muzam1l
a29368d633 update wabt 1.0.30 -> 1.0.32 2023-01-30 15:41:42 +05:30
muzam1l
0f32fcb71c asc 0.0.8. 2023-01-19 20:05:07 +05:30
muzam1l
90db6b1f12 assemblyscript 0.0.6. 2023-01-16 18:36:25 +05:30
muzam1l
dde0317544 Update assemblyscript. 2023-01-13 14:36:26 +05:30
muzam1l
a6ad39f6e8 Update nextjs. 2023-01-11 21:08:17 +05:30
muzam1l
0536e48cfe Fix some type errors. 2023-01-11 20:17:21 +05:30
muzam1l
a08823a38b Better lang warning. 2023-01-11 20:01:02 +05:30
muzam1l
653e28583d Compile ts files. 2023-01-11 19:52:45 +05:30
muzam1l
e75443c8e2 Detect ts files. 2023-01-06 19:58:03 +05:30
21 changed files with 1194 additions and 620 deletions

1
.gitignore vendored
View File

@@ -23,6 +23,7 @@
npm-debug.log* npm-debug.log*
yarn-debug.log* yarn-debug.log*
yarn-error.log* yarn-error.log*
.yarn
# local env files # local env files
.env.local .env.local

View File

@@ -94,7 +94,7 @@ const DeployEditor = () => {
}} }}
> >
{`You haven't compiled any files yet, compile files on `} {`You haven't compiled any files yet, compile files on `}
<NextLink shallow href={`/develop/${router.query.slug}`} passHref> <NextLink legacyBehavior shallow href={`/develop/${router.query.slug}`} passHref>
<Link as="a">develop view</Link> <Link as="a">develop view</Link>
</NextLink> </NextLink>
</Text> </Text>

View File

@@ -155,9 +155,11 @@ const EditorNavigation = ({ renderNav }: { renderNav?: () => ReactNode }) => {
> >
<Image <Image
src={session?.user?.image || ''} src={session?.user?.image || ''}
width="30px" width="30"
height="30px" height="30"
objectFit="cover" style={{
objectFit: 'cover'
}}
alt="User avatar" alt="User avatar"
/> />
</Box> </Box>

View File

@@ -40,7 +40,6 @@ const EnrichLog: FC<EnrichLogProps> = ({ str }) => {
if (match.startsWith('HookSet')) { if (match.startsWith('HookSet')) {
const code = match.match(/^HookSet\((\d+)\)/)?.[1] const code = match.match(/^HookSet\((\d+)\)/)?.[1]
const val = hookSetCodes.find(v => code && v.code === +code) const val = hookSetCodes.find(v => code && v.code === +code)
console.log({ code, val })
if (!val) return match if (!val) return match
const content = capitalize(val.description) || 'No hint available!' const content = capitalize(val.description) || 'No hint available!'

View File

@@ -94,6 +94,14 @@ const setMarkers = (monacoE: typeof monaco) => {
}) })
} }
const langWarnings: Record<string, { shown: boolean; message: string }> = {
ts: {
shown: false,
message:
'Typescript suppport for hooks is still in early planning stage, write actual hooks in C only for now!'
}
}
const HooksEditor = () => { const HooksEditor = () => {
const editorRef = useRef<monaco.editor.IStandaloneCodeEditor>() const editorRef = useRef<monaco.editor.IStandaloneCodeEditor>()
const monacoRef = useRef<typeof monaco>() const monacoRef = useRef<typeof monaco>()
@@ -125,6 +133,14 @@ const HooksEditor = () => {
const file = snap.files[snap.active] const file = snap.files[snap.active]
useEffect(() => {
let warning = langWarnings[file?.language || '']
if (warning && !warning.shown) {
alert(warning.message) // TODO Custom dialog.
warning.shown = true
}
}, [file])
const renderNav = () => ( const renderNav = () => (
<Tabs <Tabs
label="File" label="File"
@@ -221,7 +237,7 @@ const HooksEditor = () => {
monaco.languages.register({ monaco.languages.register({
id: 'text', id: 'text',
extensions: ['.txt'], extensions: ['.txt'],
mimetypes: ['text/plain'], mimetypes: ['text/plain']
}) })
MonacoServices.install(monaco) MonacoServices.install(monaco)
const webSocket = createWebSocket( const webSocket = createWebSocket(
@@ -240,7 +256,7 @@ const HooksEditor = () => {
try { try {
disposable.dispose() disposable.dispose()
} catch (err) { } catch (err) {
console.log('err', err) console.error('err', err)
} }
}) })
} }

View File

@@ -160,7 +160,7 @@ export const Log: FC<ILog> = ({
)} )}
<Pre>{message}</Pre> <Pre>{message}</Pre>
{link && ( {link && (
<NextLink href={link} shallow passHref> <NextLink legacyBehavior href={link} shallow passHref>
<Link as="a">{linkText}</Link> <Link as="a">{linkText}</Link>
</NextLink> </NextLink>
)} )}

View File

@@ -1,5 +1,5 @@
import React from 'react' import React from 'react'
import Link from 'next/link' import NextLink from 'next/link'
import { useSnapshot } from 'valtio' import { useSnapshot } from 'valtio'
import { useRouter } from 'next/router' import { useRouter } from 'next/router'
@@ -78,7 +78,7 @@ const Navigation = () => {
pr: '$4' pr: '$4'
}} }}
> >
<Link href={gistId ? `/develop/${gistId}` : '/develop'} passHref> <NextLink legacyBehavior href={gistId ? `/develop/${gistId}` : '/develop'} passHref>
<Box <Box
as="a" as="a"
css={{ css={{
@@ -89,7 +89,7 @@ const Navigation = () => {
> >
<Logo width="32px" height="32px" /> <Logo width="32px" height="32px" />
</Box> </Box>
</Link> </NextLink>
<Flex <Flex
css={{ css={{
ml: '$5', ml: '$5',
@@ -105,7 +105,8 @@ const Navigation = () => {
<Text css={{ fontSize: '$xs', color: '$mauve10', lineHeight: 1 }}> <Text css={{ fontSize: '$xs', color: '$mauve10', lineHeight: 1 }}>
{snap.files.length > 0 ? 'Gist: ' : 'Builder'} {snap.files.length > 0 ? 'Gist: ' : 'Builder'}
{snap.files.length > 0 && ( {snap.files.length > 0 && (
<Link <NextLink
legacyBehavior
href={`https://gist.github.com/${snap.gistOwner || ''}/${snap.gistId || ''}`} href={`https://gist.github.com/${snap.gistOwner || ''}/${snap.gistId || ''}`}
passHref passHref
> >
@@ -117,7 +118,7 @@ const Navigation = () => {
> >
{`${snap.gistOwner || '-'}/${truncate(snap.gistId || '')}`} {`${snap.gistOwner || '-'}/${truncate(snap.gistId || '')}`}
</Text> </Text>
</Link> </NextLink>
)} )}
</Text> </Text>
</> </>
@@ -336,29 +337,39 @@ const Navigation = () => {
}} }}
> >
<ButtonGroup> <ButtonGroup>
<Link href={gistId ? `/develop/${gistId}` : '/develop'} passHref shallow> <NextLink
legacyBehavior
href={gistId ? `/develop/${gistId}` : '/develop'}
passHref
shallow
>
<Button as="a" outline={!router.pathname.includes('/develop')} uppercase> <Button as="a" outline={!router.pathname.includes('/develop')} uppercase>
Develop Develop
</Button> </Button>
</Link> </NextLink>
<Link href={gistId ? `/deploy/${gistId}` : '/deploy'} passHref shallow> <NextLink
legacyBehavior
href={gistId ? `/deploy/${gistId}` : '/deploy'}
passHref
shallow
>
<Button as="a" outline={!router.pathname.includes('/deploy')} uppercase> <Button as="a" outline={!router.pathname.includes('/deploy')} uppercase>
Deploy Deploy
</Button> </Button>
</Link> </NextLink>
<Link href={gistId ? `/test/${gistId}` : '/test'} passHref shallow> <NextLink legacyBehavior href={gistId ? `/test/${gistId}` : '/test'} passHref shallow>
<Button as="a" outline={!router.pathname.includes('/test')} uppercase> <Button as="a" outline={!router.pathname.includes('/test')} uppercase>
Test Test
</Button> </Button>
</Link> </NextLink>
</ButtonGroup> </ButtonGroup>
<Link href="https://xrpl-hooks.readme.io/v2.0" passHref> <NextLink legacyBehavior href="https://xrpl-hooks.readme.io/v2.0" passHref>
<a target="_blank" rel="noreferrer noopener"> <a target="_blank" rel="noreferrer noopener">
<Button outline> <Button outline>
<BookOpen size="15px" /> <BookOpen size="15px" />
</Button> </Button>
</a> </a>
</Link> </NextLink>
</Stack> </Stack>
</Flex> </Flex>
</Container> </Container>

View File

@@ -1,7 +1,7 @@
import type { NextRequest, NextFetchEvent } from 'next/server' import type { NextRequest } from 'next/server'
import { NextResponse as Response } from 'next/server' import { NextResponse as Response } from 'next/server'
export default function middleware(req: NextRequest, ev: NextFetchEvent) { export default function middleware(req: NextRequest) {
if (req.nextUrl.pathname === '/') { if (req.nextUrl.pathname === '/') {
const url = req.nextUrl.clone() const url = req.nextUrl.clone()
url.pathname = '/develop' url.pathname = '/develop'

View File

@@ -8,8 +8,16 @@ module.exports = {
config.resolve.alias['vscode'] = require.resolve( config.resolve.alias['vscode'] = require.resolve(
'@codingame/monaco-languageclient/lib/vscode-compatibility' '@codingame/monaco-languageclient/lib/vscode-compatibility'
) )
config.experiments = {
topLevelAwait: true,
layers: true
}
if (!isServer) { if (!isServer) {
config.resolve.fallback.fs = false config.resolve.fallback = {
...config.resolve.fallback,
fs: false,
module: false
}
} }
config.module.rules.push({ config.module.rules.push({
test: [/\.md$/, /hook-bundle\.js$/], test: [/\.md$/, /hook-bundle\.js$/],

View File

@@ -14,6 +14,7 @@
"dependencies": { "dependencies": {
"@codingame/monaco-jsonrpc": "^0.3.1", "@codingame/monaco-jsonrpc": "^0.3.1",
"@codingame/monaco-languageclient": "^0.17.0", "@codingame/monaco-languageclient": "^0.17.0",
"@eqlabs/assemblyscript": "^0.0.0-alpha.1680097351",
"@monaco-editor/react": "^4.4.5", "@monaco-editor/react": "^4.4.5",
"@octokit/core": "^3.5.1", "@octokit/core": "^3.5.1",
"@radix-ui/colors": "^0.1.7", "@radix-ui/colors": "^0.1.7",
@@ -37,7 +38,7 @@
"lodash.uniqby": "^4.7.0", "lodash.uniqby": "^4.7.0",
"lodash.xor": "^4.5.0", "lodash.xor": "^4.5.0",
"monaco-editor": "^0.33.0", "monaco-editor": "^0.33.0",
"next": "^12.0.4", "next": "^13.1.1",
"next-auth": "^4.10.3", "next-auth": "^4.10.3",
"next-plausible": "^3.2.0", "next-plausible": "^3.2.0",
"next-themes": "^0.1.1", "next-themes": "^0.1.1",
@@ -49,8 +50,8 @@
"postinstall-postinstall": "^2.1.0", "postinstall-postinstall": "^2.1.0",
"prettier": "^2.7.1", "prettier": "^2.7.1",
"re-resizable": "^6.9.1", "re-resizable": "^6.9.1",
"react": "17.0.2", "react": "^18.2.0",
"react-dom": "17.0.2", "react-dom": "^18.2.0",
"react-hook-form": "^7.28.0", "react-hook-form": "^7.28.0",
"react-hot-keys": "^2.7.1", "react-hot-keys": "^2.7.1",
"react-hot-toast": "^2.1.1", "react-hot-toast": "^2.1.1",
@@ -65,7 +66,7 @@
"valtio": "^1.2.5", "valtio": "^1.2.5",
"vscode-languageserver": "^7.0.0", "vscode-languageserver": "^7.0.0",
"vscode-uri": "^3.0.2", "vscode-uri": "^3.0.2",
"wabt": "^1.0.30", "wabt": "^1.0.32",
"xrpl-accountlib": "^1.6.1", "xrpl-accountlib": "^1.6.1",
"xrpl-client": "^2.0.2" "xrpl-client": "^2.0.2"
}, },
@@ -78,7 +79,7 @@
"@types/react": "17.0.31", "@types/react": "17.0.31",
"browserify": "^17.0.0", "browserify": "^17.0.0",
"eslint": "7.32.0", "eslint": "7.32.0",
"eslint-config-next": "11.1.2", "eslint-config-next": "^13.1.1",
"raw-loader": "^4.0.2", "raw-loader": "^4.0.2",
"typescript": "4.4.4" "typescript": "4.4.4"
}, },

View File

@@ -24,7 +24,7 @@ import { ChatCircleText } from 'phosphor-react'
TimeAgo.setDefaultLocale(en.locale) TimeAgo.setDefaultLocale(en.locale)
TimeAgo.addLocale(en) TimeAgo.addLocale(en)
function MyApp({ Component, pageProps: { session, ...pageProps } }: AppProps) { function MyApp({ Component, pageProps: { session, ...pageProps } }: AppProps<{ session?: any }>) {
const router = useRouter() const router = useRouter()
const slug = router.query?.slug const slug = router.query?.slug
const gistId = (Array.isArray(slug) && slug[0]) ?? null const gistId = (Array.isArray(slug) && slug[0]) ?? null

View File

@@ -40,7 +40,7 @@ export default async function handler(
} }
return res.status(200).json(json) return res.status(200).json(json)
} catch (err) { } catch (err) {
console.log(err) console.error(err)
return res.status(500).json({ error: 'Server error' }) return res.status(500).json({ error: 'Server error' })
} }
return res.status(500).json({ error: 'Not able to create faucet, try again' }) return res.status(500).json({ error: 'Not able to create faucet, try again' })

View File

@@ -150,7 +150,9 @@ const Home: NextPage = () => {
const activeFile = snap.files[snap.active] as IFile | undefined const activeFile = snap.files[snap.active] as IFile | undefined
const activeFileExt = getFileExtention(activeFile?.name) const activeFileExt = getFileExtention(activeFile?.name)
const canCompile = activeFileExt === 'c' || activeFileExt === 'wat' const canCompile = activeFileExt === 'c' || activeFileExt === 'wat' || activeFileExt === 'ts'
const isCompiling = snap.compiling.includes(snap.active);
return ( return (
<Split <Split
direction="vertical" direction="vertical"
@@ -166,7 +168,9 @@ const Home: NextPage = () => {
{canCompile && ( {canCompile && (
<Hotkeys <Hotkeys
keyName="command+b,ctrl+b" keyName="command+b,ctrl+b"
onKeyDown={() => !snap.compiling && snap.files.length && compileCode(snap.active)} onKeyDown={() =>
snap.compiling === undefined && snap.files.length && compileCode(snap.active)
}
> >
<Flex <Flex
css={{ css={{
@@ -183,7 +187,7 @@ const Home: NextPage = () => {
variant="primary" variant="primary"
uppercase uppercase
disabled={!snap.files.length} disabled={!snap.files.length}
isLoading={snap.compiling} isLoading={isCompiling}
onClick={() => compileCode(snap.active)} onClick={() => compileCode(snap.active)}
> >
<Play weight="bold" size="16px" /> <Play weight="bold" size="16px" />
@@ -200,7 +204,9 @@ const Home: NextPage = () => {
{activeFileExt === 'js' && ( {activeFileExt === 'js' && (
<Hotkeys <Hotkeys
keyName="command+b,ctrl+b" keyName="command+b,ctrl+b"
onKeyDown={() => !snap.compiling && snap.files.length && compileCode(snap.active)} onKeyDown={() =>
!isCompiling && snap.files.length && compileCode(snap.active)
}
> >
<Flex <Flex
css={{ css={{

View File

@@ -1,40 +1,91 @@
import toast from 'react-hot-toast' import toast from 'react-hot-toast'
import Router from 'next/router' import Router from 'next/router'
import state from '../index' import state, { IFile } from '../index'
import { saveFile } from './saveFile' import { saveFile } from './saveFile'
import { decodeBinary } from '../../utils/decodeBinary' import { decodeBinary } from '../../utils/decodeBinary'
import { ref } from 'valtio' import { ref } from 'valtio'
import asc from "@eqlabs/assemblyscript/dist/asc"
import { getFileExtention } from '../../utils/helpers'
/* compileCode sends the code of the active file to compile endpoint type CompilationResult = Pick<IFile, "compiledContent" | "compiledWatContent">
export const compileCode = async (activeId: number) => {
// Save the file to global state
saveFile(false, activeId)
const file = state.files[activeId]
// Bail out if we're already compiling the file.
if (!file || state.compiling.includes(activeId)) {
return
}
try {
state.compiling.push(activeId)
state.logs = []
file.containsErrors = false
let result: CompilationResult;
if (file.name.endsWith('.wat')) {
result = await compileWat(file);
}
else if (file.language === "ts") {
result = await compileTs(file);
}
else if (navigator?.onLine === false) {
throw Error('You seem offline, check you internet connection and try again!')
}
else if (file.language === 'c') {
result = await compileC(file)
}
else throw Error("Unknown file type.")
file.lastCompiled = new Date();
file.compiledValueSnapshot = file.content;
file.compiledContent = result.compiledContent;
file.compiledWatContent = result.compiledWatContent;
toast.success('Compiled successfully!', { position: 'bottom-center' })
state.logs.push({
type: 'success',
message: `File ${state.files?.[activeId]?.name} compiled successfully. Ready to deploy.`,
link: Router.asPath.replace('develop', 'deploy'),
linkText: 'Go to deploy'
})
} catch (err) {
console.error(err)
let message: string;
if (err instanceof Array && typeof err[0] === 'string') {
err.forEach(message => {
state.logs.push({
type: 'error',
message
})
})
message = "Compilation errors occurred, see logs for more info."
} else if (err instanceof Error) {
message = err.message
} else {
message = 'Something went wrong, try again later!'
}
toast.error(message, { position: 'bottom-center' })
file.containsErrors = true
}
state.compiling = state.compiling.filter(id => id !== activeId);
}
/* compileC sends the code of the active file to compile endpoint
* If all goes well you will get base64 encoded wasm file back with * If all goes well you will get base64 encoded wasm file back with
* some extra logging information if we can provide it. This function * some extra logging information if we can provide it. This function
* also decodes the returned wasm and creates human readable WAT file * also decodes the returned wasm and creates human readable WAT file
* out of it and store both in global state. * out of it and store both in global state.
*/ */
export const compileCode = async (activeId: number) => { export const compileC = async (file: IFile): Promise<CompilationResult> => {
// Save the file to global state
saveFile(false, activeId)
const file = state.files[activeId]
if (file.name.endsWith('.wat')) {
return compileWat(activeId)
}
if (!process.env.NEXT_PUBLIC_COMPILE_API_ENDPOINT) { if (!process.env.NEXT_PUBLIC_COMPILE_API_ENDPOINT) {
throw Error('Missing env!') throw Error('Missing C compile endpoint!')
} }
// Bail out if we're already compiling
if (state.compiling) {
// if compiling is ongoing return // TODO Inform user about it.
return
}
// Set loading state to true
state.compiling = true
state.logs = []
try {
file.containsErrors = false
let res: Response let res: Response
try {
res = await fetch(process.env.NEXT_PUBLIC_COMPILE_API_ENDPOINT, { res = await fetch(process.env.NEXT_PUBLIC_COMPILE_API_ENDPOINT, {
method: 'POST', method: 'POST',
headers: { headers: {
@@ -54,11 +105,8 @@ export const compileCode = async (activeId: number) => {
] ]
}) })
}) })
} catch (error) {
throw Error('Something went wrong, check your network connection and try again!')
}
const json = await res.json() const json = await res.json()
state.compiling = false
if (!json.success) { if (!json.success) {
const errors = [json.message] const errors = [json.message]
if (json.tasks && json.tasks.length > 0) { if (json.tasks && json.tasks.length > 0) {
@@ -84,88 +132,87 @@ export const compileCode = async (activeId: number) => {
const wast = myModule.toText({ foldExprs: false, inlineExport: false }) const wast = myModule.toText({ foldExprs: false, inlineExport: false })
file.compiledContent = ref(bufferData) return {
file.lastCompiled = new Date() compiledContent: ref(bufferData),
file.compiledValueSnapshot = file.content compiledWatContent: wast
file.compiledWatContent = wast }
} catch (error) { } catch (error) {
throw Error('Invalid compilation result produced, check your code for errors and try again!') throw Error('Invalid compilation result produced, check your code for errors and try again!')
} }
toast.success('Compiled successfully!', { position: 'bottom-center' })
state.logs.push({
type: 'success',
message: `File ${state.files?.[activeId]?.name} compiled successfully. Ready to deploy.`,
link: Router.asPath.replace('develop', 'deploy'),
linkText: 'Go to deploy'
})
} catch (err) {
console.log(err)
if (err instanceof Array && typeof err[0] === 'string') {
err.forEach(message => {
state.logs.push({
type: 'error',
message
})
})
} else if (err instanceof Error) {
state.logs.push({
type: 'error',
message: err.message
})
} else {
state.logs.push({
type: 'error',
message: 'Something went wrong, come back later!'
})
}
state.compiling = false
toast.error(`Error occurred while compiling!`, { position: 'bottom-center' })
file.containsErrors = true
}
} }
export const compileWat = async (activeId: number) => { export const compileWat = async (file: IFile): Promise<CompilationResult> => {
if (state.compiling) return;
const file = state.files[activeId]
state.compiling = true
state.logs = []
try {
const wabt = await (await import('wabt')).default() const wabt = await (await import('wabt')).default()
const module = wabt.parseWat(file.name, file.content); const mod = wabt.parseWat(file.name, file.content);
module.resolveNames(); mod.resolveNames();
module.validate(); mod.validate();
const { buffer } = module.toBinary({ const { buffer } = mod.toBinary({
log: false, log: false,
write_debug_names: true, write_debug_names: true,
}); });
file.compiledContent = ref(buffer) return {
file.lastCompiled = new Date() compiledContent: ref(buffer),
file.compiledValueSnapshot = file.content compiledWatContent: file.content,
file.compiledWatContent = file.content
toast.success('Compiled successfully!', { position: 'bottom-center' })
state.logs.push({
type: 'success',
message: `File ${state.files?.[activeId]?.name} compiled successfully. Ready to deploy.`,
link: Router.asPath.replace('develop', 'deploy'),
linkText: 'Go to deploy'
})
} catch (err) {
console.log(err)
let message = "Error compiling WAT file!"
if (err instanceof Error) {
message = err.message
} }
state.logs.push({ }
type: 'error',
message export const compileTs = async (file: IFile): Promise<CompilationResult> => {
}) return new Promise(async (resolve, reject) => {
toast.error(`Error occurred while compiling!`, { position: 'bottom-center' }) let result: Partial<CompilationResult> = {}
file.containsErrors = true const { error, stdout, stderr } = await asc.main([
} // Command line options
state.compiling = false file.name,
"--outFile", `${file.name}.wasm`,
"--textFile", `${file.name}.wat`,
"--runtime", "stub",
"--initialMemory", "1",
"--maximumMemory", "1",
"--noExportMemory",
"--optimize",
"--topLevelToHook"
], {
readFile: (name, baseDir) => {
const file = state.files.find(file => file.name === name)
if (file) {
return file.content
}
return null
},
writeFile: async (name, data: ArrayBuffer | string, baseDir) => {
const ext = getFileExtention(name);
if (ext === 'wasm') {
result.compiledContent = data as ArrayBuffer;
}
else if (ext === 'wat') {
result.compiledWatContent = data as string;
}
if (result.compiledContent && result.compiledWatContent) {
resolve({ ...result });
}
},
listFiles: (dirname, baseDir) => {
return state.files.map(file => file.name)
},
// reportDiagnostic?: ...,
});
let logMsg = stdout.toString()
let errMsg = stderr.toString()
if (logMsg) {
state.logs.push({
type: "log",
message: logMsg
})
}
if (errMsg) {
state.logs.push({
type: "error",
message: errMsg
})
}
if (error) return reject(error)
})
} }

View File

@@ -1,8 +1,8 @@
import { getFileExtention } from '../../utils/helpers' import { getFileExtention } from '../../utils/helpers'
import state, { IFile } from '../index' import state, { IFile, ILang } from '../index'
const languageMapping: Record<string, string | undefined> = { const languageMapping: Record<string, ILang | undefined> = {
ts: 'typescript', ts: 'ts',
js: 'javascript', js: 'javascript',
md: 'markdown', md: 'markdown',
c: 'c', c: 'c',

View File

@@ -247,7 +247,7 @@ export const deleteHook = async (account: IAccount & { name?: string }) => {
}) })
} }
} catch (err) { } catch (err) {
console.log(err) console.error(err)
toast.error('Error occurred while deleting hook', { id: toastId }) toast.error('Error occurred while deleting hook', { id: toastId })
state.deployLogs.push({ state.deployLogs.push({
type: 'error', type: 'error',

View File

@@ -1,5 +1,5 @@
import { Octokit } from '@octokit/core' import { Octokit } from '@octokit/core'
import state, { IFile } from '../index' import state, { IFile, ILang } from '../index'
import { templateFileIds } from '../constants' import { templateFileIds } from '../constants'
const octokit = new Octokit() const octokit = new Octokit()
@@ -48,7 +48,7 @@ export const fetchFiles = async (gistId: string) => {
const files: IFile[] = Object.keys(res.data.files).map(filename => ({ const files: IFile[] = Object.keys(res.data.files).map(filename => ({
name: res.data.files?.[filename]?.filename || 'untitled.c', name: res.data.files?.[filename]?.filename || 'untitled.c',
language: res.data.files?.[filename]?.language?.toLowerCase() || '', language: res.data.files?.[filename]?.language?.toLowerCase() as ILang | undefined,
content: res.data.files?.[filename]?.content || '' content: res.data.files?.[filename]?.content || ''
})) }))

View File

@@ -55,7 +55,7 @@ export const syncToGist = async (session?: Session | null, createNewGist?: boole
return toast.success('Updated to gist successfully!', { id: toastId }) return toast.success('Updated to gist successfully!', { id: toastId })
}) })
.catch(err => { .catch(err => {
console.log(err) console.error(err)
state.gistLoading = false state.gistLoading = false
return toast.error(`Could not update Gist, try again later!`, { return toast.error(`Could not update Gist, try again later!`, {
id: toastId id: toastId
@@ -85,7 +85,7 @@ export const syncToGist = async (session?: Session | null, createNewGist?: boole
return toast.success('Created new gist successfully!', { id: toastId }) return toast.success('Created new gist successfully!', { id: toastId })
}) })
.catch(err => { .catch(err => {
console.log(err) console.error(err)
state.gistLoading = false state.gistLoading = false
return toast.error(`Could not create Gist, try again later!`, { return toast.error(`Could not create Gist, try again later!`, {
id: toastId id: toastId

View File

@@ -9,9 +9,10 @@ declare module 'valtio' {
function snapshot<T extends object>(p: T): T function snapshot<T extends object>(p: T): T
} }
export type ILang = "ts" | "javascript" | "markdown" | "c" | "text"
export interface IFile { export interface IFile {
name: string name: string
language: string language: ILang | undefined
content: string content: string
compiledValueSnapshot?: string compiledValueSnapshot?: string
compiledContent?: ArrayBuffer | null compiledContent?: ArrayBuffer | null
@@ -66,7 +67,7 @@ export interface IState {
loading: boolean loading: boolean
gistLoading: boolean gistLoading: boolean
zipLoading: boolean zipLoading: boolean
compiling: boolean compiling: /* file id */ number[]
logs: ILog[] logs: ILog[]
deployLogs: ILog[] deployLogs: ILog[]
transactionLogs: ILog[] transactionLogs: ILog[]
@@ -98,7 +99,7 @@ let initialState: IState = {
// Active file index on the Deploy page editor // Active file index on the Deploy page editor
activeWat: 0, activeWat: 0,
loading: false, loading: false,
compiling: false, compiling: [],
logs: [], logs: [],
deployLogs: [], deployLogs: [],
transactionLogs: [], transactionLogs: [],
@@ -135,7 +136,7 @@ if (typeof window !== 'undefined') {
try { try {
localStorageAccounts = localStorage.getItem('hooksIdeAccounts') localStorageAccounts = localStorage.getItem('hooksIdeAccounts')
} catch (err) { } catch (err) {
console.log(`localStorage state broken`) console.error(`localStorage state broken`)
localStorage.removeItem('hooksIdeAccounts') localStorage.removeItem('hooksIdeAccounts')
} }
if (localStorageAccounts) { if (localStorageAccounts) {

View File

@@ -20,6 +20,12 @@ export const getFileExtention = (filename?: string): string | undefined => {
return ext return ext
} }
export const getFileNamePart = (filename?: string): string | undefined => {
if (!filename) return
const name = (filename.includes('.') && filename.split('.').slice(0, -1).join(".")) || filename
return name
}
type Type = "array" | "undefined" | "object" | "string" | "number" | "bigint" | "boolean" | "symbol" | "function" type Type = "array" | "undefined" | "object" | "string" | "number" | "bigint" | "boolean" | "symbol" | "function"
type obj = Record<string | number | symbol, unknown> type obj = Record<string | number | symbol, unknown>
type arr = unknown[] type arr = unknown[]

1374
yarn.lock

File diff suppressed because it is too large Load Diff