Improve: replace recoil with jotai to reduce bundle

This commit is contained in:
Dreamacro 2021-06-24 00:02:18 +08:00
parent 56fa045ec7
commit 1c9b0669a9
16 changed files with 279 additions and 295 deletions

View File

@ -26,29 +26,29 @@
}, },
"devDependencies": { "devDependencies": {
"@types/lodash-es": "^4.17.4", "@types/lodash-es": "^4.17.4",
"@types/node": "^15.12.2", "@types/node": "^15.12.4",
"@types/react": "^17.0.11", "@types/react": "^17.0.11",
"@types/react-dom": "^17.0.7", "@types/react-dom": "^17.0.8",
"@types/react-router-dom": "^5.1.7", "@types/react-router-dom": "^5.1.7",
"@types/react-table": "^7.7.1", "@types/react-table": "^7.7.1",
"@types/react-virtualized-auto-sizer": "^1.0.0", "@types/react-virtualized-auto-sizer": "^1.0.0",
"@types/react-window": "^1.8.3", "@types/react-window": "^1.8.3",
"@typescript-eslint/eslint-plugin": "^4.26.1", "@typescript-eslint/eslint-plugin": "^4.28.0",
"@typescript-eslint/parser": "^4.26.1", "@typescript-eslint/parser": "^4.28.0",
"@vitejs/plugin-react-refresh": "^1.3.3", "@vitejs/plugin-react-refresh": "^1.3.3",
"babel-eslint": "^10.1.0", "babel-eslint": "^10.1.0",
"eslint": "^7.28.0", "eslint": "^7.29.0",
"eslint-config-react-app": "^6.0.0", "eslint-config-react-app": "^6.0.0",
"eslint-plugin-flowtype": "^5.7.2", "eslint-plugin-flowtype": "^5.7.2",
"eslint-plugin-import": "^2.23.4", "eslint-plugin-import": "^2.23.4",
"eslint-plugin-jsx-a11y": "^6.4.1", "eslint-plugin-jsx-a11y": "^6.4.1",
"eslint-plugin-react": "^7.24.0", "eslint-plugin-react": "^7.24.0",
"eslint-plugin-react-hooks": "^4.2.0", "eslint-plugin-react-hooks": "^4.2.0",
"sass": "^1.34.1", "sass": "^1.35.1",
"type-fest": "^1.2.0", "type-fest": "^1.2.1",
"typescript": "^4.3.2", "typescript": "^4.3.4",
"vite": "2.3.5", "vite": "^2.3.8",
"vite-plugin-windicss": "^1.0.3", "vite-plugin-windicss": "^1.1.1",
"vite-tsconfig-paths": "^3.3.13", "vite-tsconfig-paths": "^3.3.13",
"windicss": "^3.1.3" "windicss": "^3.1.3"
}, },
@ -58,7 +58,9 @@
"dayjs": "^1.10.5", "dayjs": "^1.10.5",
"eventemitter3": "^4.0.7", "eventemitter3": "^4.0.7",
"immer": "^9.0.3", "immer": "^9.0.3",
"jotai": "^1.0.0",
"lodash-es": "^4.17.21", "lodash-es": "^4.17.21",
"neverthrow": "^4.2.1",
"react": "^17.0.2", "react": "^17.0.2",
"react-dom": "^17.0.2", "react-dom": "^17.0.2",
"react-router-dom": "^5.2.0", "react-router-dom": "^5.2.0",
@ -66,7 +68,6 @@
"react-use": "^17.2.4", "react-use": "^17.2.4",
"react-virtualized-auto-sizer": "^1.0.5", "react-virtualized-auto-sizer": "^1.0.5",
"react-window": "^1.8.6", "react-window": "^1.8.6",
"recoil": "^0.3.1",
"swr": "^0.5.6", "swr": "^0.5.6",
"use-immer": "^0.5.2" "use-immer": "^0.5.2"
} }

View File

@ -42,7 +42,7 @@ export default function Logs () {
return ( return (
<div className="page"> <div className="page">
<Header title={ t('title') } /> <Header title={ t('title') } />
<Card className="flex flex-col flex-1 mt-3"> <Card className="flex flex-col flex-1 mt-2.5 md:mt-4">
<ul className="logs-panel" ref={listRef}> <ul className="logs-panel" ref={listRef}>
{ {
logs.map( logs.map(

View File

@ -1,5 +1,5 @@
import React, { useMemo } from 'react' import React, { useMemo } from 'react'
import { useRecoilValue } from 'recoil' import { useAtom } from 'jotai'
import { useProxy, useConfig, proxyMapping } from '@stores' import { useProxy, useConfig, proxyMapping } from '@stores'
import { changeProxySelected, Group as IGroup, getConnections, closeConnection } from '@lib/request' import { changeProxySelected, Group as IGroup, getConnections, closeConnection } from '@lib/request'
import { Tags, Tag } from '@components' import { Tags, Tag } from '@components'
@ -11,7 +11,7 @@ interface GroupProps {
export function Group (props: GroupProps) { export function Group (props: GroupProps) {
const { markProxySelected } = useProxy() const { markProxySelected } = useProxy()
const proxyMap = useRecoilValue(proxyMapping) const [proxyMap] = useAtom(proxyMapping)
const { data: Config } = useConfig() const { data: Config } = useConfig()
const { config } = props const { config } = props

View File

@ -1,11 +1,13 @@
import React, { useMemo, useLayoutEffect, useCallback } from 'react' import React, { useMemo, useLayoutEffect, useCallback } from 'react'
import { ResultAsync } from 'neverthrow'
import type{ AxiosError } from 'axios'
import classnames from 'classnames' import classnames from 'classnames'
import { BaseComponentProps } from '@models' import { BaseComponentProps } from '@models'
import { useProxy } from '@stores' import { useProxy } from '@stores'
import { getProxyDelay, Proxy as IProxy } from '@lib/request' import { getProxyDelay, Proxy as IProxy } from '@lib/request'
import EE, { Action } from '@lib/event' import EE, { Action } from '@lib/event'
import { isClashX, jsBridge } from '@lib/jsBridge' import { isClashX, jsBridge } from '@lib/jsBridge'
import { to } from '@lib/helper'
import './style.scss' import './style.scss'
interface ProxyProps extends BaseComponentProps { interface ProxyProps extends BaseComponentProps {
@ -34,9 +36,9 @@ export function Proxy (props: ProxyProps) {
const { set } = useProxy() const { set } = useProxy()
const speedTest = useCallback(async function () { const speedTest = useCallback(async function () {
const [delay, err] = await to(getDelay(config.name)) const result = await ResultAsync.fromPromise(getDelay(config.name), e => e as AxiosError)
const validDelay = err ? 0 : delay const validDelay = result.isErr() ? 0 : result.value
set(draft => { set(draft => {
const proxy = draft.proxies.find(p => p.name === config.name) const proxy = draft.proxies.find(p => p.name === config.name)
if (proxy) { if (proxy) {

View File

@ -41,7 +41,7 @@ function ProxyGroups () {
return <> return <>
{ {
list.length !== 0 && list.length !== 0 &&
<div className="proxies-container"> <div className="flex flex-col">
<Header title={t('groupTitle')}> <Header title={t('groupTitle')}>
<Checkbox <Checkbox
className="text-primary-600 text-sm text-shadow-primary cursor-pointer" className="text-primary-600 text-sm text-shadow-primary cursor-pointer"
@ -50,7 +50,7 @@ function ProxyGroups () {
{t('breakConnectionsText')} {t('breakConnectionsText')}
</Checkbox> </Checkbox>
</Header> </Header>
<Card className="my-3 md:my-5 p-0"> <Card className="my-2.5 md:my-4 p-0">
<ul className="list-none"> <ul className="list-none">
{ {
list.map(p => ( list.map(p => (
@ -74,12 +74,12 @@ function ProxyProviders () {
return <> return <>
{ {
providers.length !== 0 && providers.length !== 0 &&
<div className="proxies-container"> <div className="flex flex-col">
<Header title={t('providerTitle')} /> <Header title={t('providerTitle')} />
<ul className="list-none"> <ul className="list-none">
{ {
providers.map(p => ( providers.map(p => (
<li className="my-5" key={p.name}> <li className="my-2.5 md:my-4" key={p.name}>
<Provider provider={p} /> <Provider provider={p} />
</li> </li>
)) ))
@ -117,7 +117,7 @@ function Proxies () {
return <> return <>
{ {
sortedProxies.length !== 0 && sortedProxies.length !== 0 &&
<div className="proxies-container"> <div className="flex flex-col">
<Header title={t('title')}> <Header title={t('title')}>
<Icon className="ml-3" type={sortMap[sort]} onClick={handleSort} size={20} /> <Icon className="ml-3" type={sortMap[sort]} onClick={handleSort} size={20} />
<Icon className="ml-3" type="speed" size={20} /> <Icon className="ml-3" type="speed" size={20} />

View File

@ -15,7 +15,7 @@ function RuleProviders () {
return <> return <>
{ {
providers.length !== 0 && providers.length !== 0 &&
<div className="proxies-container"> <div className="flex flex-col">
<Header title={t('providerTitle')} /> <Header title={t('providerTitle')} />
<ul className="proxies-providers-list"> <ul className="proxies-providers-list">
{ {
@ -55,7 +55,7 @@ export default function Rules () {
<div className="page"> <div className="page">
<RuleProviders /> <RuleProviders />
<Header title={t('title')} /> <Header title={t('title')} />
<Card className="flex flex-col flex-1 mt-3 p-0 focus:outline-none"> <Card className="flex flex-col flex-1 mt-2.5 md:mt-4 p-0 focus:outline-none">
<AutoSizer className="rules"> <AutoSizer className="rules">
{ {
({ height, width }) => ( ({ height, width }) => (

View File

@ -1,7 +1,7 @@
import React, { useEffect, useMemo } from 'react' import React, { useEffect, useMemo } from 'react'
import classnames from 'classnames' import classnames from 'classnames'
import { capitalize } from 'lodash-es' import { capitalize } from 'lodash-es'
import { Header, Card, Switch, ButtonSelect, ButtonSelectOptions, Input, Icon } from '@components' import { Header, Card, Switch, ButtonSelect, ButtonSelectOptions, Input } from '@components'
import { useI18n, useClashXData, useAPIInfo, useGeneral, useIdentity, useVersion } from '@stores' import { useI18n, useClashXData, useAPIInfo, useGeneral, useIdentity, useVersion } from '@stores'
import { updateConfig } from '@lib/request' import { updateConfig } from '@lib/request'
import { useObject } from '@lib/hook' import { useObject } from '@lib/hook'

View File

@ -16,19 +16,6 @@ export function getSearchParam(key: string) {
return new URLSearchParams(window.location.search).get(key) return new URLSearchParams(window.location.search).get(key)
} }
/**
* to return Promise<[T, Error]>
* @param {Promise<T>} promise
*/
export async function to <T, E = Error> (promise: Promise<T>): Promise<[T, E]> {
try {
const ret = await promise
return [ret, null as unknown as E]
} catch (e) {
return [null as unknown as T, e]
}
}
export function partition<T> (arr: T[], fn: (arg: T) => boolean): [T[], T[]] { export function partition<T> (arr: T[], fn: (arg: T) => boolean): [T[], T[]] {
const left: T[] = [] const left: T[] = []
const right: T[] = [] const right: T[] = []

View File

@ -1,27 +1,25 @@
/* eslint-disable no-redeclare */
import { useRecoilState, RecoilState } from 'recoil'
import produce, { Draft } from 'immer' import produce, { Draft } from 'immer'
import { useMemo } from 'react' import { useMemo } from 'react'
export function useRecoilObjectWithImmer<T> (value: RecoilState<T>) { type WritableDraft<T> = (draft: Draft<T>) => void
const [copy, rawSet] = useRecoilState(value)
export function useWarpImmerSetter<T> (setter: (f: WritableDraft<T>) => void) {
const set = useMemo(() => { const set = useMemo(() => {
function set<K extends keyof Draft<T>> (key: K, value: Draft<T>[K]): void function set<K extends keyof Draft<T>> (key: K, value: Draft<T>[K]): void
function set (data: Partial<T>): void function set (data: Partial<T>): void
function set (f: (draft: Draft<T>) => void | T): void function set (f: (draft: Draft<T>) => void | T): void
function set<K extends keyof Draft<T>> (data: any, value?: Draft<T>[K]): void { function set<K extends keyof Draft<T>> (data: any, value?: Draft<T>[K]): void {
if (typeof data === 'string') { if (typeof data === 'string') {
rawSet(pre => produce(pre, (draft: Draft<T>) => { setter((draft: Draft<T>) => {
const key = data as K const key = data as K
const v = value const v = value
draft[key] = v! draft[key] = v!
})) })
} else if (typeof data === 'function') { } else if (typeof data === 'function') {
const fn = data as (draft: Draft<T>) => void | T const fn = data as (draft: Draft<T>) => void | T
rawSet(pre => produce(pre, fn) as T) setter(draft => fn(draft))
} else if (typeof data === 'object') { } else if (typeof data === 'object') {
rawSet(pre => produce(pre, (draft: Draft<T>) => { setter(pre => produce(pre, (draft: Draft<T>) => {
const obj = data as Draft<T> const obj = data as Draft<T>
for (const key of Object.keys(obj)) { for (const key of Object.keys(obj)) {
const k = key as keyof Draft<T> const k = key as keyof Draft<T>
@ -32,7 +30,7 @@ export function useRecoilObjectWithImmer<T> (value: RecoilState<T>) {
} }
return set return set
}, [rawSet]) }, [setter])
return [copy, set] as [T, typeof set] return set
} }

View File

@ -1,4 +1,5 @@
import axios from 'axios' import axios, { AxiosError } from 'axios'
import { ResultAsync } from 'neverthrow'
import { getLocalStorageItem, getSearchParam, to } from '@lib/helper' import { getLocalStorageItem, getSearchParam, to } from '@lib/helper'
import { isClashX, jsBridge } from '@lib/jsBridge' import { isClashX, jsBridge } from '@lib/jsBridge'
import { createAsyncSingleton } from '@lib/asyncSingleton' import { createAsyncSingleton } from '@lib/asyncSingleton'
@ -250,8 +251,8 @@ export async function changeProxySelected (name: string, select: string) {
export const getLogsStreamReader = createAsyncSingleton(async function () { export const getLogsStreamReader = createAsyncSingleton(async function () {
const externalController = await getExternalControllerConfig() const externalController = await getExternalControllerConfig()
const { data: config } = await getConfig() const { data: config } = await getConfig()
const [data, err] = await to(getVersion()) const result = await ResultAsync.fromPromise(getVersion(), err => err as AxiosError)
const version = err ? 'unkonwn version' : data.data.version const version = result.isErr() ? 'unkonwn version' : result.value.data.version
const useWebsocket = !!version || true const useWebsocket = !!version || true
const logUrl = `${externalController.protocol}//${externalController.hostname}:${externalController.port}/logs?level=${config['log-level']}` const logUrl = `${externalController.protocol}//${externalController.hostname}:${externalController.port}/logs?level=${config['log-level']}`
@ -260,8 +261,8 @@ export const getLogsStreamReader = createAsyncSingleton(async function () {
export const getConnectionStreamReader = createAsyncSingleton(async function () { export const getConnectionStreamReader = createAsyncSingleton(async function () {
const externalController = await getExternalControllerConfig() const externalController = await getExternalControllerConfig()
const [data, err] = await to(getVersion()) const result = await ResultAsync.fromPromise(getVersion(), err => err as AxiosError)
const version = err ? 'unkonwn version' : data.data.version const version = result.isErr() ? 'unkonwn version' : result.value.data.version
const useWebsocket = !!version || true const useWebsocket = !!version || true
const logUrl = `${externalController.protocol}//${externalController.hostname}:${externalController.port}/connections` const logUrl = `${externalController.protocol}//${externalController.hostname}:${externalController.port}/connections`

View File

@ -1,5 +1,6 @@
import EventEmitter from 'eventemitter3' import EventEmitter from 'eventemitter3'
import { SetRequired } from 'type-fest' import { SetRequired } from 'type-fest'
import { ResultAsync } from 'neverthrow'
import { to } from '@lib/helper' import { to } from '@lib/helper'
export interface Config { export interface Config {
@ -56,32 +57,35 @@ export class StreamReader<T> {
} }
protected async loop () { protected async loop () {
const [resp, err] = await to(fetch( const result = await ResultAsync.fromPromise(fetch(
this.config.url, this.config.url,
{ {
mode: 'cors', mode: 'cors',
headers: this.config.token ? { Authorization: `Bearer ${this.config.token}` } : {} headers: this.config.token ? { Authorization: `Bearer ${this.config.token}` } : {}
} }
)) ), e => e as Error)
if (err || !resp.body) { if (result.isErr()) {
this.retry(err) this.retry(result.error)
return
} else if (!result.value.body) {
this.retry(new Error('fetch body error'))
return return
} }
const reader = resp.body.getReader() const reader = result.value.body.getReader()
const decoder = new TextDecoder() const decoder = new TextDecoder()
while (true) { while (true) {
if (this.isClose) { if (this.isClose) {
break break
} }
const [{ value }, err] = await to(reader?.read()) const result = await ResultAsync.fromPromise(reader?.read(), e => e as Error)
if (err) { if (result.isErr()) {
this.retry(err) this.retry(result.error)
break break
} }
const lines = decoder.decode(value).trim().split('\n') const lines = decoder.decode(result.value.value).trim().split('\n')
const data = lines.map(l => JSON.parse(l)) const data = lines.map(l => JSON.parse(l))
this.EE.emit('data', data) this.EE.emit('data', data)
if (this.config.bufferLength! > 0) { if (this.config.bufferLength! > 0) {

View File

@ -1,18 +1,15 @@
import React from 'react' import React from 'react'
import { render } from 'react-dom' import { render } from 'react-dom'
import { HashRouter } from 'react-router-dom' import { HashRouter } from 'react-router-dom'
import { RecoilRoot } from 'recoil'
import App from '@containers/App' import App from '@containers/App'
import 'virtual:windi.css' import 'virtual:windi.css'
export default function renderApp () { export default function renderApp () {
const rootEl = document.getElementById('root') const rootEl = document.getElementById('root')
const AppInstance = ( const AppInstance = (
<RecoilRoot> <HashRouter>
<HashRouter> <App />
<App /> </HashRouter>
</HashRouter>
</RecoilRoot>
) )
render(AppInstance, rootEl) render(AppInstance, rootEl)

View File

@ -1 +1 @@
export * from './recoil' export * from './jotai'

View File

@ -1,49 +1,47 @@
import { atom, useRecoilState, selector } from 'recoil' import { ResultAsync } from 'neverthrow'
import { get } from 'lodash-es'
import { useCallback, useEffect } from 'react'
import { AxiosError } from 'axios' import { AxiosError } from 'axios'
import swr from 'swr' import { atom, useAtom } from 'jotai'
import { atomWithImmer } from 'jotai/immer'
import { useCallback, useEffect } from 'react'
import { get } from 'lodash-es'
import useSWR from 'swr'
import { getLanguage, setLanguage, Lang, locales, Language } from '@i18n' import { getLanguage, Language, setLanguage, locales, Lang } from '@i18n'
import { useRecoilObjectWithImmer } from '@lib/recoil' import { useWarpImmerSetter } from '@lib/jotai'
import * as API from '@lib/request' import * as API from '@lib/request'
import { setLocalStorageItem, partition, to } from '@lib/helper'
import { jsBridge, isClashX } from '@lib/jsBridge'
import * as Models from '@models' import * as Models from '@models'
import { partition, setLocalStorageItem } from '@lib/helper'
import { isClashX, jsBridge } from '@lib/jsBridge'
const identity = atom({ const identity = atom(true)
key: 'identity',
default: true
})
type AsyncFunction<A, O> = (...args: A[]) => Promise<O> type AsyncFunction<A, O> = (...args: A[]) => Promise<O>
export function useIdentity () { export function useIdentity () {
const [id, set] = useRecoilState(identity) const [id, set] = useAtom(identity)
function wrapFetcher<A, O> (fn: AsyncFunction<A, O>) { function wrapFetcher<A, O> (fn: AsyncFunction<A, O>) {
return async function (...args: A[]) { return async function (...args: A[]) {
const [resp, err] = await to(fn(...args)) const result = await ResultAsync.fromPromise(fn(...args), e => e as AxiosError)
const rErr = err as AxiosError if (result.isErr()) {
if (rErr && (!rErr.response || rErr.response.status === 401)) { if (result.error.response?.status === 401) {
set(false) set(false)
throw err }
throw result.error
} }
set(true) set(true)
return resp return result.value
} }
} }
return { identity: id, wrapFetcher, set } return { identity: id, wrapFetcher, set }
} }
const language = atom({ const language = atom(getLanguage())
key: 'i18n',
default: getLanguage()
})
export function useI18n () { export function useI18n () {
const [lang, set] = useRecoilState(language) const [lang, set] = useAtom(language)
function setLang (lang: Lang) { function setLang (lang: Lang) {
set(lang) set(lang)
@ -64,69 +62,32 @@ export function useI18n () {
} }
export const version = atom({ export const version = atom({
key: 'version', version: '',
default: { premium: false
version: '',
premium: false
}
}) })
export function useVersion () { export function useVersion () {
const [data, set] = useRecoilState(version) const [data, set] = useAtom(version)
const { set: setIdentity } = useIdentity() const { set: setIdentity } = useIdentity()
async function update () { async function update () {
const [resp, err] = await to(API.getVersion()) const result = await ResultAsync.fromPromise(API.getVersion(), e => e as AxiosError)
setIdentity(!err) setIdentity(result.isOk())
set( set(
err result.isErr()
? { version: '', premium: false } ? { version: '', premium: false }
: { version: resp.data.version, premium: !!resp.data.premium } : { version: result.value.data.version, premium: !!result.value.data.premium }
) )
} }
return { version: data.version, premium: data.premium, update } return { version: data.version, premium: data.premium, update }
} }
export const config = atom({
key: 'config',
default: {
breakConnections: false
}
})
export function useConfig () {
const [data, set] = useRecoilObjectWithImmer(config)
return { data, set }
}
export const proxyProvider = atom({
key: 'proxyProvider',
default: [] as API.Provider[]
})
export function useProxyProviders () {
const [providers, set] = useRecoilState(proxyProvider)
const { data, mutate } = swr('/providers/proxy', async () => {
const proxyProviders = await API.getProxyProviders()
return Object.keys(proxyProviders.data.providers)
.map<API.Provider>(name => proxyProviders.data.providers[name])
.filter(pd => pd.name !== 'default')
.filter(pd => pd.vehicleType !== 'Compatible')
})
useEffect(() => set(data ?? []), [data, set])
return { providers, update: mutate }
}
export function useRuleProviders () { export function useRuleProviders () {
const [{ premium }] = useRecoilState(version) const [{ premium }] = useAtom(version)
const { data, mutate } = swr('/providers/rule', async () => { const { data, mutate } = useSWR('/providers/rule', async () => {
if (!premium) { if (!premium) {
return [] return []
} }
@ -140,8 +101,36 @@ export function useRuleProviders () {
return { providers: data ?? [], update: mutate } return { providers: data ?? [], update: mutate }
} }
export const config = atomWithImmer({
breakConnections: false
})
export function useConfig () {
const [data, set] = useAtom(config)
return { data, set: useWarpImmerSetter(set) }
}
export const proxyProvider = atom([] as API.Provider[])
export function useProxyProviders () {
const [providers, set] = useAtom(proxyProvider)
const { data, mutate } = useSWR('/providers/proxy', async () => {
const proxyProviders = await API.getProxyProviders()
return Object.keys(proxyProviders.data.providers)
.map<API.Provider>(name => proxyProviders.data.providers[name])
.filter(pd => pd.name !== 'default')
.filter(pd => pd.vehicleType !== 'Compatible')
})
useEffect(() => set(data ?? []), [data, set])
return { providers, update: mutate }
}
export function useGeneral () { export function useGeneral () {
const { data, mutate } = swr('/config', async () => { const { data, mutate } = useSWR('/config', async () => {
const resp = await API.getConfig() const resp = await API.getConfig()
const data = resp.data const data = resp.data
return { return {
@ -158,25 +147,23 @@ export function useGeneral () {
return { general: data ?? {} as Models.Data['general'], update: mutate } return { general: data ?? {} as Models.Data['general'], update: mutate }
} }
export const proxies = atom({ export const proxies = atomWithImmer({
key: 'proxies', proxies: [] as API.Proxy[],
default: { groups: [] as API.Group[],
proxies: [] as API.Proxy[], global: {
groups: [] as API.Group[], name: 'GLOBAL',
global: { type: 'Selector',
name: 'GLOBAL', now: '',
type: 'Selector', history: [],
now: '', all: []
history: [], } as API.Group
all: []
} as API.Group
}
}) })
export function useProxy () { export function useProxy () {
const [allProxy, set] = useRecoilObjectWithImmer(proxies) const [allProxy, rawSet] = useAtom(proxies)
const set = useWarpImmerSetter(rawSet)
const { mutate } = swr('/proxies', async () => { const { mutate } = useSWR('/proxies', async () => {
const allProxies = await API.getProxies() const allProxies = await API.getProxies()
const global = allProxies.data.proxies.GLOBAL as API.Group const global = allProxies.data.proxies.GLOBAL as API.Group
@ -215,28 +202,25 @@ export function useProxy () {
} }
} }
export const proxyMapping = selector({ export const proxyMapping = atom((get) => {
key: 'proxyMapping', const ps = get(proxies)
get: ({ get }) => { const providers = get(proxyProvider)
const ps = get(proxies) const proxyMap = new Map<string, API.Proxy>()
const providers = get(proxyProvider) for (const p of ps.proxies) {
const proxyMap = new Map<string, API.Proxy>() proxyMap.set(p.name, p as API.Proxy)
for (const p of ps.proxies) { }
for (const provider of providers) {
for (const p of provider.proxies) {
proxyMap.set(p.name, p as API.Proxy) proxyMap.set(p.name, p as API.Proxy)
} }
for (const provider of providers) {
for (const p of provider.proxies) {
proxyMap.set(p.name, p as API.Proxy)
}
}
return proxyMap
} }
return proxyMap
}) })
export function useClashXData () { export function useClashXData () {
const { data, mutate } = swr('/clashx', async () => { const { data, mutate } = useSWR('/clashx', async () => {
if (!isClashX()) { if (!isClashX()) {
return { return {
isClashX: false, isClashX: false,
@ -255,16 +239,13 @@ export function useClashXData () {
} }
export const apiData = atom({ export const apiData = atom({
key: 'apiData', hostname: '127.0.0.1',
default: { port: '9090',
hostname: '127.0.0.1', secret: ''
port: '9090',
secret: ''
}
}) })
export function useAPIInfo () { export function useAPIInfo () {
const [data, set] = useRecoilState(apiData) const [data, set] = useAtom(apiData)
const fetch = useCallback(async function fetch () { const fetch = useCallback(async function fetch () {
const info = await API.getExternalControllerConfig() const info = await API.getExternalControllerConfig()
@ -282,13 +263,11 @@ export function useAPIInfo () {
return { data, fetch, update } return { data, fetch, update }
} }
export const rules = atom({ export const rules = atomWithImmer([] as API.Rule[])
key: 'rules',
default: [] as API.Rule[]
})
export function useRule () { export function useRule () {
const [data, set] = useRecoilObjectWithImmer(rules) const [data, rawSet] = useAtom(rules)
const set = useWarpImmerSetter(rawSet)
async function update () { async function update () {
const resp = await API.getRules() const resp = await API.getRules()
@ -297,3 +276,4 @@ export function useRule () {
return { rules: data, update } return { rules: data, update }
} }

View File

@ -7,7 +7,17 @@ export default defineConfig({
plugins: [ plugins: [
reactRefresh(), reactRefresh(),
tsConfigPath(), tsConfigPath(),
windiCSS() windiCSS(),
// https://github.com/vitejs/vite/issues/2144
{
name: 'remove-css-in-js',
enforce: 'post',
transform(_, id) {
if (id.endsWith('.scss') || id.endsWith('.css')) {
return ''
}
},
}
], ],
base: './', base: './',
css: { css: {

226
yarn.lock
View File

@ -2,10 +2,12 @@
# yarn lockfile v1 # yarn lockfile v1
"@antfu/utils@^0.1.6": "@antfu/utils@^0.2.3":
version "0.1.6" version "0.2.4"
resolved "https://registry.yarnpkg.com/@antfu/utils/-/utils-0.1.6.tgz#a9e801f103fd14a59785dd0485fec06b6dc34d94" resolved "https://registry.yarnpkg.com/@antfu/utils/-/utils-0.2.4.tgz#c7d33fc6faa0d3a6fcc2555673f5e9b19c0fbc15"
integrity sha512-1lcCCEOv4gYlYa/OCjM2JA5nbNll04mNMhSXYu4QetbG14m3LdCvkyDAPlc2AmqRQEqkKpJldRL++9sPpOIydw== integrity sha512-2bZNkVfL9IZESmvE26UKi8SzyvSoaIsGXDcnbHFMtmGMqUiB1fXpAJ1ijGf+tSqKRQ5yagck2U1Qk0p+705/kw==
dependencies:
"@types/throttle-debounce" "^2.1.0"
"@babel/code-frame@7.12.11": "@babel/code-frame@7.12.11":
version "7.12.11" version "7.12.11"
@ -312,20 +314,20 @@
resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.168.tgz#fe24632e79b7ade3f132891afff86caa5e5ce008" resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.168.tgz#fe24632e79b7ade3f132891afff86caa5e5ce008"
integrity sha512-oVfRvqHV/V6D1yifJbVRU3TMp8OT6o6BG+U9MkwuJ3U8/CsDHvalRpsxBqivn71ztOFZBTfJMvETbqHiaNSj7Q== integrity sha512-oVfRvqHV/V6D1yifJbVRU3TMp8OT6o6BG+U9MkwuJ3U8/CsDHvalRpsxBqivn71ztOFZBTfJMvETbqHiaNSj7Q==
"@types/node@^15.12.2": "@types/node@^15.12.4":
version "15.12.2" version "15.12.4"
resolved "https://registry.yarnpkg.com/@types/node/-/node-15.12.2.tgz#1f2b42c4be7156ff4a6f914b2fb03d05fa84e38d" resolved "https://registry.yarnpkg.com/@types/node/-/node-15.12.4.tgz#e1cf817d70a1e118e81922c4ff6683ce9d422e26"
integrity sha512-zjQ69G564OCIWIOHSXyQEEDpdpGl+G348RAKY0XXy9Z5kU9Vzv1GMNnkar/ZJ8dzXB3COzD9Mo9NtRZ4xfgUww== integrity sha512-zrNj1+yqYF4WskCMOHwN+w9iuD12+dGm0rQ35HLl9/Ouuq52cEtd0CH9qMgrdNmi5ejC1/V7vKEXYubB+65DkA==
"@types/prop-types@*": "@types/prop-types@*":
version "15.7.3" version "15.7.3"
resolved "https://registry.yarnpkg.com/@types/prop-types/-/prop-types-15.7.3.tgz#2ab0d5da2e5815f94b0b9d4b95d1e5f243ab2ca7" resolved "https://registry.yarnpkg.com/@types/prop-types/-/prop-types-15.7.3.tgz#2ab0d5da2e5815f94b0b9d4b95d1e5f243ab2ca7"
integrity sha512-KfRL3PuHmqQLOG+2tGpRO26Ctg+Cq1E01D2DMriKEATHgWLfeNDmq9e29Q9WIky0dQ3NPkd1mzYH8Lm936Z9qw== integrity sha512-KfRL3PuHmqQLOG+2tGpRO26Ctg+Cq1E01D2DMriKEATHgWLfeNDmq9e29Q9WIky0dQ3NPkd1mzYH8Lm936Z9qw==
"@types/react-dom@^17.0.7": "@types/react-dom@^17.0.8":
version "17.0.7" version "17.0.8"
resolved "https://registry.yarnpkg.com/@types/react-dom/-/react-dom-17.0.7.tgz#b8ee15ead9e5d6c2c858b44949fdf2ebe5212232" resolved "https://registry.yarnpkg.com/@types/react-dom/-/react-dom-17.0.8.tgz#3180de6d79bf53762001ad854e3ce49f36dd71fc"
integrity sha512-Wd5xvZRlccOrCTej8jZkoFZuZRKHzanDDv1xglI33oBNFMWrqOSzrvWFw7ngSiZjrpJAzPKFtX7JvuXpkNmQHA== integrity sha512-0ohAiJAx1DAUEcY9UopnfwCE9sSMDGnY/oXjWMax6g3RpzmTt2GMyMVAXcbn0mo8XAff0SbQJl2/SBU+hjSZ1A==
dependencies: dependencies:
"@types/react" "*" "@types/react" "*"
@ -390,74 +392,78 @@
resolved "https://registry.yarnpkg.com/@types/scheduler/-/scheduler-0.16.1.tgz#18845205e86ff0038517aab7a18a62a6b9f71275" resolved "https://registry.yarnpkg.com/@types/scheduler/-/scheduler-0.16.1.tgz#18845205e86ff0038517aab7a18a62a6b9f71275"
integrity sha512-EaCxbanVeyxDRTQBkdLb3Bvl/HK7PBK6UJjsSixB0iHKoWxE5uu2Q/DgtpOhPIojN0Zl1whvOd7PoHs2P0s5eA== integrity sha512-EaCxbanVeyxDRTQBkdLb3Bvl/HK7PBK6UJjsSixB0iHKoWxE5uu2Q/DgtpOhPIojN0Zl1whvOd7PoHs2P0s5eA==
"@typescript-eslint/eslint-plugin@^4.26.1": "@types/throttle-debounce@^2.1.0":
version "4.26.1" version "2.1.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.26.1.tgz#b9c7313321cb837e2bf8bebe7acc2220659e67d3" resolved "https://registry.yarnpkg.com/@types/throttle-debounce/-/throttle-debounce-2.1.0.tgz#1c3df624bfc4b62f992d3012b84c56d41eab3776"
integrity sha512-aoIusj/8CR+xDWmZxARivZjbMBQTT9dImUtdZ8tVCVRXgBUuuZyM5Of5A9D9arQPxbi/0rlJLcuArclz/rCMJw== integrity sha512-5eQEtSCoESnh2FsiLTxE121IiE60hnMqcb435fShf4bpLRjEu1Eoekht23y6zXS9Ts3l+Szu3TARnTsA0GkOkQ==
"@typescript-eslint/eslint-plugin@^4.28.0":
version "4.28.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.28.0.tgz#1a66f03b264844387beb7dc85e1f1d403bd1803f"
integrity sha512-KcF6p3zWhf1f8xO84tuBailV5cN92vhS+VT7UJsPzGBm9VnQqfI9AsiMUFUCYHTYPg1uCCo+HyiDnpDuvkAMfQ==
dependencies: dependencies:
"@typescript-eslint/experimental-utils" "4.26.1" "@typescript-eslint/experimental-utils" "4.28.0"
"@typescript-eslint/scope-manager" "4.26.1" "@typescript-eslint/scope-manager" "4.28.0"
debug "^4.3.1" debug "^4.3.1"
functional-red-black-tree "^1.0.1" functional-red-black-tree "^1.0.1"
lodash "^4.17.21"
regexpp "^3.1.0" regexpp "^3.1.0"
semver "^7.3.5" semver "^7.3.5"
tsutils "^3.21.0" tsutils "^3.21.0"
"@typescript-eslint/experimental-utils@4.26.1": "@typescript-eslint/experimental-utils@4.28.0":
version "4.26.1" version "4.28.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/experimental-utils/-/experimental-utils-4.26.1.tgz#a35980a2390da9232aa206b27f620eab66e94142" resolved "https://registry.yarnpkg.com/@typescript-eslint/experimental-utils/-/experimental-utils-4.28.0.tgz#13167ed991320684bdc23588135ae62115b30ee0"
integrity sha512-sQHBugRhrXzRCs9PaGg6rowie4i8s/iD/DpTB+EXte8OMDfdCG5TvO73XlO9Wc/zi0uyN4qOmX9hIjQEyhnbmQ== integrity sha512-9XD9s7mt3QWMk82GoyUpc/Ji03vz4T5AYlHF9DcoFNfJ/y3UAclRsfGiE2gLfXtyC+JRA3trR7cR296TEb1oiQ==
dependencies: dependencies:
"@types/json-schema" "^7.0.7" "@types/json-schema" "^7.0.7"
"@typescript-eslint/scope-manager" "4.26.1" "@typescript-eslint/scope-manager" "4.28.0"
"@typescript-eslint/types" "4.26.1" "@typescript-eslint/types" "4.28.0"
"@typescript-eslint/typescript-estree" "4.26.1" "@typescript-eslint/typescript-estree" "4.28.0"
eslint-scope "^5.1.1" eslint-scope "^5.1.1"
eslint-utils "^3.0.0" eslint-utils "^3.0.0"
"@typescript-eslint/parser@^4.26.1": "@typescript-eslint/parser@^4.28.0":
version "4.26.1" version "4.28.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-4.26.1.tgz#cecfdd5eb7a5c13aabce1c1cfd7fbafb5a0f1e8e" resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-4.28.0.tgz#2404c16751a28616ef3abab77c8e51d680a12caa"
integrity sha512-q7F3zSo/nU6YJpPJvQveVlIIzx9/wu75lr6oDbDzoeIRWxpoc/HQ43G4rmMoCc5my/3uSj2VEpg/D83LYZF5HQ== integrity sha512-7x4D22oPY8fDaOCvkuXtYYTQ6mTMmkivwEzS+7iml9F9VkHGbbZ3x4fHRwxAb5KeuSkLqfnYjs46tGx2Nour4A==
dependencies: dependencies:
"@typescript-eslint/scope-manager" "4.26.1" "@typescript-eslint/scope-manager" "4.28.0"
"@typescript-eslint/types" "4.26.1" "@typescript-eslint/types" "4.28.0"
"@typescript-eslint/typescript-estree" "4.26.1" "@typescript-eslint/typescript-estree" "4.28.0"
debug "^4.3.1" debug "^4.3.1"
"@typescript-eslint/scope-manager@4.26.1": "@typescript-eslint/scope-manager@4.28.0":
version "4.26.1" version "4.28.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-4.26.1.tgz#075a74a15ff33ee3a7ed33e5fce16ee86689f662" resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-4.28.0.tgz#6a3009d2ab64a30fc8a1e257a1a320067f36a0ce"
integrity sha512-TW1X2p62FQ8Rlne+WEShyd7ac2LA6o27S9i131W4NwDSfyeVlQWhw8ylldNNS8JG6oJB9Ha9Xyc+IUcqipvheQ== integrity sha512-eCALCeScs5P/EYjwo6se9bdjtrh8ByWjtHzOkC4Tia6QQWtQr3PHovxh3TdYTuFcurkYI4rmFsRFpucADIkseg==
dependencies: dependencies:
"@typescript-eslint/types" "4.26.1" "@typescript-eslint/types" "4.28.0"
"@typescript-eslint/visitor-keys" "4.26.1" "@typescript-eslint/visitor-keys" "4.28.0"
"@typescript-eslint/types@4.26.1": "@typescript-eslint/types@4.28.0":
version "4.26.1" version "4.28.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-4.26.1.tgz#9e7c523f73c34b04a765e4167ca5650436ef1d38" resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-4.28.0.tgz#a33504e1ce7ac51fc39035f5fe6f15079d4dafb0"
integrity sha512-STyMPxR3cS+LaNvS8yK15rb8Y0iL0tFXq0uyl6gY45glyI7w0CsyqyEXl/Fa0JlQy+pVANeK3sbwPneCbWE7yg== integrity sha512-p16xMNKKoiJCVZY5PW/AfILw2xe1LfruTcfAKBj3a+wgNYP5I9ZEKNDOItoRt53p4EiPV6iRSICy8EPanG9ZVA==
"@typescript-eslint/typescript-estree@4.26.1": "@typescript-eslint/typescript-estree@4.28.0":
version "4.26.1" version "4.28.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-4.26.1.tgz#b2ce2e789233d62283fae2c16baabd4f1dbc9633" resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-4.28.0.tgz#e66d4e5aa2ede66fec8af434898fe61af10c71cf"
integrity sha512-l3ZXob+h0NQzz80lBGaykdScYaiEbFqznEs99uwzm8fPHhDjwaBFfQkjUC/slw6Sm7npFL8qrGEAMxcfBsBJUg== integrity sha512-m19UQTRtxMzKAm8QxfKpvh6OwQSXaW1CdZPoCaQuLwAq7VZMNuhJmZR4g5281s2ECt658sldnJfdpSZZaxUGMQ==
dependencies: dependencies:
"@typescript-eslint/types" "4.26.1" "@typescript-eslint/types" "4.28.0"
"@typescript-eslint/visitor-keys" "4.26.1" "@typescript-eslint/visitor-keys" "4.28.0"
debug "^4.3.1" debug "^4.3.1"
globby "^11.0.3" globby "^11.0.3"
is-glob "^4.0.1" is-glob "^4.0.1"
semver "^7.3.5" semver "^7.3.5"
tsutils "^3.21.0" tsutils "^3.21.0"
"@typescript-eslint/visitor-keys@4.26.1": "@typescript-eslint/visitor-keys@4.28.0":
version "4.26.1" version "4.28.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-4.26.1.tgz#0d55ea735cb0d8903b198017d6d4f518fdaac546" resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-4.28.0.tgz#255c67c966ec294104169a6939d96f91c8a89434"
integrity sha512-IGouNSSd+6x/fHtYRyLOM6/C+QxMDzWlDtN41ea+flWuSF9g02iqcIlX8wM53JkfljoIjP0U+yp7SiTS1onEkw== integrity sha512-PjJyTWwrlrvM5jazxYF5ZPs/nl0kHDZMVbuIcbpawVXaDPelp3+S9zpOz5RmVUfS/fD5l5+ZXNKnWhNYjPzCvw==
dependencies: dependencies:
"@typescript-eslint/types" "4.26.1" "@typescript-eslint/types" "4.28.0"
eslint-visitor-keys "^2.0.0" eslint-visitor-keys "^2.0.0"
"@vitejs/plugin-react-refresh@^1.3.3": "@vitejs/plugin-react-refresh@^1.3.3":
@ -470,12 +476,12 @@
"@babel/plugin-transform-react-jsx-source" "^7.12.13" "@babel/plugin-transform-react-jsx-source" "^7.12.13"
react-refresh "^0.9.0" react-refresh "^0.9.0"
"@windicss/plugin-utils@1.0.3": "@windicss/plugin-utils@1.1.1":
version "1.0.3" version "1.1.1"
resolved "https://registry.yarnpkg.com/@windicss/plugin-utils/-/plugin-utils-1.0.3.tgz#04d039ef56b58180079df3f9b3bd8a21a57368d3" resolved "https://registry.yarnpkg.com/@windicss/plugin-utils/-/plugin-utils-1.1.1.tgz#7f70952adc8d33f607706e434a153e2cdff52b64"
integrity sha512-SBYjmWBO+dOqxJgyyOAETOuMdcugvVgZYQc3rb7KtcTW5u9UkFXtiuGdoq8cWyFpSkn46gmjCb4WNbY3kEIVnQ== integrity sha512-niKEDyUpOfCGemFHopI9fxdWPpJQIZ/jmaU4spQXsGc1oEts164P8LUJPQmXc8C6vjKwkrH7KA+lxYNG5LmlDA==
dependencies: dependencies:
"@antfu/utils" "^0.1.6" "@antfu/utils" "^0.2.3"
debug "^4.3.2" debug "^4.3.2"
fast-glob "^3.2.5" fast-glob "^3.2.5"
jiti "^1.10.1" jiti "^1.10.1"
@ -983,10 +989,10 @@ es-to-primitive@^1.2.1:
is-date-object "^1.0.1" is-date-object "^1.0.1"
is-symbol "^1.0.2" is-symbol "^1.0.2"
esbuild@^0.12.5: esbuild@^0.12.8:
version "0.12.5" version "0.12.9"
resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.12.5.tgz#36076a6bc1966ba2741981d30512e95e8aaff495" resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.12.9.tgz#bed4e7087c286cd81d975631f77d47feb1660070"
integrity sha512-vcuP53pA5XiwUU4FnlXM+2PnVjTfHGthM7uP1gtp+9yfheGvFFbq/KyuESThmtoHPUrfZH5JpxGVJIFDVD1Egw== integrity sha512-MWRhAbMOJ9RJygCrt778rz/qNYgA4ZVj6aXnNPxFjs7PmIpb0fuB9Gmg5uWrr6n++XKwwm/RmSz6RR5JL2Ocsw==
escalade@^3.1.1: escalade@^3.1.1:
version "3.1.1" version "3.1.1"
@ -1127,10 +1133,10 @@ eslint-visitor-keys@^2.0.0:
resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz#f65328259305927392c938ed44eb0a5c9b2bd303" resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz#f65328259305927392c938ed44eb0a5c9b2bd303"
integrity sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw== integrity sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==
eslint@^7.28.0: eslint@^7.29.0:
version "7.28.0" version "7.29.0"
resolved "https://registry.yarnpkg.com/eslint/-/eslint-7.28.0.tgz#435aa17a0b82c13bb2be9d51408b617e49c1e820" resolved "https://registry.yarnpkg.com/eslint/-/eslint-7.29.0.tgz#ee2a7648f2e729485e4d0bd6383ec1deabc8b3c0"
integrity sha512-UMfH0VSjP0G4p3EWirscJEQ/cHqnT/iuH6oNZOB94nBjWbMnhGEPxsZm1eyIW0C/9jLI0Fow4W5DXLjEI7mn1g== integrity sha512-82G/JToB9qIy/ArBzIWG9xvvwL3R86AlCjtGw+A29OMZDqhTybz/MByORSukGxeI+YPCR4coYyITKk8BFH9nDA==
dependencies: dependencies:
"@babel/code-frame" "7.12.11" "@babel/code-frame" "7.12.11"
"@eslint/eslintrc" "^0.4.2" "@eslint/eslintrc" "^0.4.2"
@ -1308,7 +1314,7 @@ fs.realpath@^1.0.0:
resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f"
integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8= integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8=
fsevents@~2.3.1: fsevents@~2.3.1, fsevents@~2.3.2:
version "2.3.2" version "2.3.2"
resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.2.tgz#8a526f78b8fdf4623b709e0b975c52c24c02fd1a" resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.2.tgz#8a526f78b8fdf4623b709e0b975c52c24c02fd1a"
integrity sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA== integrity sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==
@ -1402,11 +1408,6 @@ graceful-fs@^4.1.2:
resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.6.tgz#ff040b2b0853b23c3d31027523706f1885d76bee" resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.6.tgz#ff040b2b0853b23c3d31027523706f1885d76bee"
integrity sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ== integrity sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ==
hamt_plus@1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/hamt_plus/-/hamt_plus-1.0.2.tgz#e21c252968c7e33b20f6a1b094cd85787a265601"
integrity sha1-4hwlKWjH4zsg9qGwlM2FeHomVgE=
has-bigints@^1.0.1: has-bigints@^1.0.1:
version "1.0.1" version "1.0.1"
resolved "https://registry.yarnpkg.com/has-bigints/-/has-bigints-1.0.1.tgz#64fe6acb020673e3b78db035a5af69aa9d07b113" resolved "https://registry.yarnpkg.com/has-bigints/-/has-bigints-1.0.1.tgz#64fe6acb020673e3b78db035a5af69aa9d07b113"
@ -1633,6 +1634,11 @@ jiti@^1.10.1:
resolved "https://registry.yarnpkg.com/jiti/-/jiti-1.10.1.tgz#bc2a175b9435274dc8659d3d9a121a91c6b3a1af" resolved "https://registry.yarnpkg.com/jiti/-/jiti-1.10.1.tgz#bc2a175b9435274dc8659d3d9a121a91c6b3a1af"
integrity sha512-qux9juDtAC8HlZxAk/fku73ak4TWNLigRFTNzFShE/kw4bXVFsVu538vLXAxvNyPszXgpX4YxkXfwTYEi+zf5A== integrity sha512-qux9juDtAC8HlZxAk/fku73ak4TWNLigRFTNzFShE/kw4bXVFsVu538vLXAxvNyPszXgpX4YxkXfwTYEi+zf5A==
jotai@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/jotai/-/jotai-1.0.0.tgz#d5e7f7044d89e543a9c7429a9723e11528b2760e"
integrity sha512-6hZGy3hqIlBlLSKppTrxDc1Vb7mi3I8eEQOIu7Kj6ceX1PSzjxdsEVC9TjAqaio8gZJEz+2ufNUf4afvbs0RXg==
js-cookie@^2.2.1: js-cookie@^2.2.1:
version "2.2.1" version "2.2.1"
resolved "https://registry.yarnpkg.com/js-cookie/-/js-cookie-2.2.1.tgz#69e106dc5d5806894562902aa5baec3744e9b2b8" resolved "https://registry.yarnpkg.com/js-cookie/-/js-cookie-2.2.1.tgz#69e106dc5d5806894562902aa5baec3744e9b2b8"
@ -1756,7 +1762,7 @@ lodash.truncate@^4.4.2:
resolved "https://registry.yarnpkg.com/lodash.truncate/-/lodash.truncate-4.4.2.tgz#5a350da0b1113b837ecfffd5812cbe58d6eae193" resolved "https://registry.yarnpkg.com/lodash.truncate/-/lodash.truncate-4.4.2.tgz#5a350da0b1113b837ecfffd5812cbe58d6eae193"
integrity sha1-WjUNoLERO4N+z//VgSy+WNbq4ZM= integrity sha1-WjUNoLERO4N+z//VgSy+WNbq4ZM=
lodash@^4.17.15, lodash@^4.17.21: lodash@^4.17.15:
version "4.17.21" version "4.17.21"
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c"
integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==
@ -1864,6 +1870,11 @@ natural-compare@^1.4.0:
resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7"
integrity sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc= integrity sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=
neverthrow@^4.2.1:
version "4.2.1"
resolved "https://registry.yarnpkg.com/neverthrow/-/neverthrow-4.2.1.tgz#c582dee4772528d15c9a170599c5382d366fd419"
integrity sha512-faWQGNqVQrXOuG8K7E0PRzsfBHzfVqeDX9nwawKDseuH/qEGIH02Nrq03OJOs5eTFML03xeol3otzagPoHyEPA==
node-releases@^1.1.71: node-releases@^1.1.71:
version "1.1.71" version "1.1.71"
resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.71.tgz#cb1334b179896b1c89ecfdd4b725fb7bbdfc7dbb" resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.71.tgz#cb1334b179896b1c89ecfdd4b725fb7bbdfc7dbb"
@ -2063,10 +2074,10 @@ pkg-up@^2.0.0:
dependencies: dependencies:
find-up "^2.1.0" find-up "^2.1.0"
postcss@^8.2.10: postcss@^8.3.4:
version "8.3.2" version "8.3.5"
resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.3.2.tgz#ed3ec489f5428af5740cd6effcc216b4d455ee64" resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.3.5.tgz#982216b113412bc20a86289e91eb994952a5b709"
integrity sha512-y1FK/AWdZlBF5lusS5j5l4/vF67+vQZt1SXPVJ32y1kRGDQyrs1zk32hG1cInRTu14P0V+orPz+ifwW/7rR4bg== integrity sha512-NxTuJocUhYGsMiMFHDUkmjSKT3EdH4/WbGF6GCi1NDGk+vbcUTun4fpbOqaPtD8IIsztA2ilZm2DhYCuyN58gA==
dependencies: dependencies:
colorette "^1.2.2" colorette "^1.2.2"
nanoid "^3.1.23" nanoid "^3.1.23"
@ -2224,13 +2235,6 @@ readdirp@~3.5.0:
dependencies: dependencies:
picomatch "^2.2.1" picomatch "^2.2.1"
recoil@^0.3.1:
version "0.3.1"
resolved "https://registry.yarnpkg.com/recoil/-/recoil-0.3.1.tgz#40ef544160d19d76e25de8929d7e512eace13b90"
integrity sha512-KNA3DRqgxX4rRC8E7fc6uIw7BACmMPuraIYy+ejhE8tsw7w32CetMm8w7AMZa34wzanKKkev3vl3H7Z4s0QSiA==
dependencies:
hamt_plus "1.0.2"
recrawl-sync@^2.0.3: recrawl-sync@^2.0.3:
version "2.2.1" version "2.2.1"
resolved "https://registry.yarnpkg.com/recrawl-sync/-/recrawl-sync-2.2.1.tgz#cb02c8084c22b3cea103abf46bb88734076ed6bb" resolved "https://registry.yarnpkg.com/recrawl-sync/-/recrawl-sync-2.2.1.tgz#cb02c8084c22b3cea103abf46bb88734076ed6bb"
@ -2279,7 +2283,7 @@ resolve-pathname@^3.0.0:
resolved "https://registry.yarnpkg.com/resolve-pathname/-/resolve-pathname-3.0.0.tgz#99d02224d3cf263689becbb393bc560313025dcd" resolved "https://registry.yarnpkg.com/resolve-pathname/-/resolve-pathname-3.0.0.tgz#99d02224d3cf263689becbb393bc560313025dcd"
integrity sha512-C7rARubxI8bXFNB/hqcp/4iUeIXJhJZvFPFPiSPRnhU5UPxzMFIl+2E6yY6c4k9giDJAhtV+enfA+G89N6Csng== integrity sha512-C7rARubxI8bXFNB/hqcp/4iUeIXJhJZvFPFPiSPRnhU5UPxzMFIl+2E6yY6c4k9giDJAhtV+enfA+G89N6Csng==
resolve@^1.10.0, resolve@^1.12.0, resolve@^1.13.1, resolve@^1.19.0, resolve@^1.20.0: resolve@^1.10.0, resolve@^1.12.0, resolve@^1.13.1, resolve@^1.20.0:
version "1.20.0" version "1.20.0"
resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.20.0.tgz#629a013fb3f70755d6f0b7935cc1c2c5378b1975" resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.20.0.tgz#629a013fb3f70755d6f0b7935cc1c2c5378b1975"
integrity sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A== integrity sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A==
@ -2333,10 +2337,10 @@ safe-buffer@~5.1.1:
resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d"
integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==
sass@^1.34.1: sass@^1.35.1:
version "1.34.1" version "1.35.1"
resolved "https://registry.yarnpkg.com/sass/-/sass-1.34.1.tgz#30f45c606c483d47b634f1e7371e13ff773c96ef" resolved "https://registry.yarnpkg.com/sass/-/sass-1.35.1.tgz#90ecf774dfe68f07b6193077e3b42fb154b9e1cd"
integrity sha512-scLA7EIZM+MmYlej6sdVr0HRbZX5caX5ofDT9asWnUJj21oqgsC+1LuNfm0eg+vM0fCTZHhwImTiCU0sx9h9CQ== integrity sha512-oCisuQJstxMcacOPmxLNiLlj4cUyN2+8xJnG7VanRoh2GOLr9RqkvI4AxA4a6LHVg/rsu+PmxXeGhrdSF9jCiQ==
dependencies: dependencies:
chokidar ">=3.0.0 <4.0.0" chokidar ">=3.0.0 <4.0.0"
@ -2675,15 +2679,15 @@ type-fest@^0.20.2:
resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.20.2.tgz#1bf207f4b28f91583666cb5fbd327887301cd5f4" resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.20.2.tgz#1bf207f4b28f91583666cb5fbd327887301cd5f4"
integrity sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ== integrity sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==
type-fest@^1.2.0: type-fest@^1.2.1:
version "1.2.0" version "1.2.1"
resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-1.2.0.tgz#4cdf38ef9b047922c26038080cb269752ae359a2" resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-1.2.1.tgz#232990aa513f3f5223abf54363975dfe3a121a2e"
integrity sha512-++0N6KyAj0t2webXst0PE0xuXb4Dv3z1Z+4SGzK+j/epeWBZCfkQbkW/ezscZwpinmBQ5wu/l4TqagKSVcAGCA== integrity sha512-SbmIRuXhJs8KTneu77Ecylt9zuqL683tuiLYpTRil4H++eIhqCmx6ko6KAFem9dty8sOdnEiX7j4K1nRE628fQ==
typescript@^4.3.2: typescript@^4.3.4:
version "4.3.2" version "4.3.4"
resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.3.2.tgz#399ab18aac45802d6f2498de5054fcbbe716a805" resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.3.4.tgz#3f85b986945bcf31071decdd96cf8bfa65f9dcbc"
integrity sha512-zZ4hShnmnoVnAHpVHWpTcxdv7dWP60S2FsydQLV8V5PbS3FifjWFFRiHSWpDJahly88PRyV5teTSLoq4eG7mKw== integrity sha512-uauPG7XZn9F/mo+7MrsRjyvbxFpzemRjKEZXS4AK83oP2KKOJPvb+9cO/gmnv8arWZvhnjVOXz7B49m1l0e9Ew==
unbox-primitive@^1.0.0, unbox-primitive@^1.0.1: unbox-primitive@^1.0.0, unbox-primitive@^1.0.1:
version "1.0.1" version "1.0.1"
@ -2725,12 +2729,12 @@ value-equal@^1.0.1:
resolved "https://registry.yarnpkg.com/value-equal/-/value-equal-1.0.1.tgz#1e0b794c734c5c0cade179c437d356d931a34d6c" resolved "https://registry.yarnpkg.com/value-equal/-/value-equal-1.0.1.tgz#1e0b794c734c5c0cade179c437d356d931a34d6c"
integrity sha512-NOJ6JZCAWr0zlxZt+xqCHNTEKOsrks2HQd4MqhP1qy4z1SkbEP467eNx6TgDKXMvUOb+OENfJCZwM+16n7fRfw== integrity sha512-NOJ6JZCAWr0zlxZt+xqCHNTEKOsrks2HQd4MqhP1qy4z1SkbEP467eNx6TgDKXMvUOb+OENfJCZwM+16n7fRfw==
vite-plugin-windicss@^1.0.3: vite-plugin-windicss@^1.1.1:
version "1.0.3" version "1.1.1"
resolved "https://registry.yarnpkg.com/vite-plugin-windicss/-/vite-plugin-windicss-1.0.3.tgz#bd45cfee13777e7b57c37a257ebcb7e73fee94ab" resolved "https://registry.yarnpkg.com/vite-plugin-windicss/-/vite-plugin-windicss-1.1.1.tgz#c13d4c2d9fec4afae2eea5058f426c693255d02f"
integrity sha512-y9pudcMajdI88PTs49qGftlfAvsLUUhK2Eig+xn5sgxPCbAc3Rj5phXJkRzGDqfmEzGwbpF6JwjmiGmZkm8V+g== integrity sha512-J1n3DoSg8BkQ42HDNzh+FqPhvBgCRgQ0Nvp2HLvb5FVl8FKEPw26Frc/oLaC1g9ypSlvkSM8011gHi+c+pxsRQ==
dependencies: dependencies:
"@windicss/plugin-utils" "1.0.3" "@windicss/plugin-utils" "1.1.1"
chalk "^4.1.1" chalk "^4.1.1"
debug "^4.3.2" debug "^4.3.2"
windicss "^3.1.3" windicss "^3.1.3"
@ -2745,17 +2749,17 @@ vite-tsconfig-paths@^3.3.13:
recrawl-sync "^2.0.3" recrawl-sync "^2.0.3"
tsconfig-paths "^3.9.0" tsconfig-paths "^3.9.0"
vite@2.3.5: vite@^2.3.8:
version "2.3.5" version "2.3.8"
resolved "https://registry.yarnpkg.com/vite/-/vite-2.3.5.tgz#0f5e750317e6f00e5343dd8272f64c2261f026b3" resolved "https://registry.yarnpkg.com/vite/-/vite-2.3.8.tgz#42e3e03953859fd410e4e6ab3d1cca0aab2adc3c"
integrity sha512-Jh3uySLlofx+t+uqznnzJFTNgeqYQLhR6xMx61VYN5KTlVirJXBPkFW2+aigHN6d1mOo6rM7DWnU6gjnudVozw== integrity sha512-QiEx+iqNnJntSgSF2fWRQvRey9pORIrtNJzNyBJXwc+BdzWs83FQolX84cTBo393cfhObrtWa6180dAa4NLDiQ==
dependencies: dependencies:
esbuild "^0.12.5" esbuild "^0.12.8"
postcss "^8.2.10" postcss "^8.3.4"
resolve "^1.19.0" resolve "^1.20.0"
rollup "^2.38.5" rollup "^2.38.5"
optionalDependencies: optionalDependencies:
fsevents "~2.3.1" fsevents "~2.3.2"
which-boxed-primitive@^1.0.2: which-boxed-primitive@^1.0.2:
version "1.0.2" version "1.0.2"