Remove unnecessary json parse and stringify step when importing

This commit is contained in:
Misode
2024-10-24 15:57:14 +02:00
parent 9f1ae01d91
commit ee655b39e5
7 changed files with 28 additions and 102 deletions

View File

@@ -1,8 +1,8 @@
import { useCallback, useMemo, useRef, useState } from 'preact/hooks'
import config from '../../Config.js'
import { deepClone, deepEqual, writeZip } from '../../Utils.js'
import { useVersion } from '../../contexts/Version.jsx'
import { stringifySource } from '../../services/Source.js'
import { deepClone, deepEqual, writeZip } from '../../Utils.js'
import { Btn } from '../Btn.jsx'
import { ErrorPanel } from '../ErrorPanel.jsx'
import { Octicon } from '../Octicon.jsx'
@@ -44,11 +44,11 @@ export function CustomizedPanel({ tab }: Props) {
const entries = Object.entries(pack).flatMap(([type, files]) => {
const prefix = `data/minecraft/${type}/`
return [...files.entries()].map(([name, data]) => {
return [prefix + name + '.json', stringifySource(data, 'json')] as [string, string]
return [prefix + name + '.json', stringifySource(JSON.stringify(data, null, 2), 'json')] as [string, string]
})
})
const pack_format = config.versions.find(v => v.id === version)!.pack_format
entries.push(['pack.mcmeta', stringifySource({ pack: { pack_format, description: 'Customized world from misode.github.io' } }, 'json')])
entries.push(['pack.mcmeta', stringifySource(JSON.stringify({ pack: { pack_format, description: 'Customized world from misode.github.io' } }, null, 2), 'json')])
const url = await writeZip(entries)
download.current.setAttribute('href', url)
download.current.setAttribute('download', 'customized.zip')

View File

@@ -48,7 +48,8 @@ export function ProjectCreation({ onClose }: Props) {
const file = disectFilePath(entry[0], version)
if (file) {
try {
const data = await parseSource(entry[1], 'json')
const text = await parseSource(entry[1], 'json')
const data = JSON.parse(text)
project.files!.push({ ...file, data })
return
} catch (e) {

View File

@@ -70,14 +70,14 @@ export function ProjectPanel({ onRename, onCreate, onDeleteProject }: Props) {
const path = getFilePath(file, version)
if (path === undefined) return []
if (path === 'pack.mcmeta') hasPack = true
return [[path, stringifySource(file.data)]] as [string, string][]
return [[path, stringifySource(JSON.stringify(file.data))]] as [string, string][]
})
project.unknownFiles?.forEach(({ path, data }) => {
entries.push([path, data])
})
if (!hasPack) {
const pack_format = config.versions.find(v => v.id === version)!.pack_format
entries.push(['pack.mcmeta', stringifySource({ pack: { pack_format, description: '' } })])
entries.push(['pack.mcmeta', stringifySource(JSON.stringify({ pack: { pack_format, description: '' } }, null, 2))])
}
const url = await writeZip(entries)
download.current.setAttribute('href', url)

View File

@@ -4,7 +4,7 @@ import { useCallback, useEffect, useRef, useState } from 'preact/hooks'
import { useLocale } from '../../contexts/index.js'
import { useDocAndNode, useSpyglass } from '../../contexts/Spyglass.jsx'
import { useLocalStorage } from '../../hooks/index.js'
import { getSourceFormats, getSourceIndent, getSourceIndents, parseSource, sortData, stringifySource } from '../../services/index.js'
import { getSourceFormats, getSourceIndent, getSourceIndents, parseSource, stringifySource } from '../../services/index.js'
import { Store } from '../../Store.js'
import { message } from '../../Utils.js'
import { Btn, BtnMenu } from '../index.js'
@@ -40,11 +40,11 @@ export function SourcePanel({ docAndNode, doCopy, doDownload, doImport, copySucc
const editor = useRef<Editor>()
const getSerializedOutput = useCallback((text: string) => {
let data = JSON.parse(text)
if (sort === 'alphabetically') {
data = sortData(data)
}
return stringifySource(data, format, indent)
// TODO: implement sort
// if (sort === 'alphabetically') {
// data = sortData(data)
// }
return stringifySource(text, format, indent)
}, [indent, format, sort])
const text = useDocAndNode(docAndNode)?.doc.getText()
@@ -75,8 +75,8 @@ export function SourcePanel({ docAndNode, doCopy, doDownload, doImport, copySucc
if (value.length === 0) return
if (!service || !docAndNode) return
try {
const data = await parseSource(value, format)
await service.writeFile(docAndNode.doc.uri, JSON.stringify(data))
const text = await parseSource(value, format)
await service.writeFile(docAndNode.doc.uri, text)
} catch (e) {
if (e instanceof Error) {
e.message = `Error importing: ${e.message}`

View File

@@ -10,28 +10,18 @@ const INDENTS: Record<string, number | string | undefined> = {
minified: undefined,
}
// eslint-disable-next-line @typescript-eslint/consistent-type-imports
let commentJson: typeof import('comment-json') | null = null
const FORMATS: Record<string, {
parse: (v: string) => Promise<unknown>,
stringify: (v: unknown, indentation: string | number | undefined) => string,
parse: (source: string) => string,
stringify: (source: string, indent: string | number | undefined) => string,
}> = {
json: {
parse: async (v) => {
try {
return JSON.parse(v)
} catch (e) {
commentJson = await import('comment-json')
return commentJson.parse(v)
}
},
stringify: (v, i) => (commentJson ?? JSON).stringify(v, null, i) + '\n',
parse: (s) => s,
stringify: (s) => s,
},
snbt: {
parse: async (v) => NbtTag.fromString(v).toSimplifiedJson(),
stringify: (v, i) => {
const tag = jsonToNbt(v)
parse: (s) => JSON.stringify(NbtTag.fromString(s).toSimplifiedJson(), null, 2),
stringify: (s, i) => {
const tag = jsonToNbt(JSON.parse(s))
if (i === undefined) {
return tag.toString()
}
@@ -39,20 +29,20 @@ const FORMATS: Record<string, {
},
},
yaml: {
parse: async (v) => yaml.load(v),
stringify: (v, i) => yaml.dump(v, {
parse: (s) => JSON.stringify(yaml.load(s), null, 2),
stringify: (s, i) => yaml.dump(JSON.parse(s), {
flowLevel: i === undefined ? 0 : -1,
indent: typeof i === 'string' ? 4 : i,
}),
},
}
export function stringifySource(data: unknown, format?: string, indent?: string) {
return FORMATS[format ?? Store.getFormat()].stringify(data, INDENTS[indent ?? Store.getIndent()])
export function stringifySource(source: string, format?: string, indent?: string) {
return FORMATS[format ?? Store.getFormat()].stringify(source, INDENTS[indent ?? Store.getIndent()])
}
export async function parseSource(data: string, format: string) {
return await FORMATS[format].parse(data)
export async function parseSource(source: string, format: string) {
return FORMATS[format].parse(source)
}
export function getSourceIndent(indent: string) {