mirror of
https://github.com/NebulaServices/Nebula.git
synced 2025-05-12 19:40:02 -04:00
168 lines
5.1 KiB
JavaScript
168 lines
5.1 KiB
JavaScript
importScripts("./WWError.js");
|
|
const dbg = console.log.bind(console, "[WorkerWare]");
|
|
const time = console.time.bind(console, "[WorkerWare]");
|
|
const timeEnd = console.timeEnd.bind(console, "[WorkerWare]");
|
|
|
|
/*
|
|
OPTS:
|
|
debug - Enables debug logging.
|
|
randomNames - Generate random names for middlewares.
|
|
timing - Logs timing for each middleware.
|
|
*/
|
|
|
|
const defaultOpt = {
|
|
debug: false,
|
|
randomNames: false,
|
|
timing: false,
|
|
};
|
|
|
|
const validEvents = [
|
|
"abortpayment",
|
|
"activate",
|
|
"backgroundfetchabort",
|
|
"backgroundfetchclick",
|
|
"backgroundfetchfail",
|
|
"backgroundfetchsuccess",
|
|
"canmakepayment",
|
|
"contentdelete",
|
|
"cookiechange",
|
|
"fetch",
|
|
"install",
|
|
"message",
|
|
"messageerror",
|
|
"notificationclick",
|
|
"notificationclose",
|
|
"paymentrequest",
|
|
"periodicsync",
|
|
"push",
|
|
"pushsubscriptionchange",
|
|
"sync",
|
|
];
|
|
|
|
class WorkerWare {
|
|
constructor(opt) {
|
|
this._opt = Object.assign({}, defaultOpt, opt);
|
|
this._middlewares = [];
|
|
}
|
|
info() {
|
|
return {
|
|
version: "0.1.0",
|
|
middlewares: this._middlewares,
|
|
options: this._opt,
|
|
};
|
|
}
|
|
use(middleware) {
|
|
let validateMW = this.validateMiddleware(middleware);
|
|
if (validateMW.error) throw new WWError(validateMW.error);
|
|
// This means the middleware is an anonymous function, or the user is silly and named their function "function"
|
|
if (middleware.function.name == "function") middleware.name = crypto.randomUUID();
|
|
if (!middleware.name) middleware.name = middleware.function.name;
|
|
if (this._opt.randomNames) middleware.name = crypto.randomUUID();
|
|
if (this._opt.debug) dbg("Adding middleware:", middleware.name);
|
|
this._middlewares.push(middleware);
|
|
}
|
|
// Run all middlewares for the event type passed in.
|
|
run(event) {
|
|
const middlewares = this._middlewares;
|
|
const returnList = [];
|
|
let fn = async () => {
|
|
for (let i = 0; i < middlewares.length; i++) {
|
|
if (middlewares[i].events.includes(event.type)) {
|
|
if (this._opt.timing) console.time(middlewares[i].name);
|
|
// Add the configuration to the event object.
|
|
event.workerware = {
|
|
config: middlewares[i].configuration || {},
|
|
};
|
|
if (!middlewares[i].explicitCall) {
|
|
let res = await middlewares[i].function(event);
|
|
if (this._opt.timing) console.timeEnd(middlewares[i].name);
|
|
returnList.push(res);
|
|
}
|
|
}
|
|
}
|
|
return returnList;
|
|
};
|
|
return fn;
|
|
}
|
|
deleteByName(middlewareID) {
|
|
if (this._opt.debug) dbg("Deleting middleware:", middlewareID);
|
|
this._middlewares = this._middlewares.filter((mw) => mw.name !== middlewareID);
|
|
}
|
|
deleteByEvent(middlewareEvent) {
|
|
if (this._opt.debug) dbg("Deleting middleware by event:", middlewareEvent);
|
|
this._middlewares = this._middlewares.filter((mw) => !mw.events.includes(middlewareEvent));
|
|
}
|
|
get() {
|
|
return this._middlewares;
|
|
}
|
|
/*
|
|
Run a single middleware by ID.
|
|
This assumes that the user knows what they're doing, and is running the middleware on an event that it's supposed to run on.
|
|
*/
|
|
runMW(name, event) {
|
|
const middlewares = this._middlewares;
|
|
if (this._opt.debug) dbg("Running middleware:", name);
|
|
// if (middlewares.includes(name)) {
|
|
// return middlewares[name](event);
|
|
// } else {
|
|
// throw new WWError("Middleware not found!");
|
|
// }
|
|
let didCall = false;
|
|
for (let i = 0; i < middlewares.length; i++) {
|
|
if (middlewares[i].name == name) {
|
|
didCall = true;
|
|
event.workerware = {
|
|
config: middlewares[i].configuration || {},
|
|
}
|
|
if (this._opt.timing) console.time(middlewares[i].name);
|
|
let call = middlewares[i].function(event);
|
|
if (this._opt.timing) console.timeEnd(middlewares[i].name);
|
|
return call;
|
|
}
|
|
}
|
|
if (!didCall) {
|
|
throw new WWError("Middleware not found!");
|
|
}
|
|
}
|
|
// type middlewareManifest = {
|
|
// function: Function,
|
|
// name?: string,
|
|
// events: string[], // Should be a union of validEvents.
|
|
// configuration?: Object // Optional configuration for the middleware.
|
|
// }
|
|
validateMiddleware(middleware) {
|
|
if (!middleware.function)
|
|
return {
|
|
error: "middleware.function is required",
|
|
};
|
|
if (typeof middleware.function !== "function")
|
|
return {
|
|
error: "middleware.function must be typeof function",
|
|
};
|
|
if (typeof middleware.configuration !== "object" && middleware.configuration !== undefined) {
|
|
return {
|
|
error: "middleware.configuration must be typeof object",
|
|
};
|
|
}
|
|
if (!middleware.events)
|
|
return {
|
|
error: "middleware.events is required",
|
|
};
|
|
if (!Array.isArray(middleware.events))
|
|
return {
|
|
error: "middleware.events must be an array",
|
|
};
|
|
if (middleware.events.some((ev) => !validEvents.includes(ev)))
|
|
return {
|
|
error: "Invalid event type! Must be one of the following: " + validEvents.join(", "),
|
|
};
|
|
if (middleware.explicitCall && typeof middleware.explicitCall !== "boolean") {
|
|
return {
|
|
error: "middleware.explicitCall must be typeof boolean",
|
|
};
|
|
}
|
|
return {
|
|
error: undefined,
|
|
};
|
|
}
|
|
}
|