Skip to content

Commit

Permalink
Event processor first commit
Browse files Browse the repository at this point in the history
  • Loading branch information
bogdan-rosianu committed Sep 23, 2024
0 parents commit 71ce047
Show file tree
Hide file tree
Showing 15 changed files with 608 additions and 0 deletions.
25 changes: 25 additions & 0 deletions .eslintrc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
module.exports = {
parser: '@typescript-eslint/parser',
parserOptions: {
project: 'tsconfig.json',
sourceType: 'module',
},
plugins: ['@typescript-eslint/eslint-plugin'],
extends: [
'plugin:@typescript-eslint/recommended',
],
root: true,
env: {
node: true,
jest: true,
},
rules: {
"@typescript-eslint/no-inferrable-types": ["off"],
"max-len": ["off"],
"semi": ["error"],
"comma-dangle": ["error", "always-multiline"],
"@typescript-eslint/no-explicit-any": ["off"],
"@typescript-eslint/ban-types": ["off"]
},
ignorePatterns: ['.eslintrc.js'],
};
32 changes: 32 additions & 0 deletions .github/workflows/npm-publish.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
name: Publish event processor

on:
workflow_dispatch:

permissions:
contents: write

jobs:
publish-npm:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
with:
node-version: 16
registry-url: https://registry.npmjs.org/

- name: Create release
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
RELEASE_TAG=v$(node -p "require('./package.json').version")
gh release create $RELEASE_TAG --target=$GITHUB_SHA --title="$RELEASE_TAG" --generate-notes
- run: npm ci
- run: npm run build

- name: Publish to npmjs
env:
NODE_AUTH_TOKEN: ${{secrets.NPM_TOKEN}}
run: npm publish --access=public
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
node_modules/
lib/

.DS_Store
20 changes: 20 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# Event Processor for JavaScript

Event processor for JavaScript and TypeScript (written in TypeScript).

## Distribution

[npm](https://www.npmjs.com/package/@multiversx/sdk-event-processor)

## Usage

```js
let eventProcessor = new EventProcessor();
await eventProcessor.start({
onEventsReceived: (highestTimestamp, events) => {
console.log(`Received ${events.length} events with the latest timestamp ${highestTimestamp}`);
},
});
```

[Here](example) is a full application ready to play with in.
14 changes: 14 additions & 0 deletions example/crons/event.processor.module.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { Module } from '@nestjs/common';
import { ScheduleModule } from '@nestjs/schedule';
import { EventProcessorService } from './event.processor.service';

@Module({
imports: [
ScheduleModule.forRoot(),
],
providers: [
EventProcessorService,
],
})

export class EventProcessorModule {}
40 changes: 40 additions & 0 deletions example/crons/event.processor.service.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import { Injectable, Logger } from '@nestjs/common';
import { Cron } from '@nestjs/schedule';
import { Locker } from '../utils/locker';
import { EventProcessor } from "../../src/event.processor";

@Injectable()
export class EventProcessorService {
private readonly logger: Logger;
private lastTimestamp: number | undefined;

constructor() {
this.logger = new Logger(EventProcessorService.name);
}

@Cron('*/1 * * * * *')
async handleNewMultiversxEvents() {
Locker.lock('newMultiversxEvents', async () => {
const eventProcessor = new EventProcessor();
await eventProcessor.start({
elasticUrl: 'https://index.multiversx.com',
eventIdentifiers: ['ESDTTransfer'],
emitterAddresses: ['erd1r44w4rky0l29pynkp4hrmrjdhnmd5knrrmevarp6h2dg9cu74sas597hhl'],
pageSize: 1,
scrollTimeout: "1m",
getLastProcessedTimestamp: async () => {
await Promise.resolve();
return this.lastTimestamp ?? 0;
},
setLastProcessedTimestamp: async (timestamp: number) => {
this.lastTimestamp = timestamp;
},
onEventsReceived: async (highestTimestamp, events) => {
await Promise.resolve();
console.log(`onEventsReceived -> highestTimestamp: ${highestTimestamp}`);
console.log(`onEventsReceived -> events: ${JSON.stringify(events)}`);
},
});
});
}
}
9 changes: 9 additions & 0 deletions example/main.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { NestFactory } from '@nestjs/core';
import { EventProcessorModule } from "./crons/event.processor.module";

async function start() {
const eventProcessorApp = await NestFactory.create(EventProcessorModule);
await eventProcessorApp.listen(4242);
}

start().then()
37 changes: 37 additions & 0 deletions example/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
{
"name": "@multiversx/sdk-event-processor",
"version": "1.0.0",
"description": "Real-time event processor",
"main": "lib/event.processor.js",
"types": "lib/event.processor.d.ts",
"files": [
"lib"
],
"scripts": {
"example": "npx ts-node ./main.ts",
"test": "echo \"Error: no test specified\" && exit 1",
"build": "tsc"
},
"repository": {
"type": "git",
"url": "git+https://github.com/multiversx/mx-sdk-event-processor.git"
},
"keywords": [
"multiversx",
"event",
"processor"
],
"author": "MultiversX",
"license": "GPL-3.0-or-later",
"devDependencies": {
"@types/axios": "^0.14.0",
"@types/node": "^16.11.10",
"typescript": "^4.3.5"
},
"dependencies": {
"@nestjs/common": "^10.4.1",
"@nestjs/platform-express": "^10.4.1",
"@nestjs/schedule": "^4.1.0",
"axios": "^1.7.4"
}
}
12 changes: 12 additions & 0 deletions example/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"compilerOptions": {
"experimentalDecorators": true,
"target": "es2015",
"module": "commonjs",
"declaration": true,
"outDir": "./lib",
"baseUrl": "./",
"strict": true
},
"exclude": ["node_modules", "**/__tests__/*"]
}
32 changes: 32 additions & 0 deletions example/utils/locker.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import { Logger } from '@nestjs/common';
import { PerformanceProfiler } from "./performance.profiler";

export class Locker {
private static lockArray: string[] = [];

static async lock(key: string, func: () => Promise<void>, log: boolean = false) {
const logger = new Logger('Lock');

if (Locker.lockArray.includes(key) && log) {
logger.log(`${key} is already running`);
return;
}

Locker.lockArray.push(key);

const profiler = new PerformanceProfiler();

try {
await func();
} catch (error) {
logger.error(`Error running ${key}`);
logger.error(error);
} finally {
profiler.stop(`Running ${key}`, log);
const index = Locker.lockArray.indexOf(key);
if (index >= 0) {
Locker.lockArray.splice(index, 1);
}
}
}
}
25 changes: 25 additions & 0 deletions example/utils/performance.profiler.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { Logger } from '@nestjs/common';

export class PerformanceProfiler {
started: number;
description: string;

stopped: number = 0;
duration: number = 0;

constructor(description: string = '') {
this.started = Date.now();
this.description = description;
}

stop(description: string | null = null, log: boolean = false) {
this.stopped = Date.now();
this.duration = this.stopped - this.started;

if (log) {
const logger = new Logger(PerformanceProfiler.name);

logger.log(`${description ?? this.description}: ${this.duration}ms`);
}
}
}
Loading

0 comments on commit 71ce047

Please sign in to comment.