@nixia/2d 0.0.0-stage → 0.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Aedan
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -1,3 +1,6 @@
1
- # Temporary Holding Version
1
+ # Nixia 2D Game Engine
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ ## Getting started
4
+ ```bash
5
+ npm i -D @aedanmaki/nixia-2d
6
+ ```
package/cli.js ADDED
@@ -0,0 +1,108 @@
1
+ #!/usr/bin/env node
2
+ import * as fs from 'fs';
3
+ import * as path from 'path';
4
+
5
+ const BASE_URL = "https://nixia-2d-cli.nakoyasoftware.com/components/";
6
+
7
+ // Define all components in a single configuration array to maintain DRY principles
8
+ const COMPONENTS = [
9
+ { name: "index.html", dest: "index.html" },
10
+ { name: "vite.config.ts", dest: "vite.config.ts" },
11
+ { name: "tsconfig.json", dest: "tsconfig.json" },
12
+ { name: "main.ts", dest: path.join("src", "main.ts") }
13
+ ];
14
+
15
+ /**
16
+ * Generic helper function to download any file from the remote components repository.
17
+ */
18
+ async function downloadFile(filename) {
19
+ try {
20
+ const response = await fetch(`${BASE_URL}${filename}`);
21
+ if (!response.ok) {
22
+ throw new Error(`HTTP Error: ${response.status} ${response.statusText}`);
23
+ }
24
+ return await response.text();
25
+ } catch (e) {
26
+ throw new Error(`Failed to download '${filename}': ${e.message}`);
27
+ }
28
+ }
29
+
30
+ async function runCli() {
31
+ console.log('🔍 Running pre-flight environment checks...');
32
+
33
+ // Centralized pre-flight checks to prevent accidental overwrites
34
+ const existenceChecks = [
35
+ { target: "src", message: "Error: The 'src/' directory already exists. Aborting to protect your files." },
36
+ { target: "tsconfig.json", message: "Error: 'tsconfig.json' already exists in this directory." },
37
+ { target: "vite.config.ts", message: "Error: 'vite.config.ts' already exists in this directory." }
38
+ ];
39
+
40
+ for (const check of existenceChecks) {
41
+ if (fs.existsSync(check.target)) {
42
+ throw new Error(check.message);
43
+ }
44
+ }
45
+ console.log('✅ Pre-flight checks passed successfully!');
46
+
47
+ console.log('🚀 Downloading project components from remote server...');
48
+ const downloadedContent = {};
49
+
50
+ // Loop through our configuration array instead of writing duplicate functions
51
+ for (let i = 0; i < COMPONENTS.length; i++) {
52
+ const component = COMPONENTS[i];
53
+ console.log(`📥 Downloading component ${i + 1} of ${COMPONENTS.length}: ${component.name}...`);
54
+ downloadedContent[component.name] = await downloadFile(component.name);
55
+ }
56
+
57
+ console.log('💾 Writing files to disk...');
58
+
59
+ // Ensure the src directory exists before writing nested files
60
+ fs.mkdirSync("src", { recursive: true });
61
+
62
+ // Write all downloaded files to their respective destinations
63
+ for (const component of COMPONENTS) {
64
+ let content = downloadedContent[component.name];
65
+
66
+ // Pretty-print tsconfig.json so it looks clean and readable for humans
67
+ if (component.name === "tsconfig.json") {
68
+ try {
69
+ const parsedJson = JSON.parse(content);
70
+ content = JSON.stringify(parsedJson, null, 2);
71
+ } catch (jsonError) {
72
+ console.warn(`⚠️ Warning: Could not parse downloaded tsconfig.json as JSON. Writing raw text.`);
73
+ }
74
+ }
75
+
76
+ fs.writeFileSync(component.dest, content);
77
+ }
78
+ console.log('✅ All components written to disk successfully!');
79
+
80
+ console.log('📦 Updating package.json configuration...');
81
+ const packageJsonPath = path.join("package.json");
82
+
83
+ if (fs.existsSync(packageJsonPath)) {
84
+ const packageData = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8'));
85
+
86
+ // Safely inject scripts and type module setting
87
+ packageData.scripts = {
88
+ ...(packageData.scripts || {}),
89
+ "dev": "vite",
90
+ "build": "vite build",
91
+ "preview": "vite preview"
92
+ };
93
+ packageData.type = "module";
94
+
95
+ fs.writeFileSync(packageJsonPath, JSON.stringify(packageData, null, 2));
96
+ console.log('✨ package.json updated successfully with Vite scripts and ESM type!');
97
+ } else {
98
+ console.warn('⚠️ Warning: package.json not found in the current directory. Skipping script injection.');
99
+ }
100
+
101
+ console.log('🎉 Project scaffolding completed successfully! Happy coding! 🚀✨');
102
+ }
103
+
104
+ // Global execution wrapper with robust error catching
105
+ runCli().catch((error) => {
106
+ console.error(`\n💥 Fatal CLI Error: ${error.message}`);
107
+ process.exit(1);
108
+ });
package/cli.json ADDED
@@ -0,0 +1,3 @@
1
+ {
2
+ "url": "https://nixia-2d-cli.nakoyasoftware.com/"
3
+ }
package/index.html ADDED
@@ -0,0 +1,11 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="utf-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>Nixia Engine</title>
7
+ </head>
8
+ <body>
9
+ <script type="module" src="./src/main.ts"></script>
10
+ </body>
11
+ </html>
package/package.json CHANGED
@@ -1,6 +1,31 @@
1
1
  {
2
- "name": "@nixia/2d",
3
- "version": "0.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
6
- }
2
+ "name": "@nixia/2d",
3
+ "version": "0.0.2",
4
+ "author": {
5
+ "name": "Aedan Maki",
6
+ "email": "aedanmaki@gmail.com"
7
+ },
8
+ "bin": "./cli.js",
9
+ "license": "MIT",
10
+ "type": "module",
11
+ "main": "./src/index.ts",
12
+ "module": "./src/index.ts",
13
+ "exports": {
14
+ ".": {
15
+ "import": "./src/index.ts",
16
+ "types": "./src/index.ts"
17
+ }
18
+ },
19
+ "scripts": {
20
+ "dev": "vite",
21
+ "build": "vite build",
22
+ "preview": "vite preview"
23
+ },
24
+ "dependencies": {
25
+ "fs": "^0.0.1-security",
26
+ "path": "^0.12.7",
27
+ "typescript": "^7.0.2",
28
+ "vite": "^8.3.5",
29
+ "vite-plugin-singlefile": "^2.3.4"
30
+ }
31
+ }
@@ -0,0 +1,14 @@
1
+ // src/core/Actor.ts
2
+ import { Base } from "./Base";
3
+
4
+ /**
5
+ * Represents an Actor.
6
+ */
7
+ export class Actor extends Base {
8
+ /**
9
+ * Creates a new Actor.
10
+ */
11
+ constructor() {
12
+ super();
13
+ }
14
+ }
@@ -0,0 +1,51 @@
1
+ // src/core/Application.ts
2
+ import { Base } from "./Base";
3
+
4
+ /**
5
+ * Represents an Application.
6
+ */
7
+ export class Application extends Base {
8
+ /**
9
+ * If the game has already been initialized.
10
+ */
11
+ private wasInitialized: boolean = false;
12
+
13
+ /**
14
+ * Creates a new Application.
15
+ */
16
+ constructor() {
17
+ super();
18
+ }
19
+
20
+ /**
21
+ * Initialize the Application.
22
+ */
23
+ init() {
24
+ if (this.wasInitialized) throw new Error('Application is already initialized.');
25
+ this.wasInitialized = true;
26
+
27
+ if (document.readyState === 'complete') {
28
+ this._ready();
29
+ } else {
30
+ window.addEventListener('load', () => {
31
+ this._ready();
32
+ });
33
+ }
34
+ }
35
+
36
+ /**
37
+ * Called when the game is ready.
38
+ */
39
+ private _ready() {
40
+ this.fire('ready');
41
+
42
+ requestAnimationFrame(this._tick);
43
+ }
44
+
45
+ /**
46
+ * Called on tick.
47
+ */
48
+ private _tick = () => {
49
+ requestAnimationFrame(this._tick);
50
+ }
51
+ }
@@ -0,0 +1,25 @@
1
+ // src/core/Base.ts
2
+
3
+ /**
4
+ * Base class containing code for replication and events.
5
+ */
6
+ export abstract class Base {
7
+ private events: Map<string, Function[]> = new Map();
8
+
9
+ on(event: string, callback: Function) {
10
+ const callbacks = this.events.get(event);
11
+ if (!callbacks) this.events.set(event, [callback]); else {
12
+ callbacks.push(callback);
13
+ this.events.set(event, callbacks);
14
+ }
15
+ }
16
+
17
+ fire(event: string) {
18
+ const callbacks = this.events.get(event);
19
+ if (!callbacks) return;
20
+ const len = callbacks.length;
21
+ for (let i = 0; i < len; i++) {
22
+ callbacks[i]();
23
+ }
24
+ }
25
+ }
@@ -0,0 +1,14 @@
1
+ // src/core/Level.ts
2
+ import { Base } from "./Base";
3
+
4
+ /**
5
+ * Represents a Level.
6
+ */
7
+ export class Level extends Base {
8
+ /**
9
+ * Creates a new Level.
10
+ */
11
+ constructor() {
12
+ super();
13
+ }
14
+ }
@@ -0,0 +1,14 @@
1
+ // src/core/Renderer.ts
2
+ import { Base } from "./Base";
3
+
4
+ /**
5
+ * Represents a Renderer.
6
+ */
7
+ export class Renderer extends Base {
8
+ /**
9
+ * Creates a new Renderer.
10
+ */
11
+ constructor() {
12
+ super();
13
+ }
14
+ }
package/src/index.ts ADDED
@@ -0,0 +1,7 @@
1
+ // src/index.ts
2
+
3
+ export * from './core/Actor';
4
+ export * from './core/Application';
5
+ export * from './core/Base';
6
+ export * from './core/Level';
7
+ export * from './core/Renderer';
package/src/main.ts ADDED
@@ -0,0 +1,4 @@
1
+ import * as NIXIA from './index';
2
+
3
+ const app = new NIXIA.Application();
4
+ app.init();
package/tsconfig.json ADDED
@@ -0,0 +1,19 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ESNext",
4
+ "useDefineForClassFields": true,
5
+ "module": "ESNext",
6
+ "moduleResolution": "bundler",
7
+ "isolatedModules": true,
8
+ "strict": true,
9
+ "noUnusedLocals": true,
10
+ "noUnusedParameters": true,
11
+ "noImplicitReturns": true,
12
+ "skipLibCheck": true,
13
+ "resolveJsonModule": true,
14
+ "esModuleInterop": true,
15
+ "allowSyntheticDefaultImports": true,
16
+ "types": ["vite/client"]
17
+ },
18
+ "include": ["src/**/*", "vite.config.ts"]
19
+ }
package/vite.config.ts ADDED
@@ -0,0 +1,17 @@
1
+ import { defineConfig } from 'vite';
2
+ import { viteSingleFile } from 'vite-plugin-singlefile';
3
+
4
+ export default defineConfig({
5
+ plugins: [viteSingleFile()],
6
+ build: {
7
+ target: 'esnext',
8
+ assetsInlineLimit: 100000000,
9
+ chunkSizeWarningLimit: 100000000,
10
+ cssCodeSplit: false,
11
+ rollupOptions: {
12
+ output: {
13
+ inlineDynamicImports: true,
14
+ },
15
+ },
16
+ },
17
+ });