UNPKG

@neurosity/sdk

Version:
646 lines (643 loc) 19.4 kB
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";