valaxy 0.17.5 → 0.18.0-beta.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/client/components/ValaxyMd.vue +1 -4
- package/client/components/builtin/ValaxyMermaid.vue +86 -0
- package/client/components/internals/ShadowRoot.vue +24 -0
- package/client/composables/common.ts +4 -2
- package/client/composables/dark.ts +3 -2
- package/client/composables/{post.ts → post/index.ts} +7 -34
- package/client/composables/post/usePrevNext.ts +30 -0
- package/client/constants/index.ts +0 -0
- package/client/main.ts +4 -0
- package/client/modules/devtools.ts +1 -1
- package/client/modules/mermaid.ts +26 -0
- package/client/modules/valaxy.ts +3 -0
- package/client/setup/main.ts +8 -6
- package/client/setup/mermaid.ts +15 -0
- package/client/setups.ts +8 -0
- package/client/stores/index.ts +1 -0
- package/client/stores/router.ts +10 -0
- package/client/stores/site.ts +12 -6
- package/client/types/index.ts +3 -0
- package/client/utils/code.ts +24 -0
- package/client/utils/dev.ts +13 -0
- package/client/utils/index.ts +1 -0
- package/client/utils/time.ts +0 -6
- package/dist/chunk-OKWTZ6SV.mjs +145 -0
- package/dist/chunk-V3BYMJ7P.cjs +144 -0
- package/dist/{config-hM2lXH4J.d.cts → config-qoiMoYQY.d.cts} +0 -6
- package/dist/{config-hM2lXH4J.d.ts → config-qoiMoYQY.d.ts} +0 -6
- package/dist/node/cli/index.cjs +1 -1
- package/dist/node/cli/index.mjs +1 -1
- package/dist/node/index.cjs +1 -1
- package/dist/node/index.d.cts +73 -25
- package/dist/node/index.d.ts +73 -25
- package/dist/node/index.mjs +1 -1
- package/dist/types/index.cjs +1 -1
- package/dist/types/index.d.cts +2 -2
- package/dist/types/index.d.ts +2 -2
- package/dist/types/index.mjs +1 -1
- package/package.json +12 -10
- package/shims.d.ts +12 -1
- package/types/config.ts +0 -8
- package/types/data.ts +0 -1
- package/dist/chunk-CBD6N7G5.cjs +0 -145
- package/dist/chunk-YJCKNZWO.mjs +0 -146
- /package/dist/{chunk-R4WV6S3O.mjs → chunk-MJRGR35B.mjs} +0 -0
- /package/dist/{chunk-FNMRWIFM.cjs → chunk-RWOIGW5M.cjs} +0 -0
|
@@ -45,10 +45,7 @@ useVanillaLazyLoad()
|
|
|
45
45
|
|
|
46
46
|
<template>
|
|
47
47
|
<article v-if="$slots.default" :class="frontmatter.markdown !== false && 'markdown-body'">
|
|
48
|
-
<
|
|
49
|
-
<ValaxyDecrypt :encrypted-content="frontmatter.encryptedContent" />
|
|
50
|
-
</template>
|
|
51
|
-
<slot v-else ref="contentRef" @vue:updated="runContentUpdated" />
|
|
48
|
+
<slot ref="contentRef" @vue:updated="runContentUpdated" />
|
|
52
49
|
|
|
53
50
|
<div v-if="frontmatter.url" text="center">
|
|
54
51
|
<a
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
<!--
|
|
2
|
+
Mermaid
|
|
3
|
+
(auto transformed, you don't need to use this component directly)
|
|
4
|
+
|
|
5
|
+
Usage:
|
|
6
|
+
|
|
7
|
+
```mermaid
|
|
8
|
+
pie
|
|
9
|
+
"Dogs" : 386
|
|
10
|
+
"Cats" : 85
|
|
11
|
+
"Rats" : 15
|
|
12
|
+
```
|
|
13
|
+
-->
|
|
14
|
+
|
|
15
|
+
<script setup lang="ts">
|
|
16
|
+
import { getCurrentInstance, ref, watch, watchEffect } from 'vue'
|
|
17
|
+
|
|
18
|
+
import { isClient } from '@vueuse/core'
|
|
19
|
+
import { renderMermaid } from '../../modules/mermaid'
|
|
20
|
+
import ShadowRoot from '../internals/ShadowRoot.vue'
|
|
21
|
+
|
|
22
|
+
import { isDark } from '../../composables'
|
|
23
|
+
|
|
24
|
+
const props = defineProps<{
|
|
25
|
+
code: string
|
|
26
|
+
scale?: number
|
|
27
|
+
theme?: string
|
|
28
|
+
}>()
|
|
29
|
+
|
|
30
|
+
const vm = getCurrentInstance()
|
|
31
|
+
const el = ref<ShadowRoot>()
|
|
32
|
+
const html = ref('')
|
|
33
|
+
|
|
34
|
+
if (isClient) {
|
|
35
|
+
// dynamic import to reduce initial bundle size
|
|
36
|
+
import('mermaid').then(m => m.default)
|
|
37
|
+
.then((mermaid) => {
|
|
38
|
+
mermaid.startOnLoad = false
|
|
39
|
+
mermaid.initialize({ startOnLoad: false })
|
|
40
|
+
|
|
41
|
+
watchEffect(async (onCleanup) => {
|
|
42
|
+
let disposed = false
|
|
43
|
+
onCleanup(() => {
|
|
44
|
+
disposed = true
|
|
45
|
+
})
|
|
46
|
+
const svg = await renderMermaid(
|
|
47
|
+
mermaid,
|
|
48
|
+
props.code || '',
|
|
49
|
+
{
|
|
50
|
+
theme: props.theme || (isDark.value ? 'dark' : undefined),
|
|
51
|
+
...vm!.attrs,
|
|
52
|
+
},
|
|
53
|
+
)
|
|
54
|
+
if (!disposed)
|
|
55
|
+
html.value = svg
|
|
56
|
+
})
|
|
57
|
+
|
|
58
|
+
const actualHeight = ref<number>()
|
|
59
|
+
|
|
60
|
+
watch(html, () => {
|
|
61
|
+
actualHeight.value = undefined
|
|
62
|
+
})
|
|
63
|
+
|
|
64
|
+
watchEffect(() => {
|
|
65
|
+
const svgEl = el.value?.children?.[0] as SVGElement | undefined
|
|
66
|
+
if (svgEl && svgEl.hasAttribute('viewBox') && actualHeight.value == null) {
|
|
67
|
+
const v = Number.parseFloat(svgEl.getAttribute('viewBox')?.split(' ')[3] || '')
|
|
68
|
+
actualHeight.value = Number.isNaN(v) ? undefined : v
|
|
69
|
+
}
|
|
70
|
+
}, { flush: 'post' })
|
|
71
|
+
|
|
72
|
+
watchEffect(() => {
|
|
73
|
+
const svgEl = el.value?.children?.[0] as SVGElement | undefined
|
|
74
|
+
if (svgEl != null && props.scale != null && actualHeight.value != null) {
|
|
75
|
+
svgEl.setAttribute('height', `${actualHeight.value * props.scale}`)
|
|
76
|
+
svgEl.removeAttribute('width')
|
|
77
|
+
svgEl.removeAttribute('style')
|
|
78
|
+
}
|
|
79
|
+
}, { flush: 'post' })
|
|
80
|
+
})
|
|
81
|
+
}
|
|
82
|
+
</script>
|
|
83
|
+
|
|
84
|
+
<template>
|
|
85
|
+
<ShadowRoot class="mermaid" :inner-html="html" @shadow="el = $event" />
|
|
86
|
+
</template>
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import { computed, ref, watchEffect } from 'vue'
|
|
3
|
+
|
|
4
|
+
const props = defineProps<{
|
|
5
|
+
innerHtml: string
|
|
6
|
+
}>()
|
|
7
|
+
|
|
8
|
+
const emit = defineEmits<{
|
|
9
|
+
(event: 'shadow', div: ShadowRoot): void
|
|
10
|
+
}>()
|
|
11
|
+
|
|
12
|
+
const el = ref<HTMLDivElement>()
|
|
13
|
+
const shadow = computed(() => el.value ? (el.value.shadowRoot || el.value.attachShadow({ mode: 'open' })) : null)
|
|
14
|
+
watchEffect(() => {
|
|
15
|
+
if (shadow.value && props.innerHtml) {
|
|
16
|
+
emit('shadow', shadow.value)
|
|
17
|
+
shadow.value.innerHTML = props.innerHtml
|
|
18
|
+
}
|
|
19
|
+
})
|
|
20
|
+
</script>
|
|
21
|
+
|
|
22
|
+
<template>
|
|
23
|
+
<div ref="el" />
|
|
24
|
+
</template>
|
|
@@ -6,9 +6,11 @@ import type { PageData, Post } from 'valaxy/types'
|
|
|
6
6
|
import { useSiteConfig } from '../config'
|
|
7
7
|
|
|
8
8
|
export function useFrontmatter() {
|
|
9
|
+
// inject not in app root
|
|
9
10
|
const route = useRoute()
|
|
10
|
-
const frontmatter = computed<Post>(() =>
|
|
11
|
-
|
|
11
|
+
const frontmatter = computed<Post>(() => {
|
|
12
|
+
return route.meta.frontmatter || {}
|
|
13
|
+
})
|
|
12
14
|
return frontmatter
|
|
13
15
|
}
|
|
14
16
|
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import { useDark, useToggle } from '@vueuse/core'
|
|
1
|
+
import { isClient, useDark, useToggle } from '@vueuse/core'
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
if (isClient)
|
|
4
|
+
import('valaxy/client/styles/common/view-transition.css')
|
|
4
5
|
|
|
5
6
|
export const isDark = useDark()
|
|
6
7
|
export const toggleDark = useToggle(isDark)
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import type { ComputedRef } from 'vue'
|
|
2
2
|
import { computed } from 'vue'
|
|
3
|
-
import { useRoute, useRouter } from 'vue-router'
|
|
4
3
|
import { useI18n } from 'vue-i18n'
|
|
5
4
|
import type { Post } from 'valaxy'
|
|
6
|
-
import { sortByDate } from '
|
|
7
|
-
import {
|
|
5
|
+
import { sortByDate } from '../../utils'
|
|
6
|
+
import { useRouterStore } from '../../stores'
|
|
7
|
+
|
|
8
|
+
export * from './usePrevNext'
|
|
8
9
|
|
|
9
10
|
export function usePostTitle(post: ComputedRef<Post>) {
|
|
10
11
|
const { locale } = useI18n()
|
|
@@ -18,12 +19,11 @@ export function usePostTitle(post: ComputedRef<Post>) {
|
|
|
18
19
|
* get all page in 'pages' folder
|
|
19
20
|
*/
|
|
20
21
|
export function usePageList() {
|
|
21
|
-
const
|
|
22
|
+
const routerStore = useRouterStore()
|
|
23
|
+
const router = routerStore.router
|
|
24
|
+
|
|
22
25
|
return computed<Post[]>(() => {
|
|
23
26
|
const excludePages = ['/:..all', '/:all(.*)*', '/', '/:path(.*)']
|
|
24
|
-
if (!router)
|
|
25
|
-
return []
|
|
26
|
-
|
|
27
27
|
const routes = router.getRoutes()
|
|
28
28
|
.filter(i => i.name)
|
|
29
29
|
.filter(i => i.meta)
|
|
@@ -63,30 +63,3 @@ export function usePostList(params: {
|
|
|
63
63
|
return topPosts.concat(otherPosts)
|
|
64
64
|
})
|
|
65
65
|
}
|
|
66
|
-
|
|
67
|
-
/**
|
|
68
|
-
* get prev and next post
|
|
69
|
-
* @param path
|
|
70
|
-
*/
|
|
71
|
-
export function usePrevNext(path?: string) {
|
|
72
|
-
const route = useRoute()
|
|
73
|
-
const p = computed(() => path || route.path)
|
|
74
|
-
const site = useSiteStore()
|
|
75
|
-
|
|
76
|
-
const index = computed(() => {
|
|
77
|
-
let order = -1
|
|
78
|
-
site.postList.find((item, i) => {
|
|
79
|
-
if (item.path === p.value) {
|
|
80
|
-
order = i
|
|
81
|
-
return true
|
|
82
|
-
}
|
|
83
|
-
return false
|
|
84
|
-
})
|
|
85
|
-
return order
|
|
86
|
-
})
|
|
87
|
-
|
|
88
|
-
const prev = computed(() => index.value - 1 >= 0 ? site.postList[index.value - 1] : null)
|
|
89
|
-
const next = computed(() => index.value + 1 < site.postList.length ? site.postList[index.value + 1] : null)
|
|
90
|
-
|
|
91
|
-
return [prev, next]
|
|
92
|
-
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { computed } from 'vue'
|
|
2
|
+
import { useRoute } from 'vue-router'
|
|
3
|
+
import { useSiteStore } from '../../stores'
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* get prev and next post
|
|
7
|
+
* @param path
|
|
8
|
+
*/
|
|
9
|
+
export function usePrevNext(path?: string) {
|
|
10
|
+
const route = useRoute()
|
|
11
|
+
const p = computed(() => path || route.path)
|
|
12
|
+
const site = useSiteStore()
|
|
13
|
+
|
|
14
|
+
const index = computed(() => {
|
|
15
|
+
let order = -1
|
|
16
|
+
site.postList.find((item, i) => {
|
|
17
|
+
if (item.path === p.value) {
|
|
18
|
+
order = i
|
|
19
|
+
return true
|
|
20
|
+
}
|
|
21
|
+
return false
|
|
22
|
+
})
|
|
23
|
+
return order
|
|
24
|
+
})
|
|
25
|
+
|
|
26
|
+
const prev = computed(() => index.value - 1 >= 0 ? site.postList[index.value - 1] : null)
|
|
27
|
+
const next = computed(() => index.value + 1 < site.postList.length ? site.postList[index.value + 1] : null)
|
|
28
|
+
|
|
29
|
+
return [prev, next]
|
|
30
|
+
}
|
|
File without changes
|
package/client/main.ts
CHANGED
|
@@ -20,6 +20,7 @@ import '/@valaxyjs/styles'
|
|
|
20
20
|
import 'uno.css'
|
|
21
21
|
|
|
22
22
|
import setupMain from './setup/main'
|
|
23
|
+
import { initDevToolsClientLogic } from './utils/dev'
|
|
23
24
|
|
|
24
25
|
const valaxyConfig = initValaxyConfig()
|
|
25
26
|
|
|
@@ -58,6 +59,9 @@ const routesWithLayout = setupLayouts(import.meta.env.DEV
|
|
|
58
59
|
: filterDraft(routes),
|
|
59
60
|
)
|
|
60
61
|
|
|
62
|
+
if (import.meta.env.DEV)
|
|
63
|
+
initDevToolsClientLogic()
|
|
64
|
+
|
|
61
65
|
// https://github.com/antfu/vite-ssg
|
|
62
66
|
export const createApp = ViteSSG(
|
|
63
67
|
App,
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { customAlphabet } from 'nanoid'
|
|
2
|
+
import { decode } from 'js-base64'
|
|
3
|
+
import { clearUndefined } from '@antfu/utils'
|
|
4
|
+
import type { Mermaid } from 'mermaid'
|
|
5
|
+
import setupMermaid from '../setup/mermaid'
|
|
6
|
+
|
|
7
|
+
const nanoid = customAlphabet('abcedfghicklmn', 10)
|
|
8
|
+
const cache = new Map<string, string>()
|
|
9
|
+
|
|
10
|
+
export async function renderMermaid(mermaid: Mermaid, encoded: string, options: any) {
|
|
11
|
+
const key = encoded + JSON.stringify(options)
|
|
12
|
+
const _cache = cache.get(key)
|
|
13
|
+
if (_cache)
|
|
14
|
+
return _cache
|
|
15
|
+
|
|
16
|
+
mermaid.initialize({
|
|
17
|
+
startOnLoad: false,
|
|
18
|
+
...clearUndefined(setupMermaid() || {}),
|
|
19
|
+
...clearUndefined(options),
|
|
20
|
+
})
|
|
21
|
+
const code = decode(encoded)
|
|
22
|
+
const id = nanoid()
|
|
23
|
+
const { svg } = await mermaid.render(id, code)
|
|
24
|
+
cache.set(key, svg)
|
|
25
|
+
return svg
|
|
26
|
+
}
|
package/client/modules/valaxy.ts
CHANGED
|
@@ -63,6 +63,9 @@ function handleHMR(router: Router): void {
|
|
|
63
63
|
if (import.meta.hot) {
|
|
64
64
|
import.meta.hot.on('valaxy:pageData', (payload: PageDataPayload) => {
|
|
65
65
|
if (shouldHotReload(payload)) {
|
|
66
|
+
// @ts-expect-error $pageData
|
|
67
|
+
window.$pageData = payload.pageData
|
|
68
|
+
|
|
66
69
|
// console.log(payload.pageData.headers)
|
|
67
70
|
Object.assign(router.currentRoute.value.meta, payload.pageData)
|
|
68
71
|
}
|
package/client/setup/main.ts
CHANGED
|
@@ -26,12 +26,6 @@ export default function setupMain(ctx: ViteSSGContext, config: ComputedRef<Valax
|
|
|
26
26
|
|
|
27
27
|
installValaxy(ctx, config)
|
|
28
28
|
|
|
29
|
-
if (import.meta.env.DEV && ctx.isClient) {
|
|
30
|
-
import('../modules/devtools').then(({ install: installDevtools }) => {
|
|
31
|
-
installDevtools(ctx)
|
|
32
|
-
})
|
|
33
|
-
}
|
|
34
|
-
|
|
35
29
|
installSchema(ctx)
|
|
36
30
|
|
|
37
31
|
installPinia(ctx)
|
|
@@ -42,5 +36,13 @@ export default function setupMain(ctx: ViteSSGContext, config: ComputedRef<Valax
|
|
|
42
36
|
dayjs.extend(utc)
|
|
43
37
|
dayjs.extend(timezone)
|
|
44
38
|
|
|
39
|
+
if (import.meta.env.DEV && ctx.isClient) {
|
|
40
|
+
import('../modules/devtools').then(({ install: installDevtools }) => {
|
|
41
|
+
setTimeout(() => {
|
|
42
|
+
installDevtools(ctx)
|
|
43
|
+
}, 0)
|
|
44
|
+
})
|
|
45
|
+
}
|
|
46
|
+
|
|
45
47
|
/* __injections__ */
|
|
46
48
|
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/* __imports__ */
|
|
2
|
+
|
|
3
|
+
import { defineMermaidSetup } from 'valaxy'
|
|
4
|
+
import type { MermaidOptions } from '../types'
|
|
5
|
+
|
|
6
|
+
export default defineMermaidSetup(() => {
|
|
7
|
+
// eslint-disable-next-line prefer-const
|
|
8
|
+
let injection_return: MermaidOptions = {
|
|
9
|
+
theme: 'default',
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
/* __injections__ */
|
|
13
|
+
|
|
14
|
+
return injection_return
|
|
15
|
+
})
|
package/client/setups.ts
CHANGED
|
@@ -1,10 +1,18 @@
|
|
|
1
1
|
import type { ViteSSGContext } from 'vite-ssg'
|
|
2
2
|
import type { Awaitable } from '@antfu/utils'
|
|
3
|
+
import type { MermaidOptions } from './types'
|
|
3
4
|
|
|
4
5
|
export type AppContext = ViteSSGContext
|
|
5
6
|
|
|
6
7
|
export type AppSetup = (ctx: AppContext) => Awaitable<void>
|
|
7
8
|
|
|
9
|
+
// client
|
|
10
|
+
export type MermaidSetup = () => Partial<MermaidOptions> | void
|
|
11
|
+
|
|
8
12
|
export function defineAppSetup(fn: AppSetup) {
|
|
9
13
|
return fn
|
|
10
14
|
}
|
|
15
|
+
|
|
16
|
+
export function defineMermaidSetup(fn: MermaidSetup) {
|
|
17
|
+
return fn
|
|
18
|
+
}
|
package/client/stores/index.ts
CHANGED
package/client/stores/site.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { computed, ref } from 'vue'
|
|
2
2
|
import { acceptHMRUpdate, defineStore } from 'pinia'
|
|
3
|
-
import {
|
|
4
|
-
import { usePostList } from '..'
|
|
3
|
+
import { usePostList, useRouterStore } from '..'
|
|
5
4
|
import type { PageDataPayload } from '../../types'
|
|
5
|
+
import { setWindowValaxyProp } from '../utils/dev'
|
|
6
6
|
|
|
7
7
|
/**
|
|
8
8
|
* cache site global store
|
|
@@ -11,18 +11,21 @@ import type { PageDataPayload } from '../../types'
|
|
|
11
11
|
* - category
|
|
12
12
|
*/
|
|
13
13
|
export const useSiteStore = defineStore('site', () => {
|
|
14
|
+
const routerStore = useRouterStore()
|
|
15
|
+
const router = routerStore.router
|
|
16
|
+
|
|
14
17
|
const reload = ref(1)
|
|
15
18
|
// for dev hot reload
|
|
16
19
|
const postList = computed(() => {
|
|
17
|
-
|
|
18
|
-
|
|
20
|
+
const val = usePostList().value
|
|
21
|
+
if (reload.value && val)
|
|
22
|
+
return val
|
|
19
23
|
else
|
|
20
|
-
return
|
|
24
|
+
return val
|
|
21
25
|
})
|
|
22
26
|
|
|
23
27
|
// const postList = usePostList()
|
|
24
28
|
|
|
25
|
-
const router = useRouter()
|
|
26
29
|
if (router) {
|
|
27
30
|
router.isReady().then(() => {
|
|
28
31
|
// hot reload when save md
|
|
@@ -55,6 +58,9 @@ export const useSiteStore = defineStore('site', () => {
|
|
|
55
58
|
})
|
|
56
59
|
}
|
|
57
60
|
|
|
61
|
+
if (import.meta.env.DEV)
|
|
62
|
+
setWindowValaxyProp('postList', postList)
|
|
63
|
+
|
|
58
64
|
return {
|
|
59
65
|
postList,
|
|
60
66
|
}
|
package/client/types/index.ts
CHANGED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { range, uniq } from '@antfu/utils'
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* 1,3-5,8 => [1, 3, 4, 5, 8]
|
|
5
|
+
*/
|
|
6
|
+
export function parseRangeString(total: number, rangeStr?: string) {
|
|
7
|
+
if (!rangeStr || rangeStr === 'all' || rangeStr === '*')
|
|
8
|
+
return range(1, total + 1)
|
|
9
|
+
|
|
10
|
+
const pages: number[] = []
|
|
11
|
+
for (const part of rangeStr.split(/[,;]/g)) {
|
|
12
|
+
if (!part.includes('-')) {
|
|
13
|
+
pages.push(+part)
|
|
14
|
+
}
|
|
15
|
+
else {
|
|
16
|
+
const [start, end] = part.split('-', 2)
|
|
17
|
+
pages.push(
|
|
18
|
+
...range(+start, !end ? (total + 1) : (+end + 1)),
|
|
19
|
+
)
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
return uniq(pages).filter(i => i <= total).sort((a, b) => a - b)
|
|
24
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export function initDevToolsClientLogic() {
|
|
2
|
+
|
|
3
|
+
}
|
|
4
|
+
|
|
5
|
+
export function setWindowValaxyProp(property: string, value: any) {
|
|
6
|
+
if (!(window as any).$valaxy) {
|
|
7
|
+
;(window as any).$valaxy = {}
|
|
8
|
+
}
|
|
9
|
+
const $valaxy = ((window as any).$valaxy) as {
|
|
10
|
+
[key: string]: any
|
|
11
|
+
}
|
|
12
|
+
$valaxy[property] = value
|
|
13
|
+
}
|
package/client/utils/index.ts
CHANGED
package/client/utils/time.ts
CHANGED