dep: add package `living-object` for object serialization (support symbols)

pull/4663/head
Yuxuan Zhang 5 months ago
parent 6b4d214b92
commit 46d8ccc29b
No known key found for this signature in database
GPG Key ID: 6910B04F3351EF7D

@ -107,6 +107,7 @@
"@vueuse/core": "^13.0.0",
"@vueuse/integrations": "^13.0.0",
"focus-trap": "^7.6.4",
"living-object": "0.0.3",
"mark.js": "8.11.1",
"minisearch": "^7.1.2",
"shiki": "^3.2.1",

@ -55,6 +55,9 @@ importers:
focus-trap:
specifier: ^7.6.4
version: 7.6.4
living-object:
specifier: 0.0.3
version: 0.0.3
mark.js:
specifier: 8.11.1
version: 8.11.1
@ -1923,6 +1926,9 @@ packages:
resolution: {integrity: sha512-iyAZCeyD+c1gPyE9qpFu8af0Y+MRtmKOncdGoA2S5EY8iFq99dmmvkNnHiWo+pj0s7yH7l3KPIgee77tKpXPWQ==}
engines: {node: '>=18.0.0'}
living-object@0.0.3:
resolution: {integrity: sha512-GBTVXuwoxsU+OF7he9ZbAWh56QhHVtpD5cL+REAq7EFR8rtnkjZIztduJ0hm2rdwRa0XyaGrsNypTqTdrhep6A==}
local-pkg@1.1.1:
resolution: {integrity: sha512-WunYko2W1NcdfAFpuLUoucsgULmgDBRkdxHxWQ7mK0cQqwPiy8E1enjuRBrhLtZkB5iScJ1XIPdhVEFK8aOLSg==}
engines: {node: '>=14'}
@ -4486,6 +4492,8 @@ snapshots:
rfdc: 1.4.1
wrap-ansi: 9.0.0
living-object@0.0.3: {}
local-pkg@1.1.1:
dependencies:
mlly: 1.7.4

@ -11,11 +11,11 @@ import type { BuildOptions, Rollup } from 'vite'
import { resolveConfig, type SiteConfig } from '../config'
import { clearCache } from '../markdownToVue'
import { slash, type Awaitable, type HeadConfig } from '../shared'
import { deserializeFunctions, serializeFunctions } from '../utils/fnSerialize'
import { task } from '../utils/task'
import { bundle } from './bundle'
import { generateSitemap } from './generateSitemap'
import { renderPage } from './render'
import LivingObject from 'living-object'
const require = createRequire(import.meta.url)
@ -202,15 +202,11 @@ function generateMetadataScript(
// It's also embedded as a string and JSON.parsed from the client because
// it's faster than embedding as JS object literal.
const hashMapString = JSON.stringify(JSON.stringify(pageToHashMap))
const siteDataString = JSON.stringify(
JSON.stringify(serializeFunctions({ ...config.site, head: [] }))
)
const siteDataString = new LivingObject({ ...config.site, head: [] })
.compile()
.complete((root) => `window.__VP_SITE_DATA__=${root}`)
const metadataContent = `window.__VP_HASH_MAP__=JSON.parse(${hashMapString});${
siteDataString.includes('_vp-fn_')
? `${deserializeFunctions};window.__VP_SITE_DATA__=deserializeFunctions(JSON.parse(${siteDataString}));`
: `window.__VP_SITE_DATA__=JSON.parse(${siteDataString});`
}`
const metadataContent = `{window.__VP_HASH_MAP__=JSON.parse(${hashMapString});${siteDataString};}`
if (!config.metaChunk) {
return { html: `<script>${metadataContent}</script>`, inHead: false }

@ -28,7 +28,7 @@ import { rewritesPlugin } from './plugins/rewritesPlugin'
import { staticDataPlugin } from './plugins/staticDataPlugin'
import { webFontsPlugin } from './plugins/webFontsPlugin'
import { slash, type PageDataPayload } from './shared'
import { deserializeFunctions, serializeFunctions } from './utils/fnSerialize'
import { stringify as serializeSiteData } from 'living-object'
declare module 'vite' {
interface UserConfig {
@ -198,8 +198,7 @@ export async function createVitePressPlugin(
return `export default window.__VP_SITE_DATA__`
}
}
data = serializeFunctions(data)
return `${deserializeFunctions};export default deserializeFunctions(JSON.parse(${JSON.stringify(JSON.stringify(data))}))`
return serializeSiteData(data, { target: 'module' })
}
},

@ -1,42 +0,0 @@
export function serializeFunctions(value: any, key?: string): any {
if (Array.isArray(value)) {
return value.map((v) => serializeFunctions(v))
} else if (typeof value === 'object' && value !== null) {
return Object.keys(value).reduce((acc, key) => {
if (key[0] === '_') return acc
acc[key] = serializeFunctions(value[key], key)
return acc
}, {} as any)
} else if (typeof value === 'function') {
let serialized = value.toString()
if (
key &&
(serialized.startsWith(key) || serialized.startsWith('async ' + key))
) {
serialized = serialized.replace(key, 'function')
}
return `_vp-fn_${serialized}`
} else {
return value
}
}
/*
export function deserializeFunctions(value: any): any {
if (Array.isArray(value)) {
return value.map(deserializeFunctions)
} else if (typeof value === 'object' && value !== null) {
return Object.keys(value).reduce((acc, key) => {
acc[key] = deserializeFunctions(value[key])
return acc
}, {} as any)
} else if (typeof value === 'string' && value.startsWith('_vp-fn_')) {
return new Function(`return ${value.slice(7)}`)()
} else {
return value
}
}
*/
export const deserializeFunctions =
'function deserializeFunctions(r){return Array.isArray(r)?r.map(deserializeFunctions):typeof r=="object"&&r!==null?Object.keys(r).reduce((t,n)=>(t[n]=deserializeFunctions(r[n]),t),{}):typeof r=="string"&&r.startsWith("_vp-fn_")?new Function(`return ${r.slice(7)}`)():r}'
Loading…
Cancel
Save