Skip to content

Commit

Permalink
feat: rewrite into ESM (#281)
Browse files Browse the repository at this point in the history
drop node 12, node 14 support
add node 20 support, add node 18 support

BREAKING CHANGE: prefer .make static functions to constructors
  • Loading branch information
TobiTenno authored Feb 2, 2024
1 parent 20fa666 commit cd70cec
Show file tree
Hide file tree
Showing 28 changed files with 2,571 additions and 8,201 deletions.
27 changes: 9 additions & 18 deletions .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,12 @@ jobs:
lint:
name: Lint
runs-on: ubuntu-latest
strategy:
matrix:
node-version: [16]
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v4
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v3
uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node-version }}
node-version-file: .nvmrc
- name: Install Dependencies
run: |
npm ci --omit=optional
Expand All @@ -30,11 +27,11 @@ jobs:
needs: lint
strategy:
matrix:
node-version: [12, 14, 16, 'lts/*']
node-version: ['lts/*', '20', '18']
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v4
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v3
uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node-version }}
- name: Install Dependencies
Expand All @@ -49,15 +46,11 @@ jobs:
name: Coverage
runs-on: ubuntu-latest
needs: lint
strategy:
matrix:
node-version: [16]
steps:
- uses: actions/checkout@v2
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v3
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node-version }}
node-version-file: .nvmrc
- name: Install Dependencies
run: |
npm ci --omit=optional
Expand All @@ -67,5 +60,3 @@ jobs:
CI: true
- name: Coveralls
uses: coverallsapp/github-action@master
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
8 changes: 4 additions & 4 deletions .github/workflows/codeql-analysis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,12 @@ jobs:
language: [ 'javascript' ]
steps:
- name: Checkout repository
uses: actions/checkout@v2
uses: actions/checkout@v4
- name: Initialize CodeQL
uses: github/codeql-action/init@v1
uses: github/codeql-action/init@v2
with:
languages: ${{ matrix.language }}
- name: Autobuild
uses: github/codeql-action/autobuild@v1
uses: github/codeql-action/autobuild@v2
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v1
uses: github/codeql-action/analyze@v2
2 changes: 1 addition & 1 deletion .github/workflows/docs.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v4
- run: npm i
- run: npm i ink-docstrap jsdoc taffydb
- name: Build
Expand Down
10 changes: 3 additions & 7 deletions .github/workflows/release.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,12 @@ jobs:
release:
name: Release
runs-on: ubuntu-latest
strategy:
matrix:
node-version: [16]
steps:
- name: Checkout
uses: actions/checkout@v2
uses: actions/checkout@v4
with:
token: ${{ secrets.GH_TOKEN }}
- uses: actions/setup-node@v3
- uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node-version }}
- name: Verify
Expand All @@ -27,11 +24,10 @@ jobs:
npm run lint
npm test
- name: Semantic Release
uses: cycjimmy/semantic-release-action@v2
uses: cycjimmy/semantic-release-action@v4
env:
GITHUB_TOKEN: ${{ secrets.GH_TOKEN }}
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
with:
semantic_version: 17
branches: |
['master']
2 changes: 1 addition & 1 deletion .nvmrc
Original file line number Diff line number Diff line change
@@ -1 +1 @@
lts/gallium
lts/iron
12 changes: 4 additions & 8 deletions handlers/RSS.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,12 @@
'use strict';
import RssFeedEmitter from 'rss-feed-emitter';
import feeds from '../resources/rssFeeds.json' assert { type: 'json' };

const RssFeedEmitter = require('rss-feed-emitter');
const feeds = require('../resources/rssFeeds.json');

const { logger } = require('../utilities');
import { logger } from '../utilities/index.js';

/**
* RSS Emitter, leverages [rss-feed-emitter](https://npmjs.org/package/rss-feed-emitter)
*/
class RSS {
export default class RSS {
/**
* Set up emitting events for warframe forum entries
* @param {EventEmitter} eventEmitter Emitter to send events from
Expand Down Expand Up @@ -66,5 +64,3 @@ class RSS {
}
}
}

module.exports = RSS;
29 changes: 8 additions & 21 deletions handlers/Twitter.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
'use strict';

const Twitter = require('twitter');
const toWatch = require('../resources/tweeters.json');

const { logger } = require('../utilities');
import Twitter from 'twitter';
import toWatch from '../resources/tweeters.json' assert { type: 'json' };
import { logger } from '../utilities/index.js';
import { twiClientInfo, TWITTER_TIMEOUT } from '../utilities/env.js';

const determineTweetType = (tweet) => {
if (tweet.in_reply_to_status_id) {
Expand Down Expand Up @@ -56,25 +54,16 @@ const parseTweet = (tweets, watchable) => {
/**
* Twitter event handler
*/
class TwitterCache {
export default class TwitterCache {
/**
* Create a new Twitter self-updating cache
* @param {EventEmitter} eventEmitter emitter to push new tweets to
*/
constructor(eventEmitter) {
this.emitter = eventEmitter;
this.timeout = process.env.TWITTER_TIMEOUT || 60000;
this.initTime = Date.now();

const clientInfo = {
consumer_key: process.env.TWITTER_KEY,
consumer_secret: process.env.TWITTER_SECRET,
bearer_token: process.env.TWITTER_BEARER_TOKEN,
};

this.clientInfoValid = clientInfo.consumer_key && clientInfo.consumer_secret && clientInfo.bearer_token;

this.initClient(clientInfo);
this.timeout = TWITTER_TIMEOUT;
this.clientInfoValid = twiClientInfo.consumer_key && twiClientInfo.consumer_secret && twiClientInfo.bearer_token;
this.initClient(twiClientInfo);
}

initClient(clientInfo) {
Expand Down Expand Up @@ -177,5 +166,3 @@ class TwitterCache {
return this.currentData;
}
}

module.exports = TwitterCache;
132 changes: 57 additions & 75 deletions handlers/Worldstate.js
Original file line number Diff line number Diff line change
@@ -1,90 +1,77 @@
'use strict';
import wsData from 'warframe-worldstate-data';
import WSCache from '../utilities/WSCache.js';
import { logger, lastUpdated } from '../utilities/index.js';
import parseNew from './events/parse.js';
import Cache from '../utilities/Cache.js';

const Cache = require('json-fetch-cache');
const { locales } = require('warframe-worldstate-data');

const WSCache = require('../utilities/WSCache');

const { logger, lastUpdated } = require('../utilities');

const parseNew = require('./events/parse');

const wsTimeout = process.env.CACHE_TIMEOUT || 60000;
const platforms = ['pc', 'ps4', 'xb1', 'swi'];
const worldStates = {};
const wsRawCaches = {};
const { locales } = wsData;

const debugEvents = ['arbitration', 'kuva', 'nightwave'];
const smTimeout = process.env.SEMLAR_TIMEOUT || 300000;
const kuvaCache = new Cache('https://10o.io/arbitrations.json', smTimeout, { logger, maxRetry: 0 });
const sentientCache = new Cache('https://semlar.com/anomaly.json', smTimeout, { logger });
const smCron = `0 */10 * * * *`;

/**
* Handler for worldstate data
*/
class Worldstate {
export default class Worldstate {
#emitter;
#locale;
#worldStates = {};
#wsRawCache;
#kuvaCache;
#sentientCache;

/**
* Set up listening for specific platform and locale if provided.
* @param {EventEmitter} eventEmitter Emitter to push new worldstate events to
* @param {string} platform Platform to watch (optional)
* @param {string} locale Locale (actually just language) to watch
*/
constructor(eventEmitter, platform, locale) {
this.emitter = eventEmitter;
this.platform = platform;
this.locale = locale;
constructor(eventEmitter, locale) {
this.#emitter = eventEmitter;
this.#locale = locale;
logger.silly('starting up worldstate listener...');
if (platform) {
logger.debug(`only listening for ${platform}...`);
}
if (locale) {
logger.debug(`only listening for ${locale}...`);
}
}

this.setUpRawEmitters();
async init() {
this.#wsRawCache = await Cache.make('https://content.warframe.com/dynamic/worldState.php', '*/10 * * * * *');
this.#kuvaCache = await Cache.make('https://10o.io/arbitrations.json', smCron);
this.#sentientCache = await Cache.make('https://semlar.com/anomaly.json', smCron);

await this.setUpRawEmitters();
this.setupParsedEvents();
}

/**
* Set up emitting raw worldstate data
*/
setUpRawEmitters() {
platforms.forEach((p) => {
if (this.platform && this.platform !== p) return;

const url = `https://content${p === 'pc' ? '' : `.${p}`}.warframe.com/dynamic/worldState.php`;
worldStates[p] = {};

locales.forEach(async (locale) => {
if (!this.locale || this.locale === locale) {
worldStates[p][locale] = new WSCache({
platform: p,
language: locale,
kuvaCache,
sentientCache,
eventEmitter: this.emitter,
});
}
});

wsRawCaches[p] = new Cache(url, wsTimeout, {
delayStart: false,
parser: (str) => str,
useEmitter: true,
logger,
});
async setUpRawEmitters() {
this.#worldStates = {};

// eslint-disable-next-line no-restricted-syntax
for await (const locale of locales) {
if (!this.#locale || this.#locale === locale) {
this.#worldStates[locale] = new WSCache({
language: locale,
kuvaCache: this.#kuvaCache,
sentientCache: this.#sentientCache,
eventEmitter: this.#emitter,
});
}
}

/* listen for the raw cache updates so we can emit them from the super emitter */
wsRawCaches[p].on('update', (dataStr) => {
this.emitter.emit('ws:update:raw', { platform: p, data: dataStr });
});
/* listen for the raw cache updates so we can emit them from the super emitter */
this.#wsRawCache.on('update', (dataStr) => {
this.#emitter.emit('ws:update:raw', { platform: 'pc', data: dataStr });
});

/* when the raw emits happen, parse them and store them on parsed worldstate caches */
this.emitter.on('ws:update:raw', ({ platform, data }) => {
this.#emitter.on('ws:update:raw', ({ data }) => {
logger.debug('ws:update:raw - updating locales data');
locales.forEach((locale) => {
if (!this.locale || this.locale === locale) {
worldStates[platform][locale].data = data;
if (!this.#locale || this.#locale === locale) {
this.#worldStates[locale].data = data;
}
});
});
Expand All @@ -94,17 +81,17 @@ class Worldstate {
* Set up listeners for the parsed worldstate updates
*/
setupParsedEvents() {
this.emitter.on('ws:update:parsed', ({ language, platform, data }) => {
this.#emitter.on('ws:update:parsed', ({ language, platform, data }) => {
const packet = { platform, worldstate: data, language };
this.parseEvents(packet, this.emitter);
this.parseEvents(packet);
});
}

/**
* Parse new worldstate events
* @param {Object} worldstate worldstate to find packets from
* @param {string} platform platform the worldstate corresponds to
* @param {string} [language='en'] langauge of the worldstate (defaults to 'en')
* @param {string} [language='en'] language of the worldstate (defaults to 'en')
*/
parseEvents({ worldstate, platform, language = 'en' }) {
const cycleStart = Date.now();
Expand Down Expand Up @@ -147,25 +134,20 @@ class Worldstate {

logger.silly(`ws:update:event - emitting ${packet.id}`);
delete packet.cycleStart;
this.emitter.emit(id, packet);
this.#emitter.emit(id, packet);
}

/**
* get a specific worldstate version
* @param {string} [platform='pc'] Platform of the worldstate
* @param {string} [locale='en'] Locale of the worldsttate
* @returns {Object} Worldstate corresponding to provided data
* @param {string} [language='en'] Locale of the worldsttate
* @returns {Object} Worldstate corresponding to provided data
* @throws {Error} when the platform or locale aren't tracked and aren't updated
*/
// eslint-disable-next-line class-methods-use-this
get(platform = 'pc', language = 'en') {
if (worldStates[platform] && worldStates[platform][language]) {
return worldStates[platform][language].data;
get(language = 'en') {
logger.warn(`getting worldstate ${language}...`);
if (this.#worldStates?.[language]) {
return this.#worldStates?.[language]?.data;
}
throw new Error(
`Platform (${platform}) or language (${language}) not tracked.\nEnsure that the parameters passed are correct`
);
throw new Error(`Language (${language}) not tracked.\nEnsure that the parameters passed are correct`);
}
}

module.exports = Worldstate;
Loading

0 comments on commit cd70cec

Please sign in to comment.