@al8b/player 0.1.0
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/.turbo/turbo-build.log +19 -0
- package/.turbo/turbo-test.log +9 -0
- package/README.md +21 -0
- package/dist/index.d.mts +40 -0
- package/dist/index.d.ts +40 -0
- package/dist/index.js +76 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +51 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +27 -0
- package/src/index.ts +2 -0
- package/src/player-service.ts +56 -0
- package/src/types.ts +20 -0
- package/tsconfig.json +16 -0
- package/tsup.config.ts +9 -0
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
$ tsup
|
|
2
|
+
[34mCLI[39m Building entry: src/index.ts
|
|
3
|
+
[34mCLI[39m Using tsconfig: tsconfig.json
|
|
4
|
+
[34mCLI[39m tsup v8.5.1
|
|
5
|
+
[34mCLI[39m Using tsup config: /home/runner/work/l8b/l8b/packages/core/player/tsup.config.ts
|
|
6
|
+
[34mCLI[39m Target: es2022
|
|
7
|
+
[34mCLI[39m Cleaning output folder
|
|
8
|
+
[34mCJS[39m Build start
|
|
9
|
+
[34mESM[39m Build start
|
|
10
|
+
[32mCJS[39m [1mdist/index.js [22m[32m2.53 KB[39m
|
|
11
|
+
[32mCJS[39m [1mdist/index.js.map [22m[32m2.84 KB[39m
|
|
12
|
+
[32mCJS[39m ⚡️ Build success in 78ms
|
|
13
|
+
[32mESM[39m [1mdist/index.mjs [22m[32m1.56 KB[39m
|
|
14
|
+
[32mESM[39m [1mdist/index.mjs.map [22m[32m2.70 KB[39m
|
|
15
|
+
[32mESM[39m ⚡️ Build success in 77ms
|
|
16
|
+
[34mDTS[39m Build start
|
|
17
|
+
[32mDTS[39m ⚡️ Build success in 4112ms
|
|
18
|
+
[32mDTS[39m [1mdist/index.d.ts [22m[32m1.17 KB[39m
|
|
19
|
+
[32mDTS[39m [1mdist/index.d.mts [22m[32m1.17 KB[39m
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
$ vitest run --passWithNoTests
|
|
2
|
+
|
|
3
|
+
[1m[46m RUN [49m[22m [36mv4.1.2 [39m[90m/home/runner/work/l8b/l8b/packages/core/player[39m
|
|
4
|
+
|
|
5
|
+
No test files found, exiting with code 0
|
|
6
|
+
|
|
7
|
+
[2minclude: [22m[33m**/*.{test,spec}.?(c|m)[jt]s?(x)[39m
|
|
8
|
+
[2mexclude: [22m[33m**/node_modules/**[2m, [22m**/.git/**[39m
|
|
9
|
+
|
package/README.md
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# @al8b/player
|
|
2
|
+
|
|
3
|
+
Player control bridge for L8B. It exposes the runtime-to-host lifecycle hooks used by game code for pause/resume, performance settings, and outbound messages.
|
|
4
|
+
|
|
5
|
+
## Public API
|
|
6
|
+
|
|
7
|
+
- `PlayerService`
|
|
8
|
+
- Type: `PlayerDelegate`
|
|
9
|
+
|
|
10
|
+
## Notes
|
|
11
|
+
|
|
12
|
+
- Consumed by `@al8b/runtime` to build the script-facing `player.*` API.
|
|
13
|
+
- This package is intentionally small and host-integration focused.
|
|
14
|
+
|
|
15
|
+
## Scripts
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
bun run build
|
|
19
|
+
bun run test
|
|
20
|
+
bun run clean
|
|
21
|
+
```
|
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Delegate interface for PlayerService.
|
|
3
|
+
*
|
|
4
|
+
* The orchestrator provides concrete implementations of these callbacks
|
|
5
|
+
* so the PlayerService stays decoupled from runtime internals.
|
|
6
|
+
*/
|
|
7
|
+
interface PlayerDelegate {
|
|
8
|
+
/** Pause the game loop */
|
|
9
|
+
pause: () => void;
|
|
10
|
+
/** Resume the game loop */
|
|
11
|
+
resume: () => void;
|
|
12
|
+
/** Send an arbitrary message to the host application */
|
|
13
|
+
postMessage: (message: any) => void;
|
|
14
|
+
/** Get current FPS */
|
|
15
|
+
getFps: () => number;
|
|
16
|
+
/** Get target update rate (Hz) */
|
|
17
|
+
getUpdateRate: () => number;
|
|
18
|
+
/** Set target update rate (Hz) */
|
|
19
|
+
setUpdateRate: (rate: number) => void;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* PlayerService - Controls player UX from LootiScript
|
|
24
|
+
*
|
|
25
|
+
* Provides game scripts with the ability to control the player lifecycle
|
|
26
|
+
* (quit, pause, resume, exit), adjust performance (fps, update_rate),
|
|
27
|
+
* and communicate with the host application (postMessage).
|
|
28
|
+
*/
|
|
29
|
+
|
|
30
|
+
declare class PlayerService {
|
|
31
|
+
private delegate;
|
|
32
|
+
private interfaceCache;
|
|
33
|
+
constructor(delegate: PlayerDelegate);
|
|
34
|
+
/**
|
|
35
|
+
* Get interface for game code (LootiScript `player.*`)
|
|
36
|
+
*/
|
|
37
|
+
getInterface(): Record<string, any>;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export { type PlayerDelegate, PlayerService };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Delegate interface for PlayerService.
|
|
3
|
+
*
|
|
4
|
+
* The orchestrator provides concrete implementations of these callbacks
|
|
5
|
+
* so the PlayerService stays decoupled from runtime internals.
|
|
6
|
+
*/
|
|
7
|
+
interface PlayerDelegate {
|
|
8
|
+
/** Pause the game loop */
|
|
9
|
+
pause: () => void;
|
|
10
|
+
/** Resume the game loop */
|
|
11
|
+
resume: () => void;
|
|
12
|
+
/** Send an arbitrary message to the host application */
|
|
13
|
+
postMessage: (message: any) => void;
|
|
14
|
+
/** Get current FPS */
|
|
15
|
+
getFps: () => number;
|
|
16
|
+
/** Get target update rate (Hz) */
|
|
17
|
+
getUpdateRate: () => number;
|
|
18
|
+
/** Set target update rate (Hz) */
|
|
19
|
+
setUpdateRate: (rate: number) => void;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* PlayerService - Controls player UX from LootiScript
|
|
24
|
+
*
|
|
25
|
+
* Provides game scripts with the ability to control the player lifecycle
|
|
26
|
+
* (quit, pause, resume, exit), adjust performance (fps, update_rate),
|
|
27
|
+
* and communicate with the host application (postMessage).
|
|
28
|
+
*/
|
|
29
|
+
|
|
30
|
+
declare class PlayerService {
|
|
31
|
+
private delegate;
|
|
32
|
+
private interfaceCache;
|
|
33
|
+
constructor(delegate: PlayerDelegate);
|
|
34
|
+
/**
|
|
35
|
+
* Get interface for game code (LootiScript `player.*`)
|
|
36
|
+
*/
|
|
37
|
+
getInterface(): Record<string, any>;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export { type PlayerDelegate, PlayerService };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,76 @@
|
|
|
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 __name = (target, value) => __defProp(target, "name", { value, configurable: true });
|
|
7
|
+
var __export = (target, all) => {
|
|
8
|
+
for (var name in all)
|
|
9
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
10
|
+
};
|
|
11
|
+
var __copyProps = (to, from, except, desc) => {
|
|
12
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
13
|
+
for (let key of __getOwnPropNames(from))
|
|
14
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
15
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
16
|
+
}
|
|
17
|
+
return to;
|
|
18
|
+
};
|
|
19
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
20
|
+
|
|
21
|
+
// src/index.ts
|
|
22
|
+
var index_exports = {};
|
|
23
|
+
__export(index_exports, {
|
|
24
|
+
PlayerService: () => PlayerService
|
|
25
|
+
});
|
|
26
|
+
module.exports = __toCommonJS(index_exports);
|
|
27
|
+
|
|
28
|
+
// src/player-service.ts
|
|
29
|
+
var PlayerService = class {
|
|
30
|
+
static {
|
|
31
|
+
__name(this, "PlayerService");
|
|
32
|
+
}
|
|
33
|
+
delegate;
|
|
34
|
+
interfaceCache = null;
|
|
35
|
+
constructor(delegate) {
|
|
36
|
+
this.delegate = delegate;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Get interface for game code (LootiScript `player.*`)
|
|
40
|
+
*/
|
|
41
|
+
getInterface() {
|
|
42
|
+
if (this.interfaceCache) {
|
|
43
|
+
return this.interfaceCache;
|
|
44
|
+
}
|
|
45
|
+
const iface = {
|
|
46
|
+
pause: /* @__PURE__ */ __name(() => this.delegate.pause(), "pause"),
|
|
47
|
+
resume: /* @__PURE__ */ __name(() => this.delegate.resume(), "resume"),
|
|
48
|
+
postMessage: /* @__PURE__ */ __name((message) => this.delegate.postMessage(message), "postMessage"),
|
|
49
|
+
setFps: /* @__PURE__ */ __name((fps) => {
|
|
50
|
+
if (typeof fps === "number" && isFinite(fps) && fps > 0) {
|
|
51
|
+
this.delegate.setUpdateRate(fps);
|
|
52
|
+
}
|
|
53
|
+
}, "setFps")
|
|
54
|
+
};
|
|
55
|
+
Object.defineProperty(iface, "fps", {
|
|
56
|
+
get: /* @__PURE__ */ __name(() => this.delegate.getFps(), "get"),
|
|
57
|
+
enumerable: true
|
|
58
|
+
});
|
|
59
|
+
Object.defineProperty(iface, "update_rate", {
|
|
60
|
+
get: /* @__PURE__ */ __name(() => this.delegate.getUpdateRate(), "get"),
|
|
61
|
+
set: /* @__PURE__ */ __name((value) => {
|
|
62
|
+
if (typeof value === "number" && isFinite(value) && value > 0) {
|
|
63
|
+
this.delegate.setUpdateRate(value);
|
|
64
|
+
}
|
|
65
|
+
}, "set"),
|
|
66
|
+
enumerable: true
|
|
67
|
+
});
|
|
68
|
+
this.interfaceCache = iface;
|
|
69
|
+
return this.interfaceCache;
|
|
70
|
+
}
|
|
71
|
+
};
|
|
72
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
73
|
+
0 && (module.exports = {
|
|
74
|
+
PlayerService
|
|
75
|
+
});
|
|
76
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/player-service.ts"],"sourcesContent":["export { PlayerService } from \"./player-service\";\nexport type { PlayerDelegate } from \"./types\";\n","/**\n * PlayerService - Controls player UX from LootiScript\n *\n * Provides game scripts with the ability to control the player lifecycle\n * (quit, pause, resume, exit), adjust performance (fps, update_rate),\n * and communicate with the host application (postMessage).\n */\n\nimport type { PlayerDelegate } from \"./types\";\n\nexport class PlayerService {\n\tprivate delegate: PlayerDelegate;\n\tprivate interfaceCache: Record<string, any> | null = null;\n\n\tconstructor(delegate: PlayerDelegate) {\n\t\tthis.delegate = delegate;\n\t}\n\n\t/**\n\t * Get interface for game code (LootiScript `player.*`)\n\t */\n\tgetInterface(): Record<string, any> {\n\t\tif (this.interfaceCache) {\n\t\t\treturn this.interfaceCache;\n\t\t}\n\n\t\tconst iface: Record<string, any> = {\n\t\t\tpause: () => this.delegate.pause(),\n\t\t\tresume: () => this.delegate.resume(),\n\t\t\tpostMessage: (message: any) => this.delegate.postMessage(message),\n\t\t\tsetFps: (fps: number) => {\n\t\t\t\tif (typeof fps === \"number\" && isFinite(fps) && fps > 0) {\n\t\t\t\t\tthis.delegate.setUpdateRate(fps);\n\t\t\t\t}\n\t\t\t},\n\t\t};\n\n\t\tObject.defineProperty(iface, \"fps\", {\n\t\t\tget: () => this.delegate.getFps(),\n\t\t\tenumerable: true,\n\t\t});\n\n\t\tObject.defineProperty(iface, \"update_rate\", {\n\t\t\tget: () => this.delegate.getUpdateRate(),\n\t\t\tset: (value: number) => {\n\t\t\t\tif (typeof value === \"number\" && isFinite(value) && value > 0) {\n\t\t\t\t\tthis.delegate.setUpdateRate(value);\n\t\t\t\t}\n\t\t\t},\n\t\t\tenumerable: true,\n\t\t});\n\n\t\tthis.interfaceCache = iface;\n\t\treturn this.interfaceCache;\n\t}\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;AAAA;;;;;;;ACUO,IAAMA,gBAAN,MAAMA;EAVb,OAUaA;;;EACJC;EACAC,iBAA6C;EAErD,YAAYD,UAA0B;AACrC,SAAKA,WAAWA;EACjB;;;;EAKAE,eAAoC;AACnC,QAAI,KAAKD,gBAAgB;AACxB,aAAO,KAAKA;IACb;AAEA,UAAME,QAA6B;MAClCC,OAAO,6BAAM,KAAKJ,SAASI,MAAK,GAAzB;MACPC,QAAQ,6BAAM,KAAKL,SAASK,OAAM,GAA1B;MACRC,aAAa,wBAACC,YAAiB,KAAKP,SAASM,YAAYC,OAAAA,GAA5C;MACbC,QAAQ,wBAACC,QAAAA;AACR,YAAI,OAAOA,QAAQ,YAAYC,SAASD,GAAAA,KAAQA,MAAM,GAAG;AACxD,eAAKT,SAASW,cAAcF,GAAAA;QAC7B;MACD,GAJQ;IAKT;AAEAG,WAAOC,eAAeV,OAAO,OAAO;MACnCW,KAAK,6BAAM,KAAKd,SAASe,OAAM,GAA1B;MACLC,YAAY;IACb,CAAA;AAEAJ,WAAOC,eAAeV,OAAO,eAAe;MAC3CW,KAAK,6BAAM,KAAKd,SAASiB,cAAa,GAAjC;MACLC,KAAK,wBAACC,UAAAA;AACL,YAAI,OAAOA,UAAU,YAAYT,SAASS,KAAAA,KAAUA,QAAQ,GAAG;AAC9D,eAAKnB,SAASW,cAAcQ,KAAAA;QAC7B;MACD,GAJK;MAKLH,YAAY;IACb,CAAA;AAEA,SAAKf,iBAAiBE;AACtB,WAAO,KAAKF;EACb;AACD;","names":["PlayerService","delegate","interfaceCache","getInterface","iface","pause","resume","postMessage","message","setFps","fps","isFinite","setUpdateRate","Object","defineProperty","get","getFps","enumerable","getUpdateRate","set","value"]}
|
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
|
|
3
|
+
|
|
4
|
+
// src/player-service.ts
|
|
5
|
+
var PlayerService = class {
|
|
6
|
+
static {
|
|
7
|
+
__name(this, "PlayerService");
|
|
8
|
+
}
|
|
9
|
+
delegate;
|
|
10
|
+
interfaceCache = null;
|
|
11
|
+
constructor(delegate) {
|
|
12
|
+
this.delegate = delegate;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Get interface for game code (LootiScript `player.*`)
|
|
16
|
+
*/
|
|
17
|
+
getInterface() {
|
|
18
|
+
if (this.interfaceCache) {
|
|
19
|
+
return this.interfaceCache;
|
|
20
|
+
}
|
|
21
|
+
const iface = {
|
|
22
|
+
pause: /* @__PURE__ */ __name(() => this.delegate.pause(), "pause"),
|
|
23
|
+
resume: /* @__PURE__ */ __name(() => this.delegate.resume(), "resume"),
|
|
24
|
+
postMessage: /* @__PURE__ */ __name((message) => this.delegate.postMessage(message), "postMessage"),
|
|
25
|
+
setFps: /* @__PURE__ */ __name((fps) => {
|
|
26
|
+
if (typeof fps === "number" && isFinite(fps) && fps > 0) {
|
|
27
|
+
this.delegate.setUpdateRate(fps);
|
|
28
|
+
}
|
|
29
|
+
}, "setFps")
|
|
30
|
+
};
|
|
31
|
+
Object.defineProperty(iface, "fps", {
|
|
32
|
+
get: /* @__PURE__ */ __name(() => this.delegate.getFps(), "get"),
|
|
33
|
+
enumerable: true
|
|
34
|
+
});
|
|
35
|
+
Object.defineProperty(iface, "update_rate", {
|
|
36
|
+
get: /* @__PURE__ */ __name(() => this.delegate.getUpdateRate(), "get"),
|
|
37
|
+
set: /* @__PURE__ */ __name((value) => {
|
|
38
|
+
if (typeof value === "number" && isFinite(value) && value > 0) {
|
|
39
|
+
this.delegate.setUpdateRate(value);
|
|
40
|
+
}
|
|
41
|
+
}, "set"),
|
|
42
|
+
enumerable: true
|
|
43
|
+
});
|
|
44
|
+
this.interfaceCache = iface;
|
|
45
|
+
return this.interfaceCache;
|
|
46
|
+
}
|
|
47
|
+
};
|
|
48
|
+
export {
|
|
49
|
+
PlayerService
|
|
50
|
+
};
|
|
51
|
+
//# sourceMappingURL=index.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/player-service.ts"],"sourcesContent":["/**\n * PlayerService - Controls player UX from LootiScript\n *\n * Provides game scripts with the ability to control the player lifecycle\n * (quit, pause, resume, exit), adjust performance (fps, update_rate),\n * and communicate with the host application (postMessage).\n */\n\nimport type { PlayerDelegate } from \"./types\";\n\nexport class PlayerService {\n\tprivate delegate: PlayerDelegate;\n\tprivate interfaceCache: Record<string, any> | null = null;\n\n\tconstructor(delegate: PlayerDelegate) {\n\t\tthis.delegate = delegate;\n\t}\n\n\t/**\n\t * Get interface for game code (LootiScript `player.*`)\n\t */\n\tgetInterface(): Record<string, any> {\n\t\tif (this.interfaceCache) {\n\t\t\treturn this.interfaceCache;\n\t\t}\n\n\t\tconst iface: Record<string, any> = {\n\t\t\tpause: () => this.delegate.pause(),\n\t\t\tresume: () => this.delegate.resume(),\n\t\t\tpostMessage: (message: any) => this.delegate.postMessage(message),\n\t\t\tsetFps: (fps: number) => {\n\t\t\t\tif (typeof fps === \"number\" && isFinite(fps) && fps > 0) {\n\t\t\t\t\tthis.delegate.setUpdateRate(fps);\n\t\t\t\t}\n\t\t\t},\n\t\t};\n\n\t\tObject.defineProperty(iface, \"fps\", {\n\t\t\tget: () => this.delegate.getFps(),\n\t\t\tenumerable: true,\n\t\t});\n\n\t\tObject.defineProperty(iface, \"update_rate\", {\n\t\t\tget: () => this.delegate.getUpdateRate(),\n\t\t\tset: (value: number) => {\n\t\t\t\tif (typeof value === \"number\" && isFinite(value) && value > 0) {\n\t\t\t\t\tthis.delegate.setUpdateRate(value);\n\t\t\t\t}\n\t\t\t},\n\t\t\tenumerable: true,\n\t\t});\n\n\t\tthis.interfaceCache = iface;\n\t\treturn this.interfaceCache;\n\t}\n}\n"],"mappings":";;;;AAUO,IAAMA,gBAAN,MAAMA;EAVb,OAUaA;;;EACJC;EACAC,iBAA6C;EAErD,YAAYD,UAA0B;AACrC,SAAKA,WAAWA;EACjB;;;;EAKAE,eAAoC;AACnC,QAAI,KAAKD,gBAAgB;AACxB,aAAO,KAAKA;IACb;AAEA,UAAME,QAA6B;MAClCC,OAAO,6BAAM,KAAKJ,SAASI,MAAK,GAAzB;MACPC,QAAQ,6BAAM,KAAKL,SAASK,OAAM,GAA1B;MACRC,aAAa,wBAACC,YAAiB,KAAKP,SAASM,YAAYC,OAAAA,GAA5C;MACbC,QAAQ,wBAACC,QAAAA;AACR,YAAI,OAAOA,QAAQ,YAAYC,SAASD,GAAAA,KAAQA,MAAM,GAAG;AACxD,eAAKT,SAASW,cAAcF,GAAAA;QAC7B;MACD,GAJQ;IAKT;AAEAG,WAAOC,eAAeV,OAAO,OAAO;MACnCW,KAAK,6BAAM,KAAKd,SAASe,OAAM,GAA1B;MACLC,YAAY;IACb,CAAA;AAEAJ,WAAOC,eAAeV,OAAO,eAAe;MAC3CW,KAAK,6BAAM,KAAKd,SAASiB,cAAa,GAAjC;MACLC,KAAK,wBAACC,UAAAA;AACL,YAAI,OAAOA,UAAU,YAAYT,SAASS,KAAAA,KAAUA,QAAQ,GAAG;AAC9D,eAAKnB,SAASW,cAAcQ,KAAAA;QAC7B;MACD,GAJK;MAKLH,YAAY;IACb,CAAA;AAEA,SAAKf,iBAAiBE;AACtB,WAAO,KAAKF;EACb;AACD;","names":["PlayerService","delegate","interfaceCache","getInterface","iface","pause","resume","postMessage","message","setFps","fps","isFinite","setUpdateRate","Object","defineProperty","get","getFps","enumerable","getUpdateRate","set","value"]}
|
package/package.json
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@al8b/player",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Player control API for L8B - lifecycle, performance, and host communication",
|
|
5
|
+
"main": "./dist/index.js",
|
|
6
|
+
"module": "./dist/index.mjs",
|
|
7
|
+
"types": "./dist/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"types": "./dist/index.d.ts",
|
|
11
|
+
"import": "./dist/index.mjs",
|
|
12
|
+
"require": "./dist/index.js"
|
|
13
|
+
}
|
|
14
|
+
},
|
|
15
|
+
"scripts": {
|
|
16
|
+
"build": "tsup",
|
|
17
|
+
"clean": "bun --bun ../../../scripts/clean-package.mjs dist .turbo node_modules",
|
|
18
|
+
"test": "vitest run --passWithNoTests"
|
|
19
|
+
},
|
|
20
|
+
"devDependencies": {
|
|
21
|
+
"tsup": "^8.0.0",
|
|
22
|
+
"typescript": "^5.9.3"
|
|
23
|
+
},
|
|
24
|
+
"publishConfig": {
|
|
25
|
+
"access": "public"
|
|
26
|
+
}
|
|
27
|
+
}
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PlayerService - Controls player UX from LootiScript
|
|
3
|
+
*
|
|
4
|
+
* Provides game scripts with the ability to control the player lifecycle
|
|
5
|
+
* (quit, pause, resume, exit), adjust performance (fps, update_rate),
|
|
6
|
+
* and communicate with the host application (postMessage).
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import type { PlayerDelegate } from "./types";
|
|
10
|
+
|
|
11
|
+
export class PlayerService {
|
|
12
|
+
private delegate: PlayerDelegate;
|
|
13
|
+
private interfaceCache: Record<string, any> | null = null;
|
|
14
|
+
|
|
15
|
+
constructor(delegate: PlayerDelegate) {
|
|
16
|
+
this.delegate = delegate;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Get interface for game code (LootiScript `player.*`)
|
|
21
|
+
*/
|
|
22
|
+
getInterface(): Record<string, any> {
|
|
23
|
+
if (this.interfaceCache) {
|
|
24
|
+
return this.interfaceCache;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
const iface: Record<string, any> = {
|
|
28
|
+
pause: () => this.delegate.pause(),
|
|
29
|
+
resume: () => this.delegate.resume(),
|
|
30
|
+
postMessage: (message: any) => this.delegate.postMessage(message),
|
|
31
|
+
setFps: (fps: number) => {
|
|
32
|
+
if (typeof fps === "number" && isFinite(fps) && fps > 0) {
|
|
33
|
+
this.delegate.setUpdateRate(fps);
|
|
34
|
+
}
|
|
35
|
+
},
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
Object.defineProperty(iface, "fps", {
|
|
39
|
+
get: () => this.delegate.getFps(),
|
|
40
|
+
enumerable: true,
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
Object.defineProperty(iface, "update_rate", {
|
|
44
|
+
get: () => this.delegate.getUpdateRate(),
|
|
45
|
+
set: (value: number) => {
|
|
46
|
+
if (typeof value === "number" && isFinite(value) && value > 0) {
|
|
47
|
+
this.delegate.setUpdateRate(value);
|
|
48
|
+
}
|
|
49
|
+
},
|
|
50
|
+
enumerable: true,
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
this.interfaceCache = iface;
|
|
54
|
+
return this.interfaceCache;
|
|
55
|
+
}
|
|
56
|
+
}
|
package/src/types.ts
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Delegate interface for PlayerService.
|
|
3
|
+
*
|
|
4
|
+
* The orchestrator provides concrete implementations of these callbacks
|
|
5
|
+
* so the PlayerService stays decoupled from runtime internals.
|
|
6
|
+
*/
|
|
7
|
+
export interface PlayerDelegate {
|
|
8
|
+
/** Pause the game loop */
|
|
9
|
+
pause: () => void;
|
|
10
|
+
/** Resume the game loop */
|
|
11
|
+
resume: () => void;
|
|
12
|
+
/** Send an arbitrary message to the host application */
|
|
13
|
+
postMessage: (message: any) => void;
|
|
14
|
+
/** Get current FPS */
|
|
15
|
+
getFps: () => number;
|
|
16
|
+
/** Get target update rate (Hz) */
|
|
17
|
+
getUpdateRate: () => number;
|
|
18
|
+
/** Set target update rate (Hz) */
|
|
19
|
+
setUpdateRate: (rate: number) => void;
|
|
20
|
+
}
|
package/tsconfig.json
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
{
|
|
2
|
+
"extends": "../../../tsconfig.base.json",
|
|
3
|
+
"compilerOptions": {
|
|
4
|
+
"outDir": "dist",
|
|
5
|
+
"rootDir": "src",
|
|
6
|
+
"ignoreDeprecations": "5.0"
|
|
7
|
+
},
|
|
8
|
+
"include": [
|
|
9
|
+
"src/**/*"
|
|
10
|
+
],
|
|
11
|
+
"exclude": [
|
|
12
|
+
"node_modules",
|
|
13
|
+
"dist",
|
|
14
|
+
"**/*.test.ts"
|
|
15
|
+
]
|
|
16
|
+
}
|