npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

pnw-rexec

v1.1.3

Published

Request builder and executor for the Politics and War API.

Downloads

9

Readme

PnW Rexec

A Request Builder and Executor for the Politics and War API

Features

  • Create different profiles for queries.
  • Chain executors to create the behavior you want.
  • Log your requests with a log callback.
  • Paginator results have helper methods.
  • Requests are typed with the fields you request and nothing more.

Sections

Install

npm i pnw-rexec

Usage

import { RequesterProfile } from 'pnw-rexec';

or

const { RequesterProfile } = require('pnw-rexec');

and

const profile = new RequesterProfile().key('my-key');

const { me } = await profile.request().me((me) => me
    .child('nation', (n) => n.fields('nation_name', 'leader_name'))
  )
  .send();
const { leader_name, nation_name } = me.nation;
console.log(`Hello, I'm ${leader_name} of ${nation_name}`);

Executors

You can set up your profiles to use one of the available executors, or write your own.

new RequesterProfile()
  .bin({defer: true, timeout: 1000})
  .cache({cache: true, lifetime: 60_000});

This profile, for example, has three executors chained:

  • An instantaneous executor, that gets created with the profile.
  • A bin executor, that merges together requests of different endpoints.
  • A cache executor, that hashes requests and throws them in a cache.

They are called from the last to the first, so this requester will first look at the cache, then for an empty bin, then execute. You may specify default configurations for each executor, but they can also be overriden in the request itself.

const urgentRequest = await profile.request().send({defer: false});
const unlikelyToChange = await profile.request().send({cache: true, lifetime: 7_200_000})

Logging

You can specify a log callback, that gets a Date object, a query string and a node-fetch Response as parameters.

profile.log((log) => {
  console.log("I was ran on ", log.date);
  console.log("I tried to get", log.query);
  console.log("I got", log.result);
});

Paginators

You can fetch until there are no more pages

const { tradeprices } = await profile.request()
  .tradeprices({}, (t) => t.fields('food','date'))
  .send();
await tradeprices.fetchAll();

Fetch until a callback returns false

const thisYear = '2022-01-01';
await tradeprices.fetchWhile((p) => p.lastItem?.date >= thisYear);

And then filter the results

const filtered = tradeprices.filter((t) => t.date >= thisYear);

Or fetch only the next page

await tradeprices.fetchMore();

The return type of these functions is a parsed version of paginator info

const p = await tradeprices.fetchMore();
console.log('The first price of food was', p.lastItem?.food);

That is also available in the first page

const p = tradeprices.info;
console.log('The last price of food was', p?.firstItem?.food);

You can also send executor options to these functions

await tradeprices.fetchAll({defer:false});
await tradeprices.fetchWhile(() => false, {defer:false});
await tradeprices.fetchMore({defer:false});

And then you use your result as you wish

tradeprices.forEach((d) => console.log('Food was',d.food,'on',d.date));

Writing an Executor

To create an executor you must import a few types

import { Executor, RequesterProfile, BaseRequest, Types } from 'pnw-rexec';
type Query = Types.Query;

Then you declare your config type

interface MyOptions {...}

Then create an executor class

class MyExecutor<O> implements Executor<MyOptions & O> {
  config: RequesterProfile<MyOptions & O>;
  executor: Executor<O>;
  defaultOptions: MyOptions & O;
}

config is the profile that created your executor

executor is the next executor down the line

defaultOptions is an object that merges executor previous

Now we need a constructor

constructor(
  config: RequesterProfile<O & MyOptions>,
  executor: Executor<O>,
  options: MyOptions & O
) {
  this.config = config;
  this.executor = executor;
  this.defaultOptions = options;
}

And a push() method, where you do your stuff and send the request.

async push<R>(
 requests: [keyof Query, BaseRequest<any, any>][],
 options?: O & MyOptions
): Promise<R> {
 // DoStuff
 // ...
 // Send
 const res = await this.executor.push(requests, options);
 return res as R;
}

To use your executor, you attach it to a profile like so

const profile = new RequesterProfile().executor(MyExecutor, {});

And that's it

Credits

This package was created by the tech team at Rose.

The basic types were generated with help from GraphQL Code Generator.