miaoda-game-devkit 0.2.9 → 0.2.11
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/README.md +27 -1
- package/dist/cli/lint.js +32 -1
- package/dist/game-clock-suUidZdT.d.mts +11 -0
- package/dist/game-clock-suUidZdT.d.ts +11 -0
- package/dist/{gameplay-audit-CCJo4Qhk.d.mts → gameplay-audit-DmbBA0M_.d.mts} +7 -1
- package/dist/{gameplay-audit-CCJo4Qhk.d.ts → gameplay-audit-DmbBA0M_.d.ts} +7 -1
- package/dist/index.d.mts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +165 -4
- package/dist/index.mjs +165 -4
- package/dist/lint/game-telemetry.contract.mjs +165 -4
- package/dist/lint/gameplay-contract.contract.mjs +165 -4
- package/dist/lint/phaser-headless.contract.mjs +281 -4
- package/dist/lint/vitest-config.contract.mjs +234 -11
- package/dist/phaser-facade.mjs +156 -0
- package/dist/react/index.d.mts +13 -0
- package/dist/react/index.d.ts +13 -0
- package/dist/react/index.js +57 -0
- package/dist/react/index.mjs +29 -0
- package/dist/react/testing.d.mts +21 -0
- package/dist/react/testing.d.ts +21 -0
- package/dist/react/testing.js +82 -0
- package/dist/react/testing.mjs +57 -0
- package/dist/react/vitest-config.d.mts +14 -0
- package/dist/react/vitest-config.d.ts +14 -0
- package/dist/react/vitest-config.js +57 -0
- package/dist/react/vitest-config.mjs +32 -0
- package/dist/react/vitest-setup.d.mts +2 -0
- package/dist/react/vitest-setup.d.ts +2 -0
- package/dist/react/vitest-setup.js +35 -0
- package/dist/react/vitest-setup.mjs +33 -0
- package/dist/vite.d.mts +22 -0
- package/dist/vite.d.ts +22 -0
- package/dist/vite.js +93 -0
- package/dist/vite.mjs +67 -0
- package/dist/vitest-config.d.mts +2 -2
- package/dist/vitest-config.d.ts +2 -2
- package/dist/vitest-config.js +53 -3
- package/dist/vitest-config.mjs +53 -3
- package/package.json +72 -2
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/react/manual-game-clock.ts
|
|
21
|
+
var manual_game_clock_exports = {};
|
|
22
|
+
__export(manual_game_clock_exports, {
|
|
23
|
+
ManualGameClock: () => ManualGameClock
|
|
24
|
+
});
|
|
25
|
+
module.exports = __toCommonJS(manual_game_clock_exports);
|
|
26
|
+
var ManualGameClock = class {
|
|
27
|
+
time = 0;
|
|
28
|
+
nextId = 1;
|
|
29
|
+
frames = /* @__PURE__ */ new Map();
|
|
30
|
+
timers = /* @__PURE__ */ new Map();
|
|
31
|
+
now() {
|
|
32
|
+
return this.time;
|
|
33
|
+
}
|
|
34
|
+
requestFrame(callback) {
|
|
35
|
+
const id = this.nextId++;
|
|
36
|
+
this.frames.set(id, callback);
|
|
37
|
+
return id;
|
|
38
|
+
}
|
|
39
|
+
cancelFrame(id) {
|
|
40
|
+
this.frames.delete(id);
|
|
41
|
+
}
|
|
42
|
+
setTimeout(callback, delayMs) {
|
|
43
|
+
const id = this.nextId++;
|
|
44
|
+
this.timers.set(id, { callback, dueAt: this.time + delayMs });
|
|
45
|
+
return id;
|
|
46
|
+
}
|
|
47
|
+
clearTimeout(id) {
|
|
48
|
+
this.timers.delete(id);
|
|
49
|
+
}
|
|
50
|
+
advanceBy(deltaMs) {
|
|
51
|
+
if (!Number.isFinite(deltaMs) || deltaMs < 0) {
|
|
52
|
+
throw new RangeError("deltaMs must be a non-negative finite number");
|
|
53
|
+
}
|
|
54
|
+
this.time += deltaMs;
|
|
55
|
+
const dueTimers = [...this.timers.entries()].filter(([, timer]) => timer.dueAt <= this.time).sort((left, right) => left[1].dueAt - right[1].dueAt);
|
|
56
|
+
for (const [id, timer] of dueTimers) {
|
|
57
|
+
if (timer.dueAt <= this.time && this.timers.delete(id)) timer.callback();
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
stepFrame(deltaMs = 16) {
|
|
61
|
+
this.advanceBy(deltaMs);
|
|
62
|
+
const callbacks = [...this.frames.values()];
|
|
63
|
+
this.frames.clear();
|
|
64
|
+
for (const callback of callbacks) callback(this.time);
|
|
65
|
+
}
|
|
66
|
+
stepFrames(count, deltaMs = 16) {
|
|
67
|
+
if (!Number.isInteger(count) || count < 0) {
|
|
68
|
+
throw new RangeError("count must be a non-negative integer");
|
|
69
|
+
}
|
|
70
|
+
for (let index = 0; index < count; index += 1) this.stepFrame(deltaMs);
|
|
71
|
+
}
|
|
72
|
+
pendingFrameCount() {
|
|
73
|
+
return this.frames.size;
|
|
74
|
+
}
|
|
75
|
+
pendingTimerCount() {
|
|
76
|
+
return this.timers.size;
|
|
77
|
+
}
|
|
78
|
+
};
|
|
79
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
80
|
+
0 && (module.exports = {
|
|
81
|
+
ManualGameClock
|
|
82
|
+
});
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
// src/react/manual-game-clock.ts
|
|
2
|
+
var ManualGameClock = class {
|
|
3
|
+
time = 0;
|
|
4
|
+
nextId = 1;
|
|
5
|
+
frames = /* @__PURE__ */ new Map();
|
|
6
|
+
timers = /* @__PURE__ */ new Map();
|
|
7
|
+
now() {
|
|
8
|
+
return this.time;
|
|
9
|
+
}
|
|
10
|
+
requestFrame(callback) {
|
|
11
|
+
const id = this.nextId++;
|
|
12
|
+
this.frames.set(id, callback);
|
|
13
|
+
return id;
|
|
14
|
+
}
|
|
15
|
+
cancelFrame(id) {
|
|
16
|
+
this.frames.delete(id);
|
|
17
|
+
}
|
|
18
|
+
setTimeout(callback, delayMs) {
|
|
19
|
+
const id = this.nextId++;
|
|
20
|
+
this.timers.set(id, { callback, dueAt: this.time + delayMs });
|
|
21
|
+
return id;
|
|
22
|
+
}
|
|
23
|
+
clearTimeout(id) {
|
|
24
|
+
this.timers.delete(id);
|
|
25
|
+
}
|
|
26
|
+
advanceBy(deltaMs) {
|
|
27
|
+
if (!Number.isFinite(deltaMs) || deltaMs < 0) {
|
|
28
|
+
throw new RangeError("deltaMs must be a non-negative finite number");
|
|
29
|
+
}
|
|
30
|
+
this.time += deltaMs;
|
|
31
|
+
const dueTimers = [...this.timers.entries()].filter(([, timer]) => timer.dueAt <= this.time).sort((left, right) => left[1].dueAt - right[1].dueAt);
|
|
32
|
+
for (const [id, timer] of dueTimers) {
|
|
33
|
+
if (timer.dueAt <= this.time && this.timers.delete(id)) timer.callback();
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
stepFrame(deltaMs = 16) {
|
|
37
|
+
this.advanceBy(deltaMs);
|
|
38
|
+
const callbacks = [...this.frames.values()];
|
|
39
|
+
this.frames.clear();
|
|
40
|
+
for (const callback of callbacks) callback(this.time);
|
|
41
|
+
}
|
|
42
|
+
stepFrames(count, deltaMs = 16) {
|
|
43
|
+
if (!Number.isInteger(count) || count < 0) {
|
|
44
|
+
throw new RangeError("count must be a non-negative integer");
|
|
45
|
+
}
|
|
46
|
+
for (let index = 0; index < count; index += 1) this.stepFrame(deltaMs);
|
|
47
|
+
}
|
|
48
|
+
pendingFrameCount() {
|
|
49
|
+
return this.frames.size;
|
|
50
|
+
}
|
|
51
|
+
pendingTimerCount() {
|
|
52
|
+
return this.timers.size;
|
|
53
|
+
}
|
|
54
|
+
};
|
|
55
|
+
export {
|
|
56
|
+
ManualGameClock
|
|
57
|
+
};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { ViteUserConfig } from 'vitest/config';
|
|
2
|
+
|
|
3
|
+
interface ReactGameVitestConfigOptions {
|
|
4
|
+
/** React 模板的绝对根目录,通常传入 `import.meta.dirname`。 */
|
|
5
|
+
projectRoot: string;
|
|
6
|
+
aliases?: Record<string, string>;
|
|
7
|
+
additionalSetupFiles?: string[];
|
|
8
|
+
testTimeout?: number;
|
|
9
|
+
hookTimeout?: number;
|
|
10
|
+
}
|
|
11
|
+
/** 创建默认使用 JSDOM 的 React 游戏 Vitest 配置。 */
|
|
12
|
+
declare function defineReactGameVitestConfig(options: ReactGameVitestConfigOptions): ViteUserConfig;
|
|
13
|
+
|
|
14
|
+
export { type ReactGameVitestConfigOptions, defineReactGameVitestConfig };
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { ViteUserConfig } from 'vitest/config';
|
|
2
|
+
|
|
3
|
+
interface ReactGameVitestConfigOptions {
|
|
4
|
+
/** React 模板的绝对根目录,通常传入 `import.meta.dirname`。 */
|
|
5
|
+
projectRoot: string;
|
|
6
|
+
aliases?: Record<string, string>;
|
|
7
|
+
additionalSetupFiles?: string[];
|
|
8
|
+
testTimeout?: number;
|
|
9
|
+
hookTimeout?: number;
|
|
10
|
+
}
|
|
11
|
+
/** 创建默认使用 JSDOM 的 React 游戏 Vitest 配置。 */
|
|
12
|
+
declare function defineReactGameVitestConfig(options: ReactGameVitestConfigOptions): ViteUserConfig;
|
|
13
|
+
|
|
14
|
+
export { type ReactGameVitestConfigOptions, defineReactGameVitestConfig };
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/react-vitest-config.ts
|
|
21
|
+
var react_vitest_config_exports = {};
|
|
22
|
+
__export(react_vitest_config_exports, {
|
|
23
|
+
defineReactGameVitestConfig: () => defineReactGameVitestConfig
|
|
24
|
+
});
|
|
25
|
+
module.exports = __toCommonJS(react_vitest_config_exports);
|
|
26
|
+
var import_node_path = require("path");
|
|
27
|
+
var import_config = require("vitest/config");
|
|
28
|
+
function defineReactGameVitestConfig(options) {
|
|
29
|
+
return (0, import_config.defineConfig)({
|
|
30
|
+
resolve: {
|
|
31
|
+
alias: { ...options.aliases, "@": (0, import_node_path.resolve)(options.projectRoot, "src") }
|
|
32
|
+
},
|
|
33
|
+
test: {
|
|
34
|
+
include: [
|
|
35
|
+
"src/**/*.{test,spec}.{ts,tsx}",
|
|
36
|
+
"tests/**/*.{test,spec}.{ts,tsx}"
|
|
37
|
+
],
|
|
38
|
+
environment: "jsdom",
|
|
39
|
+
environmentOptions: {
|
|
40
|
+
jsdom: { url: "http://localhost/", pretendToBeVisual: true }
|
|
41
|
+
},
|
|
42
|
+
setupFiles: [
|
|
43
|
+
"miaoda-game-devkit/react/vitest-setup",
|
|
44
|
+
...options.additionalSetupFiles ?? []
|
|
45
|
+
],
|
|
46
|
+
reporters: ["minimal"],
|
|
47
|
+
restoreMocks: true,
|
|
48
|
+
clearMocks: true,
|
|
49
|
+
testTimeout: options.testTimeout,
|
|
50
|
+
hookTimeout: options.hookTimeout
|
|
51
|
+
}
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
55
|
+
0 && (module.exports = {
|
|
56
|
+
defineReactGameVitestConfig
|
|
57
|
+
});
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
// src/react-vitest-config.ts
|
|
2
|
+
import { resolve } from "path";
|
|
3
|
+
import { defineConfig } from "vitest/config";
|
|
4
|
+
function defineReactGameVitestConfig(options) {
|
|
5
|
+
return defineConfig({
|
|
6
|
+
resolve: {
|
|
7
|
+
alias: { ...options.aliases, "@": resolve(options.projectRoot, "src") }
|
|
8
|
+
},
|
|
9
|
+
test: {
|
|
10
|
+
include: [
|
|
11
|
+
"src/**/*.{test,spec}.{ts,tsx}",
|
|
12
|
+
"tests/**/*.{test,spec}.{ts,tsx}"
|
|
13
|
+
],
|
|
14
|
+
environment: "jsdom",
|
|
15
|
+
environmentOptions: {
|
|
16
|
+
jsdom: { url: "http://localhost/", pretendToBeVisual: true }
|
|
17
|
+
},
|
|
18
|
+
setupFiles: [
|
|
19
|
+
"miaoda-game-devkit/react/vitest-setup",
|
|
20
|
+
...options.additionalSetupFiles ?? []
|
|
21
|
+
],
|
|
22
|
+
reporters: ["minimal"],
|
|
23
|
+
restoreMocks: true,
|
|
24
|
+
clearMocks: true,
|
|
25
|
+
testTimeout: options.testTimeout,
|
|
26
|
+
hookTimeout: options.hookTimeout
|
|
27
|
+
}
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
export {
|
|
31
|
+
defineReactGameVitestConfig
|
|
32
|
+
};
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
// src/react-vitest-setup.ts
|
|
4
|
+
var import_vitest = require("@testing-library/jest-dom/vitest");
|
|
5
|
+
var import_react = require("@testing-library/react");
|
|
6
|
+
var import_vitest2 = require("vitest");
|
|
7
|
+
var failures = [];
|
|
8
|
+
var consoleError;
|
|
9
|
+
var onError = (event) => failures.push(event.error ?? event.message);
|
|
10
|
+
var onRejection = (event) => failures.push(event.reason);
|
|
11
|
+
(0, import_vitest2.beforeEach)(() => {
|
|
12
|
+
failures = [];
|
|
13
|
+
window.addEventListener("error", onError);
|
|
14
|
+
window.addEventListener("unhandledrejection", onRejection);
|
|
15
|
+
consoleError = import_vitest2.vi.spyOn(console, "error").mockImplementation((...args) => {
|
|
16
|
+
failures.push(args);
|
|
17
|
+
});
|
|
18
|
+
});
|
|
19
|
+
(0, import_vitest2.afterEach)(() => {
|
|
20
|
+
try {
|
|
21
|
+
(0, import_react.cleanup)();
|
|
22
|
+
} catch (error) {
|
|
23
|
+
failures.push(error);
|
|
24
|
+
} finally {
|
|
25
|
+
window.removeEventListener("error", onError);
|
|
26
|
+
window.removeEventListener("unhandledrejection", onRejection);
|
|
27
|
+
consoleError?.mockRestore();
|
|
28
|
+
consoleError = void 0;
|
|
29
|
+
}
|
|
30
|
+
if (failures.length > 0) {
|
|
31
|
+
const captured = failures;
|
|
32
|
+
failures = [];
|
|
33
|
+
throw new AggregateError(captured, "Unexpected React/JSDOM runtime failures");
|
|
34
|
+
}
|
|
35
|
+
});
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
// src/react-vitest-setup.ts
|
|
2
|
+
import "@testing-library/jest-dom/vitest";
|
|
3
|
+
import { cleanup } from "@testing-library/react";
|
|
4
|
+
import { afterEach, beforeEach, vi } from "vitest";
|
|
5
|
+
var failures = [];
|
|
6
|
+
var consoleError;
|
|
7
|
+
var onError = (event) => failures.push(event.error ?? event.message);
|
|
8
|
+
var onRejection = (event) => failures.push(event.reason);
|
|
9
|
+
beforeEach(() => {
|
|
10
|
+
failures = [];
|
|
11
|
+
window.addEventListener("error", onError);
|
|
12
|
+
window.addEventListener("unhandledrejection", onRejection);
|
|
13
|
+
consoleError = vi.spyOn(console, "error").mockImplementation((...args) => {
|
|
14
|
+
failures.push(args);
|
|
15
|
+
});
|
|
16
|
+
});
|
|
17
|
+
afterEach(() => {
|
|
18
|
+
try {
|
|
19
|
+
cleanup();
|
|
20
|
+
} catch (error) {
|
|
21
|
+
failures.push(error);
|
|
22
|
+
} finally {
|
|
23
|
+
window.removeEventListener("error", onError);
|
|
24
|
+
window.removeEventListener("unhandledrejection", onRejection);
|
|
25
|
+
consoleError?.mockRestore();
|
|
26
|
+
consoleError = void 0;
|
|
27
|
+
}
|
|
28
|
+
if (failures.length > 0) {
|
|
29
|
+
const captured = failures;
|
|
30
|
+
failures = [];
|
|
31
|
+
throw new AggregateError(captured, "Unexpected React/JSDOM runtime failures");
|
|
32
|
+
}
|
|
33
|
+
});
|
package/dist/vite.d.mts
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { UserConfig, UserConfigFnObject, UserConfigFnPromise, UserConfigFn, UserConfigExport, Plugin } from 'vite';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* 将生产 Scene 对裸模块 `phaser` 的导入重定向到 devkit facade。
|
|
5
|
+
*
|
|
6
|
+
* 只处理 `src/scenes`,因为只有 Scene 的继承入口需要增强;其余模块继续直接使用
|
|
7
|
+
* Phaser,可减少构建影响面,并避免普通模块观察到被替换的 Scene 构造器。
|
|
8
|
+
*/
|
|
9
|
+
declare function phaserRexUIScenePlugin(projectRoot?: string): Plugin;
|
|
10
|
+
/**
|
|
11
|
+
* 生成游戏项目的 Vite 配置,并把强制 Scene 重定向放在用户插件之前。
|
|
12
|
+
* 模板只暴露此稳定入口,具体拦截逻辑保留在生成项目只读的 devkit 内。
|
|
13
|
+
* 调用签名与 Vite `defineConfig` 保持一致,支持对象、Promise 和配置函数。
|
|
14
|
+
*/
|
|
15
|
+
declare function defineGameViteConfig(config: UserConfig): UserConfig;
|
|
16
|
+
declare function defineGameViteConfig(config: Promise<UserConfig>): Promise<UserConfig>;
|
|
17
|
+
declare function defineGameViteConfig(config: UserConfigFnObject): UserConfigFnObject;
|
|
18
|
+
declare function defineGameViteConfig(config: UserConfigFnPromise): UserConfigFnPromise;
|
|
19
|
+
declare function defineGameViteConfig(config: UserConfigFn): UserConfigFn;
|
|
20
|
+
declare function defineGameViteConfig(config: UserConfigExport): UserConfigExport;
|
|
21
|
+
|
|
22
|
+
export { defineGameViteConfig, phaserRexUIScenePlugin };
|
package/dist/vite.d.ts
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { UserConfig, UserConfigFnObject, UserConfigFnPromise, UserConfigFn, UserConfigExport, Plugin } from 'vite';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* 将生产 Scene 对裸模块 `phaser` 的导入重定向到 devkit facade。
|
|
5
|
+
*
|
|
6
|
+
* 只处理 `src/scenes`,因为只有 Scene 的继承入口需要增强;其余模块继续直接使用
|
|
7
|
+
* Phaser,可减少构建影响面,并避免普通模块观察到被替换的 Scene 构造器。
|
|
8
|
+
*/
|
|
9
|
+
declare function phaserRexUIScenePlugin(projectRoot?: string): Plugin;
|
|
10
|
+
/**
|
|
11
|
+
* 生成游戏项目的 Vite 配置,并把强制 Scene 重定向放在用户插件之前。
|
|
12
|
+
* 模板只暴露此稳定入口,具体拦截逻辑保留在生成项目只读的 devkit 内。
|
|
13
|
+
* 调用签名与 Vite `defineConfig` 保持一致,支持对象、Promise 和配置函数。
|
|
14
|
+
*/
|
|
15
|
+
declare function defineGameViteConfig(config: UserConfig): UserConfig;
|
|
16
|
+
declare function defineGameViteConfig(config: Promise<UserConfig>): Promise<UserConfig>;
|
|
17
|
+
declare function defineGameViteConfig(config: UserConfigFnObject): UserConfigFnObject;
|
|
18
|
+
declare function defineGameViteConfig(config: UserConfigFnPromise): UserConfigFnPromise;
|
|
19
|
+
declare function defineGameViteConfig(config: UserConfigFn): UserConfigFn;
|
|
20
|
+
declare function defineGameViteConfig(config: UserConfigExport): UserConfigExport;
|
|
21
|
+
|
|
22
|
+
export { defineGameViteConfig, phaserRexUIScenePlugin };
|
package/dist/vite.js
ADDED
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/vite.ts
|
|
21
|
+
var vite_exports = {};
|
|
22
|
+
__export(vite_exports, {
|
|
23
|
+
defineGameViteConfig: () => defineGameViteConfig,
|
|
24
|
+
phaserRexUIScenePlugin: () => phaserRexUIScenePlugin
|
|
25
|
+
});
|
|
26
|
+
module.exports = __toCommonJS(vite_exports);
|
|
27
|
+
var import_node_fs = require("fs");
|
|
28
|
+
var import_node_module = require("module");
|
|
29
|
+
var import_node_path = require("path");
|
|
30
|
+
var PHASER_MODULE_ID = "phaser";
|
|
31
|
+
function isPromiseLike(value) {
|
|
32
|
+
return typeof value === "object" && value !== null && "then" in value && typeof value.then === "function";
|
|
33
|
+
}
|
|
34
|
+
function resolvePhaserFacade(projectRoot) {
|
|
35
|
+
const requireFromProject = (0, import_node_module.createRequire)((0, import_node_path.join)(projectRoot, "package.json"));
|
|
36
|
+
const viteEntry = requireFromProject.resolve("miaoda-game-devkit/vite");
|
|
37
|
+
const facade = (0, import_node_path.join)((0, import_node_path.dirname)(viteEntry), "phaser-facade.mjs");
|
|
38
|
+
if (!(0, import_node_fs.existsSync)(facade)) {
|
|
39
|
+
throw new Error(
|
|
40
|
+
`miaoda-game-devkit \u7F3A\u5C11 Phaser facade\uFF1A${facade}`
|
|
41
|
+
);
|
|
42
|
+
}
|
|
43
|
+
return facade;
|
|
44
|
+
}
|
|
45
|
+
function isInsideDirectory(filePath, directory) {
|
|
46
|
+
const normalizedFile = (0, import_node_path.normalize)(filePath);
|
|
47
|
+
const normalizedDirectory = `${(0, import_node_path.normalize)(directory)}${import_node_path.sep}`;
|
|
48
|
+
return normalizedFile.startsWith(normalizedDirectory);
|
|
49
|
+
}
|
|
50
|
+
function phaserRexUIScenePlugin(projectRoot) {
|
|
51
|
+
let scenesRoot = projectRoot ? (0, import_node_path.resolve)(projectRoot, "src/scenes") : void 0;
|
|
52
|
+
let phaserFacade = projectRoot ? resolvePhaserFacade(projectRoot) : void 0;
|
|
53
|
+
return {
|
|
54
|
+
name: "miaoda-phaser-rexui-scene",
|
|
55
|
+
enforce: "pre",
|
|
56
|
+
configResolved(config) {
|
|
57
|
+
const resolvedProjectRoot = projectRoot ?? config.root;
|
|
58
|
+
scenesRoot ??= (0, import_node_path.resolve)(resolvedProjectRoot, "src/scenes");
|
|
59
|
+
phaserFacade ??= resolvePhaserFacade(resolvedProjectRoot);
|
|
60
|
+
},
|
|
61
|
+
/** 查询参数属于构建工具元数据,去除后才能稳定判断真实源码位置。 */
|
|
62
|
+
resolveId(source, importer) {
|
|
63
|
+
if (source !== PHASER_MODULE_ID || !importer || !scenesRoot) {
|
|
64
|
+
return null;
|
|
65
|
+
}
|
|
66
|
+
const cleanImporter = importer.split("?", 1)[0] ?? importer;
|
|
67
|
+
return isInsideDirectory(cleanImporter, scenesRoot) ? phaserFacade ?? null : null;
|
|
68
|
+
}
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
function withGameDefaults(config) {
|
|
72
|
+
return {
|
|
73
|
+
...config,
|
|
74
|
+
plugins: [
|
|
75
|
+
phaserRexUIScenePlugin(),
|
|
76
|
+
...config.plugins ?? []
|
|
77
|
+
]
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
function defineGameViteConfig(config) {
|
|
81
|
+
if (typeof config === "function") {
|
|
82
|
+
return (env) => {
|
|
83
|
+
const resolved = config(env);
|
|
84
|
+
return isPromiseLike(resolved) ? resolved.then(withGameDefaults) : withGameDefaults(resolved);
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
return isPromiseLike(config) ? config.then(withGameDefaults) : withGameDefaults(config);
|
|
88
|
+
}
|
|
89
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
90
|
+
0 && (module.exports = {
|
|
91
|
+
defineGameViteConfig,
|
|
92
|
+
phaserRexUIScenePlugin
|
|
93
|
+
});
|
package/dist/vite.mjs
ADDED
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
// src/vite.ts
|
|
2
|
+
import { existsSync } from "fs";
|
|
3
|
+
import { createRequire } from "module";
|
|
4
|
+
import { dirname, join, normalize, resolve, sep } from "path";
|
|
5
|
+
var PHASER_MODULE_ID = "phaser";
|
|
6
|
+
function isPromiseLike(value) {
|
|
7
|
+
return typeof value === "object" && value !== null && "then" in value && typeof value.then === "function";
|
|
8
|
+
}
|
|
9
|
+
function resolvePhaserFacade(projectRoot) {
|
|
10
|
+
const requireFromProject = createRequire(join(projectRoot, "package.json"));
|
|
11
|
+
const viteEntry = requireFromProject.resolve("miaoda-game-devkit/vite");
|
|
12
|
+
const facade = join(dirname(viteEntry), "phaser-facade.mjs");
|
|
13
|
+
if (!existsSync(facade)) {
|
|
14
|
+
throw new Error(
|
|
15
|
+
`miaoda-game-devkit \u7F3A\u5C11 Phaser facade\uFF1A${facade}`
|
|
16
|
+
);
|
|
17
|
+
}
|
|
18
|
+
return facade;
|
|
19
|
+
}
|
|
20
|
+
function isInsideDirectory(filePath, directory) {
|
|
21
|
+
const normalizedFile = normalize(filePath);
|
|
22
|
+
const normalizedDirectory = `${normalize(directory)}${sep}`;
|
|
23
|
+
return normalizedFile.startsWith(normalizedDirectory);
|
|
24
|
+
}
|
|
25
|
+
function phaserRexUIScenePlugin(projectRoot) {
|
|
26
|
+
let scenesRoot = projectRoot ? resolve(projectRoot, "src/scenes") : void 0;
|
|
27
|
+
let phaserFacade = projectRoot ? resolvePhaserFacade(projectRoot) : void 0;
|
|
28
|
+
return {
|
|
29
|
+
name: "miaoda-phaser-rexui-scene",
|
|
30
|
+
enforce: "pre",
|
|
31
|
+
configResolved(config) {
|
|
32
|
+
const resolvedProjectRoot = projectRoot ?? config.root;
|
|
33
|
+
scenesRoot ??= resolve(resolvedProjectRoot, "src/scenes");
|
|
34
|
+
phaserFacade ??= resolvePhaserFacade(resolvedProjectRoot);
|
|
35
|
+
},
|
|
36
|
+
/** 查询参数属于构建工具元数据,去除后才能稳定判断真实源码位置。 */
|
|
37
|
+
resolveId(source, importer) {
|
|
38
|
+
if (source !== PHASER_MODULE_ID || !importer || !scenesRoot) {
|
|
39
|
+
return null;
|
|
40
|
+
}
|
|
41
|
+
const cleanImporter = importer.split("?", 1)[0] ?? importer;
|
|
42
|
+
return isInsideDirectory(cleanImporter, scenesRoot) ? phaserFacade ?? null : null;
|
|
43
|
+
}
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
function withGameDefaults(config) {
|
|
47
|
+
return {
|
|
48
|
+
...config,
|
|
49
|
+
plugins: [
|
|
50
|
+
phaserRexUIScenePlugin(),
|
|
51
|
+
...config.plugins ?? []
|
|
52
|
+
]
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
function defineGameViteConfig(config) {
|
|
56
|
+
if (typeof config === "function") {
|
|
57
|
+
return (env) => {
|
|
58
|
+
const resolved = config(env);
|
|
59
|
+
return isPromiseLike(resolved) ? resolved.then(withGameDefaults) : withGameDefaults(resolved);
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
return isPromiseLike(config) ? config.then(withGameDefaults) : withGameDefaults(config);
|
|
63
|
+
}
|
|
64
|
+
export {
|
|
65
|
+
defineGameViteConfig,
|
|
66
|
+
phaserRexUIScenePlugin
|
|
67
|
+
};
|
package/dist/vitest-config.d.mts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { ViteUserConfig } from 'vitest/config';
|
|
2
|
-
import {
|
|
2
|
+
import { G as GameplayAuditOptions } from './gameplay-audit-DmbBA0M_.mjs';
|
|
3
3
|
import 'phaser';
|
|
4
4
|
|
|
5
5
|
interface GameVitestConfigOptions {
|
|
@@ -11,7 +11,7 @@ interface GameVitestConfigOptions {
|
|
|
11
11
|
aliases?: Record<string, string>;
|
|
12
12
|
/** 在 devkit 基础 setup 之后执行的项目级 setup 文件。 */
|
|
13
13
|
additionalSetupFiles?: string[];
|
|
14
|
-
/**
|
|
14
|
+
/** 除 devkit 内置 Phaser/RexUI 边界外,还需要由 Vite 转换的项目依赖。 */
|
|
15
15
|
inlineDependencies?: RegExp[];
|
|
16
16
|
/** 单个游戏运行时测试的超时时间。 */
|
|
17
17
|
testTimeout?: number;
|
package/dist/vitest-config.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { ViteUserConfig } from 'vitest/config';
|
|
2
|
-
import {
|
|
2
|
+
import { G as GameplayAuditOptions } from './gameplay-audit-DmbBA0M_.js';
|
|
3
3
|
import 'phaser';
|
|
4
4
|
|
|
5
5
|
interface GameVitestConfigOptions {
|
|
@@ -11,7 +11,7 @@ interface GameVitestConfigOptions {
|
|
|
11
11
|
aliases?: Record<string, string>;
|
|
12
12
|
/** 在 devkit 基础 setup 之后执行的项目级 setup 文件。 */
|
|
13
13
|
additionalSetupFiles?: string[];
|
|
14
|
-
/**
|
|
14
|
+
/** 除 devkit 内置 Phaser/RexUI 边界外,还需要由 Vite 转换的项目依赖。 */
|
|
15
15
|
inlineDependencies?: RegExp[];
|
|
16
16
|
/** 单个游戏运行时测试的超时时间。 */
|
|
17
17
|
testTimeout?: number;
|
package/dist/vitest-config.js
CHANGED
|
@@ -23,7 +23,7 @@ __export(vitest_config_exports, {
|
|
|
23
23
|
defineGameVitestConfig: () => defineGameVitestConfig
|
|
24
24
|
});
|
|
25
25
|
module.exports = __toCommonJS(vitest_config_exports);
|
|
26
|
-
var
|
|
26
|
+
var import_node_path4 = require("path");
|
|
27
27
|
var import_config = require("vitest/config");
|
|
28
28
|
|
|
29
29
|
// src/gameplay-audit.ts
|
|
@@ -627,7 +627,52 @@ GAMEPLAY_AUDIT: ALL CONTRACTS PASSED (${tests.filter((test) => test.metadata).le
|
|
|
627
627
|
}
|
|
628
628
|
};
|
|
629
629
|
|
|
630
|
+
// src/vite.ts
|
|
631
|
+
var import_node_fs2 = require("fs");
|
|
632
|
+
var import_node_module = require("module");
|
|
633
|
+
var import_node_path3 = require("path");
|
|
634
|
+
var PHASER_MODULE_ID = "phaser";
|
|
635
|
+
function resolvePhaserFacade(projectRoot) {
|
|
636
|
+
const requireFromProject = (0, import_node_module.createRequire)((0, import_node_path3.join)(projectRoot, "package.json"));
|
|
637
|
+
const viteEntry = requireFromProject.resolve("miaoda-game-devkit/vite");
|
|
638
|
+
const facade = (0, import_node_path3.join)((0, import_node_path3.dirname)(viteEntry), "phaser-facade.mjs");
|
|
639
|
+
if (!(0, import_node_fs2.existsSync)(facade)) {
|
|
640
|
+
throw new Error(
|
|
641
|
+
`miaoda-game-devkit \u7F3A\u5C11 Phaser facade\uFF1A${facade}`
|
|
642
|
+
);
|
|
643
|
+
}
|
|
644
|
+
return facade;
|
|
645
|
+
}
|
|
646
|
+
function isInsideDirectory(filePath, directory) {
|
|
647
|
+
const normalizedFile = (0, import_node_path3.normalize)(filePath);
|
|
648
|
+
const normalizedDirectory = `${(0, import_node_path3.normalize)(directory)}${import_node_path3.sep}`;
|
|
649
|
+
return normalizedFile.startsWith(normalizedDirectory);
|
|
650
|
+
}
|
|
651
|
+
function phaserRexUIScenePlugin(projectRoot) {
|
|
652
|
+
let scenesRoot = projectRoot ? (0, import_node_path3.resolve)(projectRoot, "src/scenes") : void 0;
|
|
653
|
+
let phaserFacade = projectRoot ? resolvePhaserFacade(projectRoot) : void 0;
|
|
654
|
+
return {
|
|
655
|
+
name: "miaoda-phaser-rexui-scene",
|
|
656
|
+
enforce: "pre",
|
|
657
|
+
configResolved(config) {
|
|
658
|
+
const resolvedProjectRoot = projectRoot ?? config.root;
|
|
659
|
+
scenesRoot ??= (0, import_node_path3.resolve)(resolvedProjectRoot, "src/scenes");
|
|
660
|
+
phaserFacade ??= resolvePhaserFacade(resolvedProjectRoot);
|
|
661
|
+
},
|
|
662
|
+
/** 查询参数属于构建工具元数据,去除后才能稳定判断真实源码位置。 */
|
|
663
|
+
resolveId(source, importer) {
|
|
664
|
+
if (source !== PHASER_MODULE_ID || !importer || !scenesRoot) {
|
|
665
|
+
return null;
|
|
666
|
+
}
|
|
667
|
+
const cleanImporter = importer.split("?", 1)[0] ?? importer;
|
|
668
|
+
return isInsideDirectory(cleanImporter, scenesRoot) ? phaserFacade ?? null : null;
|
|
669
|
+
}
|
|
670
|
+
};
|
|
671
|
+
}
|
|
672
|
+
|
|
630
673
|
// src/vitest-config.ts
|
|
674
|
+
var PHASER_FACADE_DEPENDENCY = /miaoda-game-devkit[\\/]dist[\\/]phaser-facade\.mjs$/;
|
|
675
|
+
var REXUI_DEPENDENCY = /phaser4-rex-plugins/;
|
|
631
676
|
function defineGameVitestConfig(options) {
|
|
632
677
|
const auditIssues = validateGameplayAuditOptions(options.gameplayAudit, options.projectRoot);
|
|
633
678
|
if (auditIssues.length > 0) {
|
|
@@ -637,10 +682,11 @@ function defineGameVitestConfig(options) {
|
|
|
637
682
|
);
|
|
638
683
|
}
|
|
639
684
|
return (0, import_config.defineConfig)({
|
|
685
|
+
plugins: [phaserRexUIScenePlugin(options.projectRoot)],
|
|
640
686
|
resolve: {
|
|
641
687
|
alias: {
|
|
642
688
|
...options.aliases,
|
|
643
|
-
"@": (0,
|
|
689
|
+
"@": (0, import_node_path4.resolve)(options.projectRoot, "src")
|
|
644
690
|
}
|
|
645
691
|
},
|
|
646
692
|
// devkit 作为 external ESM 加载时,应用测试也必须 externalize Phaser,
|
|
@@ -658,7 +704,11 @@ function defineGameVitestConfig(options) {
|
|
|
658
704
|
// 如果强制内联,Vite 会把这些模块按浏览器模块转换,
|
|
659
705
|
// 最终触发 "No such built-in module: node:"。
|
|
660
706
|
external: [/miaoda-game-devkit/],
|
|
661
|
-
inline:
|
|
707
|
+
inline: [
|
|
708
|
+
PHASER_FACADE_DEPENDENCY,
|
|
709
|
+
REXUI_DEPENDENCY,
|
|
710
|
+
...options.inlineDependencies ?? []
|
|
711
|
+
]
|
|
662
712
|
}
|
|
663
713
|
},
|
|
664
714
|
environment: "jsdom",
|