8.5.0 • Published 6 days ago

@corva/node-sdk v8.5.0

Weekly downloads
-
License
UNLICENSED
Repository
-
Last release
6 days ago

node-sdk

Corva node-sdk is a framework for building Corva DevCenter apps.

Contents

Requirements

Node.js 12+

Installation

$ npm i @corva/node-sdk

App types

There are 4 app types that you can build:

  1. stream - works with real-time data
  2. scheduled - works with data at defined schedules/intervals (e. g. once an hour)
  3. task - works with data on-demand

Note: Use type hints like those in the examples below for better support from editors and tools.

Stream

/* eslint-disable camelcase */
import { StreamEventHandler, Corva } from '@corva/node-sdk';

const streamApp: StreamEventHandler<any, void> = async (event, { api }) => {
    // get some data from api
    const { body: drillstrings } = await api.request<DrillStringRecord[]>(
        'api/v1/data/corva/data.drillstring/',
        {
            searchParams: {
                query: JSON.stringify({ asset_id: event.asset_id }),
                sort: JSON.stringify({ timestamp: 1 }),
                limit: 1,
            },
        }
    );

    // do some calculations/modifications to the data
    const total = drillstrings.reduce((acc, drillstring) => acc + drillstring.data.bit_depth, 0);
    const average = total / drillstrings.length;

    // save the data to private collection
    await api.request('api/v1/data/my_provider/my_collection/', {
        method: 'POST',
        json: [
            {
                timestamp: Date.now() / 1000,
                company_id: 42,
                asset_id: 42,
                version: 1,
                data: { average },
            },
        ],
    });
};

exports.handler = new Corva().stream(streamApp, {
  appKey: 'app-key',
  name: 'app-name',
  provider: 'app-provider',
});

Corva#stream provides an optional parameter:

  • filteringMode - set to timestamp or depth to clear event data with previously processed timestamp or measured_depth to prevent duplicate records.

Scheduled

import { ScheduledEventHandler, Corva } from '@corva/node-sdk';

const scheduledApp: ScheduledEventHandler<{ status: string }> = async (
    event,
    { api, logger }
) => {
  const queryTo = Math.floor(event.schedule_start / 1000);
  const { body: records } = await api.request('api/v1/data/my_provider/my_collection/', {
      method: 'GET',
      searchParams: {
          query: JSON.stringify({
              asset_id: event.asset_id,
              timestamp: {
                  $gt: queryTo - event.interval,
                  $lte: queryTo,
              },
          }),
          sort: JSON.stringify({ timestamp: 1 }),
          limit: 100,
          skip: 0,
      },
  });

  logger.info(records);

  return { status: 'OK' };
};

export const handler = new Corva().scheduled(scheduledApp);

Task

/* eslint-disable camelcase */
import { Corva, TaskEventHandler } from '@corva/node-sdk';

interface TaskProps {
    some: { input: string };
}

interface DatasetRecord {
    data: { foo: string };
}

interface TaskOutput {
    opts: string;
    some: {
        output: DatasetRecord[];
    };
}

const timezonesShift = {
    'America/Chicago': 6,
};

const taskApp: TaskEventHandler<TaskProps, TaskOutput> = async (event, { api }) => {
    // get some data from api
    const settings = await api.getAppSettings();
    // now - 7 days + timezone shift
    const timestampToLoadDataFrom =
        Date.now() / 1000 - 7 * 24 * 60 * 60 + timezonesShift[settings.timezone] || 0;

    const results = await api.getDataset<DatasetRecord>({
        dataset: 'some-dataset',
        query: {
            timestamp: { $gte: timestampToLoadDataFrom },
        },
        sort: { timestamp: 1 },
        limit: 1000,
        fields: ['data.foo'],
    });

    return {
        opts: event.properties.some.input,
        some: { output: results },
    };
};

export const handler = new Corva().task(taskApp);

Event

An event is an object that contains data for an app function to process. event instance is inserted automatically as the first parameter to each app type. There are different event types for every app type: StreamLambdaEvent, ScheduledLambdaEvent, and Task.

Api Client

Apps might need to communicate with the Corva Platform API and Corva Data API. This SDK provides an CorvaDataSource class, which is node-api-client and based on got

Examples:

import { ScheduledEventHandler, Corva } from '@corva/node-sdk';

const scheduledApp: ScheduledEventHandler<{ status: string }> = async (event, { api }) => {
  // Corva API calls
  await api.request('/v2/pads', {
    searchParams: { param: 'val' },
  });
  await api.request('/v2/pads', {
    method: 'POST',
    json: { key: 'val' },
  });
  await api.request('/v2/pads', {
    method: 'PUT',
    json: { key: 'val' },
  });
  await api.request('/v2/pads', {
    method: 'DELETE',
  });

  // Corva Data API calls
  await api.request('api/v1/data/provider/dataset/', {
    searchParams: { param: 'val' },
  });
  await api.request('api/v1/data/provider/dataset/', {
    method: 'POST',
    json: { key: 'val' },
  });
  await api.request('api/v1/data/provider/dataset/', {
    method: 'PUT',
    json: { key: 'val' },
  });
  await api.request('api/v1/data/provider/dataset/', {
    method: 'DELETE',
  });

  return { status: 'OK' };
};

export const handler = new Corva().scheduled(scheduledApp);

Cache

Apps might need to share some data between runs. The SDK provides a Cache class that allows you to store, load, and do other operations with data. Cache instance is inserted automatically to stream and scheduled apps. Note: task apps don't get a Cache parameter as they aren't meant to store data between invokes.

Cache uses a dict-like database, so the data is stored as key:value pairs. key should be of string type, and value can have any of the following types: string, Buffer, number,any[].

Examples:

See source codes.

Store and load:

import { ScheduledEventHandler, Corva } from '@corva/node-sdk';

const scheduledApp: ScheduledEventHandler<{ status: string }> = async (event, { cache }) => {
  await cache.store({ key: 'val' });

  // val
  const res = await cache.load('key');

  return { status: 'OK' };
};

export const handler = new Corva().scheduled(scheduledApp);

Store and load multiple:

import { ScheduledEventHandler, Corva } from '../../lib';

const scheduledApp: ScheduledEventHandler<{ status: string }> = async (event, { cache }) => {
  await cache.store({ key1: 'val1', key2: 'val2', key3: 'val3' });

  // { key1: 'val1', key2: 'val2' }
  const res = await cache.loadAll();

  return { status: 'OK' };
};

export const handler = new Corva().scheduled(scheduledApp);

Delete and delete all:

import { ScheduledEventHandler, Corva } from '@corva/node-sdk';

const scheduledApp: ScheduledEventHandler<{ status: string }> = async (event, { cache }) => {
  await cache.store({ key1: 'val1', key2: 'val2', key3: 'val3' });
  // cache: { key1: 'val1', key2: 'val2', key3: 'val3' }

  await cache.delete('key1');
  // cache: { key2: 'val2', key3: 'val3' }

  await cache.deleteAll();
  // cache: {}

  return { status: 'OK' };
};

export const handler = new Corva().scheduled(scheduledApp);

Expiry, TTL, and exists.

Note: by default, Cache sets an expiry to 60 days.

import { ScheduledEventHandler, Corva } from '../../lib';

const sleep = (seconds: number) => new Promise((resolve) => setTimeout(resolve, seconds * 1000));

const scheduledApp: ScheduledEventHandler<{ status: string }> = async (event, { cache }) => {
  await cache.store({ key1: 'val1', key2: 'val2', key3: 'val3' }, 60 /* seconds */);
  // cache: { key1: 'val1', key2: 'val2', key3: 'val3' }

  await cache.ttl(); // 60 seconds
  await cache.pttl(); // 60000 milliseconds
  await cache.exists(); // true

  await sleep(60);
  // cache: {}

  await cache.exists(); // false
  await cache.ttl(); // -2: doesn't exist
  await cache.pttl(); // -2: doesn't exist

  return { status: 'OK' };
};

export const handler = new Corva().scheduled(scheduledApp);

Contributing

Set up the project

$ cd ~/YOUR_PATH/node-sdk
$ npm ci

Run tests

$ npm test

Run code linter

$ npm run lint
8.6.0-rc.10

6 days ago

8.6.0-rc.9

25 days ago

8.6.0-rc.8

1 month ago

8.6.0-rc.7

1 month ago

8.6.0-rc.559

1 month ago

8.6.0-rc.558

1 month ago

8.6.0-rc.557

1 month ago

8.6.0-rc.556

2 months ago

8.6.0-rc.6

2 months ago

8.6.0-rc.5

2 months ago

8.6.0-rc.4

2 months ago

8.6.0-rc.3

2 months ago

8.6.0-rc.2

3 months ago

8.6.0-rc.1

3 months ago

8.6.0-rc.0

3 months ago

8.5.1-rc.4

5 months ago

8.5.1-rc.1

5 months ago

8.5.1-rc.0

5 months ago

8.5.1-rc.3

5 months ago

8.5.1-rc.2

5 months ago

8.5.0-rc.6

5 months ago

8.5.0

5 months ago

8.5.0-rc.5

5 months ago

8.5.0-rc.4

5 months ago

8.5.0-rc.3

5 months ago

8.5.0-rc.1

6 months ago

8.5.0-rc.2

5 months ago

8.4.1

7 months ago

8.4.0

8 months ago

8.4.0-rc.5

8 months ago

8.4.0-rc.4

8 months ago

8.4.0-rc.3

9 months ago

8.4.0-rc.1

10 months ago

8.4.0-rc.0

10 months ago

8.4.2-rc.1

7 months ago

8.4.2-rc.0

7 months ago

8.4.2-rc.6

6 months ago

8.4.2-rc.3

7 months ago

8.4.2-rc.2

7 months ago

8.4.2-rc.5

7 months ago

8.4.2-rc.4

7 months ago

8.5.0-rc.0

6 months ago

8.2.1

1 year ago

8.2.0

1 year ago

8.3.0-rc.0

1 year ago

8.3.0-rc.1

1 year ago

8.3.0-rc.2

1 year ago

8.3.0-rc.3

1 year ago

8.3.0-rc.4

1 year ago

8.3.0

11 months ago

8.2.0-rc.3

1 year ago

8.2.0-rc.1

1 year ago

8.2.0-rc.2

1 year ago

8.1.0-rc.4

1 year ago

8.1.0-rc.3

1 year ago

8.1.0-rc.6

1 year ago

8.1.0-rc.5

1 year ago

8.1.0

1 year ago

8.2.0-rc.0

1 year ago

8.1.0-rc.0

1 year ago

8.1.0-rc.2

1 year ago

8.1.0-rc.1

1 year ago

8.0.3

1 year ago

8.0.0-rc.10

1 year ago

8.0.0-rc.13

1 year ago

8.0.0-rc.11

1 year ago

8.0.0-rc.12

1 year ago

8.0.3-rc.0

1 year ago

8.0.1

1 year ago

8.0.0

1 year ago

8.0.2

1 year ago

7.2.0-rc.7

1 year ago

7.2.0-rc.6

1 year ago

7.2.0-rc.5

1 year ago

8.0.0-rc.0

1 year ago

8.0.0-rc.1

1 year ago

8.0.0-rc.2

1 year ago

8.0.0-rc.3

1 year ago

8.0.0-rc.8

1 year ago

8.0.0-rc.9

1 year ago

8.0.0-rc.4

1 year ago

8.0.0-rc.5

1 year ago

8.0.0-rc.6

1 year ago

7.2.0

1 year ago

8.0.0-rc.7

1 year ago

7.2.0-rc.4

2 years ago

7.1.1-rc.1

2 years ago

7.1.1-rc.0

2 years ago

7.0.0

2 years ago

7.1.1

2 years ago

7.1.0

2 years ago

7.2.0-rc.0

2 years ago

7.2.0-rc.3

2 years ago

7.2.0-rc.2

2 years ago

7.2.0-rc.1

2 years ago

7.0.0-rc.9

2 years ago

7.0.0-rc.8

2 years ago

7.0.0-rc.7

2 years ago

7.0.0-rc.4

2 years ago

7.0.0-rc.3

2 years ago

7.0.0-rc.6

2 years ago

7.0.0-rc.5

2 years ago

7.0.0-rc.0

2 years ago

7.0.0-rc.2

2 years ago

7.0.0-rc.1

2 years ago

6.4.0-rc.4

2 years ago

6.4.0-rc.5

2 years ago

6.4.0-rc.3

2 years ago

6.4.0-rc.6

2 years ago

6.3.0

2 years ago

6.2.1

2 years ago

6.4.0-rc.1

2 years ago

6.3.0-rc.4

2 years ago

6.4.0-rc.2

2 years ago

6.3.0-rc.5

2 years ago

6.3.0-rc.3

2 years ago

6.3.0-rc.2

2 years ago

6.3.0-rc.1

2 years ago

6.1.0

2 years ago

6.1.1-rc.0

2 years ago

6.2.0

2 years ago

6.3.0-rc.0

2 years ago

6.2.0-rc.0

2 years ago

6.2.0-rc.1

2 years ago

6.2.0-rc.2

2 years ago

6.1.0-rc.2

2 years ago

6.2.0-rc.3

2 years ago

6.1.0-rc.1

2 years ago

6.1.0-rc.8

2 years ago

6.1.0-rc.7

2 years ago

6.2.0-rc.4

2 years ago

6.1.0-rc.4

2 years ago

6.1.0-rc.3

2 years ago

6.1.0-rc.6

2 years ago

6.1.0-rc.5

2 years ago

6.0.2-rc.1

2 years ago

6.0.2-rc.0

2 years ago

6.0.2-rc.2

2 years ago

5.6.4

2 years ago

5.6.3

2 years ago

5.6.2

2 years ago

5.6.1

2 years ago

5.6.0

2 years ago

6.0.1

2 years ago

6.0.0

2 years ago

6.1.0-rc.0

2 years ago

6.0.0-rc.0

2 years ago

5.5.0

3 years ago

5.4.4

3 years ago

5.4.2

3 years ago

5.4.3

3 years ago

5.4.1

3 years ago

5.4.0

3 years ago

5.3.1

3 years ago

5.3.0

3 years ago

5.2.0

3 years ago

5.1.0

3 years ago

5.0.0

3 years ago

4.0.1

3 years ago

4.0.0

3 years ago

2.1.1

3 years ago

2.1.0

3 years ago

2.0.0

3 years ago

1.5.9

3 years ago

1.5.8

3 years ago

1.5.7

3 years ago

1.5.6

3 years ago

1.5.5

3 years ago

1.4.6

3 years ago

1.5.4

3 years ago

1.4.5

3 years ago

1.5.3

3 years ago

1.5.2

3 years ago

1.5.1

3 years ago

1.5.0

3 years ago

1.4.9

3 years ago

1.4.8

3 years ago

1.4.7

3 years ago

1.4.4

3 years ago

1.4.3

3 years ago

1.4.2

3 years ago

1.4.1

3 years ago

1.4.0

3 years ago

1.3.0

3 years ago

1.2.0

3 years ago

1.1.0

3 years ago

1.1.0-rc.1

3 years ago

1.1.0-rc.0

3 years ago

1.0.10

3 years ago

1.0.9

3 years ago

1.0.8

3 years ago

1.0.7

3 years ago

1.0.6

3 years ago

1.0.5

3 years ago

1.0.0

3 years ago