Skip to content

Commit

Permalink
feat: setup stream API class and workspace
Browse files Browse the repository at this point in the history
  • Loading branch information
Christian Bedon committed Jan 25, 2024
1 parent 39934dc commit 54b03db
Show file tree
Hide file tree
Showing 10 changed files with 6,480 additions and 3,273 deletions.
Empty file added @kiva/kv-stream/CHANGELOG.md
Empty file.
45 changes: 45 additions & 0 deletions @kiva/kv-stream/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
# kv-stream

A library of methods for web analytics on Kiva.org.

## Install

Deployed:

```bash
npm i @kiva/kv-stream
```

Local:

```bash
# Open kv-ui-elements folder in Terminal
npm link -w @kiva/kv-stream

# Open target local project folder in Terminal
npm link @kiva/kv-stream
```

## Lint

```bash
npm run lint
```

## Build

```bash
npm run build
```

## Test

```bash
npm test
```

## Contribution Guidelines

The Kiva UI project is bound by a [Code of Conduct](https://github.com/kiva/ui/blob/master/code_of_conduct.md).

Kiva welcomes outside contributions to our UI repository. If you have any ideas for a feature or improvement, create an issue and we can discuss whether it makes sense to create a pull request. Thanks for the help!
4 changes: 4 additions & 0 deletions @kiva/kv-stream/jest.config.cjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
module.exports = {
preset: 'ts-jest',
testEnvironment: 'jsdom',
};
46 changes: 46 additions & 0 deletions @kiva/kv-stream/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
{
"name": "@kiva/kv-stream",
"version": "1.0.0",
"type": "module",
"publishConfig": {
"access": "public"
},
"main": "dist/index.cjs",
"module": "dist/index.js",
"types": "dist/index.d.ts",
"files": [
"dist"
],
"exports": {
".": {
"require": "./dist/index.cjs",
"import": "./dist/index.js",
"types": "./dist/index.d.ts"
}
},
"scripts": {
"build": "tsup src/*.ts --format cjs,esm --dts --clean",
"lint": "eslint --ext .ts,.vue ./src",
"test": "jest"
},
"repository": {
"type": "git",
"url": "git+https://github.com/kiva/kv-ui-elements.git"
},
"bugs": {
"url": "https://github.com/kiva/kv-ui-elements/issues"
},
"homepage": "https://github.com/kiva/kv-ui-elements#readme",
"devDependencies": {
"@typescript-eslint/eslint-plugin": "^6.13.1",
"@typescript-eslint/parser": "^6.13.1",
"jest": "^29.7.0",
"jest-environment-jsdom": "^29.7.0",
"ts-jest": "^29.1.1",
"tsup": "^6.7.0",
"typescript": "^5.3.2"
},
"dependencies": {
"getstream": "^8.0.1"
}
}
55 changes: 55 additions & 0 deletions @kiva/kv-stream/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import {
connect,
StreamClient,
GetFeedOptions,
NewActivity,
StreamFeed,
FeedAPIResponse,
Activity,
APIResponse,
} from 'getstream';

export class StreamService {
private client: StreamClient;

/**
* Creates an instance of StreamService.
*
* @param {string} apiKey - The GetStream.io API key.
* @param {string} authToken - The auth user token.
* @param {string} appId - The GetStream.io App id.
*/
constructor(apiKey: string, authToken: string, appId: string) {
this.client = connect(apiKey, authToken, appId);
}

createUserFeed(userId: string): StreamFeed {
return this.client.feed('user', userId);
}

followUser(
sourceUserId: string,
targetSlug: string,
targetUserId: string,
options: { limit?: number } = {}
): Promise<APIResponse> {
const sourceFeed = this.createUserFeed(sourceUserId);
const targetFeed = this.createUserFeed(targetUserId);

return sourceFeed.follow(targetSlug, targetFeed, options);
}

static addActivity(
feed: StreamFeed,
activity: NewActivity
): Promise<Activity> {
return feed.addActivity(activity);
}

static getActivity(
feed: StreamFeed,
params: GetFeedOptions
): Promise<FeedAPIResponse> {
return feed.get(params);
}
}
91 changes: 91 additions & 0 deletions @kiva/kv-stream/src/tests/StreamService.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
import { StreamService } from '../index';

const mockFollow = jest.fn(() => Promise.resolve());
const mockAddActivity = jest.fn(() => Promise.resolve());
const mockGet = jest.fn(() => Promise.resolve({ results: [] }));

const mockFeed = jest.fn(() => ({
follow: mockFollow,
addActivity: mockAddActivity,
get: mockGet,
}));

jest.mock('getstream', () => ({
connect: jest.fn(() => ({
feed: mockFeed,
})),
}));

const {connect} = require('getstream');

describe('StreamService', () => {
let streamService: StreamService;

beforeEach(() => {
// Reset the mocks and create a new StreamService instance for each test
jest.clearAllMocks();
streamService = new StreamService('API_KEY', 'AUTH_TOKEN', 'APP_ID');
});

describe('createUserFeed', () => {
it('should create a user feed', () => {
const userId = 'user123';
const userFeed = streamService.createUserFeed(userId);

expect(userFeed).toBeDefined();
expect(connect).toHaveBeenCalledWith(
'API_KEY',
'AUTH_TOKEN',
'APP_ID'
);
expect(connect().feed).toHaveBeenCalledWith('user', userId);
});
});

describe('followUser', () => {
it('should follow another user', async () => {
const targetSlug = 'user';
const sourceUserId = 'user123';
const targetUserId = 'user456';

await streamService.followUser(
sourceUserId,
targetSlug,
targetUserId
);

expect(connect().feed).toHaveBeenCalledWith('user', sourceUserId);
expect(connect().feed('targetSlug').follow).toHaveBeenCalled();
});
});

describe('addActivity', () => {
it('should add an activity to the feed', async () => {
const userFeed = streamService.createUserFeed('user123');
const targetSlug = 'user';
const activity = {
actor: 'user123',
verb: 'post',
object: 'message:1',
};

await StreamService.addActivity(userFeed, activity);

expect(connect().feed).toHaveBeenCalled();
expect(connect().feed(targetSlug).addActivity).toHaveBeenCalledWith(activity);
});
});

describe('getActivity', () => {
it('should retrieve activities from the feed', async () => {
const userFeed = streamService.createUserFeed('user123');
const params = { limit: 10 };
const targetSlug = 'user';

await StreamService.getActivity(userFeed, params);

expect(connect().feed).toHaveBeenCalled();
expect(connect().feed(targetSlug).get).toHaveBeenCalledWith(params);
});
});
});
26 changes: 26 additions & 0 deletions @kiva/kv-stream/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
{
"compilerOptions": {
"module": "es2020",
"target": "es2020",
"moduleResolution": "node",
"declaration": true,
"noImplicitAny": false,
"removeComments": true,
"noLib": false,
"experimentalDecorators": true,
"allowSyntheticDefaultImports": true,
"esModuleInterop": true,
"sourceMap": true,
"lib": [
"es6",
"dom"
],
},
"include": [
"./src/**/*.ts"
],
"exclude": [
"**/*/node_modules",
"**/*/tests"
]
}
1 change: 1 addition & 0 deletions lerna.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
"@kiva/kv-tokens",
"@kiva/kv-loan-filters",
"@kiva/kv-shop",
"@kiva/kv-stream",
"test-vue2",
"test-vue3"
],
Expand Down
Loading

0 comments on commit 54b03db

Please sign in to comment.