@rpgjs/vite 5.0.0-alpha.9 → 5.0.0-beta.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.
@@ -0,0 +1,8 @@
1
+ import { Plugin } from 'vite';
2
+ interface MmorpgBuildPluginOptions {
3
+ rpgType: string;
4
+ serverEntry: string;
5
+ adapterEntries?: Record<string, string>;
6
+ }
7
+ export declare function mmorpgBuildPlugin({ rpgType, serverEntry, adapterEntries, }: MmorpgBuildPluginOptions): Plugin;
8
+ export {};
@@ -1,8 +1,13 @@
1
+ type MmorpgEntryPoints = string | {
2
+ client?: string;
3
+ server?: string;
4
+ adapters?: Record<string, string>;
5
+ };
1
6
  interface RpgjsPluginOptions {
2
7
  server: any;
3
8
  entryPoints?: {
4
- rpg: string;
5
- mmorpg: string;
9
+ rpg?: string;
10
+ mmorpg?: MmorpgEntryPoints;
6
11
  };
7
12
  }
8
13
  export declare function rpgjs({ server, entryPoints }: RpgjsPluginOptions): (import('vite').Plugin<any> | {
@@ -10,7 +15,7 @@ export declare function rpgjs({ server, entryPoints }: RpgjsPluginOptions): (imp
10
15
  transform(code: string, id: string): {
11
16
  code: string;
12
17
  map: null;
13
- } | undefined;
18
+ } | null;
14
19
  } | {
15
20
  name: string;
16
21
  transform(code: string, id: string): string | undefined;
@@ -1,155 +1,8 @@
1
- import { RpgServerEngine } from '@rpgjs/server';
1
+ import { RpgTransportServerConstructor } from '@rpgjs/server/node';
2
2
  import { ViteDevServer } from 'vite';
3
- interface WSConnection {
4
- readyState: number;
5
- send(data: string): void;
6
- close(): void;
7
- on(event: string, callback: (...args: any[]) => void): void;
8
- }
9
- /**
10
- * PartyConnection class compatible with PartyKit's Party.Connection interface
11
- *
12
- * This class implements the Connection interface expected by RPG-JS server,
13
- * providing WebSocket communication capabilities and connection state management.
14
- *
15
- * @example
16
- * ```typescript
17
- * const connection = new PartyConnection(websocket, 'player123');
18
- * connection.send('Hello player!');
19
- * connection.setState({ username: 'Alice' });
20
- * ```
21
- */
22
- declare class PartyConnection {
23
- private ws;
24
- id: string;
25
- uri: string;
26
- private _state;
27
- constructor(ws: WSConnection, id?: string, uri?: string);
28
- /**
29
- * Generates a unique identifier for the connection
30
- *
31
- * @returns {string} Unique identifier based on timestamp and random number
32
- */
33
- private generateId;
34
- /**
35
- * Sends data to the client via WebSocket
36
- *
37
- * @param {any} data - Data to send (automatically serialized to JSON if not string)
38
- */
39
- send(data: any): void;
40
- /**
41
- * Closes the WebSocket connection
42
- */
43
- close(): void;
44
- /**
45
- * Sets state data for this connection
46
- *
47
- * @param {any} value - State data to store (max 2KB as per PartyKit spec)
48
- */
49
- setState(value: any): void;
50
- /**
51
- * Gets the current state of this connection
52
- *
53
- * @returns {any} Current connection state
54
- */
55
- get state(): any;
56
- }
57
- /**
58
- * Room class compatible with PartyKit's Party.Room interface
59
- *
60
- * This class manages multiple WebSocket connections and provides broadcasting
61
- * capabilities, storage, and connection management as expected by RPG-JS server.
62
- *
63
- * @example
64
- * ```typescript
65
- * const room = new Room('lobby-1');
66
- * room.broadcast('Game started!');
67
- * const playerCount = [...room.getConnections()].length;
68
- * ```
69
- */
70
- declare class Room {
71
- id: string;
72
- internalID: string;
73
- env: Record<string, any>;
74
- context: any;
75
- private connections;
76
- private storageData;
77
- constructor(id: string);
78
- /**
79
- * Broadcasts a message to all connected clients
80
- *
81
- * @param {any} message - Message to broadcast
82
- * @param {string[]} except - Array of connection IDs to exclude from broadcast
83
- */
84
- broadcast(message: any, except?: string[]): void;
85
- /**
86
- * Gets a connection by its ID
87
- *
88
- * @param {string} id - Connection ID
89
- * @returns {PartyConnection | undefined} The connection or undefined if not found
90
- */
91
- getConnection(id: string): PartyConnection | undefined;
92
- /**
93
- * Gets all currently connected clients
94
- *
95
- * @param {string} tag - Optional tag to filter connections (not implemented yet)
96
- * @returns {IterableIterator<PartyConnection>} Iterator of all connections
97
- */
98
- getConnections(tag?: string): IterableIterator<PartyConnection>;
99
- /**
100
- * Adds a connection to this room
101
- *
102
- * @param {PartyConnection} connection - Connection to add
103
- */
104
- addConnection(connection: PartyConnection): void;
105
- /**
106
- * Removes a connection from this room
107
- *
108
- * @param {string} connectionId - ID of connection to remove
109
- */
110
- removeConnection(connectionId: string): void;
111
- /**
112
- * Simple key-value storage for the room
113
- */
114
- get storage(): {
115
- put: (key: string, value: any) => Promise<void>;
116
- get: <T = any>(key: string) => Promise<T | undefined>;
117
- delete: (key: string) => Promise<void>;
118
- list: () => Promise<string[]>;
119
- };
120
- }
121
- /**
122
- * Creates a Vite plugin for integrating RPG-JS server functionality
123
- *
124
- * This plugin configures the development server to automatically start
125
- * an RPG-JS server instance when Vite's dev server starts. It handles
126
- * the instantiation and initialization of the server module, and sets up
127
- * HTTP request and WebSocket connection forwarding to the RPG-JS server.
128
- *
129
- * The plugin intercepts:
130
- * - HTTP requests to `/parties/*` paths and forwards them to the RPG-JS server
131
- * - WebSocket upgrade requests and establishes connections with the RPG-JS server
132
- *
133
- * @param {new () => RpgServerEngine} serverModule - A class constructor that extends RpgServerEngine
134
- * @returns {Object} Vite plugin configuration object
135
- *
136
- * @example
137
- * ```typescript
138
- * // In vite.config.ts
139
- * import { serverPlugin } from '@rpgjs/vite';
140
- * import startServer from './src/server';
141
- *
142
- * export default defineConfig({
143
- * plugins: [
144
- * serverPlugin(startServer)
145
- * ]
146
- * });
147
- * ```
148
- */
149
- export declare function serverPlugin(serverModule: new (room: Room) => RpgServerEngine): {
3
+ export declare function serverPlugin(serverModule: RpgTransportServerConstructor): {
150
4
  name: string;
151
5
  configureServer(server: ViteDevServer): Promise<void>;
152
6
  buildStart(): void;
153
7
  buildEnd(): void;
154
8
  };
155
- export {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rpgjs/vite",
3
- "version": "5.0.0-alpha.9",
3
+ "version": "5.0.0-beta.2",
4
4
  "main": "dist/index.js",
5
5
  "types": "dist/index.d.ts",
6
6
  "keywords": [],
@@ -12,18 +12,19 @@
12
12
  "access": "public"
13
13
  },
14
14
  "dependencies": {
15
- "@canvasengine/compiler": "2.0.0-beta.21",
16
- "@hono/vite-dev-server": "^0.19.1",
17
- "@rpgjs/server": "5.0.0-alpha.9",
18
- "@types/node": "^20.0.0",
19
- "acorn": "^8.14.1",
20
- "acorn-walk": "^8.3.4",
21
- "magic-string": "^0.30.0",
22
- "typescript": "^5.0.0",
23
- "vite": "^6.2.5",
24
- "vite-plugin-dts": "^4.5.3",
25
- "vitest": "^3.1.1",
26
- "ws": "^8.18.0"
15
+ "@canvasengine/tiled": "2.0.0-beta.54",
16
+ "@canvasengine/compiler": "2.0.0-beta.54",
17
+ "@hono/vite-dev-server": "^0.25.0",
18
+ "@rpgjs/server": "5.0.0-beta.2",
19
+ "@types/node": "^25.3.5",
20
+ "acorn": "^8.16.0",
21
+ "acorn-walk": "^8.3.5",
22
+ "magic-string": "^0.30.21",
23
+ "typescript": "^5.9.3",
24
+ "vite": "^7.3.1",
25
+ "vite-plugin-dts": "^4.5.4",
26
+ "vitest": "^4.0.18",
27
+ "ws": "^8.19.0"
27
28
  },
28
29
  "devDependencies": {
29
30
  "@types/ws": "^8.18.1"
@@ -0,0 +1,123 @@
1
+ import { existsSync, rmSync } from "node:fs";
2
+ import { resolve } from "node:path";
3
+ import { build as viteBuild, type Plugin, type ResolvedConfig } from "vite";
4
+
5
+ interface MmorpgBuildPluginOptions {
6
+ rpgType: string;
7
+ serverEntry: string;
8
+ adapterEntries?: Record<string, string>;
9
+ }
10
+
11
+ function isBareImport(id: string): boolean {
12
+ return !id.startsWith(".") && !id.startsWith("/") && !id.startsWith("\0");
13
+ }
14
+
15
+ function resolveEntry(root: string, entry: string): string {
16
+ return resolve(root, entry);
17
+ }
18
+
19
+ function collectServerEntries(
20
+ root: string,
21
+ serverEntry: string,
22
+ adapterEntries: Record<string, string>,
23
+ ): Record<string, string> {
24
+ const entries: Record<string, string> = {};
25
+ const resolvedServerEntry = resolveEntry(root, serverEntry);
26
+
27
+ if (!existsSync(resolvedServerEntry)) {
28
+ throw new Error(`[rpgjs:mmorpg-build] Missing server entry: ${serverEntry}`);
29
+ }
30
+
31
+ entries.server = resolvedServerEntry;
32
+
33
+ for (const [name, entry] of Object.entries(adapterEntries)) {
34
+ const resolvedAdapterEntry = resolveEntry(root, entry);
35
+ if (!existsSync(resolvedAdapterEntry)) {
36
+ throw new Error(`[rpgjs:mmorpg-build] Missing adapter entry "${name}": ${entry}`);
37
+ }
38
+ entries[name] = resolvedAdapterEntry;
39
+ }
40
+
41
+ return entries;
42
+ }
43
+
44
+ export function mmorpgBuildPlugin({
45
+ rpgType,
46
+ serverEntry,
47
+ adapterEntries = {},
48
+ }: MmorpgBuildPluginOptions): Plugin {
49
+ let config: ResolvedConfig;
50
+ let didBuildServer = false;
51
+ let didCleanDist = false;
52
+
53
+ return {
54
+ name: "rpgjs:mmorpg-build",
55
+ apply: "build",
56
+ enforce: "post",
57
+ config(_, env) {
58
+ if (env.command !== "build" || rpgType !== "mmorpg") {
59
+ return;
60
+ }
61
+
62
+ return {
63
+ build: {
64
+ outDir: "dist/client",
65
+ },
66
+ };
67
+ },
68
+ configResolved(resolvedConfig) {
69
+ config = resolvedConfig;
70
+ },
71
+ buildStart() {
72
+ if (rpgType !== "mmorpg" || didCleanDist) {
73
+ return;
74
+ }
75
+ didCleanDist = true;
76
+ rmSync(resolve(config.root, "dist"), { recursive: true, force: true });
77
+ },
78
+ async closeBundle() {
79
+ if (rpgType !== "mmorpg" || didBuildServer) {
80
+ return;
81
+ }
82
+ didBuildServer = true;
83
+
84
+ const entries = collectServerEntries(config.root, serverEntry, adapterEntries);
85
+ console.log(
86
+ `[rpgjs:mmorpg-build] Building server bundle(s): ${Object.keys(entries).join(", ")}`,
87
+ );
88
+
89
+ await viteBuild({
90
+ configFile: false,
91
+ root: config.root,
92
+ define: config.define,
93
+ resolve: {
94
+ alias: config.resolve.alias,
95
+ dedupe: config.resolve.dedupe,
96
+ extensions: config.resolve.extensions,
97
+ mainFields: config.resolve.mainFields,
98
+ conditions: config.resolve.conditions,
99
+ },
100
+ publicDir: false,
101
+ build: {
102
+ emptyOutDir: true,
103
+ minify: false,
104
+ outDir: "dist/server",
105
+ sourcemap: config.build.sourcemap,
106
+ target: "node18",
107
+ lib: {
108
+ entry: entries,
109
+ formats: ["es"],
110
+ },
111
+ rollupOptions: {
112
+ external(id) {
113
+ return isBareImport(id);
114
+ },
115
+ output: {
116
+ entryFileNames: "[name].js",
117
+ },
118
+ },
119
+ },
120
+ });
121
+ },
122
+ };
123
+ }
@@ -1,6 +1,8 @@
1
1
  import { defineConfig, build } from "vite";
2
2
  import canvasengine from "@canvasengine/compiler";
3
3
  import dts from "vite-plugin-dts";
4
+ import { existsSync } from "node:fs";
5
+ import { resolve } from "node:path";
4
6
  import { directivePlugin, removeImportsPlugin } from "./index";
5
7
 
6
8
  /**
@@ -22,6 +24,14 @@ import { directivePlugin, removeImportsPlugin } from "./index";
22
24
  */
23
25
  function createBuildConfig({ side, watch }: { side: 'client' | 'server', watch: boolean }) {
24
26
  const isClient = side === 'client';
27
+ const runtimeDir = resolve(process.cwd(), "runtime");
28
+ const resolveOptions = existsSync(runtimeDir)
29
+ ? {
30
+ alias: {
31
+ "@common": runtimeDir,
32
+ },
33
+ }
34
+ : undefined;
25
35
 
26
36
  const plugins = isClient
27
37
  ? [
@@ -36,6 +46,7 @@ function createBuildConfig({ side, watch }: { side: 'client' | 'server', watch:
36
46
 
37
47
  return {
38
48
  configFile: false as const, // Prevent using this config file
49
+ resolve: resolveOptions,
39
50
  plugins: [
40
51
  ...plugins,
41
52
  dts({
@@ -57,7 +68,9 @@ function createBuildConfig({ side, watch }: { side: 'client' | 'server', watch:
57
68
  rollupOptions: {
58
69
  external: [
59
70
  /@rpgjs/,
71
+ /@signestack/,
60
72
  "canvasengine",
73
+ "pixi.js",
61
74
  "esbuild",
62
75
  "@canvasengine/presets",
63
76
  "rxjs",
@@ -2,12 +2,37 @@ import canvasengine from "@canvasengine/compiler";
2
2
  import { replaceConfigImport } from "./replace-config-import";
3
3
  import { serverPlugin } from "./server-plugin";
4
4
  import { entryPointPlugin } from "./entry-point-plugin";
5
+ import { mmorpgBuildPlugin } from "./mmorpg-build-plugin";
6
+
7
+ type MmorpgEntryPoints =
8
+ | string
9
+ | {
10
+ client?: string;
11
+ server?: string;
12
+ adapters?: Record<string, string>;
13
+ };
5
14
 
6
15
  interface RpgjsPluginOptions {
7
16
  server: any;
8
17
  entryPoints?: {
9
- rpg: string;
10
- mmorpg: string;
18
+ rpg?: string;
19
+ mmorpg?: MmorpgEntryPoints;
20
+ };
21
+ }
22
+
23
+ function normalizeMmorpgEntryPoints(entryPoints?: MmorpgEntryPoints) {
24
+ if (!entryPoints || typeof entryPoints === "string") {
25
+ return {
26
+ client: entryPoints ?? "./src/client.ts",
27
+ server: "./src/server.ts",
28
+ adapters: {},
29
+ };
30
+ }
31
+
32
+ return {
33
+ client: entryPoints.client ?? "./src/client.ts",
34
+ server: entryPoints.server ?? "./src/server.ts",
35
+ adapters: entryPoints.adapters ?? {},
11
36
  };
12
37
  }
13
38
 
@@ -15,15 +40,22 @@ export function rpgjs({
15
40
  server,
16
41
  entryPoints
17
42
  }: RpgjsPluginOptions) {
43
+ const mmorpgEntryPoints = normalizeMmorpgEntryPoints(entryPoints?.mmorpg);
44
+
18
45
  return [
19
46
  canvasengine(),
20
47
  replaceConfigImport(),
21
48
  serverPlugin(server),
49
+ mmorpgBuildPlugin({
50
+ rpgType: process.env.RPG_TYPE || "rpg",
51
+ serverEntry: mmorpgEntryPoints.server,
52
+ adapterEntries: mmorpgEntryPoints.adapters,
53
+ }),
22
54
  entryPointPlugin({
23
55
  entryPoints: {
24
56
  rpg: entryPoints?.rpg ?? './src/standalone.ts',
25
- mmorpg: entryPoints?.mmorpg ?? './src/client.ts'
57
+ mmorpg: mmorpgEntryPoints.client,
26
58
  }
27
59
  })
28
60
  ]
29
- }
61
+ }