@gjsify/gamepad 0.36.0 → 0.38.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/globals.mjs +16 -25
- package/lib/types/backend.d.ts +37 -52
- package/lib/types/button-mapping.d.ts +3 -11
- package/lib/types/gamepad-manager.d.ts +4 -9
- package/package.json +4 -4
package/globals.mjs
CHANGED
|
@@ -1,18 +1,12 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Re-exports native Gamepad API globals for browser builds
|
|
2
|
+
* Re-exports the native Gamepad API globals for browser + NativeScript builds; the
|
|
3
|
+
* libmanette GJS backend stays GJS-only.
|
|
3
4
|
*
|
|
4
|
-
*
|
|
5
|
-
* the
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
* — and the same rule routes it here for `nativescript`. That makes this file the
|
|
10
|
-
* NON-GJS entry for the package root, so every root export a consumer may import
|
|
11
|
-
* has to be answerable from here or the routed bundle dies with `MISSING_EXPORT`.
|
|
12
|
-
*
|
|
13
|
-
* NOT used on Node — Node has no Gamepad global (`gjsify.runtimes.node` is
|
|
14
|
-
* `"partial"`, which is not rewritten: the real GJS body runs through
|
|
15
|
-
* `@gjsify/node-gi`).
|
|
5
|
+
* `@gjsify/resolve-npm/runtime-aliases.mjs` routes `@gjsify/gamepad` here whenever
|
|
6
|
+
* `gjsify.runtimes.<target> === "native"`, which makes this the NON-GJS entry for the
|
|
7
|
+
* package root: every root export a consumer may import must be answerable from here or
|
|
8
|
+
* the routed bundle dies with `MISSING_EXPORT`. NOT used on Node, whose slot is
|
|
9
|
+
* `"partial"` and is not rewritten — the real GJS body runs through `@gjsify/node-gi`.
|
|
16
10
|
*/
|
|
17
11
|
|
|
18
12
|
export const Gamepad = globalThis.Gamepad;
|
|
@@ -21,20 +15,17 @@ export const GamepadEvent = globalThis.GamepadEvent;
|
|
|
21
15
|
export const GamepadHapticActuator = globalThis.GamepadHapticActuator;
|
|
22
16
|
|
|
23
17
|
/**
|
|
24
|
-
* Whether this host has a gamepad backend at all — the
|
|
25
|
-
*
|
|
26
|
-
*
|
|
18
|
+
* Whether this host has a gamepad backend at all — the GJS entry's question about
|
|
19
|
+
* `gi://Manette`, answered here about the runtime's own Gamepad API, which on these
|
|
20
|
+
* targets IS the implementation.
|
|
27
21
|
*
|
|
28
|
-
*
|
|
29
|
-
*
|
|
30
|
-
*
|
|
31
|
-
*
|
|
32
|
-
* usage at BUILD time on `--app browser` and `--app nativescript`; a thrower
|
|
33
|
-
* would break it at run time. `true` in a browser; `false` on NativeScript, which
|
|
34
|
-
* ships no Gamepad API — both are the honest answer for that host.
|
|
22
|
+
* REAL rather than stubbed or omitted (AGENTS.md § Slot routing: "Exports whose answer IS
|
|
23
|
+
* platform-independent stay REAL"): omitting it broke the README's recommended usage at
|
|
24
|
+
* BUILD time on `--app browser`/`--app nativescript`, and a thrower would break it at run
|
|
25
|
+
* time. `true` in a browser, `false` on NativeScript, which ships no Gamepad API.
|
|
35
26
|
*
|
|
36
|
-
* `async` to match the root entry's `Promise<boolean
|
|
37
|
-
*
|
|
27
|
+
* `async` to match the root entry's `Promise<boolean>`, where the answer needs a dynamic
|
|
28
|
+
* `import('gi://Manette')`.
|
|
38
29
|
*/
|
|
39
30
|
export async function hasGamepadBackend() {
|
|
40
31
|
return typeof globalThis.navigator?.getGamepads === 'function';
|
package/lib/types/backend.d.ts
CHANGED
|
@@ -3,9 +3,8 @@ import type Manette from '@girs/manette-0.2';
|
|
|
3
3
|
* What this host has.
|
|
4
4
|
*
|
|
5
5
|
* - `manette` — the Manette-0.2 typelib loaded and exposes `Monitor`.
|
|
6
|
-
* - `absent` — no backend reachable from here
|
|
7
|
-
*
|
|
8
|
-
* two targets where `gi://` is stubbed by design.
|
|
6
|
+
* - `absent` — no backend reachable from here: no libmanette, a `--app node` process
|
|
7
|
+
* without `@gjsify/node-gi`, or a target where `gi://` is stubbed by design.
|
|
9
8
|
* - `failed` — a backend should have been reachable and was not. A fault.
|
|
10
9
|
*/
|
|
11
10
|
export type GamepadBackendStatus = 'manette' | 'absent' | 'failed';
|
|
@@ -16,24 +15,20 @@ export interface GamepadBackend {
|
|
|
16
15
|
/** The original load error for `absent`/`failed`; `null` otherwise. */
|
|
17
16
|
error: unknown;
|
|
18
17
|
/**
|
|
19
|
-
* The one-time line the USE site emits
|
|
20
|
-
*
|
|
21
|
-
* query stays silent — see the module header.
|
|
18
|
+
* The one-time line the USE site emits, or `null` when there is nothing to say.
|
|
19
|
+
* Carried rather than printed so the capability query stays silent.
|
|
22
20
|
*
|
|
23
|
-
* `
|
|
24
|
-
*
|
|
25
|
-
*
|
|
21
|
+
* `'absent'` with a `null` diagnostic is the by-design `gi://` stub (see
|
|
22
|
+
* {@link isEmptiedGiModule}); `'failed'` always prints, with the original error, and
|
|
23
|
+
* needs no text here.
|
|
26
24
|
*/
|
|
27
25
|
diagnostic: string | null;
|
|
28
26
|
}
|
|
29
27
|
export interface LoadGamepadBackendOptions {
|
|
30
28
|
/**
|
|
31
|
-
* Override the `gi://Manette` import.
|
|
32
|
-
*
|
|
33
|
-
*
|
|
34
|
-
* absent and failed paths on a host where libmanette IS installed, which is
|
|
35
|
-
* every CI runner this package is tested on. Same role as
|
|
36
|
-
* `fillRandomBytes({ webcrypto })` in `@gjsify/webcrypto/random`.
|
|
29
|
+
* Override the `gi://Manette` import. Tests only — the single seam that exercises the
|
|
30
|
+
* absent and failed paths on a host where libmanette IS installed, which is every CI
|
|
31
|
+
* runner this package is tested on.
|
|
37
32
|
*/
|
|
38
33
|
importer?: () => Promise<{
|
|
39
34
|
default: typeof Manette;
|
|
@@ -45,62 +40,52 @@ interface GiLoadDiagnosis {
|
|
|
45
40
|
diagnostic: string | null;
|
|
46
41
|
}
|
|
47
42
|
/**
|
|
48
|
-
* Classify a `gi://` load failure and pick the text for it.
|
|
49
|
-
*
|
|
50
|
-
*
|
|
51
|
-
*
|
|
52
|
-
* hardcoded: the test asks for a namespace that cannot exist and classifies the
|
|
53
|
-
* error the running GJS/girepository actually produced for it.
|
|
43
|
+
* Classify a `gi://` load failure and pick the text for it. Exported (underscored) for
|
|
44
|
+
* `backend.spec.ts`, which pins the absent wording against the LIVE loader — hence the
|
|
45
|
+
* namespace parameter: the test asks for a namespace that cannot exist and classifies the
|
|
46
|
+
* error the running GJS/girepository produced for it.
|
|
54
47
|
*/
|
|
55
48
|
export declare function _diagnoseGiLoadError(error: unknown, namespace?: string): GiLoadDiagnosis;
|
|
56
49
|
/**
|
|
57
|
-
* Resolve (once) which gamepad backend this host has. Emits NOTHING
|
|
58
|
-
* module header on why the diagnostic belongs to the use site.
|
|
50
|
+
* Resolve (once) which gamepad backend this host has. Emits NOTHING.
|
|
59
51
|
*
|
|
60
|
-
*
|
|
61
|
-
*
|
|
62
|
-
* `
|
|
63
|
-
*
|
|
52
|
+
* Passing `importer` after the probe has run is a test-setup bug and THROWS rather than
|
|
53
|
+
* being silently ignored: a `cached ??= probe(options)` let a suite that forgot
|
|
54
|
+
* `_resetGamepadBackendCache()` assert against the PREVIOUS test's injected module and
|
|
55
|
+
* pass.
|
|
64
56
|
*/
|
|
65
57
|
export declare function loadGamepadBackend(options?: LoadGamepadBackendOptions): Promise<GamepadBackend>;
|
|
66
58
|
/**
|
|
67
59
|
* Emit this backend's one-time diagnostic — called by the USE site
|
|
68
60
|
* (`GamepadManager._init()`), never by the capability query.
|
|
69
61
|
*
|
|
70
|
-
* `absent` warns (a platform gap
|
|
71
|
-
*
|
|
72
|
-
*
|
|
73
|
-
*
|
|
74
|
-
*
|
|
75
|
-
*
|
|
76
|
-
* not be able to take down the host application.
|
|
62
|
+
* `absent` warns (a platform gap: expected, but never silent) and `failed` errors with
|
|
63
|
+
* the original attached — two levels for two situations. Deliberately NOT a rethrow:
|
|
64
|
+
* `GamepadManager` starts its init without awaiting it, so a rethrow becomes an unhandled
|
|
65
|
+
* rejection, unattributable on GJS and a process kill under Node's default
|
|
66
|
+
* `--unhandled-rejections=throw`. A half-installed typelib must not take down the host
|
|
67
|
+
* application.
|
|
77
68
|
*/
|
|
78
69
|
export declare function reportGamepadBackendOnce(backend: GamepadBackend): void;
|
|
79
70
|
/**
|
|
80
|
-
* The backend loaded and then the monitor did not come up
|
|
81
|
-
*
|
|
82
|
-
*
|
|
83
|
-
*
|
|
84
|
-
*
|
|
85
|
-
* shared library are both perfectly fine. Routing it through the load-failure
|
|
86
|
-
* text would re-create, one layer up, exactly the conflation this module removed.
|
|
71
|
+
* The backend loaded and then the monitor did not come up — a DIFFERENT failure from a
|
|
72
|
+
* failed load: everything after the probe (`new Manette.Monitor()`, the device walk,
|
|
73
|
+
* `connect()`) needs udev and `/dev/input`, which a sandbox can withhold from a process
|
|
74
|
+
* whose typelib and shared library are both fine. Routing it through the load-failure text
|
|
75
|
+
* would re-create the same conflation one layer up.
|
|
87
76
|
*/
|
|
88
77
|
export declare function reportGamepadMonitorFault(error: unknown): void;
|
|
89
78
|
/**
|
|
90
79
|
* Whether this host has a gamepad backend at all.
|
|
91
80
|
*
|
|
92
|
-
* `false` means `navigator.getGamepads()` can never report a controller here, no
|
|
93
|
-
*
|
|
94
|
-
*
|
|
95
|
-
* `GamepadManager.getGamepads()`). Answerable without constructing a monitor or
|
|
96
|
-
* plugging anything in, and QUIET: the diagnostic fires from the use, not from
|
|
97
|
-
* this question.
|
|
81
|
+
* `false` means `navigator.getGamepads()` can never report a controller here, no matter
|
|
82
|
+
* what is connected — something the W3C surface itself cannot express, since it returns
|
|
83
|
+
* the same list either way. Answerable without constructing a monitor, and QUIET.
|
|
98
84
|
*
|
|
99
|
-
*
|
|
100
|
-
*
|
|
101
|
-
*
|
|
102
|
-
*
|
|
103
|
-
* can still fail to start (see {@link reportGamepadMonitorFault}).
|
|
85
|
+
* `false` on every host without libmanette, which today means macOS and Windows:
|
|
86
|
+
* libmanette links libevdev unconditionally and libevdev is Linux/FreeBSD-only. Reports
|
|
87
|
+
* that the BRIDGE is usable, not that every later call succeeds — a monitor can still fail
|
|
88
|
+
* to start (see {@link reportGamepadMonitorFault}).
|
|
104
89
|
*/
|
|
105
90
|
export declare function hasGamepadBackend(): Promise<boolean>;
|
|
106
91
|
/** Reset the cached probe and its one-time diagnostic — tests only. */
|
|
@@ -1,7 +1,4 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Linux BTN_* input event codes as reported by Manette.Event.get_button().
|
|
3
|
-
* These are the actual values libmanette 0.2 passes in button-press/release signals.
|
|
4
|
-
*/
|
|
1
|
+
/** Linux BTN_* input event codes as reported by `Manette.Event.get_button()`. */
|
|
5
2
|
export declare const LinuxButton: {
|
|
6
3
|
readonly BTN_SOUTH: 304;
|
|
7
4
|
readonly BTN_EAST: 305;
|
|
@@ -23,10 +20,7 @@ export declare const LinuxButton: {
|
|
|
23
20
|
readonly BTN_DPAD_LEFT: 546;
|
|
24
21
|
readonly BTN_DPAD_RIGHT: 547;
|
|
25
22
|
};
|
|
26
|
-
/**
|
|
27
|
-
* W3C standard gamepad button indices.
|
|
28
|
-
* https://w3c.github.io/gamepad/#remapping
|
|
29
|
-
*/
|
|
23
|
+
/** W3C standard gamepad button indices — https://w3c.github.io/gamepad/#remapping */
|
|
30
24
|
export declare const W3CButton: {
|
|
31
25
|
readonly FACE_1: 0;
|
|
32
26
|
readonly FACE_2: 1;
|
|
@@ -48,8 +42,6 @@ export declare const W3CButton: {
|
|
|
48
42
|
};
|
|
49
43
|
/** Total number of buttons in the W3C standard mapping. */
|
|
50
44
|
export declare const W3C_BUTTON_COUNT = 17;
|
|
51
|
-
/**
|
|
52
|
-
* Maps Linux BTN_* code → W3C standard button index.
|
|
53
|
-
*/
|
|
45
|
+
/** Linux BTN_* code → W3C standard button index. */
|
|
54
46
|
export declare const MANETTE_TO_W3C_BUTTON: ReadonlyMap<number, number>;
|
|
55
47
|
export { LinuxButton as ManetteButton };
|
|
@@ -1,10 +1,8 @@
|
|
|
1
1
|
import { Gamepad } from './gamepad.js';
|
|
2
2
|
/**
|
|
3
|
-
* Singleton manager
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
* caches the latest state so that `getGamepads()` can return a snapshot
|
|
7
|
-
* matching the W3C Gamepad API's polling model.
|
|
3
|
+
* Singleton manager wrapping `Manette.Monitor`. libmanette fires GObject signals on
|
|
4
|
+
* button/axis changes, so this caches the latest state and `getGamepads()` returns a
|
|
5
|
+
* snapshot, matching the W3C polling model.
|
|
8
6
|
*/
|
|
9
7
|
export declare class GamepadManager {
|
|
10
8
|
private _monitor;
|
|
@@ -18,10 +16,7 @@ export declare class GamepadManager {
|
|
|
18
16
|
private _ManetteModule;
|
|
19
17
|
private _initPromise;
|
|
20
18
|
private _initialized;
|
|
21
|
-
/**
|
|
22
|
-
* Lazily initialize the Manette.Monitor.
|
|
23
|
-
* Called on first `getGamepads()` invocation.
|
|
24
|
-
*/
|
|
19
|
+
/** Lazily initialize the `Manette.Monitor`, on the first `getGamepads()`. */
|
|
25
20
|
private _ensureInit;
|
|
26
21
|
private _init;
|
|
27
22
|
private _onDeviceConnected;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gjsify/gamepad",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.38.0",
|
|
4
4
|
"description": "Gamepad Web API for GJS using libmanette as backend",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"module": "lib/esm/index.js",
|
|
@@ -43,14 +43,14 @@
|
|
|
43
43
|
"controller"
|
|
44
44
|
],
|
|
45
45
|
"dependencies": {
|
|
46
|
-
"@gjsify/dom-events": "^0.
|
|
46
|
+
"@gjsify/dom-events": "^0.38.0"
|
|
47
47
|
},
|
|
48
48
|
"devDependencies": {
|
|
49
49
|
"@girs/gjs": "^4.1.0",
|
|
50
50
|
"@girs/glib-2.0": "^4.1.0",
|
|
51
51
|
"@girs/manette-0.2": "^4.1.0",
|
|
52
|
-
"@gjsify/cli": "^0.
|
|
53
|
-
"@gjsify/unit": "^0.
|
|
52
|
+
"@gjsify/cli": "^0.38.0",
|
|
53
|
+
"@gjsify/unit": "^0.38.0",
|
|
54
54
|
"@types/node": "^25.9.2",
|
|
55
55
|
"typescript": "^6.0.3"
|
|
56
56
|
},
|