virtual-keypad 5.13.0 → 5.13.2

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/src/keypadPeer.js CHANGED
@@ -1,189 +1,191 @@
1
- // require("peerjs");
2
- // import { QRCode } from "qrcode";
3
- import { Peer } from "peerjs";
4
-
5
- export let keypadUrl;
6
- if (process.env.NODE_ENV !== "production") {
7
- keypadUrl = "http://localhost:8080/keypad.html?";
8
- } else {
9
- keypadUrl = "https://keypad.website/keypad?";
10
- }
11
- // -- Parameters --
12
-
13
- export class KeypadPeer {
14
- constructor(
15
- parameters = {
16
- keypadUrl: keypadUrl,
17
- targetElementId: null,
18
- }
19
- ) {
20
- this.conn = null;
21
- this.lastPeerId = null;
22
- this.keypadUrl = parameters.hasOwnProperty("keypadUrl")
23
- ? parameters.keypadUrl
24
- : keypadUrl;
25
- this.targetElement = parameters.hasOwnProperty("targetElementId")
26
- ? parameters.targetElementId
27
- : null;
28
- // TODO add support for ttd (ms)
29
- this.ttd = parameters.hasOwnProperty("ttd")
30
- ? parameters.hasOwnProperty("ttd")
31
- : 8000;
32
- // TODO add support for heartRate (ms)
33
- this.heartbeatIntervalMs = parameters.hasOwnProperty("heartRate")
34
- ? parameters.hasOwnProperty("heartRate")
35
- : 2000;
36
- this.lastHeartbeat = performance.now();
37
- this.heartBeatInterval = undefined;
38
- this.heartCheckInterval = undefined;
39
-
40
- /* Create the Peer object for our end of the connection. */
41
- this.peer = new Peer(null, {
42
- pingInterval: this.heartbeatIntervalMs,
43
- debug: 2,
44
- config: {
45
- iceServers: [
46
- {
47
- urls: "stun:stun.relay.metered.ca:80",
48
- },
49
- {
50
- urls: "turn:global.relay.metered.ca:80",
51
- username: "de884cfc34189cdf1a5dd616",
52
- credential: "IcOpouU9/TYBmpHU",
53
- },
54
- {
55
- urls: "turn:global.relay.metered.ca:80?transport=tcp",
56
- username: "de884cfc34189cdf1a5dd616",
57
- credential: "IcOpouU9/TYBmpHU",
58
- },
59
- {
60
- urls: "turn:global.relay.metered.ca:443",
61
- username: "de884cfc34189cdf1a5dd616",
62
- credential: "IcOpouU9/TYBmpHU",
63
- },
64
- {
65
- urls: "turns:global.relay.metered.ca:443?transport=tcp",
66
- username: "de884cfc34189cdf1a5dd616",
67
- credential: "IcOpouU9/TYBmpHU",
68
- },
69
- ],
70
- },
71
- });
72
-
73
- this.alphabet = null;
74
- this.font = null;
75
- this.keypressFeedbackSound =
76
- "data:audio/mpeg;base64,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VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV//uSZIIP9BFGHYksMlIAAA0gAAABAAABpAAAACAAADSAAAAEVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVQ==";
77
- }
78
-
79
- displayUpdate = (message, append = false) => {
80
- // If the specified elem exists, update that elem
81
- if (!!document.getElementById(this.targetElement)) {
82
- const displayElement = document.getElementById(this.targetElement);
83
- if (append) {
84
- const oldInnerText = displayElement.innerText;
85
- displayElement.innerText = message + "\n" + oldInnerText;
86
- } else {
87
- displayElement.innerText = message;
88
- }
89
- } else {
90
- console.log("MESSAGE: ", message);
91
- }
92
- };
93
- onPeerDisconnected = () => {
94
- this.displayUpdate("Connection lost. Please reconnect");
95
- // Workaround for peer.reconnect deleting previous id
96
- this.peer.id = this.lastPeerId;
97
- this.peer._lastServerId = this.lastPeerId;
98
- this.peer.reconnect();
99
- };
100
- onPeerClose = () => {
101
- this.displayUpdate("Connection closed");
102
- this.conn = null;
103
- };
104
- onPeerError = (err) => {
105
- this.displayUpdate(err);
106
- alert("" + err);
107
- };
108
- parseParams = (params) => {
109
- const font = params.get("font");
110
- const alphabet = this.checkAlphabet(
111
- decodeURIComponent(params.get("alphabet")).split(",")
112
- );
113
- const peerId = params.get("peerID");
114
- return { alphabet: alphabet, font: font, peerId: peerId };
115
- };
116
- queryStringFromObject = (params) => {
117
- return Object.keys(params)
118
- .map((key) => key + "=" + encodeURIComponent(params[key]))
119
- .join("&");
120
- };
121
- checkAlphabet = (proposedAlphabet) => {
122
- let validAlphabet;
123
- if (Array.isArray(proposedAlphabet)) {
124
- // ARRAY : good
125
- // FUTURE verify that symbols are displayable in desired font
126
- validAlphabet = proposedAlphabet;
127
- } else if (typeof proposedAlphabet == "string") {
128
- // STRING : ok
129
- if (
130
- proposedAlphabet.toUpperCase() === "SPACE" ||
131
- proposedAlphabet.toUpperCase() == "RETURN"
132
- ) {
133
- validAlphabet = [proposedAlphabet];
134
- } else {
135
- validAlphabet = proposedAlphabet.split("");
136
- }
137
- } else {
138
- // SOMETHING ELSE : bad
139
- console.error(
140
- "Error! Alphabet must be specified as an array of symbols, including 'RETURN', 'SPACE'"
141
- );
142
- validAlphabet = [];
143
- }
144
- // Return unique elements, see: https://stackoverflow.com/questions/11246758/how-to-get-unique-values-in-an-array
145
- const uniqueValidAlphabet = [...new Set(validAlphabet)];
146
-
147
- // Order alphabet so that if 'SPACE' and 'RETURN' are in the list, they are correctly positioned
148
- if ("SPACE" in uniqueValidAlphabet) {
149
- uniqueValidAlphabet = moveElementToEndOfArray(
150
- uniqueValidAlphabet,
151
- "SPACE"
152
- );
153
- }
154
- if ("RETURN" in uniqueValidAlphabet) {
155
- uniqueValidAlphabet = moveElementToEndOfArray(
156
- uniqueValidAlphabet,
157
- "RETURN"
158
- );
159
- }
160
- return uniqueValidAlphabet;
161
- };
162
- _setupHeartBeatIntervals = () => {
163
- this.heartBeatInterval = setInterval(
164
- () => this.conn?.send({ message: "Heartbeat" }),
165
- this.heartbeatIntervalMs
166
- );
167
-
168
- this.heartCheckInterval = setInterval(() => {
169
- const timeSinceHeartbeatMs = performance.now() - this.lastHeartbeat;
170
- if (timeSinceHeartbeatMs > this.ttd) {
171
- console.log("Closing connection due to lack of heartbeat.");
172
- this.conn?.close();
173
- this.conn = undefined;
174
- clearInterval(this.heartBeatInterval);
175
- clearInterval(this.heartCheckInterval);
176
- this.heartBeatInterval = undefined;
177
- this.heartCheckInterval = undefined;
178
- }
179
- }, this.ttd);
180
- };
181
- }
182
-
183
- const moveElementToEndOfArray = (array, element) => {
184
- return [
185
- ...array.slice(0, array.indexOf(element)),
186
- ...array.slice(array.indexOf(element) + 1),
187
- element,
188
- ];
189
- };
1
+ // require("peerjs");
2
+ // import { QRCode } from "qrcode";
3
+ import { Peer } from "peerjs";
4
+
5
+ export let keypadUrl;
6
+ if (process.env.NODE_ENV !== "production") {
7
+ keypadUrl = "http://localhost:8080/keypad.html?";
8
+ } else {
9
+ keypadUrl = "https://keypad.website/keypad?";
10
+ }
11
+ // -- Parameters --
12
+
13
+ export class KeypadPeer {
14
+ constructor(
15
+ parameters = {
16
+ keypadUrl: keypadUrl,
17
+ targetElementId: null,
18
+ onErrorReconnectMessage: "Connection lost. Please reconnect...",
19
+ }
20
+ ) {
21
+ this.onErrorReconnectMessage = parameters.onErrorReconnectMessage;
22
+ this.conn = null;
23
+ this.lastPeerId = null;
24
+ this.keypadUrl = parameters.hasOwnProperty("keypadUrl")
25
+ ? parameters.keypadUrl
26
+ : keypadUrl;
27
+ this.targetElement = parameters.hasOwnProperty("targetElementId")
28
+ ? parameters.targetElementId
29
+ : null;
30
+ // TODO add support for ttd (ms)
31
+ this.ttd = parameters.hasOwnProperty("ttd")
32
+ ? parameters.hasOwnProperty("ttd")
33
+ : 8000;
34
+ // TODO add support for heartRate (ms)
35
+ this.heartbeatIntervalMs = parameters.hasOwnProperty("heartRate")
36
+ ? parameters.hasOwnProperty("heartRate")
37
+ : 2000;
38
+ this.lastHeartbeat = performance.now();
39
+ this.heartBeatInterval = undefined;
40
+ this.heartCheckInterval = undefined;
41
+
42
+ /* Create the Peer object for our end of the connection. */
43
+ this.peer = new Peer(null, {
44
+ pingInterval: this.heartbeatIntervalMs,
45
+ debug: 2,
46
+ config: {
47
+ iceServers: [
48
+ {
49
+ urls: "stun:stun.relay.metered.ca:80",
50
+ },
51
+ {
52
+ urls: "turn:global.relay.metered.ca:80",
53
+ username: "de884cfc34189cdf1a5dd616",
54
+ credential: "IcOpouU9/TYBmpHU",
55
+ },
56
+ {
57
+ urls: "turn:global.relay.metered.ca:80?transport=tcp",
58
+ username: "de884cfc34189cdf1a5dd616",
59
+ credential: "IcOpouU9/TYBmpHU",
60
+ },
61
+ {
62
+ urls: "turn:global.relay.metered.ca:443",
63
+ username: "de884cfc34189cdf1a5dd616",
64
+ credential: "IcOpouU9/TYBmpHU",
65
+ },
66
+ {
67
+ urls: "turns:global.relay.metered.ca:443?transport=tcp",
68
+ username: "de884cfc34189cdf1a5dd616",
69
+ credential: "IcOpouU9/TYBmpHU",
70
+ },
71
+ ],
72
+ },
73
+ });
74
+
75
+ this.alphabet = null;
76
+ this.font = null;
77
+ this.keypressFeedbackSound =
78
+ "data:audio/mpeg;base64,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VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV//uSZIIP9BFGHYksMlIAAA0gAAABAAABpAAAACAAADSAAAAEVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVQ==";
79
+ }
80
+
81
+ displayUpdate = (message, append = false) => {
82
+ // If the specified elem exists, update that elem
83
+ if (!!document.getElementById(this.targetElement)) {
84
+ const displayElement = document.getElementById(this.targetElement);
85
+ if (append) {
86
+ const oldInnerText = displayElement.innerText;
87
+ displayElement.innerText = message + "\n" + oldInnerText;
88
+ } else {
89
+ displayElement.innerText = message;
90
+ }
91
+ } else {
92
+ console.log("MESSAGE: ", message);
93
+ }
94
+ };
95
+ onPeerDisconnected = () => {
96
+ this.displayUpdate(this.onErrorReconnectMessage);
97
+ // Workaround for peer.reconnect deleting previous id
98
+ this.peer.id = this.lastPeerId;
99
+ this.peer._lastServerId = this.lastPeerId;
100
+ this.peer.reconnect();
101
+ };
102
+ onPeerClose = () => {
103
+ this.displayUpdate("Connection closed");
104
+ this.conn = null;
105
+ };
106
+ onPeerError = (err) => {
107
+ this.displayUpdate(err);
108
+ alert("" + err);
109
+ };
110
+ parseParams = (params) => {
111
+ const font = params.get("font");
112
+ const alphabet = this.checkAlphabet(
113
+ decodeURIComponent(params.get("alphabet")).split(",")
114
+ );
115
+ const peerId = params.get("peerID");
116
+ return { alphabet: alphabet, font: font, peerId: peerId };
117
+ };
118
+ queryStringFromObject = (params) => {
119
+ return Object.keys(params)
120
+ .map((key) => key + "=" + encodeURIComponent(params[key]))
121
+ .join("&");
122
+ };
123
+ checkAlphabet = (proposedAlphabet) => {
124
+ let validAlphabet;
125
+ if (Array.isArray(proposedAlphabet)) {
126
+ // ARRAY : good
127
+ // FUTURE verify that symbols are displayable in desired font
128
+ validAlphabet = proposedAlphabet;
129
+ } else if (typeof proposedAlphabet == "string") {
130
+ // STRING : ok
131
+ if (
132
+ proposedAlphabet.toUpperCase() === "SPACE" ||
133
+ proposedAlphabet.toUpperCase() == "RETURN"
134
+ ) {
135
+ validAlphabet = [proposedAlphabet];
136
+ } else {
137
+ validAlphabet = proposedAlphabet.split("");
138
+ }
139
+ } else {
140
+ // SOMETHING ELSE : bad
141
+ console.error(
142
+ "Error! Alphabet must be specified as an array of symbols, including 'RETURN', 'SPACE'"
143
+ );
144
+ validAlphabet = [];
145
+ }
146
+ // Return unique elements, see: https://stackoverflow.com/questions/11246758/how-to-get-unique-values-in-an-array
147
+ const uniqueValidAlphabet = [...new Set(validAlphabet)];
148
+
149
+ // Order alphabet so that if 'SPACE' and 'RETURN' are in the list, they are correctly positioned
150
+ if ("SPACE" in uniqueValidAlphabet) {
151
+ uniqueValidAlphabet = moveElementToEndOfArray(
152
+ uniqueValidAlphabet,
153
+ "SPACE"
154
+ );
155
+ }
156
+ if ("RETURN" in uniqueValidAlphabet) {
157
+ uniqueValidAlphabet = moveElementToEndOfArray(
158
+ uniqueValidAlphabet,
159
+ "RETURN"
160
+ );
161
+ }
162
+ return uniqueValidAlphabet;
163
+ };
164
+ _setupHeartBeatIntervals = () => {
165
+ this.heartBeatInterval = setInterval(
166
+ () => this.conn?.send({ message: "Heartbeat" }),
167
+ this.heartbeatIntervalMs
168
+ );
169
+
170
+ this.heartCheckInterval = setInterval(() => {
171
+ const timeSinceHeartbeatMs = performance.now() - this.lastHeartbeat;
172
+ if (timeSinceHeartbeatMs > this.ttd) {
173
+ console.log("Closing connection due to lack of heartbeat.");
174
+ this.conn?.close();
175
+ this.conn = undefined;
176
+ clearInterval(this.heartBeatInterval);
177
+ clearInterval(this.heartCheckInterval);
178
+ this.heartBeatInterval = undefined;
179
+ this.heartCheckInterval = undefined;
180
+ }
181
+ }, this.ttd);
182
+ };
183
+ }
184
+
185
+ const moveElementToEndOfArray = (array, element) => {
186
+ return [
187
+ ...array.slice(0, array.indexOf(element)),
188
+ ...array.slice(array.indexOf(element) + 1),
189
+ element,
190
+ ];
191
+ };
package/src/main.js CHANGED
@@ -1,5 +1,5 @@
1
- // import './keypadPeer.js';
2
- import { Keypad } from './keypad.js';
3
- import { Receiver } from './receiver.js';
4
-
1
+ // import './keypadPeer.js';
2
+ import { Keypad } from './keypad.js';
3
+ import { Receiver } from './receiver.js';
4
+
5
5
  export { Receiver, Keypad };