diff --git a/esbuild.mjs b/esbuild.mjs
index 2d18ae3a..30480e0c 100644
--- a/esbuild.mjs
+++ b/esbuild.mjs
@@ -3,7 +3,7 @@ import * as esbuild from 'esbuild'
import fs from 'fs'
// import htmlPlugin from '@chialab/esbuild-plugin-html'
import server from './server.js'
-import { clients, plugins } from './scripts/esbuildPlugins.mjs'
+import { clients, plugins, setSingleFileBuild } from './scripts/esbuildPlugins.mjs'
import { generateSW } from 'workbox-build'
import { getSwAdditionalEntries } from './scripts/build.js'
import { build } from 'esbuild'
@@ -11,7 +11,11 @@ import { build } from 'esbuild'
//@ts-ignore
try { await import('./localSettings.mjs') } catch { }
-fs.writeFileSync('dist/index.html', fs.readFileSync('index.html', 'utf8').replace('', ''), 'utf8')
+const singleFileBuild = false
+
+setSingleFileBuild(singleFileBuild)
+
+fs.writeFileSync('./dist/index.html', fs.readFileSync('index.html', 'utf8').replace('', ''), 'utf8')
const watch = process.argv.includes('--watch') || process.argv.includes('-w')
const prod = process.argv.includes('--prod')
diff --git a/prismarine-viewer/esbuild.mjs b/prismarine-viewer/esbuild.mjs
index 91b787db..900895ad 100644
--- a/prismarine-viewer/esbuild.mjs
+++ b/prismarine-viewer/esbuild.mjs
@@ -6,6 +6,7 @@ import * as esbuild from 'esbuild'
import { polyfillNode } from 'esbuild-plugin-polyfill-node'
import path, { dirname, join } from 'path'
import { fileURLToPath } from 'url'
+import { spawn } from 'child_process'
const dev = process.argv.includes('-w')
@@ -22,17 +23,20 @@ fs.copyFileSync(join(__dirname, 'playground.html'), join(__dirname, 'public/inde
fsExtra.copySync(mcDataPath, join(__dirname, 'public/mc-data'))
const availableVersions = fs.readdirSync(mcDataPath).map(ver => ver.replace('.js', ''))
+const headlessBuild = process.argv.includes('--headless')
+let prevExec
+
/** @type {import('esbuild').BuildOptions} */
const buildOptions = {
bundle: true,
- entryPoints: [join(__dirname, './examples/playground.ts')],
+ entryPoints: [join(__dirname, headlessBuild ? './examples/headless.js' : './examples/playground.ts')],
// target: ['es2020'],
// logLevel: 'debug',
logLevel: 'info',
- platform: 'browser',
+ platform: headlessBuild ? 'node' : 'browser',
sourcemap: dev ? 'inline' : false,
minify: !dev,
- outfile: join(__dirname, 'public/playground.js'),
+ outfile: join(__dirname, headlessBuild ? 'public/headless.js' : 'public/playground.js'),
mainFields: [
'browser', 'module', 'main'
],
@@ -48,42 +52,53 @@ const buildOptions = {
stream: 'stream-browserify',
net: 'net-browserify',
},
+ external: headlessBuild ? ['minecraft-data'] : [],
inject: [],
metafile: true,
loader: {
'.png': 'dataurl',
},
plugins: [
- {
- name: 'minecraft-data',
+ ...headlessBuild ? [{
+ name: 'starter',
setup (build) {
- build.onLoad({
- filter: /minecraft-data[\/\\]data.js$/,
- }, () => {
- const defaultVersionsObj = {}
- return {
- contents: `window.mcData ??= ${JSON.stringify(defaultVersionsObj)};module.exports = { pc: window.mcData }`,
- loader: 'js',
- }
- })
- build.onEnd((e) => {
- if (e.errors.length) return
- fs.writeFileSync(join(__dirname, 'public/metafile.json'), JSON.stringify(e.metafile), 'utf8')
+ prevExec?.kill()
+ prevExec = spawn(`node`, [join(__dirname, 'public/headless.js')], {
+ stdio: 'inherit'
})
}
- },
- polyfillNode({
- polyfills: {
- fs: false,
- crypto: false,
- events: false,
- http: false,
- stream: false,
- buffer: false,
- perf_hooks: false,
- net: false,
+ }] : [
+ {
+ name: 'minecraft-data',
+ setup (build) {
+ build.onLoad({
+ filter: /minecraft-data[\/\\]data.js$/,
+ }, () => {
+ const defaultVersionsObj = {}
+ return {
+ contents: `window.mcData ??= ${JSON.stringify(defaultVersionsObj)};module.exports = { pc: window.mcData }`,
+ loader: 'js',
+ }
+ })
+ build.onEnd((e) => {
+ if (e.errors.length) return
+ fs.writeFileSync(join(__dirname, 'public/metafile.json'), JSON.stringify(e.metafile), 'utf8')
+ })
+ }
},
- })
+ polyfillNode({
+ polyfills: {
+ fs: false,
+ crypto: false,
+ events: false,
+ http: false,
+ stream: false,
+ buffer: false,
+ perf_hooks: false,
+ net: false,
+ },
+ })
+ ]
],
}
if (dev) {
diff --git a/scripts/esbuildPlugins.mjs b/scripts/esbuildPlugins.mjs
index 07938c6e..978157ff 100644
--- a/scripts/esbuildPlugins.mjs
+++ b/scripts/esbuildPlugins.mjs
@@ -12,6 +12,9 @@ const { supportedVersions } = MCProtocol
const prod = process.argv.includes('--prod')
let connectedClients = []
+let singleFileBuild = false
+export const setSingleFileBuild = (v) => singleFileBuild = v
+
/** @type {import('esbuild').Plugin[]} */
const plugins = [
{
@@ -64,11 +67,26 @@ const plugins = [
}
})
- build.onEnd(async ({ metafile, outputFiles }) => {
+ build.onEnd(async ({ metafile, outputFiles = [], errors }) => {
+ if (errors.length) return
// write outputFiles
- //@ts-ignore
- for (const file of outputFiles) {
- await fs.promises.writeFile(file.path, file.contents)
+ if (singleFileBuild) {
+ const jsFile = outputFiles.find(outputFile => outputFile.path.endsWith('.js'))?.contents
+ const cssFile = outputFiles.find(outputFile => outputFile.path.endsWith('.css'))?.contents
+ let html = fs.readFileSync('./index.html', 'utf8')
+ html = html.replace('', ``)
+ html = html.replace('', ``)
+
+ const favicon = fs.readFileSync('./assets/favicon.png', 'base64')
+ html = html.replace(``, ``)
+ html = html.replace('', '')
+ html = html.replace('', '')
+ fs.writeFileSync('./dist/minecraft.html', html)
+ outputFiles
+ } else {
+ for (const file of outputFiles) {
+ await fs.promises.writeFile(file.path, file.contents)
+ }
}
if (!prod) return
// const deps = Object.entries(metafile.inputs).sort(([, a], [, b]) => b.bytes - a.bytes).map(([x, { bytes }]) => [x, filesize(bytes)]).slice(0, 5)
@@ -133,7 +151,7 @@ const plugins = [
}
// write metafile to disk if needed to analyze
- // fs.writeFileSync('dist/meta.json', JSON.stringify(metafile, null, 2))
+ fs.writeFileSync('dist/meta.json', JSON.stringify(metafile, null, 2))
/** @type {import('esbuild').OutputFile} */
//@ts-ignore
diff --git a/src/react/Slider.tsx b/src/react/Slider.tsx
index bc6c5890..73468fe6 100644
--- a/src/react/Slider.tsx
+++ b/src/react/Slider.tsx
@@ -55,6 +55,9 @@ const Slider: React.FC = ({
max={max}
value={value}
disabled={!!disabledReason}
+ onPointerDown={(e) => {
+ (e.target as HTMLElement).setPointerCapture(e.pointerId)
+ }}
onChange={(e) => {
const newValue = Number(e.target.value)
setValue(newValue)