mirror of
https://github.com/misode/misode.github.io.git
synced 2026-04-30 17:49:34 +00:00
Use spyglass DocAndNode to store current file data
This commit is contained in:
@@ -1,8 +1,8 @@
|
||||
import config from '../Config.js'
|
||||
import { Store } from '../Store.js'
|
||||
import { message } from '../Utils.js'
|
||||
import type { VersionId } from './Schemas.js'
|
||||
import { checkVersion } from './Schemas.js'
|
||||
import type { VersionId } from './Versions.js'
|
||||
import { checkVersion } from './Versions.js'
|
||||
|
||||
const CACHE_NAME = 'misode-v2'
|
||||
const CACHE_LATEST_VERSION = 'cached_latest_version'
|
||||
|
||||
@@ -3,7 +3,7 @@ import { BlockDefinition, BlockModel, Identifier, ItemRenderer, TextureAtlas, up
|
||||
import config from '../Config.js'
|
||||
import { message } from '../Utils.js'
|
||||
import { fetchLanguage, fetchResources } from './DataFetcher.js'
|
||||
import type { VersionId } from './Schemas.js'
|
||||
import type { VersionId } from './Versions.js'
|
||||
|
||||
const Resources: Record<string, ResourceManager | Promise<ResourceManager>> = {}
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ import { BlockDefinition, BlockModel, Identifier, ItemRenderer, TextureAtlas, up
|
||||
import config from '../Config.js'
|
||||
import { message } from '../Utils.js'
|
||||
import { fetchLanguage, fetchResources } from './DataFetcher.js'
|
||||
import type { VersionId } from './Schemas.js'
|
||||
import type { VersionId } from './Versions.js'
|
||||
|
||||
const Resources: Record<string, ResourceManager | Promise<ResourceManager>> = {}
|
||||
|
||||
|
||||
@@ -1,57 +0,0 @@
|
||||
import config from '../Config.js'
|
||||
import { message } from '../Utils.js'
|
||||
import type { BlockStateData } from './DataFetcher.js'
|
||||
import { fetchBlockStates, fetchRegistries } from './DataFetcher.js'
|
||||
|
||||
export const VersionIds = ['1.15', '1.16', '1.17', '1.18', '1.18.2', '1.19', '1.19.3', '1.19.4', '1.20', '1.20.2', '1.20.3', '1.20.5', '1.21', '1.21.2'] as const
|
||||
export type VersionId = typeof VersionIds[number]
|
||||
|
||||
export const DEFAULT_VERSION: VersionId = '1.21'
|
||||
|
||||
interface VersionData {
|
||||
registries: Map<string, string[]>
|
||||
blockStates: Map<string, BlockStateData>
|
||||
}
|
||||
|
||||
const Versions: Record<string, VersionData | Promise<VersionData>> = {}
|
||||
|
||||
async function getVersion(id: VersionId): Promise<VersionData> {
|
||||
if (!Versions[id]) {
|
||||
Versions[id] = (async () => {
|
||||
try {
|
||||
const registries = await fetchRegistries(id)
|
||||
const blockStates= await fetchBlockStates(id)
|
||||
Versions[id] = { registries, blockStates }
|
||||
return Versions[id]
|
||||
} catch (e) {
|
||||
throw new Error(`Cannot get version "${id}": ${message(e)}`)
|
||||
}
|
||||
})()
|
||||
return Versions[id]
|
||||
}
|
||||
return Versions[id]
|
||||
}
|
||||
|
||||
export async function getBlockStates(version: VersionId): Promise<Map<string, BlockStateData>> {
|
||||
const versionData = await getVersion(version)
|
||||
return versionData.blockStates
|
||||
}
|
||||
|
||||
export function checkVersion(versionId: string, minVersionId: string | undefined, maxVersionId?: string) {
|
||||
const version = config.versions.findIndex(v => v.id === versionId)
|
||||
const minVersion = minVersionId ? config.versions.findIndex(v => v.id === minVersionId) : 0
|
||||
const maxVersion = maxVersionId ? config.versions.findIndex(v => v.id === maxVersionId) : config.versions.length - 1
|
||||
return minVersion <= version && version <= maxVersion
|
||||
}
|
||||
|
||||
export interface FileModel {
|
||||
get text(): string
|
||||
get data(): any
|
||||
}
|
||||
|
||||
export function createMockFileModel(): FileModel {
|
||||
return {
|
||||
text: '{}',
|
||||
data: {},
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
import lz from 'lz-string'
|
||||
import type { VersionId } from './Schemas.js'
|
||||
import type { VersionId } from './Versions.js'
|
||||
|
||||
const API_PREFIX = 'https://snippets.misode.workers.dev'
|
||||
|
||||
|
||||
@@ -9,61 +9,87 @@ import { localize } from '@spyglassmc/locales'
|
||||
import * as mcdoc from '@spyglassmc/mcdoc'
|
||||
import * as nbt from '@spyglassmc/nbt'
|
||||
import * as zip from '@zip.js/zip.js'
|
||||
import type { ConfigVersion } from '../Config.js'
|
||||
import type { ConfigGenerator, ConfigVersion } from '../Config.js'
|
||||
import siteConfig from '../Config.js'
|
||||
import type { VersionId } from './index.js'
|
||||
import { fetchBlockStates, fetchRegistries, fetchVanillaMcdoc, getVersionChecksum } from './index.js'
|
||||
import { genPath } from '../Utils.js'
|
||||
import { fetchBlockStates, fetchRegistries, fetchVanillaMcdoc, getVersionChecksum } from './DataFetcher.js'
|
||||
import type { VersionId } from './Versions.js'
|
||||
|
||||
const externals: core.Externals = {
|
||||
...BrowserExternals,
|
||||
archive: {
|
||||
...BrowserExternals.archive,
|
||||
async decompressBall(buffer, { stripLevel } = {}) {
|
||||
const reader = new zip.ZipReader(new zip.BlobReader(new Blob([buffer])))
|
||||
const entries = await reader.getEntries()
|
||||
return await Promise.all(entries.map(async e => {
|
||||
const data = await e.getData?.(new zip.Uint8ArrayWriter())
|
||||
const path = stripLevel === 1 ? e.filename.substring(e.filename.indexOf('/') + 1) : e.filename
|
||||
const type = e.directory ? 'dir' : 'file'
|
||||
return { data, path, mtime: '', type, mode: 0 }
|
||||
}))
|
||||
},
|
||||
},
|
||||
export class Spyglass {
|
||||
private static readonly INSTANCES = new Map<VersionId, Promise<Spyglass>>()
|
||||
|
||||
private constructor(
|
||||
private readonly service: core.Service,
|
||||
private readonly version: ConfigVersion,
|
||||
) {}
|
||||
|
||||
public async setFileContents(uri: string, contents: string) {
|
||||
await this.service.project.onDidOpen(uri, 'json', 1, contents)
|
||||
const docAndNode = await this.service.project.ensureClientManagedChecked(uri)
|
||||
if (!docAndNode) {
|
||||
throw new Error('[Spyglass setFileContents] Cannot get doc and node')
|
||||
}
|
||||
return docAndNode
|
||||
}
|
||||
|
||||
public getFile(uri: string): Partial<core.DocAndNode> {
|
||||
return this.service.project.getClientManaged(uri) ?? {}
|
||||
}
|
||||
|
||||
public getUnsavedFileUri(gen: ConfigGenerator) {
|
||||
return `file:project/data/draft/${genPath(gen, this.version.id)}/unsaved.json`
|
||||
}
|
||||
|
||||
public static async initialize(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: console,
|
||||
profilers: new core.ProfilerFactory(console, [
|
||||
'project#init',
|
||||
'project#ready',
|
||||
]),
|
||||
project: {
|
||||
cacheRoot: 'file:cache/',
|
||||
projectRoots: ['file:project/'],
|
||||
externals: {
|
||||
...BrowserExternals,
|
||||
archive: {
|
||||
...BrowserExternals.archive,
|
||||
decompressBall,
|
||||
},
|
||||
},
|
||||
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 Spyglass(service, version)
|
||||
})()
|
||||
this.INSTANCES.set(versionId, promise)
|
||||
return promise
|
||||
}
|
||||
}
|
||||
|
||||
export async function setupSpyglass(versionId: VersionId) {
|
||||
const version = siteConfig.versions.find(v => v.id === versionId)!
|
||||
const gameVersion = version.ref ?? version.id
|
||||
const logger: core.Logger = console
|
||||
const profilers = new core.ProfilerFactory(logger, [
|
||||
'project#init',
|
||||
'project#ready',
|
||||
'misode#setup',
|
||||
])
|
||||
const profiler = profilers.get('misode#setup')
|
||||
const service = new core.Service({
|
||||
logger,
|
||||
profilers,
|
||||
project: {
|
||||
cacheRoot: 'file:cache/',
|
||||
projectRoots: ['file:project/'],
|
||||
externals: externals,
|
||||
defaultConfig: core.ConfigService.merge(core.VanillaConfig, {
|
||||
env: {
|
||||
gameVersion: gameVersion,
|
||||
dependencies: ['@vanilla-mcdoc'],
|
||||
},
|
||||
}),
|
||||
initializers: [mcdoc.initialize, initialize],
|
||||
},
|
||||
})
|
||||
await service.project.ready()
|
||||
profiler.task('Project ready')
|
||||
await service.project.cacheService.save()
|
||||
profiler.task('Save cache')
|
||||
profiler.finalize()
|
||||
|
||||
service.logger.info(service.project.symbols.global)
|
||||
const decompressBall: core.Externals['archive']['decompressBall'] = async (buffer, options) => {
|
||||
const reader = new zip.ZipReader(new zip.BlobReader(new Blob([buffer])))
|
||||
const entries = await reader.getEntries()
|
||||
return await Promise.all(entries.map(async e => {
|
||||
const data = await e.getData?.(new zip.Uint8ArrayWriter())
|
||||
const path = options?.stripLevel === 1 ? e.filename.substring(e.filename.indexOf('/') + 1) : e.filename
|
||||
const type = e.directory ? 'dir' : 'file'
|
||||
return { data, path, mtime: '', type, mode: 0 }
|
||||
}))
|
||||
}
|
||||
|
||||
const initialize: core.ProjectInitializer = async (ctx) => {
|
||||
|
||||
13
src/app/services/Versions.ts
Normal file
13
src/app/services/Versions.ts
Normal file
@@ -0,0 +1,13 @@
|
||||
import config from '../Config.js'
|
||||
|
||||
export const VersionIds = ['1.15', '1.16', '1.17', '1.18', '1.18.2', '1.19', '1.19.3', '1.19.4', '1.20', '1.20.2', '1.20.3', '1.20.5', '1.21', '1.21.2'] as const
|
||||
export type VersionId = typeof VersionIds[number]
|
||||
|
||||
export const DEFAULT_VERSION: VersionId = '1.21'
|
||||
|
||||
export function checkVersion(versionId: string, minVersionId: string | undefined, maxVersionId?: string) {
|
||||
const version = config.versions.findIndex(v => v.id === versionId)
|
||||
const minVersion = minVersionId ? config.versions.findIndex(v => v.id === minVersionId) : 0
|
||||
const maxVersion = maxVersionId ? config.versions.findIndex(v => v.id === maxVersionId) : config.versions.length - 1
|
||||
return minVersion <= version && version <= maxVersion
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
export * from './Article.js'
|
||||
export * from './DataFetcher.js'
|
||||
export * from './Schemas.js'
|
||||
export * from './Sharing.js'
|
||||
export * from './Source.js'
|
||||
export * from './Versions.js'
|
||||
|
||||
Reference in New Issue
Block a user