Fiddle with the Request stuff

This commit is contained in:
Will Hoskings
2020-02-26 20:09:16 +00:00
parent 8c1882adf9
commit f122b3603a
3 changed files with 101 additions and 5 deletions

View File

@@ -3,10 +3,10 @@ import { RequestMethod } from "../types/fetch.ts"
// type RequestBody = string | Blob | ArrayBufferView | ArrayBuffer | FormData | URLSearchParams | null | undefined
export default class DiscordDiscordRequestManager {
constructor(public client: Client, public token: string) {
export default class DiscordRequestManager {
token = this.client.token;
constructor(public client: Client) {
this.client = client;
this.token = token;
}
async get(url: string, body?: unknown) {
@@ -35,18 +35,23 @@ export default class DiscordDiscordRequestManager {
protected async runMethod (method: RequestMethod, url: string, body?: unknown) {
const headers = this.getDiscordHeaders();
return fetch(url, {
return fetch(this.resolveURL(url), {
method,
headers,
body: body ? JSON.stringify(body) : undefined
});
}
// A hook for the RouteAwareRequestManager to override URLs.
protected resolveURL (url: string) {
return url;
}
// The Record type here plays nice with Deno's `fetch.headers` expected type.
getDiscordHeaders(): Record<string, string> {
return {
Authorization: this.token,
"User-Agent": `DiscordBot (https://github.com/skillz4killz/discordeno, 0.0.1)`
"User-Agent": `Discordeno (https://github.com/skillz4killz/discordeno, 0.0.1)`
}
}
}

View File

@@ -0,0 +1,30 @@
import DiscordRequestManager from "./discord-request-manager.ts";
import Client from "./client";
import { resolveURLs } from './url.ts';
import { baseEndpoints } from '../constants/discord.ts';
export class RouteAwareDiscordRequestManager extends DiscordRequestManager{
constructor (public client: Client, public routeName: string) {
super(client);
}
protected resolveURL (url: string) {
return resolveURLs(baseEndpoints.BASE_URL, this.routeName, url);
}
}
export class RoutedDiscordRequestManager {
protected routeMap = new Map<string, DiscordRequestManager>();
constructor (public client: Client) {}
forRoute (routeName: string) {
if (this.routeMap.has(routeName)) {
return this.routeMap.get(routeName);
}
const routeRequestManager = new RouteAwareDiscordRequestManager(this.client, routeName);
this.routeMap.set(routeName, routeRequestManager);
return routeRequestManager;
}
}

61
structures/queue.ts Normal file
View File

@@ -0,0 +1,61 @@
import { DiscordPayload } from "../types/discord";
import Gateway from "../module/gateway.ts";
export abstract class ActionQueue<Action> {
protected actions: Action[] = [];
push (action: Action) {
if (this.shouldDispatchImmediately(action)) {
this.dispatch(action);
} else {
this.actions.push(action);
}
}
async dispatchAll () {
let index = 0;
for (const action of this.actions) {
if (this.shouldDispatchImmediately(action)) {
this.actions.splice(index, 1);
await this.dispatch(action);
index++;
}
}
}
abstract dispatch (action: Action): void | Promise<void>;
abstract shouldDispatchImmediately (action: Action): boolean;
}
export interface RatelimitDetails {
/** The number of requests that can be made */
limit: number;
/** The number of remaining requests that can be made */
remaining: number;
/** Epoch time (seconds since 00:00:00 UTC on January 1, 1970) at which the rate limit resets */
reset: number;
/** A unique string denoting the rate limit being encountered (non-inclusive of major parameters in the route path) */
bucket: string;
/** Total time (in seconds) of when the current rate limit bucket will reset. */
resetAfter: number;
}
export class RatelimitedActionQueue extends ActionQueue<DiscordPayload> {
protected lastRatelimitDetails?: RatelimitDetails;
constructor (protected gateway: Gateway) {
super();
}
dispatch (action: DiscordPayload) {
this.gateway.sendObject(action);
}
shouldDispatchImmediately () {
return this.lastRatelimitDetails?.limit !== 0;
}
}