@neurosity/sdk
Version:
Neurosity SDK
646 lines (643 loc) • 19.4 kB
TypeScript
import { Observable } from "rxjs";
import { CloudClient, createUser } from "./api/index";
import { SDKOptions } from "./types/options";
import { STREAMING_MODE, STREAMING_TYPE } from "./types/streaming";
import { Training } from "./types/training";
import { Credentials } from "./types/credentials";
import { Settings } from "./types/settings";
import { SignalQuality } from "./types/signalQuality";
import { Kinesis } from "./types/kinesis";
import { Calm } from "./types/calm";
import { Focus } from "./types/focus";
import { BrainwavesLabel, Epoch, PowerByBand, PSD } from "./types/brainwaves";
import { Accelerometer } from "./types/accelerometer";
import { DeviceInfo, OSVersion } from "./types/deviceInfo";
import { DeviceStatus } from "./types/status";
import { Action } from "./types/actions";
import { HapticEffects } from "./types/hapticEffects";
import { OAuthConfig, OAuthQuery } from "./types/oauth";
import { OAuthQueryResult, OAuthRemoveResponse } from "./types/oauth";
import { Experiment } from "./types/experiment";
import { BluetoothClient } from "./api/bluetooth";
/**
* import StreamingModes from "@site/src/components/StreamingModes";
*
* Example
* ```typescript
* import { Neurosity } from "@neurosity/sdk";
*
* const neurosity = new Neurosity();
* ```
*/
export declare class Neurosity {
/**
* @hidden
*/
protected options: SDKOptions;
/**
* @hidden
*/
protected cloudClient: CloudClient;
/**
* @hidden
*/
protected bluetoothClient: BluetoothClient;
/**
* @hidden
*/
protected isMissingBluetoothTransport: boolean;
/**
* @hidden
*/
private streamingMode$;
/**
*
* @hidden
*/
static credentialWithLink: Function;
/**
*
* @hidden
*/
static createUser: typeof createUser;
/**
*
* @hidden
*/
static SERVER_TIMESTAMP: Object;
/**
* Creates new instance of the Neurosity SDK
*
* ```typescript
* const neurosity = new Neurosity();
* ```
* @param options
*/
constructor(options?: SDKOptions);
/**
*
* @hidden
*/
_initStreamingMode(streamingMode: STREAMING_MODE, hasBluetoothTransport: boolean): void;
/**
*
* @hidden
*/
_osHasBluetoothSupport(): Observable<any>;
/**
* Subscribe to the device's streaming state changes and the current strategy
*
* Streams the current mode of streaming (wifi or bluetooth).
*
* ```typescript
* neurosity.streamingState().subscribe((streamingState) => {
* console.log(streamingState);
* // { streamingMode: "wifi-only", activeMode: "wifi", connected: true }
* });
* ```
*/
streamingState(): Observable<{
connected: boolean;
activeMode: STREAMING_TYPE;
streamingMode: STREAMING_MODE;
}>;
/**
*
* @hidden
*/
_withStreamingModeObservable<T>(streams: {
wifi: () => Observable<T>;
bluetooth: () => Observable<T>;
}): Observable<any>;
/**
*
* @hidden
*/
_withStreamingModePromise<T>(promises: {
wifi: () => Promise<T>;
bluetooth: () => Promise<T>;
}): Promise<T>;
/**
*
* @hidden
*/
get bluetooth(): BluetoothClient;
/**
*
* @hidden
*/
private _getCloudMetricDependencies;
/**
* Starts user session
*
* ```typescript
* await neurosity.login({
* email: "...",
* password: "..."
* });
* ```
*
* @param credentials
*/
login(credentials: Credentials): Promise<void>;
/**
* Ends user session
*
* ```typescript
* await neurosity.logout();
* // session has ended
* ```
*
*/
logout(): Promise<void>;
/**
* Subscribe to auth state changes
*
* 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.
*
* ```typescript
* neurosity.onAuthStateChanged().subscribe((user) => {
* console.log(user);
* });
* ```
*/
onAuthStateChanged(): Observable<any>;
/**
* Get user devices
*
* Returns a list of devices claimed by the user authenticated.
*
* ```typescript
* const devices = await neurosity.getDevices();
* console.log(devices);
* ```
*/
getDevices(): Promise<DeviceInfo[]>;
/**
* Select Device
*
* Rarely necessary, but useful when the user owns multiple devices.
*
* 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.
*
* The 3 steps to manually selecting a device are:
*
* - Set `autoSelectDevice` to false when instantiating the `Neurosity` class.
* - Authenticate with your Neurosity account to access your devices by calling the `neurosity.login(...)` function.
* - Call the `neurosity.selectDevice(...)` function with a device selector function.
*
* ```typescript
* const devices = await neurosity.selectDevice((devices) =>
* devices.find((device) => device.deviceNickname === "Crown-A1B")
* );
*
* console.log(devices);
* ```
*
* > If you own multiple devices, and don't pass `autoSelectDevice`, then the first device on the list will be automatically selected.
*
* For more info, check out the "Device Selection" guide.
*/
selectDevice(deviceSelector: (devices: DeviceInfo[]) => DeviceInfo): Promise<DeviceInfo>;
/**
* Get selected device
*
* ```typescript
* const selectedDevice = await neurosity.getSelectedDevice();
* console.log(selectedDevice);
* ```
*/
getSelectedDevice(): Promise<DeviceInfo>;
/**
* ```typescript
* const info = await neurosity.getInfo();
* ```
*/
getInfo(): Promise<DeviceInfo>;
/**
* Observes selected device
*
* ```typescript
* neurosity.onDeviceChange().subscribe(device => {
* console.log(device);
* });
* ```
*/
onDeviceChange(): Observable<DeviceInfo>;
/**
* <StreamingModes wifi={true} bluetooth={true} />
*
* Ends database connection
*
* ```typescript
* await neurosity.disconnect();
* ```
*/
disconnect(): Promise<void>;
/**
* <StreamingModes wifi={true} bluetooth={true} />
*
* Injects an EEG marker to data stream
*
* ```typescript
* neurosity.addMarker("eyes-closed");
*
* // later...
*
* neurosity.addMarker("eyes-open");
* ```
*
* @param label Name the label to inject
*/
addMarker(label: string): Promise<Action>;
/**
* <StreamingModes wifi={true} bluetooth={true} />
*
* Queue haptic motor commands
*
* To queue haptic P7 only,
* ```typescript
* await neurosity.haptics({
* P7: ["tripleClick100"]
* });
* ```
*
* To queue both motors at the same time
* ```typescript
* await neurosity.haptics({
* P7: [neurosity.getHapticEffects().strongClick100],
* P8: [neurosity.getHapticEffects().strongClick100]
* });
* ```
*
* You can queue different commands to the motors too
* ```typescript
* const effects = neurosity.getHapticEffects();
* await neurosity.haptics({
* P7: [effects.transitionRampUpLongSmooth1_0_to_100,
* effects.transitionRampDownLongSmooth1_100_to_0],
* P8: [effects.strongClick100]
* });
* ```
*
* @param effects Effects to queue. The key of the object passed should be the location of the motor
* to queue. Each key can be an array of up to 7 commands. There is no haptic support for model
* version 1, Notion DK1. The Haptic motor's location is positioned in reference to the 10-10 EEG
* system used to label the channels of the Crown's EEG sensors. Notion 2 and Crown have haptics
* at P7 and P8. A list of haptic commands can be found on ./utils/hapticCodes.ts - there
* are about 127 of them!
*/
haptics(effects: any): Promise<any>;
/**
* ```typescript
* const effects = neurosity.getHapticEffects();
* ```
*/
getHapticEffects(): HapticEffects;
/**
* <StreamingModes wifi={true} bluetooth={true} />
*
* Observes accelerometer data
* Supported by the Crown and Notion 2 devices.
*
* ```typescript
* neurosity.accelerometer().subscribe(accelerometer => {
* console.log(accelerometer);
* });
*
* // { acceleration: ..., inclination: ..., orientation: ..., pitch: ..., roll: ..., x: ..., y: ..., z: ... }
* ```
*
* @returns Observable of accelerometer metric events
*/
accelerometer(): Observable<Accelerometer>;
/**
* <StreamingModes wifi={true} bluetooth={true} />
*
* The `raw` brainwaves parameter emits epochs of 16 samples for Crown and 25 for Notion 1 and 2.
*
* Example
* ```typescript
* neurosity.brainwaves("raw").subscribe(brainwaves => {
* console.log(brainwaves);
* });
* ```
*
* Raw Unfiltered - The `rawUnfiltered` brainwaves parameter emits epochs of 16 samples for Crown and 25 for Notion 1 and 2.
* Example
* ```typescript
* neurosity.brainwaves("rawUnfiltered").subscribe(brainwaves => {
* console.log(brainwaves);
* });
* ```
*
* 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.
*
* Example
* ```typescript
* neurosity.brainwaves("powerByBand").subscribe(brainwaves => {
* console.log(brainwaves);
* });
* ```
*
* 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).
*
* Example
* ```typescript
* neurosity.brainwaves("psd").subscribe(brainwaves => {
* console.log(brainwaves);
* });
* ```
*
* @param label Name of metric properties to filter by
* @returns Observable of brainwaves metric events
*/
brainwaves(label: BrainwavesLabel): Observable<Epoch | PowerByBand | PSD>;
/**
* <StreamingModes wifi={true} bluetooth={true} />
*
* Example
* ```typescript
* neurosity.calm().subscribe(calm => {
* console.log(calm.probability);
* });
*
* // 0.45
* // 0.47
* // 0.53
* // 0.51
* // ...
* ```
*
* @returns Observable of calm events - awareness/calm alias
*/
calm(): Observable<Calm>;
/**
* <StreamingModes wifi={true} bluetooth={true} />
*
* Observes signal quality data where each property is the name
* of the channel and the value includes the standard deviation and
* a status set by the device
*
* ```typescript
* neurosity.signalQuality().subscribe(signalQuality => {
* console.log(signalQuality);
* });
*
* // { FC6: { standardDeviation: 3.5, status: "good" }, C3: {...}, ... }
* ```
*
* @returns Observable of signalQuality metric events
*/
signalQuality(): Observable<SignalQuality>;
/**
* <StreamingModes wifi={true} />
*
* Observes last state of `settings` and all subsequent `settings` changes
*
* ```typescript
* neurosity.settings().subscribe(settings => {
* console.log(settings.lsl);
* });
*
* // true
* // ...
* ```
*
* @returns Observable of `settings` metric events
*/
settings(): Observable<Settings>;
/**
* <StreamingModes wifi={true} />
*
* Observes the current OS version and all subsequent version changes in real-time.
*
* ```typescript
* neurosity.osVersion().subscribe((osVersion) => {
* console.log(osVersion);
* });
*
* // "16.0.0"
* ```
*
* @returns Observable of `osVersion` events. e.g 16.0.0
*/
osVersion(): Observable<OSVersion>;
/**
* <StreamingModes wifi={true} bluetooth={true} />
*
* Example
* ```typescript
* neurosity.focus().subscribe(focus => {
* console.log(focus.probability);
* });
*
* // 0.56
* // 0.46
* // 0.31
* // 0.39
* // ...
* ```
*
* @returns Observable of focus events - awareness/focus alias
*/
focus(): Observable<Focus>;
/**
* <StreamingModes wifi={true} />
*
* @param label Name of metric properties to filter by
* @returns Observable of kinesis metric events
*/
kinesis(label: string): Observable<Kinesis>;
/**
* <StreamingModes wifi={true} />
*
* @param label Name of metric properties to filter by
* @returns Observable of predictions metric events
*/
predictions(label: string): Observable<any>;
/**
* <StreamingModes wifi={true} bluetooth={true} />
*
* Observes last state of `status` and all subsequent `status` changes
*
* ```typescript
* neurosity.status().subscribe(status => {
* console.log(status.state);
* });
*
* // "online"
* // ...
* ```
*
* @returns Observable of `status` metric events
*/
status(): Observable<DeviceStatus>;
/**
* <StreamingModes wifi={true} />
*
* ```typescript
* neurosity.training.record({
* metric: "kinesis",
* label: "push"
* });
*
* neurosity.training.stop({
* metric: "kinesis",
* label: "push"
* });
* ```
*
* @returns Training methods
*/
get training(): Training;
/**
* Create OAuth URL
* 💡 OAuth requires developers to register their apps with Neurosity
* [Read full OAuth guide](/docs/oauth)
*
* 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.
* 💡 This function is designed to only run on the server side for security reasons, as it requires your client secret.
*
* ```typescript
* const { Neurosity } = require("@neurosity/sdk");
*
* const neurosity = new Neurosity({
* autoSelectDevice: false
* });
*
* exports.handler = async function (event) {
* return neurosity
* .createOAuthURL({
* clientId: process.env.NEUROSITY_OAUTH_CLIENT_ID,
* clientSecret: process.env.NEUROSITY_OAUTH_CLIENT_SECRET,
* redirectUri: process.env.NEUROSITY_OAUTH_CLIENT_REDIRECT_URI,
* responseType: "token",
* state: Math.random().toString().split(".")[1],
* scope: [
* "read:devices-info",
* "read:devices-status",
* "read:signal-quality",
* "read:brainwaves"
* ]
* })
* .then((url) => ({
* statusCode: 200,
* body: JSON.stringify({ url })
* }))
* .catch((error) => ({
* statusCode: 400,
* body: JSON.stringify(error.response.data)
* }));
* };
* ```
* @returns custom token
*/
createOAuthURL(config: OAuthConfig): Promise<string>;
/**
* Get OAuth Token
* 💡 OAuth requires developers to register their apps with Neurosity
* [Read full OAuth guide](/docs/oauth)
*
* Gets client-specific OAuth token for a given userId.
*
* 💡 This function is designed to only run on the server side for security reasons, as it requires your client secret.
* 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.
*
*
* ```typescript
* const { Neurosity } = require("@neurosity/sdk");
*
* const neurosity = new Neurosity({
* autoSelectDevice: false
* });
*
* exports.handler = async function (event) {
* const userId = event.queryStringParameters?.userId;
*
* return neurosity
* .getOAuthToken({
* clientId: process.env.NEUROSITY_OAUTH_CLIENT_ID,
* clientSecret: process.env.NEUROSITY_OAUTH_CLIENT_SECRET,
* userId
* })
* .then((token) => ({
* statusCode: 200,
* body: JSON.stringify(token)
* }))
* .catch((error) => ({
* statusCode: 200,
* body: JSON.stringify(error.response.data)
* }));
* };
* ```
* @returns custom token
*/
getOAuthToken(query: OAuthQuery): Promise<OAuthQueryResult>;
/**
* Remove OAuth Access
* 💡 OAuth requires developers to register their apps with Neurosity
* [Read full OAuth guide](/docs/oauth)
*
* Removes client-specific OAuth token for a given userId. Requires SDK to be signed in with OAuth custom token.
*
* ```typescript
* await neurosity.removeOAuthAccess().catch((error) => {
* // handle error here...
* });
* ```
* @returns custom token
*/
removeOAuthAccess(): Promise<OAuthRemoveResponse>;
/**
* <StreamingModes wifi={true} />
*
* Observes and returns a list of all Kinesis `experiments` and all subsequent experiment changes.
* Here's an example of how to get a list of all Kinesis labels that have been trained:
*
* ```typescript
*
* const getUniqueLabels = (experiments) => {
* const labels = experiments.flatMap((experiment) => experiment.labels);
* // only return unique labels
* return [...new Set(labels)];
* }
*
* neurosity.onUserExperiments().subscribe((experiments) => {
* console.log(experiments);
* console.log("labels", getUniqueLabels(experiments));
* });
*
* // [{ id: '...', deviceId: '...', labels: [ 'drop' ], name: 'Lightgray cheetah', timestamp: 1577908381552, totalTrials: 16, userId: '...' }]
* // ["drop", "lift", "push"]
* ```
*
* @returns Observable of `experiments` events
*/
onUserExperiments(): Observable<Experiment[]>;
/**
* <StreamingModes wifi={true} />
*
* Deletes a specific experiment provided an experiment ID
*
* ```typescript
* await neurosity.deleteUserExperiment(experiment.id);
* ```
*
* @param experimentId The ID of the Experiment
* @returns void
*/
deleteUserExperiment(experimentId: string): Promise<void>;
}
/**
* @hidden
* Deprecated class kept for backwards compatibility purposes.
*/
export declare class Notion extends Neurosity {
constructor(options?: SDKOptions);
}
/**
* @hidden
* Internal use only. Will be removed in next versions.
*/
export { __firebase } from "./api/firebase";