@neurosity/sdk 6.0.0-next.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.
Files changed (312) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +46 -0
  3. package/dist/browser/neurosity.iife.js +48736 -0
  4. package/dist/browser/neurosity.js +672 -0
  5. package/dist/browser/neurosity.js.map +1 -0
  6. package/dist/cjs/Notion.d.ts +619 -0
  7. package/dist/cjs/Notion.js +1291 -0
  8. package/dist/cjs/api/bluetooth/BluetoothClient.d.ts +59 -0
  9. package/dist/cjs/api/bluetooth/BluetoothClient.js +287 -0
  10. package/dist/cjs/api/bluetooth/BluetoothTransport.d.ts +32 -0
  11. package/dist/cjs/api/bluetooth/BluetoothTransport.js +2 -0
  12. package/dist/cjs/api/bluetooth/constants.d.ts +4 -0
  13. package/dist/cjs/api/bluetooth/constants.js +9 -0
  14. package/dist/cjs/api/bluetooth/index.d.ts +4 -0
  15. package/dist/cjs/api/bluetooth/index.js +20 -0
  16. package/dist/cjs/api/bluetooth/react-native/ReactNativeTransport.d.ts +65 -0
  17. package/dist/cjs/api/bluetooth/react-native/ReactNativeTransport.js +386 -0
  18. package/dist/cjs/api/bluetooth/react-native/types/BleManagerTypes.d.ts +63 -0
  19. package/dist/cjs/api/bluetooth/react-native/types/BleManagerTypes.js +11 -0
  20. package/dist/cjs/api/bluetooth/react-native/types/ReactNativeTypes.d.ts +180 -0
  21. package/dist/cjs/api/bluetooth/react-native/types/ReactNativeTypes.js +10 -0
  22. package/dist/cjs/api/bluetooth/types/index.d.ts +31 -0
  23. package/dist/cjs/api/bluetooth/types/index.js +22 -0
  24. package/dist/cjs/api/bluetooth/utils/create6DigitPin.d.ts +1 -0
  25. package/dist/cjs/api/bluetooth/utils/create6DigitPin.js +8 -0
  26. package/dist/cjs/api/bluetooth/utils/csvBufferToEpoch.d.ts +11 -0
  27. package/dist/cjs/api/bluetooth/utils/csvBufferToEpoch.js +36 -0
  28. package/dist/cjs/api/bluetooth/utils/encoding.d.ts +3 -0
  29. package/dist/cjs/api/bluetooth/utils/encoding.js +22 -0
  30. package/dist/cjs/api/bluetooth/utils/osHasBluetoothSupport.d.ts +2 -0
  31. package/dist/cjs/api/bluetooth/utils/osHasBluetoothSupport.js +23 -0
  32. package/dist/cjs/api/bluetooth/utils/stitch.d.ts +5 -0
  33. package/dist/cjs/api/bluetooth/utils/stitch.js +22 -0
  34. package/dist/cjs/api/bluetooth/web/WebBluetoothTransport.d.ts +47 -0
  35. package/dist/cjs/api/bluetooth/web/WebBluetoothTransport.js +412 -0
  36. package/dist/cjs/api/bluetooth/web/isMaybeWebWorkerContext.d.ts +1 -0
  37. package/dist/cjs/api/bluetooth/web/isMaybeWebWorkerContext.js +8 -0
  38. package/dist/cjs/api/bluetooth/web/isWebBluetoothSupported.d.ts +1 -0
  39. package/dist/cjs/api/bluetooth/web/isWebBluetoothSupported.js +11 -0
  40. package/dist/cjs/api/firebase/FirebaseApp.d.ts +20 -0
  41. package/dist/cjs/api/firebase/FirebaseApp.js +70 -0
  42. package/dist/cjs/api/firebase/FirebaseDevice.d.ts +68 -0
  43. package/dist/cjs/api/firebase/FirebaseDevice.js +146 -0
  44. package/dist/cjs/api/firebase/FirebaseUser.d.ts +53 -0
  45. package/dist/cjs/api/firebase/FirebaseUser.js +434 -0
  46. package/dist/cjs/api/firebase/config.d.ts +8 -0
  47. package/dist/cjs/api/firebase/config.js +11 -0
  48. package/dist/cjs/api/firebase/deviceStore.d.ts +26 -0
  49. package/dist/cjs/api/firebase/deviceStore.js +191 -0
  50. package/dist/cjs/api/firebase/index.d.ts +3 -0
  51. package/dist/cjs/api/firebase/index.js +19 -0
  52. package/dist/cjs/api/https/config.d.ts +1 -0
  53. package/dist/cjs/api/https/config.js +4 -0
  54. package/dist/cjs/api/https/createOAuthURL.d.ts +3 -0
  55. package/dist/cjs/api/https/createOAuthURL.js +18 -0
  56. package/dist/cjs/api/https/getOAuthToken.d.ts +3 -0
  57. package/dist/cjs/api/https/getOAuthToken.js +34 -0
  58. package/dist/cjs/api/https/utils.d.ts +2 -0
  59. package/dist/cjs/api/https/utils.js +13 -0
  60. package/dist/cjs/api/index.d.ts +108 -0
  61. package/dist/cjs/api/index.js +306 -0
  62. package/dist/cjs/index.d.ts +3 -0
  63. package/dist/cjs/index.js +19 -0
  64. package/dist/cjs/skills/NotionOnDevice.d.ts +7 -0
  65. package/dist/cjs/skills/NotionOnDevice.js +25 -0
  66. package/dist/cjs/skills/createSkill.d.ts +7 -0
  67. package/dist/cjs/skills/createSkill.js +40 -0
  68. package/dist/cjs/skills/index.d.ts +2 -0
  69. package/dist/cjs/skills/index.js +18 -0
  70. package/dist/cjs/subscriptions/SubscriptionManager.d.ts +11 -0
  71. package/dist/cjs/subscriptions/SubscriptionManager.js +27 -0
  72. package/dist/cjs/timesync/Timesync.d.ts +20 -0
  73. package/dist/cjs/timesync/Timesync.js +78 -0
  74. package/dist/cjs/timesync/index.d.ts +1 -0
  75. package/dist/cjs/timesync/index.js +17 -0
  76. package/dist/cjs/types/accelerometer.d.ts +10 -0
  77. package/dist/cjs/types/accelerometer.js +2 -0
  78. package/dist/cjs/types/actions.d.ts +16 -0
  79. package/dist/cjs/types/actions.js +2 -0
  80. package/dist/cjs/types/awareness.d.ts +1 -0
  81. package/dist/cjs/types/awareness.js +2 -0
  82. package/dist/cjs/types/brainwaves.d.ts +26 -0
  83. package/dist/cjs/types/brainwaves.js +2 -0
  84. package/dist/cjs/types/calm.d.ts +6 -0
  85. package/dist/cjs/types/calm.js +2 -0
  86. package/dist/cjs/types/client.d.ts +22 -0
  87. package/dist/cjs/types/client.js +2 -0
  88. package/dist/cjs/types/credentials.d.ts +12 -0
  89. package/dist/cjs/types/credentials.js +2 -0
  90. package/dist/cjs/types/deviceInfo.d.ts +18 -0
  91. package/dist/cjs/types/deviceInfo.js +2 -0
  92. package/dist/cjs/types/epoch.d.ts +12 -0
  93. package/dist/cjs/types/epoch.js +2 -0
  94. package/dist/cjs/types/experiment.d.ts +9 -0
  95. package/dist/cjs/types/experiment.js +2 -0
  96. package/dist/cjs/types/focus.d.ts +6 -0
  97. package/dist/cjs/types/focus.js +2 -0
  98. package/dist/cjs/types/hapticEffects.d.ts +125 -0
  99. package/dist/cjs/types/hapticEffects.js +2 -0
  100. package/dist/cjs/types/kinesis.d.ts +6 -0
  101. package/dist/cjs/types/kinesis.js +2 -0
  102. package/dist/cjs/types/marker.d.ts +7 -0
  103. package/dist/cjs/types/marker.js +2 -0
  104. package/dist/cjs/types/metrics.d.ts +21 -0
  105. package/dist/cjs/types/metrics.js +2 -0
  106. package/dist/cjs/types/oauth.d.ts +20 -0
  107. package/dist/cjs/types/oauth.js +2 -0
  108. package/dist/cjs/types/options.d.ts +51 -0
  109. package/dist/cjs/types/options.js +2 -0
  110. package/dist/cjs/types/sample.d.ts +15 -0
  111. package/dist/cjs/types/sample.js +2 -0
  112. package/dist/cjs/types/settings.d.ts +13 -0
  113. package/dist/cjs/types/settings.js +2 -0
  114. package/dist/cjs/types/signalQuality.d.ts +13 -0
  115. package/dist/cjs/types/signalQuality.js +2 -0
  116. package/dist/cjs/types/skill.d.ts +68 -0
  117. package/dist/cjs/types/skill.js +2 -0
  118. package/dist/cjs/types/status.d.ts +26 -0
  119. package/dist/cjs/types/status.js +22 -0
  120. package/dist/cjs/types/streaming.d.ts +15 -0
  121. package/dist/cjs/types/streaming.js +20 -0
  122. package/dist/cjs/types/subscriptions.d.ts +23 -0
  123. package/dist/cjs/types/subscriptions.js +2 -0
  124. package/dist/cjs/types/training.d.ts +19 -0
  125. package/dist/cjs/types/training.js +2 -0
  126. package/dist/cjs/types/user.d.ts +12 -0
  127. package/dist/cjs/types/user.js +2 -0
  128. package/dist/cjs/utils/errors.d.ts +5 -0
  129. package/dist/cjs/utils/errors.js +17 -0
  130. package/dist/cjs/utils/filterInternalKeys.d.ts +3 -0
  131. package/dist/cjs/utils/filterInternalKeys.js +21 -0
  132. package/dist/cjs/utils/hapticEffects.d.ts +123 -0
  133. package/dist/cjs/utils/hapticEffects.js +130 -0
  134. package/dist/cjs/utils/heartbeat.d.ts +4 -0
  135. package/dist/cjs/utils/heartbeat.js +34 -0
  136. package/dist/cjs/utils/is-node.d.ts +1 -0
  137. package/dist/cjs/utils/is-node.js +9 -0
  138. package/dist/cjs/utils/metrics.d.ts +1 -0
  139. package/dist/cjs/utils/metrics.js +56 -0
  140. package/dist/cjs/utils/oauth.d.ts +9 -0
  141. package/dist/cjs/utils/oauth.js +92 -0
  142. package/dist/cjs/utils/pick.d.ts +1 -0
  143. package/dist/cjs/utils/pick.js +5 -0
  144. package/dist/cjs/utils/pipes.d.ts +46 -0
  145. package/dist/cjs/utils/pipes.js +71 -0
  146. package/dist/cjs/utils/platform.d.ts +30 -0
  147. package/dist/cjs/utils/platform.js +47 -0
  148. package/dist/cjs/utils/subscription.d.ts +6 -0
  149. package/dist/cjs/utils/subscription.js +55 -0
  150. package/dist/cjs/utils/transferDevice.d.ts +9 -0
  151. package/dist/cjs/utils/transferDevice.js +2 -0
  152. package/dist/cjs/utils/whileOnline.d.ts +8 -0
  153. package/dist/cjs/utils/whileOnline.js +15 -0
  154. package/dist/electron/index.js +92 -0
  155. package/dist/electron/index.js.map +1 -0
  156. package/dist/esm/Notion.d.ts +619 -0
  157. package/dist/esm/Notion.js +1260 -0
  158. package/dist/esm/api/bluetooth/BluetoothClient.d.ts +59 -0
  159. package/dist/esm/api/bluetooth/BluetoothClient.js +283 -0
  160. package/dist/esm/api/bluetooth/BluetoothTransport.d.ts +32 -0
  161. package/dist/esm/api/bluetooth/BluetoothTransport.js +1 -0
  162. package/dist/esm/api/bluetooth/constants.d.ts +4 -0
  163. package/dist/esm/api/bluetooth/constants.js +6 -0
  164. package/dist/esm/api/bluetooth/index.d.ts +4 -0
  165. package/dist/esm/api/bluetooth/index.js +4 -0
  166. package/dist/esm/api/bluetooth/react-native/ReactNativeTransport.d.ts +65 -0
  167. package/dist/esm/api/bluetooth/react-native/ReactNativeTransport.js +382 -0
  168. package/dist/esm/api/bluetooth/react-native/types/BleManagerTypes.d.ts +63 -0
  169. package/dist/esm/api/bluetooth/react-native/types/BleManagerTypes.js +8 -0
  170. package/dist/esm/api/bluetooth/react-native/types/ReactNativeTypes.d.ts +180 -0
  171. package/dist/esm/api/bluetooth/react-native/types/ReactNativeTypes.js +9 -0
  172. package/dist/esm/api/bluetooth/types/index.d.ts +31 -0
  173. package/dist/esm/api/bluetooth/types/index.js +19 -0
  174. package/dist/esm/api/bluetooth/utils/create6DigitPin.d.ts +1 -0
  175. package/dist/esm/api/bluetooth/utils/create6DigitPin.js +4 -0
  176. package/dist/esm/api/bluetooth/utils/csvBufferToEpoch.d.ts +11 -0
  177. package/dist/esm/api/bluetooth/utils/csvBufferToEpoch.js +31 -0
  178. package/dist/esm/api/bluetooth/utils/encoding.d.ts +3 -0
  179. package/dist/esm/api/bluetooth/utils/encoding.js +17 -0
  180. package/dist/esm/api/bluetooth/utils/osHasBluetoothSupport.d.ts +2 -0
  181. package/dist/esm/api/bluetooth/utils/osHasBluetoothSupport.js +16 -0
  182. package/dist/esm/api/bluetooth/utils/stitch.d.ts +5 -0
  183. package/dist/esm/api/bluetooth/utils/stitch.js +18 -0
  184. package/dist/esm/api/bluetooth/web/WebBluetoothTransport.d.ts +47 -0
  185. package/dist/esm/api/bluetooth/web/WebBluetoothTransport.js +408 -0
  186. package/dist/esm/api/bluetooth/web/isMaybeWebWorkerContext.d.ts +1 -0
  187. package/dist/esm/api/bluetooth/web/isMaybeWebWorkerContext.js +4 -0
  188. package/dist/esm/api/bluetooth/web/isWebBluetoothSupported.d.ts +1 -0
  189. package/dist/esm/api/bluetooth/web/isWebBluetoothSupported.js +7 -0
  190. package/dist/esm/api/firebase/FirebaseApp.d.ts +20 -0
  191. package/dist/esm/api/firebase/FirebaseApp.js +63 -0
  192. package/dist/esm/api/firebase/FirebaseDevice.d.ts +68 -0
  193. package/dist/esm/api/firebase/FirebaseDevice.js +139 -0
  194. package/dist/esm/api/firebase/FirebaseUser.d.ts +53 -0
  195. package/dist/esm/api/firebase/FirebaseUser.js +426 -0
  196. package/dist/esm/api/firebase/config.d.ts +8 -0
  197. package/dist/esm/api/firebase/config.js +8 -0
  198. package/dist/esm/api/firebase/deviceStore.d.ts +26 -0
  199. package/dist/esm/api/firebase/deviceStore.js +184 -0
  200. package/dist/esm/api/firebase/index.d.ts +3 -0
  201. package/dist/esm/api/firebase/index.js +3 -0
  202. package/dist/esm/api/https/config.d.ts +1 -0
  203. package/dist/esm/api/https/config.js +1 -0
  204. package/dist/esm/api/https/createOAuthURL.d.ts +3 -0
  205. package/dist/esm/api/https/createOAuthURL.js +11 -0
  206. package/dist/esm/api/https/getOAuthToken.d.ts +3 -0
  207. package/dist/esm/api/https/getOAuthToken.js +27 -0
  208. package/dist/esm/api/https/utils.d.ts +2 -0
  209. package/dist/esm/api/https/utils.js +9 -0
  210. package/dist/esm/api/index.d.ts +108 -0
  211. package/dist/esm/api/index.js +299 -0
  212. package/dist/esm/index.d.ts +3 -0
  213. package/dist/esm/index.js +3 -0
  214. package/dist/esm/neurosity.mjs +48722 -0
  215. package/dist/esm/skills/NotionOnDevice.d.ts +7 -0
  216. package/dist/esm/skills/NotionOnDevice.js +21 -0
  217. package/dist/esm/skills/createSkill.d.ts +7 -0
  218. package/dist/esm/skills/createSkill.js +36 -0
  219. package/dist/esm/skills/index.d.ts +2 -0
  220. package/dist/esm/skills/index.js +2 -0
  221. package/dist/esm/subscriptions/SubscriptionManager.d.ts +11 -0
  222. package/dist/esm/subscriptions/SubscriptionManager.js +23 -0
  223. package/dist/esm/timesync/Timesync.d.ts +20 -0
  224. package/dist/esm/timesync/Timesync.js +71 -0
  225. package/dist/esm/timesync/index.d.ts +1 -0
  226. package/dist/esm/timesync/index.js +1 -0
  227. package/dist/esm/types/accelerometer.d.ts +10 -0
  228. package/dist/esm/types/accelerometer.js +1 -0
  229. package/dist/esm/types/actions.d.ts +16 -0
  230. package/dist/esm/types/actions.js +1 -0
  231. package/dist/esm/types/awareness.d.ts +1 -0
  232. package/dist/esm/types/awareness.js +1 -0
  233. package/dist/esm/types/brainwaves.d.ts +26 -0
  234. package/dist/esm/types/brainwaves.js +1 -0
  235. package/dist/esm/types/calm.d.ts +6 -0
  236. package/dist/esm/types/calm.js +1 -0
  237. package/dist/esm/types/client.d.ts +22 -0
  238. package/dist/esm/types/client.js +1 -0
  239. package/dist/esm/types/credentials.d.ts +12 -0
  240. package/dist/esm/types/credentials.js +1 -0
  241. package/dist/esm/types/deviceInfo.d.ts +18 -0
  242. package/dist/esm/types/deviceInfo.js +1 -0
  243. package/dist/esm/types/epoch.d.ts +12 -0
  244. package/dist/esm/types/epoch.js +1 -0
  245. package/dist/esm/types/experiment.d.ts +9 -0
  246. package/dist/esm/types/experiment.js +1 -0
  247. package/dist/esm/types/focus.d.ts +6 -0
  248. package/dist/esm/types/focus.js +1 -0
  249. package/dist/esm/types/hapticEffects.d.ts +125 -0
  250. package/dist/esm/types/hapticEffects.js +1 -0
  251. package/dist/esm/types/kinesis.d.ts +6 -0
  252. package/dist/esm/types/kinesis.js +1 -0
  253. package/dist/esm/types/marker.d.ts +7 -0
  254. package/dist/esm/types/marker.js +1 -0
  255. package/dist/esm/types/metrics.d.ts +21 -0
  256. package/dist/esm/types/metrics.js +1 -0
  257. package/dist/esm/types/oauth.d.ts +20 -0
  258. package/dist/esm/types/oauth.js +1 -0
  259. package/dist/esm/types/options.d.ts +51 -0
  260. package/dist/esm/types/options.js +1 -0
  261. package/dist/esm/types/sample.d.ts +15 -0
  262. package/dist/esm/types/sample.js +1 -0
  263. package/dist/esm/types/settings.d.ts +13 -0
  264. package/dist/esm/types/settings.js +1 -0
  265. package/dist/esm/types/signalQuality.d.ts +13 -0
  266. package/dist/esm/types/signalQuality.js +1 -0
  267. package/dist/esm/types/skill.d.ts +68 -0
  268. package/dist/esm/types/skill.js +1 -0
  269. package/dist/esm/types/status.d.ts +26 -0
  270. package/dist/esm/types/status.js +19 -0
  271. package/dist/esm/types/streaming.d.ts +15 -0
  272. package/dist/esm/types/streaming.js +17 -0
  273. package/dist/esm/types/subscriptions.d.ts +23 -0
  274. package/dist/esm/types/subscriptions.js +1 -0
  275. package/dist/esm/types/training.d.ts +19 -0
  276. package/dist/esm/types/training.js +1 -0
  277. package/dist/esm/types/user.d.ts +12 -0
  278. package/dist/esm/types/user.js +1 -0
  279. package/dist/esm/utils/errors.d.ts +5 -0
  280. package/dist/esm/utils/errors.js +11 -0
  281. package/dist/esm/utils/filterInternalKeys.d.ts +3 -0
  282. package/dist/esm/utils/filterInternalKeys.js +17 -0
  283. package/dist/esm/utils/hapticEffects.d.ts +123 -0
  284. package/dist/esm/utils/hapticEffects.js +125 -0
  285. package/dist/esm/utils/heartbeat.d.ts +4 -0
  286. package/dist/esm/utils/heartbeat.js +29 -0
  287. package/dist/esm/utils/is-node.d.ts +1 -0
  288. package/dist/esm/utils/is-node.js +5 -0
  289. package/dist/esm/utils/metrics.d.ts +1 -0
  290. package/dist/esm/utils/metrics.js +52 -0
  291. package/dist/esm/utils/oauth.d.ts +9 -0
  292. package/dist/esm/utils/oauth.js +64 -0
  293. package/dist/esm/utils/pick.d.ts +1 -0
  294. package/dist/esm/utils/pick.js +1 -0
  295. package/dist/esm/utils/pipes.d.ts +46 -0
  296. package/dist/esm/utils/pipes.js +65 -0
  297. package/dist/esm/utils/platform.d.ts +30 -0
  298. package/dist/esm/utils/platform.js +41 -0
  299. package/dist/esm/utils/subscription.d.ts +6 -0
  300. package/dist/esm/utils/subscription.js +24 -0
  301. package/dist/esm/utils/transferDevice.d.ts +9 -0
  302. package/dist/esm/utils/transferDevice.js +1 -0
  303. package/dist/esm/utils/whileOnline.d.ts +8 -0
  304. package/dist/esm/utils/whileOnline.js +11 -0
  305. package/dist/examples/auth.html +32 -0
  306. package/dist/examples/cloud.html +17 -0
  307. package/dist/examples/index.html +1 -0
  308. package/dist/examples/neurosity.iife.js +48736 -0
  309. package/dist/examples/neurosity.js +672 -0
  310. package/dist/examples/neurosity.mjs +48722 -0
  311. package/dist/examples/training.html +49 -0
  312. package/package.json +78 -0
@@ -0,0 +1,1260 @@
1
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3
+ return new (P || (P = Promise))(function (resolve, reject) {
4
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
7
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
8
+ });
9
+ };
10
+ import { combineLatest, Observable, of, throwError } from "rxjs";
11
+ import { ReplaySubject, firstValueFrom, EMPTY } from "rxjs";
12
+ import { distinctUntilChanged, map, switchMap } from "rxjs/operators";
13
+ import isEqual from "fast-deep-equal";
14
+ import { CloudClient, createUser } from "./api/index";
15
+ import { credentialWithLink, SERVER_TIMESTAMP } from "./api/index";
16
+ import { STREAMING_MODE, STREAMING_TYPE } from "./types/streaming";
17
+ import { getLabels } from "./utils/subscription";
18
+ import { STATUS } from "./types/status";
19
+ import * as errors from "./utils/errors";
20
+ import * as platform from "./utils/platform";
21
+ import * as hapticEffects from "./utils/hapticEffects";
22
+ import { validateOAuthScopeForFunctionName } from "./utils/oauth";
23
+ import { validateOAuthScopeForAction } from "./utils/oauth";
24
+ import { createOAuthURL } from "./api/https/createOAuthURL";
25
+ import { getOAuthToken } from "./api/https/getOAuthToken";
26
+ import { isNode } from "./utils/is-node";
27
+ import { getCloudMetric } from "./utils/metrics";
28
+ import { BluetoothClient } from "./api/bluetooth";
29
+ import { BLUETOOTH_CONNECTION } from "./api/bluetooth/types";
30
+ const defaultOptions = {
31
+ timesync: false,
32
+ autoSelectDevice: true,
33
+ streamingMode: STREAMING_MODE.WIFI_ONLY,
34
+ emulator: false,
35
+ emulatorHost: "localhost",
36
+ emulatorAuthPort: 9099,
37
+ emulatorDatabasePort: 9000,
38
+ emulatorFunctionsPort: 5001,
39
+ emulatorFirestorePort: 8080,
40
+ emulatorOptions: {}
41
+ };
42
+ /**
43
+ * import StreamingModes from "@site/src/components/StreamingModes";
44
+ *
45
+ * Example
46
+ * ```typescript
47
+ * import { Neurosity } from "@neurosity/sdk";
48
+ *
49
+ * const neurosity = new Neurosity();
50
+ * ```
51
+ */
52
+ export class Neurosity {
53
+ /**
54
+ * Creates new instance of the Neurosity SDK
55
+ *
56
+ * ```typescript
57
+ * const neurosity = new Neurosity();
58
+ * ```
59
+
60
+ * @param options
61
+ */
62
+ constructor(options = {}) {
63
+ /**
64
+ * @hidden
65
+ */
66
+ this.streamingMode$ = new ReplaySubject(1);
67
+ const { streamingMode, bluetoothTransport } = options;
68
+ this.options = Object.freeze(Object.assign(Object.assign({}, defaultOptions), options));
69
+ this.cloudClient = new CloudClient(this.options);
70
+ if (!!bluetoothTransport) {
71
+ this.bluetoothClient = new BluetoothClient({
72
+ selectedDevice$: this.onDeviceChange(),
73
+ createBluetoothToken: this.createBluetoothToken.bind(this),
74
+ transport: bluetoothTransport
75
+ });
76
+ }
77
+ this._initStreamingMode(streamingMode, !!bluetoothTransport);
78
+ }
79
+ /**
80
+ *
81
+ * @hidden
82
+ */
83
+ _initStreamingMode(streamingMode, hasBluetoothTransport) {
84
+ const streamingModeFeaturesBluetooth = [
85
+ STREAMING_MODE.BLUETOOTH_WITH_WIFI_FALLBACK,
86
+ STREAMING_MODE.WIFI_WITH_BLUETOOTH_FALLBACK
87
+ ].includes(streamingMode);
88
+ const isInvalidStreamingMode = !Object.values(STREAMING_MODE).includes(streamingMode);
89
+ const isMissingBluetoothTransport = streamingModeFeaturesBluetooth && !hasBluetoothTransport;
90
+ this.isMissingBluetoothTransport = isMissingBluetoothTransport;
91
+ const shouldDefaultToCloud = !streamingMode || isInvalidStreamingMode || isMissingBluetoothTransport;
92
+ // Default to backwards compatible cloud streaming mode if:
93
+ // 1. No streaming mode is provided
94
+ // 2. An invalid streaming mode is provided
95
+ // 3. A streaming mode containing bluetooth is provided, but without a bluetooth transport
96
+ if (shouldDefaultToCloud) {
97
+ this.streamingMode$.next(STREAMING_MODE.WIFI_ONLY);
98
+ }
99
+ else {
100
+ this.streamingMode$.next(streamingMode);
101
+ }
102
+ }
103
+ /**
104
+ * Subscribe to the device's streaming state changes and the current strategy
105
+ *
106
+ * Streams the current mode of streaming (wifi or bluetooth).
107
+ *
108
+ * ```typescript
109
+ * neurosity.streamingState().subscribe((streamingState) => {
110
+ * console.log(streamingState);
111
+ * // { streamingMode: "wifi-only", activeMode: "wifi", connected: true }
112
+ * });
113
+ * ```
114
+ */
115
+ streamingState() {
116
+ const isWifiOnline = (state) => [STATUS.ONLINE, STATUS.UPDATING].includes(state);
117
+ return this.streamingMode$.pipe(switchMap((streamingMode) => {
118
+ if (this.isMissingBluetoothTransport) {
119
+ return this.cloudClient.status().pipe(map(({ state }) => ({
120
+ connected: isWifiOnline(state),
121
+ streamingMode,
122
+ activeMode: STREAMING_TYPE.WIFI
123
+ })));
124
+ }
125
+ return this.onDeviceChange().pipe(switchMap((selectDevice) => !selectDevice
126
+ ? EMPTY
127
+ : combineLatest({
128
+ wifiStatus: this.cloudClient.status(),
129
+ bluetoothConnection: !!(this === null || this === void 0 ? void 0 : this.bluetoothClient)
130
+ ? this.bluetoothClient.connection()
131
+ : of(BLUETOOTH_CONNECTION.DISCONNECTED)
132
+ }).pipe(map(({ wifiStatus, bluetoothConnection }) => {
133
+ const isBluetoothConnected = bluetoothConnection === BLUETOOTH_CONNECTION.CONNECTED;
134
+ switch (streamingMode) {
135
+ default:
136
+ case STREAMING_MODE.WIFI_ONLY:
137
+ return {
138
+ connected: isWifiOnline(wifiStatus.state),
139
+ streamingMode,
140
+ activeMode: STREAMING_TYPE.WIFI
141
+ };
142
+ case STREAMING_MODE.WIFI_WITH_BLUETOOTH_FALLBACK:
143
+ return {
144
+ connected: isWifiOnline(wifiStatus.state) ||
145
+ !isBluetoothConnected
146
+ ? isWifiOnline(wifiStatus.state)
147
+ : isBluetoothConnected,
148
+ streamingMode,
149
+ activeMode: isWifiOnline(wifiStatus.state) ||
150
+ !isBluetoothConnected
151
+ ? STREAMING_TYPE.WIFI
152
+ : STREAMING_TYPE.BLUETOOTH
153
+ };
154
+ case STREAMING_MODE.BLUETOOTH_WITH_WIFI_FALLBACK:
155
+ return {
156
+ connected: isBluetoothConnected
157
+ ? true
158
+ : isWifiOnline(wifiStatus.state),
159
+ streamingMode,
160
+ activeMode: isBluetoothConnected
161
+ ? STREAMING_TYPE.BLUETOOTH
162
+ : STREAMING_TYPE.WIFI
163
+ };
164
+ }
165
+ }), distinctUntilChanged((a, b) => isEqual(a, b)))));
166
+ }));
167
+ }
168
+ /**
169
+ *
170
+ * @hidden
171
+ */
172
+ _withStreamingModeObservable(streams) {
173
+ const { wifi, bluetooth } = streams;
174
+ return this.streamingState().pipe(switchMap(({ activeMode }) => {
175
+ switch (activeMode) {
176
+ case STREAMING_TYPE.WIFI:
177
+ return wifi();
178
+ case STREAMING_TYPE.BLUETOOTH:
179
+ return bluetooth();
180
+ default:
181
+ return wifi();
182
+ }
183
+ }));
184
+ }
185
+ /**
186
+ *
187
+ * @hidden
188
+ */
189
+ _withStreamingModePromise(promises) {
190
+ return __awaiter(this, void 0, void 0, function* () {
191
+ const { wifi, bluetooth } = promises;
192
+ const { activeMode } = yield firstValueFrom(this.streamingState());
193
+ switch (activeMode) {
194
+ case STREAMING_TYPE.WIFI:
195
+ return yield wifi();
196
+ case STREAMING_TYPE.BLUETOOTH:
197
+ return yield bluetooth();
198
+ default:
199
+ return yield wifi();
200
+ }
201
+ });
202
+ }
203
+ /**
204
+ *
205
+ * @hidden
206
+ */
207
+ get bluetooth() {
208
+ return this === null || this === void 0 ? void 0 : this.bluetoothClient;
209
+ }
210
+ /**
211
+ *
212
+ * @hidden
213
+ */
214
+ _getCloudMetricDependencies() {
215
+ return {
216
+ options: this.options,
217
+ cloudClient: this.cloudClient,
218
+ onDeviceChange: this.onDeviceChange.bind(this),
219
+ status: this.status.bind(this)
220
+ };
221
+ }
222
+ /**
223
+ * Starts user session
224
+ *
225
+ * ```typescript
226
+ * await neurosity.login({
227
+ * email: "...",
228
+ * password: "..."
229
+ * });
230
+ * ```
231
+ *
232
+ * @param credentials
233
+ */
234
+ login(credentials) {
235
+ return __awaiter(this, void 0, void 0, function* () {
236
+ return yield this.cloudClient.login(credentials);
237
+ });
238
+ }
239
+ /**
240
+ * Ends user session
241
+ *
242
+ * ```typescript
243
+ * await neurosity.logout();
244
+ * // session has ended
245
+ * ```
246
+ *
247
+ */
248
+ logout() {
249
+ return __awaiter(this, void 0, void 0, function* () {
250
+ return yield this.cloudClient.logout();
251
+ });
252
+ }
253
+ /**
254
+ * @internal
255
+ * Not user facing.
256
+ */
257
+ __getApp() {
258
+ return this.cloudClient.__getApp();
259
+ }
260
+ /**
261
+ * Subscribe to auth state changes
262
+ *
263
+ * Streams the state of the auth session. If user has logged in, the user object will be set. When logged out, the user object will be null.
264
+ *
265
+ * ```typescript
266
+ * neurosity.onAuthStateChanged().subscribe((user) => {
267
+ * console.log(user);
268
+ * });
269
+ * ```
270
+ */
271
+ onAuthStateChanged() {
272
+ return this.cloudClient.onAuthStateChanged();
273
+ }
274
+ /**
275
+ * @internal
276
+ * Not user facing yet
277
+ */
278
+ addDevice(deviceId) {
279
+ const [hasOAuthError, OAuthError] = validateOAuthScopeForFunctionName(this.cloudClient.userClaims, "addDevice");
280
+ if (hasOAuthError) {
281
+ return Promise.reject(OAuthError);
282
+ }
283
+ return this.cloudClient.addDevice(deviceId);
284
+ }
285
+ /**
286
+ * @internal
287
+ * Not user facing yet
288
+ */
289
+ removeDevice(deviceId) {
290
+ const [hasOAuthError, OAuthError] = validateOAuthScopeForFunctionName(this.cloudClient.userClaims, "removeDevice");
291
+ if (hasOAuthError) {
292
+ return Promise.reject(OAuthError);
293
+ }
294
+ return this.cloudClient.removeDevice(deviceId);
295
+ }
296
+ /**
297
+ * @internal
298
+ * Not user facing yet
299
+ */
300
+ transferDevice(options) {
301
+ const [hasOAuthError, OAuthError] = validateOAuthScopeForFunctionName(this.cloudClient.userClaims, "transferDevice");
302
+ if (hasOAuthError) {
303
+ return Promise.reject(OAuthError);
304
+ }
305
+ return this.cloudClient.transferDevice(options);
306
+ }
307
+ /**
308
+ * @internal
309
+ * Not user facing yet
310
+ */
311
+ onUserDevicesChange() {
312
+ const [hasOAuthError, OAuthError] = validateOAuthScopeForFunctionName(this.cloudClient.userClaims, "onUserDevicesChange");
313
+ if (hasOAuthError) {
314
+ return throwError(() => OAuthError);
315
+ }
316
+ return this.cloudClient.onUserDevicesChange();
317
+ }
318
+ /**
319
+ * @internal
320
+ * Not user facing yet
321
+ */
322
+ onUserClaimsChange() {
323
+ return this.cloudClient.onUserClaimsChange();
324
+ }
325
+ /**
326
+ * Get user devices
327
+ *
328
+ * Returns a list of devices claimed by the user authenticated.
329
+ *
330
+ * ```typescript
331
+ * const devices = await neurosity.getDevices();
332
+ * console.log(devices);
333
+ * ```
334
+ */
335
+ getDevices() {
336
+ return __awaiter(this, void 0, void 0, function* () {
337
+ return yield this.cloudClient.getDevices();
338
+ });
339
+ }
340
+ /**
341
+ * Select Device
342
+ *
343
+ * Rarely necessary, but useful when the user owns multiple devices.
344
+ *
345
+ * A common use case for manually selecting a device is when you wish to build a device dropdown a user can select from, instead of collecting the Device Id from the user ahead of time.
346
+ *
347
+ * The 3 steps to manually selecting a device are:
348
+ *
349
+ * - Set `autoSelectDevice` to false when instantiating the `Neurosity` class.
350
+ * - Authenticate with your Neurosity account to access your devices by calling the `neurosity.login(...)` function.
351
+ * - Call the `neurosity.selectDevice(...)` function with a device selector function.
352
+ *
353
+ * ```typescript
354
+ * const devices = await neurosity.selectDevice((devices) =>
355
+ * devices.find((device) => device.deviceNickname === "Crown-A1B")
356
+ * );
357
+ *
358
+ * console.log(devices);
359
+ * ```
360
+ *
361
+ * > If you own multiple devices, and don't pass `autoSelectDevice`, then the first device on the list will be automatically selected.
362
+ *
363
+ * For more info, check out the "Device Selection" guide.
364
+ */
365
+ selectDevice(deviceSelector) {
366
+ return __awaiter(this, void 0, void 0, function* () {
367
+ const [hasOAuthError, OAuthError] = validateOAuthScopeForFunctionName(this.cloudClient.userClaims, "selectDevice");
368
+ if (hasOAuthError) {
369
+ return Promise.reject(OAuthError);
370
+ }
371
+ return yield this.cloudClient.selectDevice(deviceSelector);
372
+ });
373
+ }
374
+ /**
375
+ * Get selected device
376
+ *
377
+ * ```typescript
378
+ * const selectedDevice = await neurosity.getSelectedDevice();
379
+ * console.log(selectedDevice);
380
+ * ```
381
+ */
382
+ getSelectedDevice() {
383
+ return __awaiter(this, void 0, void 0, function* () {
384
+ const [hasOAuthError, OAuthError] = validateOAuthScopeForFunctionName(this.cloudClient.userClaims, "getSelectedDevice");
385
+ if (hasOAuthError) {
386
+ return Promise.reject(OAuthError);
387
+ }
388
+ return yield this.cloudClient.getSelectedDevice();
389
+ });
390
+ }
391
+ /**
392
+ * ```typescript
393
+ * const info = await neurosity.getInfo();
394
+ * ```
395
+ */
396
+ getInfo() {
397
+ return __awaiter(this, void 0, void 0, function* () {
398
+ if (!(yield this.cloudClient.didSelectDevice())) {
399
+ return Promise.reject(errors.mustSelectDevice);
400
+ }
401
+ const [hasOAuthError, OAuthError] = validateOAuthScopeForFunctionName(this.cloudClient.userClaims, "getInfo");
402
+ if (hasOAuthError) {
403
+ return Promise.reject(OAuthError);
404
+ }
405
+ return yield this._withStreamingModePromise({
406
+ wifi: () => this.cloudClient.getInfo(),
407
+ bluetooth: () => this.bluetoothClient.getInfo()
408
+ });
409
+ });
410
+ }
411
+ /**
412
+ * Observes selected device
413
+ *
414
+ * ```typescript
415
+ * neurosity.onDeviceChange().subscribe(device => {
416
+ * console.log(device);
417
+ * });
418
+ * ```
419
+ */
420
+ onDeviceChange() {
421
+ const [hasOAuthError, OAuthError] = validateOAuthScopeForFunctionName(this.cloudClient.userClaims, "onDeviceChange");
422
+ if (hasOAuthError) {
423
+ return throwError(() => OAuthError);
424
+ }
425
+ return this.cloudClient.onDeviceChange();
426
+ }
427
+ /**
428
+ * <StreamingModes wifi={true} bluetooth={true} />
429
+ *
430
+ * Ends database connection
431
+ *
432
+ * ```typescript
433
+ * await neurosity.disconnect();
434
+ * ```
435
+ */
436
+ disconnect() {
437
+ return __awaiter(this, void 0, void 0, function* () {
438
+ return yield this._withStreamingModePromise({
439
+ wifi: () => this.cloudClient.disconnect(),
440
+ bluetooth: () => this.bluetoothClient.disconnect()
441
+ });
442
+ });
443
+ }
444
+ /**
445
+ * <StreamingModes wifi={true} bluetooth={true} />
446
+ *
447
+ * @internal
448
+ * Not user facing
449
+ */
450
+ dispatchAction(action) {
451
+ return __awaiter(this, void 0, void 0, function* () {
452
+ if (!(yield this.cloudClient.didSelectDevice())) {
453
+ return Promise.reject(errors.mustSelectDevice);
454
+ }
455
+ const [hasOAuthError, OAuthError] = validateOAuthScopeForAction(this.cloudClient.userClaims, action);
456
+ if (hasOAuthError) {
457
+ return Promise.reject(OAuthError);
458
+ }
459
+ return yield this._withStreamingModePromise({
460
+ wifi: () => this.cloudClient.dispatchAction(action),
461
+ bluetooth: () => this.bluetoothClient.dispatchAction(action)
462
+ });
463
+ });
464
+ }
465
+ /**
466
+ * <StreamingModes wifi={true} bluetooth={true} />
467
+ *
468
+ * Injects an EEG marker to data stream
469
+ *
470
+ * ```typescript
471
+ * neurosity.addMarker("eyes-closed");
472
+ *
473
+ * // later...
474
+ *
475
+ * neurosity.addMarker("eyes-open");
476
+ * ```
477
+ *
478
+ * @param label Name the label to inject
479
+ */
480
+ addMarker(label) {
481
+ return __awaiter(this, void 0, void 0, function* () {
482
+ if (!(yield this.cloudClient.didSelectDevice())) {
483
+ throw errors.mustSelectDevice;
484
+ }
485
+ if (!label) {
486
+ throw new Error(`${errors.prefix}A label is required for addMarker`);
487
+ }
488
+ return yield this._withStreamingModePromise({
489
+ wifi: () => this.cloudClient.dispatchAction({
490
+ command: "marker",
491
+ action: "add",
492
+ message: {
493
+ label,
494
+ timestamp: this.cloudClient.timestamp
495
+ }
496
+ }),
497
+ bluetooth: () => this.bluetoothClient.addMarker(label)
498
+ });
499
+ });
500
+ }
501
+ /**
502
+ * <StreamingModes wifi={true} bluetooth={true} />
503
+ *
504
+ * Queue haptic motor commands
505
+ *
506
+ * To queue haptic P7 only,
507
+ * ```typescript
508
+ * await neurosity.haptics({
509
+ * P7: ["tripleClick100"]
510
+ * });
511
+ * ```
512
+ *
513
+ * To queue both motors at the same time
514
+ * ```typescript
515
+ * await neurosity.haptics({
516
+ * P7: [neurosity.getHapticEffects().strongClick100],
517
+ * P8: [neurosity.getHapticEffects().strongClick100]
518
+ * });
519
+ * ```
520
+ *
521
+ * You can queue different commands to the motors too
522
+ * ```typescript
523
+ * const effects = neurosity.getHapticEffects();
524
+ * await neurosity.haptics({
525
+ * P7: [effects.transitionRampUpLongSmooth1_0_to_100,
526
+ * effects.transitionRampDownLongSmooth1_100_to_0],
527
+ * P8: [effects.strongClick100]
528
+ * });
529
+ * ```
530
+ *
531
+ * @param effects Effects to queue. The key of the object passed should be the location of the motor
532
+ * to queue. Each key can be an array of up to 7 commands. There is no haptic support for model
533
+ * version 1, Notion DK1. The Haptic motor's location is positioned in reference to the 10-10 EEG
534
+ * system used to label the channels of the Crown's EEG sensors. Notion 2 and Crown have haptics
535
+ * at P7 and P8. A list of haptic commands can be found on ./utils/hapticCodes.ts - there
536
+ * are about 127 of them!
537
+ */
538
+ haptics(effects) {
539
+ var _a;
540
+ return __awaiter(this, void 0, void 0, function* () {
541
+ const metric = "haptics";
542
+ if (!(yield this.cloudClient.didSelectDevice())) {
543
+ return Promise.reject(errors.mustSelectDevice);
544
+ }
545
+ const modelVersion = (_a = (yield this.getSelectedDevice())) === null || _a === void 0 ? void 0 : _a.modelVersion;
546
+ const supportsHaptics = platform.supportsHaptics(modelVersion);
547
+ if (!supportsHaptics) {
548
+ return Promise.reject(errors.metricNotSupportedByModel(metric, modelVersion));
549
+ }
550
+ const newPlatformHapticRequest = platform.getPlatformHapticMotors(modelVersion);
551
+ for (const key in effects) {
552
+ if (!Object.keys(newPlatformHapticRequest).includes(key)) {
553
+ return Promise.reject(errors.locationNotFound(key, modelVersion));
554
+ }
555
+ const singleMotorEffects = effects[key];
556
+ const maxItems = 7;
557
+ if (singleMotorEffects.length > maxItems) {
558
+ return Promise.reject(errors.exceededMaxItems(maxItems));
559
+ }
560
+ newPlatformHapticRequest[key] = singleMotorEffects;
561
+ }
562
+ const payload = {
563
+ command: metric,
564
+ action: "queue",
565
+ responseRequired: true,
566
+ responseTimeout: 1000,
567
+ message: { effects: newPlatformHapticRequest }
568
+ };
569
+ return yield this._withStreamingModePromise({
570
+ wifi: () => this.cloudClient.dispatchAction(payload),
571
+ bluetooth: () => this.bluetoothClient.dispatchAction(payload)
572
+ });
573
+ });
574
+ }
575
+ /**
576
+ * ```typescript
577
+ * const effects = neurosity.getHapticEffects();
578
+ * ```
579
+ */
580
+ getHapticEffects() {
581
+ return hapticEffects;
582
+ }
583
+ /**
584
+ * <StreamingModes wifi={true} bluetooth={true} />
585
+ *
586
+ * Observes accelerometer data
587
+ * Supported by the Crown and Notion 2 devices.
588
+ *
589
+ * ```typescript
590
+ * neurosity.accelerometer().subscribe(accelerometer => {
591
+ * console.log(accelerometer);
592
+ * });
593
+ *
594
+ * // { acceleration: ..., inclination: ..., orientation: ..., pitch: ..., roll: ..., x: ..., y: ..., z: ... }
595
+ * ```
596
+ *
597
+ * @returns Observable of accelerometer metric events
598
+ */
599
+ accelerometer() {
600
+ const metric = "accelerometer";
601
+ const [hasOAuthError, OAuthError] = validateOAuthScopeForFunctionName(this.cloudClient.userClaims, metric);
602
+ if (hasOAuthError) {
603
+ return throwError(() => OAuthError);
604
+ }
605
+ return this.onDeviceChange().pipe(switchMap((selectedDevice) => {
606
+ const modelVersion = (selectedDevice === null || selectedDevice === void 0 ? void 0 : selectedDevice.modelVersion) || platform.MODEL_VERSION_1;
607
+ const supportsAccel = platform.supportsAccel(modelVersion);
608
+ if (!supportsAccel) {
609
+ return throwError(() => errors.metricNotSupportedByModel(metric, modelVersion));
610
+ }
611
+ return this._withStreamingModeObservable({
612
+ wifi: () => getCloudMetric(this._getCloudMetricDependencies(), {
613
+ metric,
614
+ labels: getLabels(metric),
615
+ atomic: true
616
+ }),
617
+ bluetooth: () => this.bluetoothClient.accelerometer()
618
+ });
619
+ }));
620
+ }
621
+ /**
622
+ * <StreamingModes wifi={true} bluetooth={true} />
623
+ *
624
+ * The `raw` brainwaves parameter emits epochs of 16 samples for Crown and 25 for Notion 1 and 2.
625
+ *
626
+ * Example
627
+ * ```typescript
628
+ * neurosity.brainwaves("raw").subscribe(brainwaves => {
629
+ * console.log(brainwaves);
630
+ * });
631
+ * ```
632
+ *
633
+ * Raw Unfiltered - The `rawUnfiltered` brainwaves parameter emits epochs of 16 samples for Crown and 25 for Notion 1 and 2.
634
+
635
+ * Example
636
+ * ```typescript
637
+ * neurosity.brainwaves("rawUnfiltered").subscribe(brainwaves => {
638
+ * console.log(brainwaves);
639
+ * });
640
+ * ```
641
+ *
642
+ * Power By Band - The `powerByBand` brainwaves parameter emits epochs 4 times a second. Every frequency label (e.g. beta) contains an average power value per channel.
643
+ *
644
+ * Example
645
+ * ```typescript
646
+ * neurosity.brainwaves("powerByBand").subscribe(brainwaves => {
647
+ * console.log(brainwaves);
648
+ * });
649
+ * ```
650
+ *
651
+ * Power Spectral Density (PSD) - The `psd` brainwaves parameter emits epochs 4 times a second. Every frequency label (e.g. alpha) contains the computed FFT (Fast Fourier transform) value per channel (see the `psd` property), as well as the frequency ranges (see the `freqs` property).
652
+ *
653
+ * Example
654
+ * ```typescript
655
+ * neurosity.brainwaves("psd").subscribe(brainwaves => {
656
+ * console.log(brainwaves);
657
+ * });
658
+ * ```
659
+ *
660
+ * @param label Name of metric properties to filter by
661
+ * @returns Observable of brainwaves metric events
662
+ */
663
+ brainwaves(label) {
664
+ const [hasOAuthError, OAuthError] = validateOAuthScopeForFunctionName(this.cloudClient.userClaims, "brainwaves");
665
+ if (hasOAuthError) {
666
+ return throwError(() => OAuthError);
667
+ }
668
+ return this._withStreamingModeObservable({
669
+ wifi: () => getCloudMetric(this._getCloudMetricDependencies(), {
670
+ metric: "brainwaves",
671
+ labels: label ? [label] : [],
672
+ atomic: false
673
+ }),
674
+ // @TODO: doesn't support multiple labels, we should make the higher
675
+ // order function only support one label
676
+ bluetooth: () => this.bluetoothClient.brainwaves(label)
677
+ });
678
+ }
679
+ /**
680
+ * <StreamingModes wifi={true} bluetooth={true} />
681
+ *
682
+ * Example
683
+ * ```typescript
684
+ * neurosity.calm().subscribe(calm => {
685
+ * console.log(calm.probability);
686
+ * });
687
+ *
688
+ * // 0.45
689
+ * // 0.47
690
+ * // 0.53
691
+ * // 0.51
692
+ * // ...
693
+ * ```
694
+ *
695
+ * @returns Observable of calm events - awareness/calm alias
696
+ */
697
+ calm() {
698
+ const [hasOAuthError, OAuthError] = validateOAuthScopeForFunctionName(this.cloudClient.userClaims, "calm");
699
+ if (hasOAuthError) {
700
+ return throwError(() => OAuthError);
701
+ }
702
+ return this._withStreamingModeObservable({
703
+ wifi: () => getCloudMetric(this._getCloudMetricDependencies(), {
704
+ metric: "awareness",
705
+ labels: ["calm"],
706
+ atomic: false
707
+ }),
708
+ bluetooth: () => this.bluetoothClient.calm()
709
+ });
710
+ }
711
+ /**
712
+ * <StreamingModes wifi={true} bluetooth={true} />
713
+ *
714
+ * Observes signal quality data where each property is the name
715
+ * of the channel and the value includes the standard deviation and
716
+ * a status set by the device
717
+ *
718
+ * ```typescript
719
+ * neurosity.signalQuality().subscribe(signalQuality => {
720
+ * console.log(signalQuality);
721
+ * });
722
+ *
723
+ * // { FC6: { standardDeviation: 3.5, status: "good" }, C3: {...}, ... }
724
+ * ```
725
+ *
726
+ * @returns Observable of signalQuality metric events
727
+ */
728
+ signalQuality() {
729
+ const metric = "signalQuality";
730
+ const [hasOAuthError, OAuthError] = validateOAuthScopeForFunctionName(this.cloudClient.userClaims, metric);
731
+ if (hasOAuthError) {
732
+ return throwError(() => OAuthError);
733
+ }
734
+ return this._withStreamingModeObservable({
735
+ wifi: () => getCloudMetric(this._getCloudMetricDependencies(), {
736
+ metric,
737
+ labels: getLabels(metric),
738
+ atomic: true
739
+ }),
740
+ bluetooth: () => this.bluetoothClient.signalQuality()
741
+ });
742
+ }
743
+ /**
744
+ * <StreamingModes wifi={true} />
745
+ *
746
+ * Observes last state of `settings` and all subsequent `settings` changes
747
+ *
748
+ * ```typescript
749
+ * neurosity.settings().subscribe(settings => {
750
+ * console.log(settings.lsl);
751
+ * });
752
+ *
753
+ * // true
754
+ * // ...
755
+ * ```
756
+ *
757
+ * @returns Observable of `settings` metric events
758
+ */
759
+ settings() {
760
+ const [hasOAuthError, OAuthError] = validateOAuthScopeForFunctionName(this.cloudClient.userClaims, "settings");
761
+ if (hasOAuthError) {
762
+ return throwError(() => OAuthError);
763
+ }
764
+ return this.cloudClient.observeNamespace("settings");
765
+ }
766
+ /**
767
+ * <StreamingModes wifi={true} bluetooth={true} />
768
+ *
769
+ * Example
770
+ * ```typescript
771
+ * neurosity.focus().subscribe(focus => {
772
+ * console.log(focus.probability);
773
+ * });
774
+ *
775
+ * // 0.56
776
+ * // 0.46
777
+ * // 0.31
778
+ * // 0.39
779
+ * // ...
780
+ * ```
781
+ *
782
+ * @returns Observable of focus events - awareness/focus alias
783
+ */
784
+ focus() {
785
+ const [hasOAuthError, OAuthError] = validateOAuthScopeForFunctionName(this.cloudClient.userClaims, "focus");
786
+ if (hasOAuthError) {
787
+ return throwError(() => OAuthError);
788
+ }
789
+ return this._withStreamingModeObservable({
790
+ wifi: () => getCloudMetric(this._getCloudMetricDependencies(), {
791
+ metric: "awareness",
792
+ labels: ["focus"],
793
+ atomic: false
794
+ }),
795
+ bluetooth: () => this.bluetoothClient.focus()
796
+ });
797
+ }
798
+ /**
799
+ * <StreamingModes wifi={true} />
800
+ *
801
+ * @param label Name of metric properties to filter by
802
+ * @returns Observable of kinesis metric events
803
+ */
804
+ kinesis(label) {
805
+ const metric = "kinesis";
806
+ const [hasOAuthError, OAuthError] = validateOAuthScopeForFunctionName(this.cloudClient.userClaims, metric);
807
+ if (hasOAuthError) {
808
+ return throwError(() => OAuthError);
809
+ }
810
+ return getCloudMetric(this._getCloudMetricDependencies(), {
811
+ metric,
812
+ labels: label ? [label] : [],
813
+ atomic: false
814
+ });
815
+ }
816
+ /**
817
+ * <StreamingModes wifi={true} />
818
+ *
819
+ * @param label Name of metric properties to filter by
820
+ * @returns Observable of predictions metric events
821
+ */
822
+ predictions(label) {
823
+ const metric = "predictions";
824
+ const [hasOAuthError, OAuthError] = validateOAuthScopeForFunctionName(this.cloudClient.userClaims, metric);
825
+ if (hasOAuthError) {
826
+ return throwError(() => OAuthError);
827
+ }
828
+ return getCloudMetric(this._getCloudMetricDependencies(), {
829
+ metric,
830
+ labels: label ? [label] : [],
831
+ atomic: false
832
+ });
833
+ }
834
+ /**
835
+ * <StreamingModes wifi={true} bluetooth={true} />
836
+ *
837
+ * Observes last state of `status` and all subsequent `status` changes
838
+ *
839
+ * ```typescript
840
+ * neurosity.status().subscribe(status => {
841
+ * console.log(status.state);
842
+ * });
843
+ *
844
+ * // "online"
845
+ * // ...
846
+ * ```
847
+ *
848
+ * @returns Observable of `status` metric events
849
+ */
850
+ status() {
851
+ const [hasOAuthError, OAuthError] = validateOAuthScopeForFunctionName(this.cloudClient.userClaims, "status");
852
+ if (hasOAuthError) {
853
+ return throwError(() => OAuthError);
854
+ }
855
+ return this._withStreamingModeObservable({
856
+ wifi: () => this.cloudClient.status(),
857
+ bluetooth: () => this.bluetoothClient.status()
858
+ });
859
+ }
860
+ /**
861
+ * @internal
862
+ * Not user facing yet
863
+ *
864
+ * <StreamingModes wifi={true} />
865
+ *
866
+ * Changes device settings programmatically. These settings can be
867
+ * also changed from the developer console under device settings.
868
+ *
869
+ * Available settings [[ChangeSettings]]
870
+ *
871
+ * Example
872
+ * ```typescript
873
+ * neurosity.changeSettings({
874
+ * lsl: true
875
+ * });
876
+ * ```
877
+ */
878
+ changeSettings(settings) {
879
+ return __awaiter(this, void 0, void 0, function* () {
880
+ if (!(yield this.cloudClient.didSelectDevice())) {
881
+ return Promise.reject(errors.mustSelectDevice);
882
+ }
883
+ const [hasOAuthError, OAuthError] = validateOAuthScopeForFunctionName(this.cloudClient.userClaims, "changeSettings");
884
+ if (hasOAuthError) {
885
+ return Promise.reject(OAuthError);
886
+ }
887
+ return yield this.cloudClient.changeSettings(settings);
888
+ });
889
+ }
890
+ /**
891
+ * <StreamingModes wifi={true} />
892
+ *
893
+ * ```typescript
894
+ * neurosity.training.record({
895
+ * metric: "kinesis",
896
+ * label: "push"
897
+ * });
898
+ *
899
+ * neurosity.training.stop({
900
+ * metric: "kinesis",
901
+ * label: "push"
902
+ * });
903
+ * ```
904
+ *
905
+ * @returns Training methods
906
+ */
907
+ get training() {
908
+ return {
909
+ /**
910
+ * <StreamingModes wifi={true} />
911
+ *
912
+ * Records a training for a metric/label pair
913
+ * @category Training
914
+ */
915
+ record: (training) => __awaiter(this, void 0, void 0, function* () {
916
+ if (!(yield this.cloudClient.didSelectDevice())) {
917
+ throw errors.mustSelectDevice;
918
+ }
919
+ const userId = this.cloudClient.user && "uid" in this.cloudClient.user
920
+ ? this.cloudClient.user.uid
921
+ : null;
922
+ const message = Object.assign(Object.assign({ fit: false, baseline: false, timestamp: this.cloudClient.timestamp }, training), { userId });
923
+ yield this.cloudClient.actions.dispatch({
924
+ command: "training",
925
+ action: "record",
926
+ message
927
+ });
928
+ }),
929
+ /**
930
+ * <StreamingModes wifi={true} />
931
+ *
932
+ * Stops the training for a metric/label pair
933
+ * @category Training
934
+ */
935
+ stop: (training) => __awaiter(this, void 0, void 0, function* () {
936
+ if (!(yield this.cloudClient.didSelectDevice())) {
937
+ throw errors.mustSelectDevice;
938
+ }
939
+ yield this.cloudClient.actions.dispatch({
940
+ command: "training",
941
+ action: "stop",
942
+ message: Object.assign({}, training)
943
+ });
944
+ }),
945
+ /**
946
+ * <StreamingModes wifi={true} />
947
+ *
948
+ * Stops all trainings
949
+ * @category Training
950
+ */
951
+ stopAll: () => __awaiter(this, void 0, void 0, function* () {
952
+ if (!(yield this.cloudClient.didSelectDevice())) {
953
+ throw errors.mustSelectDevice;
954
+ }
955
+ yield this.cloudClient.actions.dispatch({
956
+ command: "training",
957
+ action: "stopAll",
958
+ message: {}
959
+ });
960
+ })
961
+ };
962
+ }
963
+ /**
964
+ * @internal
965
+ * Proof of Concept for disconnecting db
966
+ */
967
+ goOffline() {
968
+ this.cloudClient.goOffline();
969
+ }
970
+ /**
971
+ * @internal
972
+ * Proof of Concept for resuming db connection
973
+ */
974
+ goOnline() {
975
+ this.cloudClient.goOnline();
976
+ }
977
+ /**
978
+ * @internal
979
+ * Not user facing yet
980
+ *
981
+ * Creates user account and automatically signs in with same credentials
982
+ *
983
+ * @param emailAndPasswordObject
984
+ * @returns user credential
985
+ */
986
+ createAccount(credentials) {
987
+ return this.cloudClient.createAccount(credentials);
988
+ }
989
+ /**
990
+ * @internal
991
+ * Not user facing yet
992
+ *
993
+ * Removes all devices from an account and then deletes the account
994
+ */
995
+ deleteAccount() {
996
+ return this.cloudClient.deleteAccount();
997
+ }
998
+ /**
999
+ * @internal
1000
+ * Not user facing
1001
+ *
1002
+ * Creates token (JWT) designed to authenticate and authorize Bluetooth clients/centrals.
1003
+ *
1004
+ * @returns token
1005
+ */
1006
+ createBluetoothToken() {
1007
+ return this.cloudClient.createBluetoothToken();
1008
+ }
1009
+ /**
1010
+ * @internal
1011
+ * Not user facing yet
1012
+ *
1013
+ * Creates custom token (JWT) to use to login with `{ customToken }`.
1014
+ *
1015
+ * @returns custom token
1016
+ */
1017
+ createCustomToken() {
1018
+ return this.cloudClient.createCustomToken();
1019
+ }
1020
+ /**
1021
+ * @internal
1022
+ * Not user facing yet
1023
+ *
1024
+ * Gets the offset between the device's clock and the client's clock
1025
+ * Requires option.timesync to be true
1026
+ *
1027
+ * @returns timesyncOffset
1028
+ */
1029
+ getTimesyncOffset() {
1030
+ if (!this.options.timesync) {
1031
+ console.warn(`getTimesyncOffset() requires options.timesync to be true.`);
1032
+ }
1033
+ return this.options.timesync ? this.cloudClient.getTimesyncOffset() : 0;
1034
+ }
1035
+ /**
1036
+ * Create OAuth URL
1037
+ * 💡 OAuth requires developers to register their apps with Neurosity
1038
+ * [Read full OAuth guide](/docs/oauth)
1039
+ *
1040
+ * Creates client-specific OAuth URL. This is the first step of the OAuth workflow. Use this function to create a URL you can use to redirect users to the Neurosity sign-in page.
1041
+ * 💡 This function is designed to only run on the server side for security reasons, as it requires your client secret.
1042
+ *
1043
+ * ```typescript
1044
+ * const { Neurosity } = require("@neurosity/sdk");
1045
+ *
1046
+ * const neurosity = new Neurosity({
1047
+ * autoSelectDevice: false
1048
+ * });
1049
+ *
1050
+ * exports.handler = async function (event) {
1051
+ * return neurosity
1052
+ * .createOAuthURL({
1053
+ * clientId: process.env.NEUROSITY_OAUTH_CLIENT_ID,
1054
+ * clientSecret: process.env.NEUROSITY_OAUTH_CLIENT_SECRET,
1055
+ * redirectUri: process.env.NEUROSITY_OAUTH_CLIENT_REDIRECT_URI,
1056
+ * responseType: "token",
1057
+ * state: Math.random().toString().split(".")[1],
1058
+ * scope: [
1059
+ * "read:devices-info",
1060
+ * "read:devices-status",
1061
+ * "read:signal-quality",
1062
+ * "read:brainwaves"
1063
+ * ]
1064
+ * })
1065
+ * .then((url) => ({
1066
+ * statusCode: 200,
1067
+ * body: JSON.stringify({ url })
1068
+ * }))
1069
+ * .catch((error) => ({
1070
+ * statusCode: 400,
1071
+ * body: JSON.stringify(error.response.data)
1072
+ * }));
1073
+ * };
1074
+ * ```
1075
+ * @returns custom token
1076
+ */
1077
+ createOAuthURL(config) {
1078
+ if (!isNode) {
1079
+ return Promise.reject(new Error(`${errors.prefix}the createOAuthURL method must be used on the server side (node.js) for security reasons.`));
1080
+ }
1081
+ return createOAuthURL(config, this.options);
1082
+ }
1083
+ /**
1084
+ * Get OAuth Token
1085
+ * 💡 OAuth requires developers to register their apps with Neurosity
1086
+ * [Read full OAuth guide](/docs/oauth)
1087
+ *
1088
+ * Gets client-specific OAuth token for a given userId.
1089
+ *
1090
+ * 💡 This function is designed to only run on the server side for security reasons, as it requires your client secret.
1091
+ * Here's an example of a cloud function that receives a `userId` via query params and loads the client id and client secret securely via environment variables.
1092
+ *
1093
+ *
1094
+ * ```typescript
1095
+ * const { Neurosity } = require("@neurosity/sdk");
1096
+ *
1097
+ * const neurosity = new Neurosity({
1098
+ * autoSelectDevice: false
1099
+ * });
1100
+ *
1101
+ * exports.handler = async function (event) {
1102
+ * const userId = event.queryStringParameters?.userId;
1103
+ *
1104
+ * return neurosity
1105
+ * .getOAuthToken({
1106
+ * clientId: process.env.NEUROSITY_OAUTH_CLIENT_ID,
1107
+ * clientSecret: process.env.NEUROSITY_OAUTH_CLIENT_SECRET,
1108
+ * userId
1109
+ * })
1110
+ * .then((token) => ({
1111
+ * statusCode: 200,
1112
+ * body: JSON.stringify(token)
1113
+ * }))
1114
+ * .catch((error) => ({
1115
+ * statusCode: 200,
1116
+ * body: JSON.stringify(error.response.data)
1117
+ * }));
1118
+ * };
1119
+ * ```
1120
+ * @returns custom token
1121
+ */
1122
+ getOAuthToken(query) {
1123
+ if (!isNode) {
1124
+ return Promise.reject(new Error(`${errors.prefix}the getOAuthToken method must be used on the server side (node.js) for security reasons.`));
1125
+ }
1126
+ return getOAuthToken(query, this.options);
1127
+ }
1128
+ /**
1129
+ * Remove OAuth Access
1130
+ * 💡 OAuth requires developers to register their apps with Neurosity
1131
+ * [Read full OAuth guide](/docs/oauth)
1132
+ *
1133
+ * Removes client-specific OAuth token for a given userId. Requires SDK to be signed in with OAuth custom token.
1134
+ *
1135
+ * ```typescript
1136
+ * await neurosity.removeOAuthAccess().catch((error) => {
1137
+ * // handle error here...
1138
+ * });
1139
+ * ```
1140
+ * @returns custom token
1141
+ */
1142
+ removeOAuthAccess() {
1143
+ return this.cloudClient.removeOAuthAccess();
1144
+ }
1145
+ /**
1146
+ * @internal
1147
+ * Proof of Concept for Skills - Not user facing yet
1148
+ *
1149
+ * Accesses a skill by Bundle ID. Additionally, allows to observe
1150
+ * and push skill metrics
1151
+ *
1152
+ * @param bundleId Bundle ID of skill
1153
+ * @returns Skill instance
1154
+ */
1155
+ skill(bundleId) {
1156
+ return __awaiter(this, void 0, void 0, function* () {
1157
+ if (!(yield this.cloudClient.didSelectDevice())) {
1158
+ return Promise.reject(errors.mustSelectDevice);
1159
+ }
1160
+ const skillData = yield this.cloudClient.skills.get(bundleId);
1161
+ if (skillData === null) {
1162
+ return Promise.reject(new Error(`${errors.prefix}Access denied for: ${bundleId}. Make sure the skill is installed.`));
1163
+ }
1164
+ return {
1165
+ metric: (label) => {
1166
+ const metricName = `skill~${skillData.id}~${label}`;
1167
+ const subscription = new Observable((observer) => {
1168
+ const subscription = this.cloudClient.metrics.subscribe({
1169
+ metric: metricName,
1170
+ labels: [label],
1171
+ atomic: true
1172
+ });
1173
+ const listener = this.cloudClient.metrics.on(subscription, (...data) => {
1174
+ observer.next(...data);
1175
+ });
1176
+ return () => {
1177
+ this.cloudClient.metrics.unsubscribe(subscription, listener);
1178
+ };
1179
+ }).pipe(map((metric) => metric[label]));
1180
+ Object.defineProperty(subscription, "next", {
1181
+ value: (metricValue) => {
1182
+ this.cloudClient.metrics.next(metricName, {
1183
+ [label]: metricValue
1184
+ });
1185
+ }
1186
+ });
1187
+ return subscription;
1188
+ }
1189
+ };
1190
+ });
1191
+ }
1192
+ /**
1193
+ * <StreamingModes wifi={true} />
1194
+ *
1195
+ * Observes and returns a list of all Kinesis `experiments` and all subsequent experiment changes.
1196
+ * Here's an example of how to get a list of all Kinesis labels that have been trained:
1197
+ *
1198
+ * ```typescript
1199
+ *
1200
+ * const getUniqueLabels = (experiments) => {
1201
+ * const labels = experiments.flatMap((experiment) => experiment.labels);
1202
+ * // only return unique labels
1203
+ * return [...new Set(labels)];
1204
+ * }
1205
+ *
1206
+ * neurosity.onUserExperiments().subscribe((experiments) => {
1207
+ * console.log(experiments);
1208
+ * console.log("labels", getUniqueLabels(experiments));
1209
+ * });
1210
+ *
1211
+ * // [{ id: '...', deviceId: '...', labels: [ 'drop' ], name: 'Lightgray cheetah', timestamp: 1577908381552, totalTrials: 16, userId: '...' }]
1212
+ * // ["drop", "lift", "push"]
1213
+ * ```
1214
+ *
1215
+ * @returns Observable of `experiments` events
1216
+ */
1217
+ onUserExperiments() {
1218
+ return this.cloudClient.onUserExperiments();
1219
+ }
1220
+ /**
1221
+ * <StreamingModes wifi={true} />
1222
+ *
1223
+ * Deletes a specific experiment provided an experiment ID
1224
+ *
1225
+ * ```typescript
1226
+ * await neurosity.deleteUserExperiment(experiment.id);
1227
+ * ```
1228
+ *
1229
+ * @param experimentId The ID of the Experiment
1230
+ * @returns void
1231
+ */
1232
+ deleteUserExperiment(experimentId) {
1233
+ return this.cloudClient.deleteUserExperiment(experimentId);
1234
+ }
1235
+ }
1236
+ /**
1237
+ *
1238
+ * @hidden
1239
+ */
1240
+ Neurosity.credentialWithLink = credentialWithLink;
1241
+ /**
1242
+ *
1243
+ * @hidden
1244
+ */
1245
+ Neurosity.createUser = createUser;
1246
+ /**
1247
+ *
1248
+ * @hidden
1249
+ */
1250
+ Neurosity.SERVER_TIMESTAMP = SERVER_TIMESTAMP;
1251
+ /**
1252
+ * @hidden
1253
+ * Deprecated class kept for backwards compatibility purposes.
1254
+ */
1255
+ export class Notion extends Neurosity {
1256
+ constructor(options = {}) {
1257
+ super(options);
1258
+ console.log(`The Notion class is deprecated and will be removed in the next version of the SDK. Please use the Neurosity class instead. e.g. new Notion() => new Neurosity()`);
1259
+ }
1260
+ }