diff --git a/.gitignore b/.gitignore index 60b63c1..e1631e1 100644 --- a/.gitignore +++ b/.gitignore @@ -26,3 +26,4 @@ dist-ssr .env coverage *.tsbuildinfo +packages/core/src/version.ts diff --git a/package-lock.json b/package-lock.json index cab9e8c..ded3907 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10872,7 +10872,7 @@ }, "packages/bootstrap": { "name": "@mavonengine/create-bootstrap", - "version": "0.0.6", + "version": "0.0.7", "license": "MIT", "dependencies": { "adm-zip": "^0.5.16" @@ -10905,7 +10905,7 @@ }, "packages/core": { "name": "@mavonengine/core", - "version": "0.0.10", + "version": "0.0.14", "license": "MIT", "devDependencies": { "@dimforge/rapier3d-compat": "0.18.2", diff --git a/packages/bootstrap/package.json b/packages/bootstrap/package.json index 517505b..d5c23e6 100644 --- a/packages/bootstrap/package.json +++ b/packages/bootstrap/package.json @@ -1,7 +1,7 @@ { "name": "@mavonengine/create-bootstrap", "type": "module", - "version": "0.0.6", + "version": "0.0.7", "description": "Bootstrap a MavonEngine multiplayer project", "license": "MIT", "bin": { diff --git a/packages/bootstrap/src/config.ts b/packages/bootstrap/src/config.ts index ef944f4..0c50251 100644 --- a/packages/bootstrap/src/config.ts +++ b/packages/bootstrap/src/config.ts @@ -1,4 +1,4 @@ export const TAG_URL - = 'https://github.com/MavonEngine/Core/archive/refs/tags/0.0.11-alpha.zip' + = 'https://github.com/MavonEngine/Core/archive/refs/tags/0.0.12-alpha.zip' export const TEMPLATE_SUBPATH = 'packages/multiplayer-template' diff --git a/packages/core/package.json b/packages/core/package.json index 5ad82c2..ec1a914 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -1,7 +1,7 @@ { "name": "@mavonengine/core", "type": "module", - "version": "0.0.10", + "version": "0.0.14", "description": "", "author": "", "license": "MIT", @@ -34,8 +34,9 @@ "vite.config.js" ], "scripts": { - "build": "rm -f tsconfig.build.tsbuildinfo && tsc -p tsconfig.build.json && find src -name '*.glsl' -o -name '*.css' | while read f; do mkdir -p dist/$(dirname ${f#src/}) && cp $f dist/${f#src/}; done", - "dev": "rm -f tsconfig.build.tsbuildinfo && tsc -p tsconfig.build.json --watch", + "prepare": "node scripts/generate-version.js", + "build": "node scripts/generate-version.js && rm -f tsconfig.build.tsbuildinfo && tsc -p tsconfig.build.json && find src -name '*.glsl' -o -name '*.css' | while read f; do mkdir -p dist/$(dirname ${f#src/}) && cp $f dist/${f#src/}; done", + "dev": "node scripts/generate-version.js && rm -f tsconfig.build.tsbuildinfo && tsc -p tsconfig.build.json --watch", "lint": "eslint .", "lint:fix": "eslint . --fix", "bench": "vitest bench", diff --git a/packages/core/scripts/generate-version.js b/packages/core/scripts/generate-version.js new file mode 100644 index 0000000..c464cb2 --- /dev/null +++ b/packages/core/scripts/generate-version.js @@ -0,0 +1,11 @@ +import { readFileSync, writeFileSync } from 'node:fs' +import { dirname, resolve } from 'node:path' +import { fileURLToPath } from 'node:url' + +const __dirname = dirname(fileURLToPath(import.meta.url)) +const { version } = JSON.parse(readFileSync(resolve(__dirname, '../package.json'), 'utf8')) + +writeFileSync( + resolve(__dirname, '../src/version.ts'), + `export const version = '${version}'\n`, +) diff --git a/packages/core/src/BaseGame.ts b/packages/core/src/BaseGame.ts index afbe1ab..2a384ba 100644 --- a/packages/core/src/BaseGame.ts +++ b/packages/core/src/BaseGame.ts @@ -3,8 +3,8 @@ import type winston from 'winston' import type Logger from './Utils/Logger' import type GameObjectInterface from './World/GameObjectInterface' import { Clock, Raycaster, Scene } from 'three' -import { version as ENGINE_VERSION } from '../package.json' with { type: 'json' } import EventEmitter from './Utils/EventEmitter' +import { version as ENGINE_VERSION } from './version' import BaseWorld from './World/BaseWorld' diff --git a/packages/core/tests/vite/plugins/packageJsonPlugin.test.ts b/packages/core/tests/vite/plugins/packageJsonPlugin.test.ts deleted file mode 100644 index f888997..0000000 --- a/packages/core/tests/vite/plugins/packageJsonPlugin.test.ts +++ /dev/null @@ -1,70 +0,0 @@ -import { readFileSync } from 'node:fs' -import { beforeEach, describe, expect, it, vi } from 'vitest' -import { createPackageJsonPlugin } from '../../../vite/plugins/packageJsonPlugin.js' - -vi.mock('node:fs', () => ({ - readFileSync: vi.fn(), -})) - -describe('createPackageJsonPlugin', () => { - let resolveHandler: (args: { path: string }) => { path: string, namespace: string } - let loadHandler: (args: { path: string }) => { contents: string, loader: string } - - beforeEach(() => { - const plugin = createPackageJsonPlugin('/fake/core/root') - const mockBuild = { - onResolve: vi.fn((_: unknown, handler: typeof resolveHandler) => { - resolveHandler = handler - }), - onLoad: vi.fn((_: unknown, handler: typeof loadHandler) => { - loadHandler = handler - }), - } - plugin.setup(mockBuild) - }) - - describe('onResolve', () => { - it('resolves @mavonengine/core package.json to coreRoot', () => { - const result = resolveHandler({ path: '@mavonengine/core/package.json' }) - expect(result.path).toBe('/fake/core/root/package.json') - expect(result.namespace).toBe('mavonengine-pkg-json') - }) - - it('returns null for non-core package.json paths', () => { - const result = resolveHandler({ path: '/some/other/package.json' }) - expect(result).toBeNull() - }) - }) - - describe('onLoad', () => { - it('generates named exports for valid identifier keys', () => { - vi.mocked(readFileSync).mockReturnValue(JSON.stringify({ name: 'test-pkg', version: '1.0.0' })) - const result = loadHandler({ path: '/fake/package.json' }) - expect(result.contents).toContain('export const name = "test-pkg";') - expect(result.contents).toContain('export const version = "1.0.0";') - }) - - it('filters out non-identifier keys from named exports', () => { - vi.mocked(readFileSync).mockReturnValue( - JSON.stringify({ 'hyphen-key': 'value', '@scoped': 'foo', 'valid': 'yes' }), - ) - const result = loadHandler({ path: '/fake/package.json' }) - expect(result.contents).not.toContain('export const hyphen-key') - expect(result.contents).not.toContain('export const @scoped') - expect(result.contents).toContain('export const valid = "yes";') - }) - - it('includes a default export of the full package object', () => { - const pkg = { 'name': 'test', 'version': '1.0.0', 'non-identifier': true } - vi.mocked(readFileSync).mockReturnValue(JSON.stringify(pkg)) - const result = loadHandler({ path: '/fake/package.json' }) - expect(result.contents).toContain(`export default ${JSON.stringify(pkg)};`) - }) - - it('sets loader to js', () => { - vi.mocked(readFileSync).mockReturnValue(JSON.stringify({})) - const result = loadHandler({ path: '/fake/package.json' }) - expect(result.loader).toBe('js') - }) - }) -}) diff --git a/packages/core/vite.config.js b/packages/core/vite.config.js index b1618b6..4f3d90b 100644 --- a/packages/core/vite.config.js +++ b/packages/core/vite.config.js @@ -1,14 +1,9 @@ import { readFileSync } from 'node:fs' -import { dirname } from 'node:path' -import { fileURLToPath } from 'node:url' import { defineConfig } from 'vite' import glsl from 'vite-plugin-glsl' -import { createPackageJsonPlugin } from './vite/plugins/packageJsonPlugin.js' const GLSL_FILTER = /\.glsl$/ -const coreRoot = dirname(fileURLToPath(import.meta.url)) - const mavonEngineGlslPlugin = { name: 'glsl', setup(build) { @@ -29,7 +24,6 @@ export default defineConfig({ esbuildOptions: { plugins: [ mavonEngineGlslPlugin, - createPackageJsonPlugin(coreRoot), ], }, }, diff --git a/packages/core/vite/plugins/packageJsonPlugin.js b/packages/core/vite/plugins/packageJsonPlugin.js deleted file mode 100644 index 2b65047..0000000 --- a/packages/core/vite/plugins/packageJsonPlugin.js +++ /dev/null @@ -1,31 +0,0 @@ -import { readFileSync } from 'node:fs' -import { resolve } from 'node:path' - -const PACKAGE_JSON_FILTER = /[/\\]package\.json$/ -const ALL_FILTER = /.*/ -const IDENTIFIER_FILTER = /^[a-z_$][\w$]*$/i - -/* - * Allows importing package.json as an ES module with named exports so the - * client package can display the correct engine version at runtime. - */ -export function createPackageJsonPlugin(coreRoot) { - return { - name: 'package-json', - setup(build) { - build.onResolve({ filter: PACKAGE_JSON_FILTER }, (args) => { - if (!args.path.includes('@mavonengine/core')) - return null - return { path: resolve(coreRoot, 'package.json'), namespace: 'mavonengine-pkg-json' } - }) - build.onLoad({ filter: ALL_FILTER, namespace: 'mavonengine-pkg-json' }, (args) => { - const pkg = JSON.parse(readFileSync(args.path, 'utf8')) - const named = Object.entries(pkg) - .filter(([k]) => IDENTIFIER_FILTER.test(k)) - .map(([k, v]) => `export const ${k} = ${JSON.stringify(v)};`) - .join('\n') - return { contents: `${named}\nexport default ${JSON.stringify(pkg)};`, loader: 'js' } - }) - }, - } -} diff --git a/packages/multiplayer-template/package.json b/packages/multiplayer-template/package.json index cf9d5e6..cab6974 100644 --- a/packages/multiplayer-template/package.json +++ b/packages/multiplayer-template/package.json @@ -14,7 +14,7 @@ "lint:fix": "eslint . --fix" }, "dependencies": { - "@mavonengine/core": "0.0.10" + "@mavonengine/core": "0.0.14" }, "devDependencies": { "@antfu/eslint-config": "^8.0.0", diff --git a/packages/multiplayer-template/server/tsup.config.ts b/packages/multiplayer-template/server/tsup.config.ts index 88d6c3b..0a4e331 100644 --- a/packages/multiplayer-template/server/tsup.config.ts +++ b/packages/multiplayer-template/server/tsup.config.ts @@ -1,30 +1,5 @@ -import type { Plugin } from 'esbuild' -import fs from 'node:fs' -import path from 'node:path' import { defineConfig } from 'tsup' -const PACKAGE_JSON_FILTER = /[/\\]package\.json$/ -const ALL_FILTER = /.*/ -const IDENTIFIER_FILTER = /^[a-z_$][\w$]*$/i - -const packageJsonPlugin: Plugin = { - name: 'package-json', - setup(build) { - build.onResolve({ filter: PACKAGE_JSON_FILTER }, args => ({ - path: path.resolve(args.resolveDir, args.path), - namespace: 'pkg-json', - })) - build.onLoad({ filter: ALL_FILTER, namespace: 'pkg-json' }, (args) => { - const pkg = JSON.parse(fs.readFileSync(args.path, 'utf8')) - const named = Object.entries(pkg) - .filter(([k]) => IDENTIFIER_FILTER.test(k)) - .map(([k, v]) => `export const ${k} = ${JSON.stringify(v)};`) - .join('\n') - return { contents: `${named}\nexport default ${JSON.stringify(pkg)};`, loader: 'js' } - }) - }, -} - export default defineConfig({ entry: ['src/index.ts'], platform: 'node', @@ -40,5 +15,4 @@ export default defineConfig({ 'winston', 'three', ], - esbuildPlugins: [packageJsonPlugin], })