mirror of
https://github.com/misode/misode.github.io.git
synced 2026-04-24 07:37:10 +00:00
Refactor spyglass service and context
This commit is contained in:
@@ -18,18 +18,23 @@ type ErrorPanelProps = {
|
||||
}
|
||||
export function ErrorPanel({ error, prefix, reportable, onDismiss, body: body_, children }: ErrorPanelProps) {
|
||||
const { version } = useVersion()
|
||||
const { spyglass } = useSpyglass()
|
||||
const { service } = useSpyglass()
|
||||
const [stackVisible, setStackVisible] = useState(false)
|
||||
const [stack, setStack] = useState<string | undefined>(undefined)
|
||||
|
||||
const name = (prefix ?? '') + (error instanceof Error ? error.message : error)
|
||||
const gen = getGenerator(getCurrentUrl())
|
||||
const { value: source } = useAsync(async () => {
|
||||
if (gen) {
|
||||
return await spyglass?.readFile(spyglass.getUnsavedFileUri(version, gen))
|
||||
if (!service || !gen) {
|
||||
return undefined
|
||||
}
|
||||
return undefined
|
||||
}, [spyglass, version, gen])
|
||||
// TODO: read project file if open
|
||||
const uri = service.getUnsavedFileUri(gen)
|
||||
if (!uri) {
|
||||
return undefined
|
||||
}
|
||||
return await service.readFile(uri)
|
||||
}, [service, version, gen])
|
||||
|
||||
useEffect(() => {
|
||||
if (error instanceof Error) {
|
||||
|
||||
@@ -21,7 +21,7 @@ interface Props {
|
||||
export function SchemaGenerator({ gen, allowedVersions }: Props) {
|
||||
const { locale } = useLocale()
|
||||
const { version, changeVersion, changeTargetVersion } = useVersion()
|
||||
const { spyglass } = useSpyglass()
|
||||
const { service } = useSpyglass()
|
||||
const { projects, project, file, updateProject, updateFile, closeFile } = useProject()
|
||||
const [error, setError] = useState<Error | string | null>(null)
|
||||
const [errorBoundary, errorRetry] = useErrorBoundary()
|
||||
@@ -34,8 +34,8 @@ export function SchemaGenerator({ gen, allowedVersions }: Props) {
|
||||
|
||||
const uri = useMemo(() => {
|
||||
// TODO: return different uri when project file is open
|
||||
return spyglass?.getUnsavedFileUri(version, gen)
|
||||
}, [spyglass, version, gen])
|
||||
return service?.getUnsavedFileUri(gen)
|
||||
}, [service, version, gen])
|
||||
|
||||
const [currentPreset, setCurrentPreset] = useSearchParam('preset')
|
||||
const [sharedSnippetId, setSharedSnippetId] = useSearchParam(SHARE_KEY)
|
||||
@@ -82,14 +82,17 @@ export function SchemaGenerator({ gen, allowedVersions }: Props) {
|
||||
ignoreChange.current = true
|
||||
data = file.data
|
||||
}
|
||||
if (!service || !uri) {
|
||||
return AsyncCancel
|
||||
}
|
||||
if (data) {
|
||||
await spyglass.writeFile(version, uri, JSON.stringify(data))
|
||||
await service.writeFile(uri, JSON.stringify(data))
|
||||
}
|
||||
// TODO: if data is undefined, set to generator's default
|
||||
const docAndNode = await spyglass.getFile(version, uri, () => '{}')
|
||||
const docAndNode = await service.getFile(uri, () => '{}')
|
||||
Analytics.setGenerator(gen.id)
|
||||
return docAndNode
|
||||
}, [gen.id, version, sharedSnippetId, currentPreset, project.name, file?.id, spyglass])
|
||||
}, [gen.id, version, sharedSnippetId, currentPreset, project.name, file?.id, service])
|
||||
|
||||
const { doc } = docAndNode ?? {}
|
||||
|
||||
@@ -112,23 +115,32 @@ export function SchemaGenerator({ gen, allowedVersions }: Props) {
|
||||
}
|
||||
const undo = async (e: MouseEvent) => {
|
||||
e.stopPropagation()
|
||||
if (!service || !uri) {
|
||||
return
|
||||
}
|
||||
Analytics.undoGenerator(gen.id, 1, 'menu')
|
||||
await spyglass.undoEdits(version, uri)
|
||||
await service.undoEdits(uri)
|
||||
}
|
||||
const redo = async (e: MouseEvent) => {
|
||||
e.stopPropagation()
|
||||
if (!service || !uri) {
|
||||
return
|
||||
}
|
||||
Analytics.redoGenerator(gen.id, 1, 'menu')
|
||||
await spyglass.redoEdits(version, uri)
|
||||
await service?.redoEdits(uri)
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
const onKeyUp = async (e: KeyboardEvent) => {
|
||||
if (!service || !uri) {
|
||||
return
|
||||
}
|
||||
if (e.ctrlKey && e.key === 'z') {
|
||||
Analytics.undoGenerator(gen.id, 1, 'hotkey')
|
||||
await spyglass.undoEdits(version, uri)
|
||||
await service.undoEdits(uri)
|
||||
} else if (e.ctrlKey && e.key === 'y') {
|
||||
Analytics.redoGenerator(gen.id, 1, 'hotkey')
|
||||
await spyglass.redoEdits(version, uri)
|
||||
await service.redoEdits(uri)
|
||||
}
|
||||
}
|
||||
const onKeyDown = (e: KeyboardEvent) => {
|
||||
@@ -145,7 +157,7 @@ export function SchemaGenerator({ gen, allowedVersions }: Props) {
|
||||
document.removeEventListener('keyup', onKeyUp)
|
||||
document.removeEventListener('keydown', onKeyDown)
|
||||
}
|
||||
}, [gen.id, spyglass, version, uri])
|
||||
}, [gen.id, service, uri])
|
||||
|
||||
const { value: presets } = useAsync(async () => {
|
||||
const registries = await fetchRegistries(version)
|
||||
@@ -338,7 +350,7 @@ export function SchemaGenerator({ gen, allowedVersions }: Props) {
|
||||
<PreviewPanel docAndNode={docAndNode} id={gen.id} shown={previewShown} onError={setError} />
|
||||
</div>
|
||||
<div class={`popup-source${sourceShown ? ' shown' : ''}`}>
|
||||
<SourcePanel spyglass={spyglass} docAndNode={docAndNode} {...{doCopy, doDownload, doImport}} copySuccess={copySuccess} onError={setError} />
|
||||
<SourcePanel docAndNode={docAndNode} {...{doCopy, doDownload, doImport}} copySuccess={copySuccess} onError={setError} />
|
||||
</div>
|
||||
<div class={`popup-share${shareShown ? ' shown' : ''}`}>
|
||||
<TextInput value={shareUrl} readonly />
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
import type { DocAndNode } from '@spyglassmc/core'
|
||||
import { fileUtil } from '@spyglassmc/core'
|
||||
import { useCallback, useEffect, useRef, useState } from 'preact/hooks'
|
||||
import { useLocale, useVersion } from '../../contexts/index.js'
|
||||
import { useDocAndNode } from '../../contexts/Spyglass.jsx'
|
||||
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 type { Spyglass } from '../../services/Spyglass.js'
|
||||
import { Store } from '../../Store.js'
|
||||
import { message } from '../../Utils.js'
|
||||
import { Btn, BtnMenu } from '../index.js'
|
||||
@@ -18,7 +17,6 @@ interface Editor {
|
||||
}
|
||||
|
||||
type SourcePanelProps = {
|
||||
spyglass: Spyglass | undefined,
|
||||
docAndNode: DocAndNode | undefined,
|
||||
doCopy?: number,
|
||||
doDownload?: number,
|
||||
@@ -26,9 +24,9 @@ type SourcePanelProps = {
|
||||
copySuccess: () => unknown,
|
||||
onError: (message: string | Error) => unknown,
|
||||
}
|
||||
export function SourcePanel({ spyglass, docAndNode, doCopy, doDownload, doImport, copySuccess, onError }: SourcePanelProps) {
|
||||
export function SourcePanel({ docAndNode, doCopy, doDownload, doImport, copySuccess, onError }: SourcePanelProps) {
|
||||
const { locale } = useLocale()
|
||||
const { version } = useVersion()
|
||||
const { service } = useSpyglass()
|
||||
const [indent, setIndent] = useState(Store.getIndent())
|
||||
const [format, setFormat] = useState(Store.getFormat())
|
||||
const [sort, setSort] = useLocalStorage('misode_output_sort', 'schema')
|
||||
@@ -75,10 +73,10 @@ export function SourcePanel({ spyglass, docAndNode, doCopy, doDownload, doImport
|
||||
if (!editor.current) return
|
||||
const value = editor.current.getValue()
|
||||
if (value.length === 0) return
|
||||
if (!spyglass || !docAndNode) return
|
||||
if (!service || !docAndNode) return
|
||||
try {
|
||||
const data = await parseSource(value, format)
|
||||
await spyglass.writeFile(version, docAndNode.doc.uri, JSON.stringify(data))
|
||||
await service.writeFile(docAndNode.doc.uri, JSON.stringify(data))
|
||||
} catch (e) {
|
||||
if (e instanceof Error) {
|
||||
e.message = `Error importing: ${e.message}`
|
||||
@@ -89,7 +87,7 @@ export function SourcePanel({ spyglass, docAndNode, doCopy, doDownload, doImport
|
||||
console.error(e)
|
||||
}
|
||||
}
|
||||
}, [spyglass, version, docAndNode, text, indent, format, sort, highlighting])
|
||||
}, [service, docAndNode, text, indent, format, sort, highlighting])
|
||||
|
||||
useEffect(() => {
|
||||
if (highlighting) {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import type { DocAndNode } from '@spyglassmc/core'
|
||||
import { JsonFileNode } from '@spyglassmc/json'
|
||||
import { useCallback, useErrorBoundary } from 'preact/hooks'
|
||||
import { useLocale, useVersion } from '../../contexts/index.js'
|
||||
import { useLocale } from '../../contexts/index.js'
|
||||
import { useDocAndNode, useSpyglass } from '../../contexts/Spyglass.jsx'
|
||||
import type { Edit } from '../../services/Spyglass.js'
|
||||
import { McdocRoot } from './McdocRenderer.jsx'
|
||||
@@ -12,8 +12,7 @@ type TreePanelProps = {
|
||||
}
|
||||
export function Tree({ docAndNode, onError }: TreePanelProps) {
|
||||
const { lang } = useLocale()
|
||||
const { version } = useVersion()
|
||||
const { spyglass } = useSpyglass()
|
||||
const { service } = useSpyglass()
|
||||
|
||||
if (lang === 'none') return <></>
|
||||
|
||||
@@ -29,8 +28,11 @@ export function Tree({ docAndNode, onError }: TreePanelProps) {
|
||||
if (error) return <></>
|
||||
|
||||
const makeEdits = useCallback((edits: Edit[]) => {
|
||||
spyglass.applyEdits(version, docAndNode.doc.uri, edits)
|
||||
}, [spyglass, version, docAndNode])
|
||||
if (!service) {
|
||||
return
|
||||
}
|
||||
service.applyEdits(docAndNode.doc.uri, edits)
|
||||
}, [service, docAndNode])
|
||||
|
||||
return <div class="tree node-root" data-cy="tree">
|
||||
<McdocRoot node={fileChild.children[0]} makeEdits={makeEdits} />
|
||||
|
||||
@@ -3,10 +3,14 @@ import type { ComponentChildren } from 'preact'
|
||||
import { createContext } from 'preact'
|
||||
import type { Inputs } from 'preact/hooks'
|
||||
import { useContext, useEffect, useState } from 'preact/hooks'
|
||||
import { Spyglass } from '../services/Spyglass.js'
|
||||
import { useAsync } from '../hooks/useAsync.js'
|
||||
import type { SpyglassService } from '../services/Spyglass.js'
|
||||
import { SpyglassClient } from '../services/Spyglass.js'
|
||||
import { useVersion } from './Version.jsx'
|
||||
|
||||
interface SpyglassContext {
|
||||
spyglass: Spyglass,
|
||||
client: SpyglassClient
|
||||
service: SpyglassService | undefined
|
||||
}
|
||||
|
||||
const SpyglassContext = createContext<SpyglassContext | undefined>(undefined)
|
||||
@@ -24,15 +28,15 @@ export function watchSpyglassUri(
|
||||
handler: (docAndNode: DocAndNode) => void,
|
||||
inputs: Inputs = [],
|
||||
) {
|
||||
const { spyglass } = useSpyglass()
|
||||
const { service } = useSpyglass()
|
||||
|
||||
useEffect(() => {
|
||||
if (!uri || !spyglass) {
|
||||
if (!uri || !service) {
|
||||
return
|
||||
}
|
||||
spyglass.watchFile(uri, handler)
|
||||
return () => spyglass.unwatchFile(uri, handler)
|
||||
}, [spyglass, uri, handler, ...inputs])
|
||||
service.watchFile(uri, handler)
|
||||
return () => service.unwatchFile(uri, handler)
|
||||
}, [service, uri, handler, ...inputs])
|
||||
}
|
||||
|
||||
export function useDocAndNode(original: DocAndNode, inputs?: Inputs): DocAndNode
|
||||
@@ -52,10 +56,24 @@ export function useDocAndNode(original: DocAndNode | undefined, inputs: Inputs =
|
||||
}
|
||||
|
||||
export function SpyglassProvider({ children }: { children: ComponentChildren }) {
|
||||
const [spyglass] = useState(new Spyglass())
|
||||
const { version } = useVersion()
|
||||
const [client] = useState(new SpyglassClient())
|
||||
|
||||
const { value: service, error } = useAsync(() => {
|
||||
return client.createService(version)
|
||||
}, [client, version])
|
||||
|
||||
useEffect(() => {
|
||||
if (error) {
|
||||
console.warn(error)
|
||||
}
|
||||
}, [error])
|
||||
|
||||
console.log('->', service)
|
||||
|
||||
const value: SpyglassContext = {
|
||||
spyglass,
|
||||
client,
|
||||
service,
|
||||
}
|
||||
|
||||
return <SpyglassContext.Provider value={value}>
|
||||
|
||||
@@ -22,15 +22,14 @@ export interface Edit {
|
||||
text: string
|
||||
}
|
||||
|
||||
interface DocumentData {
|
||||
interface ClientDocument {
|
||||
doc: TextDocument
|
||||
undoStack: string[]
|
||||
redoStack: string[]
|
||||
}
|
||||
|
||||
export class Spyglass {
|
||||
private static readonly LOGGER: core.Logger = console
|
||||
private static readonly EXTERNALS: core.Externals = {
|
||||
export class SpyglassClient {
|
||||
public readonly externals: core.Externals = {
|
||||
...BrowserExternals,
|
||||
archive: {
|
||||
...BrowserExternals.archive,
|
||||
@@ -38,65 +37,81 @@ export class Spyglass {
|
||||
},
|
||||
}
|
||||
|
||||
private readonly instances = new Map<VersionId, Promise<core.Service>>()
|
||||
private readonly documents = new Map<string, DocumentData>()
|
||||
public readonly documents = new Map<string, ClientDocument>()
|
||||
|
||||
public async createService(version: VersionId) {
|
||||
return SpyglassService.create(version, this)
|
||||
}
|
||||
}
|
||||
|
||||
export class SpyglassService {
|
||||
private readonly watchers = new Map<string, ((docAndNode: core.DocAndNode) => void)[]>()
|
||||
|
||||
public async getFile(version: VersionId, uri: string, emptyContent?: () => string) {
|
||||
const service = await this.getService(version)
|
||||
const document = this.documents.get(uri)
|
||||
let docAndNode: core.DocAndNode | undefined
|
||||
if (document === undefined) {
|
||||
Spyglass.LOGGER.info(`[Spyglass#openFile] Opening file with content from fs: ${uri}`)
|
||||
private constructor (
|
||||
public readonly version: VersionId,
|
||||
private readonly service: core.Service,
|
||||
private readonly client: SpyglassClient,
|
||||
) {
|
||||
service.project.on('documentUpdated', (e) => {
|
||||
const uriWatchers = this.watchers.get(e.doc.uri) ?? []
|
||||
for (const handler of uriWatchers) {
|
||||
handler(e)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
public async getFile(uri: string, emptyContent?: () => string) {
|
||||
let docAndNode = this.service.project.getClientManaged(uri)
|
||||
if (docAndNode === undefined) {
|
||||
console.info(`[Spyglass#openFile] Opening file with content from fs: ${uri}`)
|
||||
const content = await this.readFile(uri)
|
||||
const doc = TextDocument.create(uri, 'json', 1, content ?? (emptyContent ? emptyContent() : ''))
|
||||
this.documents.set(uri, { doc, undoStack: [], redoStack: [] })
|
||||
await service.project.onDidOpen(doc.uri, doc.languageId, doc.version, doc.getText())
|
||||
docAndNode = await service.project.ensureClientManagedChecked(uri)
|
||||
} else {
|
||||
Spyglass.LOGGER.info(`[Spyglass#openFile] Opening already open file: ${uri}`)
|
||||
docAndNode = service.project.getClientManaged(uri)
|
||||
await this.service.project.onDidOpen(doc.uri, doc.languageId, doc.version, doc.getText())
|
||||
docAndNode = await this.service.project.ensureClientManagedChecked(uri)
|
||||
}
|
||||
if (!docAndNode) {
|
||||
throw new Error(`[Spyglass#openFile] Cannot get doc and node: ${uri}`)
|
||||
}
|
||||
const document = this.client.documents.get(uri)
|
||||
if (document === undefined) {
|
||||
this.client.documents.set(uri, { doc: docAndNode.doc, undoStack: [], redoStack: [] })
|
||||
}
|
||||
return docAndNode
|
||||
}
|
||||
|
||||
public async readFile(uri: string): Promise<string | undefined> {
|
||||
try {
|
||||
const buffer = await Spyglass.EXTERNALS.fs.readFile(uri)
|
||||
const buffer = await this.service.project.externals.fs.readFile(uri)
|
||||
return new TextDecoder().decode(buffer)
|
||||
} catch (e) {
|
||||
return undefined
|
||||
}
|
||||
}
|
||||
|
||||
private async notifyChange(versionId: VersionId, doc: TextDocument) {
|
||||
const service = await this.getService(versionId)
|
||||
await service.project.onDidChange(doc.uri, [{ text: doc.getText() }], doc.version + 1)
|
||||
const docAndNode = service.project.getClientManaged(doc.uri)
|
||||
private async notifyChange(doc: TextDocument) {
|
||||
await this.service.project.onDidChange(doc.uri, [{ text: doc.getText() }], doc.version + 1)
|
||||
const docAndNode = this.service.project.getClientManaged(doc.uri)
|
||||
if (docAndNode) {
|
||||
service.project.emit('documentUpdated', docAndNode)
|
||||
this.service.project.emit('documentUpdated', docAndNode)
|
||||
}
|
||||
return docAndNode
|
||||
}
|
||||
|
||||
public async writeFile(versionId: VersionId, uri: string, content: string) {
|
||||
const document = this.documents.get(uri)
|
||||
public async writeFile(uri: string, content: string) {
|
||||
const document = this.client.documents.get(uri)
|
||||
if (document !== undefined) {
|
||||
document.undoStack.push(document.doc.getText())
|
||||
document.redoStack = []
|
||||
TextDocument.update(document.doc, [{ text: content }], document.doc.version + 1)
|
||||
}
|
||||
await Spyglass.EXTERNALS.fs.writeFile(uri, content)
|
||||
await this.service.project.externals.fs.writeFile(uri, content)
|
||||
if (document) {
|
||||
await this.notifyChange(versionId, document.doc)
|
||||
await this.notifyChange(document.doc)
|
||||
}
|
||||
}
|
||||
|
||||
public async applyEdits(versionId: VersionId, uri: string, edits: Edit[]) {
|
||||
const document = this.documents.get(uri)
|
||||
public async applyEdits(uri: string, edits: Edit[]) {
|
||||
const document = this.client.documents.get(uri)
|
||||
if (document !== undefined) {
|
||||
document.undoStack.push(document.doc.getText())
|
||||
document.redoStack = []
|
||||
@@ -104,13 +119,13 @@ export class Spyglass {
|
||||
range: e.range ? getLsRange(e.range, document.doc) : undefined,
|
||||
text: e.text,
|
||||
})), document.doc.version + 1)
|
||||
await Spyglass.EXTERNALS.fs.writeFile(uri, document.doc.getText())
|
||||
await this.notifyChange(versionId, document.doc)
|
||||
await this.service.project.externals.fs.writeFile(uri, document.doc.getText())
|
||||
await this.notifyChange(document.doc)
|
||||
}
|
||||
}
|
||||
|
||||
public async undoEdits(versionId: VersionId, uri: string) {
|
||||
const document = this.documents.get(uri)
|
||||
public async undoEdits(uri: string) {
|
||||
const document = this.client.documents.get(uri)
|
||||
if (document === undefined) {
|
||||
throw new Error(`[Spyglass#undoEdits] Document doesn't exist: ${uri}`)
|
||||
}
|
||||
@@ -120,12 +135,12 @@ export class Spyglass {
|
||||
}
|
||||
document.redoStack.push(document.doc.getText())
|
||||
TextDocument.update(document.doc, [{ text: lastUndo }], document.doc.version + 1)
|
||||
await Spyglass.EXTERNALS.fs.writeFile(uri, document.doc.getText())
|
||||
await this.notifyChange(versionId, document.doc)
|
||||
await this.service.project.externals.fs.writeFile(uri, document.doc.getText())
|
||||
await this.notifyChange(document.doc)
|
||||
}
|
||||
|
||||
public async redoEdits(versionId: VersionId, uri: string) {
|
||||
const document = this.documents.get(uri)
|
||||
public async redoEdits(uri: string) {
|
||||
const document = this.client.documents.get(uri)
|
||||
if (document === undefined) {
|
||||
throw new Error(`[Spyglass#redoEdits] Document doesn't exist: ${uri}`)
|
||||
}
|
||||
@@ -135,15 +150,15 @@ export class Spyglass {
|
||||
}
|
||||
document.undoStack.push(document.doc.getText())
|
||||
TextDocument.update(document.doc, [{ text: lastRedo }], document.doc.version + 1)
|
||||
await Spyglass.EXTERNALS.fs.writeFile(uri, document.doc.getText())
|
||||
await this.notifyChange(versionId, document.doc)
|
||||
await this.service.project.externals.fs.writeFile(uri, document.doc.getText())
|
||||
await this.notifyChange(document.doc)
|
||||
}
|
||||
|
||||
public getUnsavedFileUri(versionId: VersionId, gen: ConfigGenerator) {
|
||||
public getUnsavedFileUri(gen: ConfigGenerator) {
|
||||
if (gen.id === 'pack_mcmeta') {
|
||||
return 'file:///project/pack.mcmeta'
|
||||
}
|
||||
return `file:///project/data/draft/${genPath(gen, versionId)}/unsaved.json`
|
||||
return `file:///project/data/draft/${genPath(gen, this.version)}/unsaved.json`
|
||||
}
|
||||
|
||||
public watchFile(uri: string, handler: (docAndNode: core.DocAndNode) => void) {
|
||||
@@ -157,44 +172,31 @@ export class Spyglass {
|
||||
uriWatchers.splice(index, 1)
|
||||
}
|
||||
|
||||
private async getService(versionId: VersionId) {
|
||||
const instance = this.instances.get(versionId)
|
||||
if (instance) {
|
||||
return instance
|
||||
}
|
||||
const promise = (async () => {
|
||||
const version = siteConfig.versions.find(v => v.id === versionId)!
|
||||
const service = new core.Service({
|
||||
logger: Spyglass.LOGGER,
|
||||
profilers: new core.ProfilerFactory(Spyglass.LOGGER, [
|
||||
'project#init',
|
||||
'project#ready',
|
||||
]),
|
||||
project: {
|
||||
cacheRoot: 'file:///cache/',
|
||||
projectRoots: ['file:///project/'],
|
||||
externals: Spyglass.EXTERNALS,
|
||||
defaultConfig: core.ConfigService.merge(core.VanillaConfig, {
|
||||
env: {
|
||||
gameVersion: version.ref ?? version.id,
|
||||
dependencies: ['@vanilla-mcdoc'],
|
||||
},
|
||||
}),
|
||||
initializers: [mcdoc.initialize, initialize],
|
||||
},
|
||||
})
|
||||
await service.project.ready()
|
||||
await service.project.cacheService.save()
|
||||
service.project.on('documentUpdated', (e) => {
|
||||
const uriWatchers = this.watchers.get(e.doc.uri) ?? []
|
||||
for (const handler of uriWatchers) {
|
||||
handler(e)
|
||||
}
|
||||
})
|
||||
return service
|
||||
})()
|
||||
this.instances.set(versionId, promise)
|
||||
return promise
|
||||
public static async create(versionId: VersionId, client: SpyglassClient) {
|
||||
const version = siteConfig.versions.find(v => v.id === versionId)!
|
||||
const logger = console
|
||||
const service = new core.Service({
|
||||
logger,
|
||||
profilers: new core.ProfilerFactory(logger, [
|
||||
'project#init',
|
||||
'project#ready',
|
||||
]),
|
||||
project: {
|
||||
cacheRoot: 'file:///cache/',
|
||||
projectRoots: ['file:///project/'],
|
||||
externals: client.externals,
|
||||
defaultConfig: core.ConfigService.merge(core.VanillaConfig, {
|
||||
env: {
|
||||
gameVersion: version.ref ?? version.id,
|
||||
dependencies: ['@vanilla-mcdoc'],
|
||||
},
|
||||
}),
|
||||
initializers: [mcdoc.initialize, initialize],
|
||||
},
|
||||
})
|
||||
await service.project.ready()
|
||||
await service.project.cacheService.save()
|
||||
return new SpyglassService(versionId, service, client)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user