Files
xrpl-hooks-ide/state/index.ts
Valtteri Karesto 6fa68b9d6b Update state type
2022-08-17 21:06:07 +03:00

191 lines
4.5 KiB
TypeScript

import type monaco from 'monaco-editor'
import { proxy, ref, subscribe } from 'valtio'
import { devtools, subscribeKey } from 'valtio/utils'
import { XrplClient } from 'xrpl-client'
import { SplitSize } from './actions/persistSplits'
declare module 'valtio' {
function useSnapshot<T extends object>(p: T): T
function snapshot<T extends object>(p: T): T
}
export interface IFile {
name: string
language: string
content: string
compiledValueSnapshot?: string
compiledContent?: ArrayBuffer | Uint8Array | null
compiledWatContent?: string | null
lastCompiled?: Date
containsErrors?: boolean
}
export interface FaucetAccountRes {
address: string
secret: string
xrp: number
hash: string
code: string
}
export interface IAccount {
name: string
address: string
secret: string
xrp: string
sequence: number
hooks: string[]
isLoading: boolean
version?: string
error?: {
message: string
code: string
} | null
}
export interface ILog {
type: 'error' | 'warning' | 'log' | 'success'
message: string | JSX.Element
key?: string
jsonData?: any
timestring?: string
link?: string
linkText?: string
defaultCollapsed?: boolean
}
export type DeployValue = Record<IFile['name'], any>
export interface IState {
files: IFile[]
gistId?: string | null
gistOwner?: string | null
gistName?: string | null
active: number
activeWat: number
loading: boolean
gistLoading: boolean
zipLoading: boolean
compiling: boolean
logs: ILog[]
deployLogs: ILog[]
transactionLogs: ILog[]
scriptLogs: ILog[]
editorCtx?: typeof monaco.editor
editorSettings: {
tabSize: number
}
splits: {
[id: string]: SplitSize
}
client: XrplClient | null
clientStatus: 'offline' | 'online'
mainModalOpen: boolean
mainModalShowed: boolean
accounts: IAccount[]
compileOptions: {
optimizationLevel: '-O0' | '-O1' | '-O2' | '-O3' | '-O4' | '-Os'
strip: boolean
}
deployValues: DeployValue
}
// let localStorageState: null | string = null;
let initialState: IState = {
files: [],
// active file index on the Develop page editor
active: 0,
// Active file index on the Deploy page editor
activeWat: 0,
loading: false,
compiling: false,
logs: [],
deployLogs: [],
transactionLogs: [],
scriptLogs: [],
editorCtx: undefined,
gistId: undefined,
gistOwner: undefined,
gistName: undefined,
gistLoading: false,
zipLoading: false,
editorSettings: {
tabSize: 2
},
splits: {},
client: null,
clientStatus: 'offline' as 'offline',
mainModalOpen: false,
mainModalShowed: false,
accounts: [],
compileOptions: {
optimizationLevel: '-O2',
strip: true
},
deployValues: {}
}
let localStorageAccounts: string | null = null
let initialAccounts: IAccount[] = []
// TODO: What exactly should we store in localStorage? editorSettings, splits, accounts?
// Check if there's a persited accounts in localStorage
if (typeof window !== 'undefined') {
try {
localStorageAccounts = localStorage.getItem('hooksIdeAccounts')
} catch (err) {
console.log(`localStorage state broken`)
localStorage.removeItem('hooksIdeAccounts')
}
if (localStorageAccounts) {
initialAccounts = JSON.parse(localStorageAccounts)
}
// filter out old accounts (they do not have version property at all)
// initialAccounts = initialAccounts.filter(acc => acc.version === '2');
}
// Initialize state
const state = proxy<IState>({
...initialState,
accounts: initialAccounts.length > 0 ? initialAccounts : [],
logs: []
})
// Initialize socket connection
const client = new XrplClient(`wss://${process.env.NEXT_PUBLIC_TESTNET_URL}`)
client.on('online', () => {
state.client = ref(client)
state.clientStatus = 'online'
})
client.on('offline', () => {
state.clientStatus = 'offline'
})
if (process.env.NODE_ENV !== 'production') {
devtools(state, 'Files State')
}
if (typeof window !== 'undefined') {
subscribe(state.accounts, () => {
const { accounts } = state
const accountsNoLoading = accounts.map(acc => ({ ...acc, isLoading: false }))
localStorage.setItem('hooksIdeAccounts', JSON.stringify(accountsNoLoading))
})
const updateActiveWat = () => {
const filename = state.files[state.active]?.name
const compiledFiles = state.files.filter(file => file.compiledContent)
const idx = compiledFiles.findIndex(file => file.name === filename)
if (idx !== -1) state.activeWat = idx
}
subscribeKey(state, 'active', updateActiveWat)
subscribeKey(state, 'files', updateActiveWat)
}
export default state
export * from './transactions'