@rpgjs/vite 5.0.0-alpha.9 → 5.0.0-beta.10

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.
Files changed (46) hide show
  1. package/CHANGELOG.md +29 -0
  2. package/LICENSE +19 -0
  3. package/dist/compatibility-v4/flag-transform.d.ts +6 -0
  4. package/dist/compatibility-v4/index.d.ts +22 -0
  5. package/dist/compatibility-v4/load-config-file.d.ts +2 -0
  6. package/dist/compatibility-v4/require-transform.d.ts +2 -0
  7. package/dist/compatibility-v4/utils.d.ts +55 -0
  8. package/dist/index.d.ts +1 -0
  9. package/dist/index.js +10232 -7505
  10. package/dist/index.js.map +1 -1
  11. package/dist/mmorpg-build-plugin.d.ts +8 -0
  12. package/dist/rpgjs-plugin.d.ts +9 -3
  13. package/dist/server-plugin.d.ts +2 -149
  14. package/package.json +22 -13
  15. package/src/compatibility-v4/flag-transform.ts +61 -0
  16. package/src/compatibility-v4/index.ts +713 -0
  17. package/src/compatibility-v4/load-config-file.ts +38 -0
  18. package/src/compatibility-v4/require-transform.ts +67 -0
  19. package/src/compatibility-v4/utils.ts +170 -0
  20. package/src/index.ts +2 -1
  21. package/src/mmorpg-build-plugin.ts +123 -0
  22. package/src/module-config.ts +13 -0
  23. package/src/rpgjs-plugin.ts +36 -4
  24. package/src/server-plugin.ts +15 -436
  25. package/tests/compatibility-v4.spec.ts +105 -0
  26. package/tests/fixtures/v4-game/rpg.toml +11 -0
  27. package/tests/fixtures/v4-game/src/modules/main/characters/assets/hero.svg +2 -0
  28. package/tests/fixtures/v4-game/src/modules/main/characters/hero.ts +2 -0
  29. package/tests/fixtures/v4-game/src/modules/main/client.ts +4 -0
  30. package/tests/fixtures/v4-game/src/modules/main/database/potion.ts +6 -0
  31. package/tests/fixtures/v4-game/src/modules/main/events/npc.ts +4 -0
  32. package/tests/fixtures/v4-game/src/modules/main/gui/menu.vue +2 -0
  33. package/tests/fixtures/v4-game/src/modules/main/maps/map.tmx +2 -0
  34. package/tests/fixtures/v4-game/src/modules/main/maps/map.ts +7 -0
  35. package/tests/fixtures/v4-game/src/modules/main/player.ts +4 -0
  36. package/tests/fixtures/v4-game/src/modules/main/scene-map.ts +4 -0
  37. package/tests/fixtures/v4-game/src/modules/main/server.ts +4 -0
  38. package/tests/fixtures/v4-game/src/modules/main/sounds/theme.ogg +2 -0
  39. package/tests/fixtures/v4-game/src/modules/main/sounds/theme.ts +5 -0
  40. package/tests/fixtures/v4-game/src/modules/main/sprite.ts +4 -0
  41. package/tests/fixtures/v4-game/src/modules/main/worlds/maps/world-map.tmx +6 -0
  42. package/tests/fixtures/v4-game/src/modules/main/worlds/world.world +13 -0
  43. package/tests/latency-simulation.spec.ts +209 -0
  44. package/tests/remove-imports-plugin.spec.ts +56 -0
  45. package/tsconfig.json +2 -2
  46. package/vite.config.ts +7 -1
@@ -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,16 +1,22 @@
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> | {
9
14
  name: string;
15
+ config(config: any, { command }: any): void;
10
16
  transform(code: string, id: string): {
11
17
  code: string;
12
18
  map: null;
13
- } | undefined;
19
+ } | null;
14
20
  } | {
15
21
  name: string;
16
22
  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.10",
4
4
  "main": "dist/index.js",
5
5
  "types": "dist/index.d.ts",
6
6
  "keywords": [],
@@ -12,20 +12,29 @@
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
+ "@babel/generator": "^7.29.1",
16
+ "@babel/parser": "^7.29.3",
17
+ "@babel/traverse": "^7.29.0",
18
+ "@babel/types": "^7.29.0",
19
+ "@canvasengine/compiler": "2.0.0-rc.1",
20
+ "@canvasengine/tiled": "2.0.0-rc.1",
21
+ "@hono/vite-dev-server": "^0.25.3",
22
+ "@iarna/toml": "^2.2.5",
23
+ "@rpgjs/server": "5.0.0-beta.10",
24
+ "@types/node": "^25.8.0",
25
+ "acorn": "^8.16.0",
26
+ "acorn-walk": "^8.3.5",
27
+ "image-size": "^2.0.2",
28
+ "magic-string": "^0.30.21",
29
+ "typescript": "^6.0.3",
30
+ "vite": "^8.0.13",
31
+ "vite-plugin-dts": "^5.0.0",
32
+ "vitest": "^4.1.6",
33
+ "ws": "^8.20.1"
27
34
  },
28
35
  "devDependencies": {
36
+ "@types/babel__generator": "^7.27.0",
37
+ "@types/babel__traverse": "^7.28.0",
29
38
  "@types/ws": "^8.18.1"
30
39
  },
31
40
  "scripts": {
@@ -0,0 +1,61 @@
1
+ import type { Plugin } from "vite";
2
+
3
+ export function flagTransform(options: { side?: "client" | "server"; mode?: string; type?: "rpg" | "mmorpg" } = {}): Plugin {
4
+ function getImportSide(importer?: string): "client" | "server" {
5
+ if (importer?.includes("?server") || importer?.includes("server-entry")) return "server";
6
+ if (importer?.includes("?client") || importer?.includes("client-entry") || importer?.includes("standalone-entry")) return "client";
7
+ return options.side ?? "client";
8
+ }
9
+
10
+ function hasFlag(id: string, flag: string) {
11
+ return id.endsWith(`?${flag}`) || id.includes(`?${flag}&`);
12
+ }
13
+
14
+ function getSideFromId(id: string): "client" | "server" {
15
+ const side = id.match(/[?&]side=(client|server)/)?.[1];
16
+ return side === "server" ? "server" : "client";
17
+ }
18
+
19
+ return {
20
+ name: "rpgjs-v4-flag-transform",
21
+ async resolveId(this: any, source: string, importer?: string, resolveOptions?: any) {
22
+ const flags = ["client!", "server!", "rpg!", "mmorpg!", "production!", "development!"];
23
+ for (const flag of flags) {
24
+ if (!source.startsWith(flag)) continue;
25
+ const id = source.slice(flag.length);
26
+ const resolution = await this.resolve(id, importer, {
27
+ skipSelf: true,
28
+ ...resolveOptions,
29
+ });
30
+ if (!resolution) return null;
31
+ const importSide = getImportSide(importer);
32
+ return {
33
+ ...resolution,
34
+ id: `${resolution.id}?${flag.slice(0, -1)}&side=${importSide}`,
35
+ };
36
+ }
37
+ return null;
38
+ },
39
+ transform(code, id) {
40
+ const { mode = "development", type = "mmorpg" } = options;
41
+ const side = getSideFromId(id);
42
+
43
+ if (mode === "test") return { code, map: null };
44
+
45
+ if (hasFlag(id, side === "client" ? "server" : "client") && type !== "rpg") {
46
+ return { code: "export default null;", map: null };
47
+ }
48
+
49
+ if (
50
+ (hasFlag(id, "production") && mode !== "production") ||
51
+ (hasFlag(id, "development") && mode !== "development") ||
52
+ (hasFlag(id, "rpg") && type !== "rpg") ||
53
+ (hasFlag(id, "mmorpg") && type !== "mmorpg")
54
+ ) {
55
+ return { code: "export default null;", map: null };
56
+ }
57
+
58
+ return { code, map: null };
59
+ },
60
+ };
61
+ }