dualsense-ts 5.0.3 → 5.0.27

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 CHANGED
@@ -8,19 +8,17 @@ This module provides a natural interface for your DualSense controller.
8
8
 
9
9
  [This package is distributed via npm](https://npmjs.org/package.dualsense-ts). Install it the usual way:
10
10
 
11
- - `yarn add dualsense-ts`
12
11
  - `npm add dualsense-ts`
13
12
 
14
- In the browser, `dualsense-ts` has zero dependencies and relies on the native WebHID interface.
13
+ In the browser, `dualsense-ts` has zero dependencies and relies on the [WebHID API](https://developer.mozilla.org/en-US/docs/Web/API/WebHID_API). At this time, only Chrome, Edge, and Opera are compatible.
15
14
 
16
- In Node.js, `dualsense-ts` relies on `node-hid`, so you'll need to add that as well:
15
+ In node.js, `dualsense-ts` relies on `node-hid` as a peer dependency, so you'll need to add it as well:
17
16
 
18
- - `yarn add node-hid`
19
17
  - `npm add node-hid`
20
18
 
21
19
  ### Connecting
22
20
 
23
- When you construct a `new Dualsense()`, the connection to your controller will be managed in the background.
21
+ When you construct a `new Dualsense()`, it will begin searching for a controller. If it finds one, it will connect automatically.
24
22
 
25
23
  ```typescript
26
24
  import { Dualsense } from "dualsense-ts";
@@ -29,7 +27,7 @@ import { Dualsense } from "dualsense-ts";
29
27
  const controller = new Dualsense();
30
28
  ```
31
29
 
32
- If your device becomes disconnected, `dualsense-ts` will quietly wait for it to come back. You can monitor the connection state using the same APIs as any other input:
30
+ If the device becomes disconnected, `dualsense-ts` will quietly wait for it to come back. You can monitor the connection status with `controller.connection` using any of the Input APIs listed in the next section.
33
31
 
34
32
  ```typescript
35
33
  const connected = controller.connection.active
@@ -112,40 +110,73 @@ for await (const { pressure } of controller.left.trigger) {
112
110
  }
113
111
  ```
114
112
 
115
- ### React
113
+ ### With React
116
114
 
117
- Set up a context for your controller:
115
+ Creating a controller interface with `new Dualsense()` is much too expensive to be done at render time. You can create a [Context](https://reactjs.org/docs/context.html) to share the controller state with your components:
118
116
 
119
117
  ```typescript
120
- // Controller.tsx
121
- import React from "react";
118
+ // DualsenseContext.tsx
119
+ import { createContext } from "react";
122
120
  import { Dualsense } from "dualsense-ts";
123
121
 
124
- export const ControllerContext = React.createContext<Dualsense>(
125
- new Dualsense()
126
- );
122
+ const controller = new Dualsense();
123
+ export const DualsenseContext = createContext(controller);
124
+ DualsenseContext.displayName = "DualsenseContext";
127
125
  ```
128
126
 
129
- Use the context to set up your component:
127
+ The user will need to grant permission before we can access new devices using the WebHID API. The `Dualsense` class provides a callback that can be used as a handler for `onClick` or [other user-triggered events](https://developer.mozilla.org/en-US/docs/Web/Security/User_activation):
130
128
 
131
129
  ```typescript
132
- // MyButton.tsx
133
- import React from "react";
134
- import { ControllerContext } from "./Controller.tsx";
135
-
136
- // A button that's only active while the user is holding triangle on the controller
137
- export const MyButton = () => {
138
- const { state: controller } = React.useContext(ControllerContext);
139
- const [triangle, setTriangle] = React.useState(controller.triangle);
140
- React.useCallback(
141
- () => triangle.on("change", (new) => setTriangle(new)),
142
- [triangle]
130
+ // PermissionComponent.tsx
131
+ import { useContext } from "react";
132
+ import { DualsenseContext } from "./DualsenseContext";
133
+
134
+ export const RequestController = () => {
135
+ const controller = useContext(DualsenseContext);
136
+ return (
137
+ <button
138
+ text="Grant Permission"
139
+ onClick={controller.hid.provider.getRequest()}
140
+ />
143
141
  );
142
+ };
143
+ ```
144
144
 
145
- return <button active={triangle.active}>
146
- }
145
+ Now components with access to this context can enjoy the shared `dualsense-ts` interface:
146
+
147
+ ```typescript
148
+ // ConnectionComponent.tsx
149
+ import { useContext, useEffect, useState } from "react";
150
+ import { DualsenseContext } from "./DualsenseContext";
151
+
152
+ export const ControllerConnection = () => {
153
+ const controller = useContext(DualsenseContext);
154
+ const [connected, setConnected] = useState(controller.connection.state);
155
+ const [triangle, setTriangle] = useState(controller.triangle.state);
156
+
157
+ useEffect(() => {
158
+ controller.connection.on("change", ({ state }) => setConnected(state));
159
+ controller.triangle.on("change", ({ state }) => setTriangle(state));
160
+ }, []);
161
+
162
+ return (
163
+ <p dir={triangle ? "ltr" : "rtl"}>{`Controller ${
164
+ state ? "" : "dis"
165
+ }connected`}</p>
166
+ );
167
+ };
147
168
  ```
148
169
 
170
+ ### It's not working
171
+
172
+ `controller.hid` manages the connection to the device and provides useful error events:
173
+
174
+ ```typescript
175
+ controller.hid.on("error", console.error);
176
+ ```
177
+
178
+ Please open an issue Github if you're having trouble.
179
+
149
180
  ## Migration Guide
150
181
 
151
182
  `dualsense-ts` uses semantic versioning. For more info on breaking changes, [check out the migration guide](MIGRATION_GUIDE.md).
@@ -1,10 +1,16 @@
1
+ /// <reference types="w3c-web-hid" />
1
2
  import { HIDProvider, DualsenseHIDState } from "./hid_provider";
2
3
  export declare class WebHIDProvider extends HIDProvider {
3
4
  private device?;
4
5
  wireless: boolean;
5
- connecting: boolean;
6
- connection: boolean;
7
6
  constructor();
7
+ attach(device: HIDDevice): void;
8
+ /**
9
+ * You need to get permission to user HID devices from an interactive
10
+ * component, like a button. This returns a callback for triggering
11
+ * the permissions request.
12
+ */
13
+ getRequest(): () => Promise<unknown>;
8
14
  connect(): void;
9
15
  get connected(): boolean;
10
16
  disconnect(): void;
@@ -1 +1 @@
1
- {"version":3,"file":"web_hid_provider.d.ts","sourceRoot":"","sources":["../../src/hid/web_hid_provider.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,WAAW,EACX,iBAAiB,EAIlB,MAAM,gBAAgB,CAAC;AAExB,qBAAa,cAAe,SAAQ,WAAW;IAC7C,OAAO,CAAC,MAAM,CAAC,CAAY;IACpB,QAAQ,EAAE,OAAO,CAAQ;IACzB,UAAU,EAAE,OAAO,CAAS;IAC5B,UAAU,EAAE,OAAO,CAAS;;IAUnC,OAAO,IAAI,IAAI;IAsCf,IAAI,SAAS,IAAI,OAAO,CAEvB;IAED,UAAU,IAAI,IAAI;IAUlB,OAAO,CAAC,MAAM,EAAE,QAAQ,GAAG,iBAAiB;CA2D7C"}
1
+ {"version":3,"file":"web_hid_provider.d.ts","sourceRoot":"","sources":["../../src/hid/web_hid_provider.ts"],"names":[],"mappings":";AAAA,OAAO,EACL,WAAW,EACX,iBAAiB,EAIlB,MAAM,gBAAgB,CAAC;AAExB,qBAAa,cAAe,SAAQ,WAAW;IAC7C,OAAO,CAAC,MAAM,CAAC,CAAY;IACpB,QAAQ,EAAE,OAAO,CAAQ;;IAchC,MAAM,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI;IAc/B;;;;OAIG;IACH,UAAU,IAAI,MAAM,OAAO,CAAC,OAAO,CAAC;IAsBpC,OAAO,IAAI,IAAI;IAIf,IAAI,SAAS,IAAI,OAAO,CAEvB;IAED,UAAU,IAAI,IAAI;IASlB,OAAO,CAAC,MAAM,EAAE,QAAQ,GAAG,iBAAiB;CA2D7C"}
@@ -6,54 +6,60 @@ class WebHIDProvider extends hid_provider_1.HIDProvider {
6
6
  constructor() {
7
7
  super();
8
8
  this.wireless = true; // TODO: Not sure what to check
9
- this.connecting = false;
10
- this.connection = false;
11
9
  if (!navigator.hid)
12
- throw new Error("");
10
+ throw new Error("WebHID not supported by this browser");
13
11
  navigator.hid.addEventListener("disconnect", ({ device }) => {
14
12
  if (device === this.device)
15
- this.connection = false;
13
+ this.device = undefined;
14
+ });
15
+ navigator.hid.addEventListener("connect", ({ device }) => {
16
+ if (!this.device)
17
+ this.attach(device);
16
18
  });
17
19
  }
18
- connect() {
19
- if (this.connected)
20
- return;
21
- if (this.connecting)
22
- return;
23
- this.connecting = true;
24
- navigator.hid
20
+ attach(device) {
21
+ device
22
+ .open()
23
+ .then(() => {
24
+ this.device = device;
25
+ this.device.addEventListener("inputreport", ({ data }) => {
26
+ this.onData(this.process(data));
27
+ });
28
+ })
29
+ .catch((err) => {
30
+ this.onError(err);
31
+ });
32
+ }
33
+ /**
34
+ * You need to get permission to user HID devices from an interactive
35
+ * component, like a button. This returns a callback for triggering
36
+ * the permissions request.
37
+ */
38
+ getRequest() {
39
+ return () => navigator.hid
25
40
  .requestDevice({
26
41
  filters: [
27
- { vendorId: hid_provider_1.HIDProvider.vendorId, productId: hid_provider_1.HIDProvider.productId },
42
+ {
43
+ vendorId: hid_provider_1.HIDProvider.vendorId,
44
+ productId: hid_provider_1.HIDProvider.productId,
45
+ },
28
46
  ],
29
47
  })
30
48
  .then((devices) => {
31
49
  if (devices.length === 0) {
32
50
  return this.onError(new Error(`No controllers available`));
33
51
  }
34
- devices[0]
35
- .open()
36
- .then(() => {
37
- this.disconnect();
38
- this.device = devices[0];
39
- this.connection = true;
40
- this.device.addEventListener("inputreport", ({ data }) => {
41
- this.onData(this.process(data));
42
- });
43
- })
44
- .catch((err) => {
45
- this.onError(err);
46
- });
52
+ this.attach(devices[0]);
47
53
  })
48
54
  .catch((err) => {
49
55
  this.onError(err);
50
- })
51
- .finally(() => {
52
- this.connecting = false;
53
56
  });
54
57
  }
58
+ connect() {
59
+ // Nothing to be done.
60
+ }
55
61
  get connected() {
56
- return this.device !== undefined && this.connection;
62
+ return this.device !== undefined;
57
63
  }
58
64
  disconnect() {
59
65
  if (this.device) {
@@ -62,7 +68,6 @@ class WebHIDProvider extends hid_provider_1.HIDProvider {
62
68
  this.wireless = false;
63
69
  });
64
70
  }
65
- this.connecting = false;
66
71
  }
67
72
  process(buffer) {
68
73
  // Bluetooth buffer starts with an extra byte
@@ -1 +1 @@
1
- {"version":3,"file":"web_hid_provider.js","sourceRoot":"","sources":["../../src/hid/web_hid_provider.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"web_hid_provider.js","sourceRoot":"","sources":["../../src/hid/web_hid_provider.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dualsense-ts",
3
- "version": "5.0.3",
3
+ "version": "5.0.27",
4
4
  "description": "A natural interface for your DualSense controller, with Typescript",
5
5
  "keywords": [
6
6
  "dualsense",
@@ -9,57 +9,66 @@ import {
9
9
  export class WebHIDProvider extends HIDProvider {
10
10
  private device?: HIDDevice;
11
11
  public wireless: boolean = true; // TODO: Not sure what to check
12
- public connecting: boolean = false;
13
- public connection: boolean = false;
14
12
 
15
13
  constructor() {
16
14
  super();
17
- if (!navigator.hid) throw new Error("");
15
+ if (!navigator.hid) throw new Error("WebHID not supported by this browser");
16
+
18
17
  navigator.hid.addEventListener("disconnect", ({ device }) => {
19
- if (device === this.device) this.connection = false;
18
+ if (device === this.device) this.device = undefined;
19
+ });
20
+ navigator.hid.addEventListener("connect", ({ device }) => {
21
+ if (!this.device) this.attach(device);
20
22
  });
21
23
  }
22
24
 
23
- connect(): void {
24
- if (this.connected) return;
25
-
26
- if (this.connecting) return;
27
- this.connecting = true;
28
- navigator.hid
29
- .requestDevice({
30
- filters: [
31
- { vendorId: HIDProvider.vendorId, productId: HIDProvider.productId },
32
- ],
33
- })
34
- .then((devices: HIDDevice[]) => {
35
- if (devices.length === 0) {
36
- return this.onError(new Error(`No controllers available`));
37
- }
38
-
39
- devices[0]
40
- .open()
41
- .then(() => {
42
- this.disconnect();
43
- this.device = devices[0];
44
- this.connection = true;
45
- this.device.addEventListener("inputreport", ({ data }) => {
46
- this.onData(this.process(data));
47
- });
48
- })
49
- .catch((err: Error) => {
50
- this.onError(err);
51
- });
25
+ attach(device: HIDDevice): void {
26
+ device
27
+ .open()
28
+ .then(() => {
29
+ this.device = device;
30
+ this.device.addEventListener("inputreport", ({ data }) => {
31
+ this.onData(this.process(data));
32
+ });
52
33
  })
53
34
  .catch((err: Error) => {
54
35
  this.onError(err);
55
- })
56
- .finally(() => {
57
- this.connecting = false;
58
36
  });
59
37
  }
60
38
 
39
+ /**
40
+ * You need to get permission to user HID devices from an interactive
41
+ * component, like a button. This returns a callback for triggering
42
+ * the permissions request.
43
+ */
44
+ getRequest(): () => Promise<unknown> {
45
+ return () =>
46
+ navigator.hid
47
+ .requestDevice({
48
+ filters: [
49
+ {
50
+ vendorId: HIDProvider.vendorId,
51
+ productId: HIDProvider.productId,
52
+ },
53
+ ],
54
+ })
55
+ .then((devices: HIDDevice[]) => {
56
+ if (devices.length === 0) {
57
+ return this.onError(new Error(`No controllers available`));
58
+ }
59
+ this.attach(devices[0]);
60
+ })
61
+ .catch((err: Error) => {
62
+ this.onError(err);
63
+ });
64
+ }
65
+
66
+ connect(): void {
67
+ // Nothing to be done.
68
+ }
69
+
61
70
  get connected(): boolean {
62
- return this.device !== undefined && this.connection;
71
+ return this.device !== undefined;
63
72
  }
64
73
 
65
74
  disconnect(): void {
@@ -69,7 +78,6 @@ export class WebHIDProvider extends HIDProvider {
69
78
  this.wireless = false;
70
79
  });
71
80
  }
72
- this.connecting = false;
73
81
  }
74
82
 
75
83
  process(buffer: DataView): DualsenseHIDState {