Path: blob/master/views/uv/workerware.js
5227 views
/* -----------------------------------------------1/* Authors: wearrrrr2/* GNU General Public License v3.0: https://www.gnu.org/licenses/gpl-3.0.en.html3/* Service Worker Middleware Script4/* ----------------------------------------------- */56importScripts('./WWError.js');7const dbg = console.log.bind(console, '[WorkerWare]');8const time = console.time.bind(console, '[WorkerWare]');9const timeEnd = console.timeEnd.bind(console, '[WorkerWare]');1011/*12OPTS:13debug - Enables debug logging.14randomNames - Generate random names for middlewares.15timing - Logs timing for each middleware.16*/1718const defaultOpt = {19debug: false,20randomNames: false,21timing: false,22};2324const validEvents = [25'abortpayment',26'activate',27'backgroundfetchabort',28'backgroundfetchclick',29'backgroundfetchfail',30'backgroundfetchsuccess',31'canmakepayment',32'contentdelete',33'cookiechange',34'fetch',35'install',36'message',37'messageerror',38'notificationclick',39'notificationclose',40'paymentrequest',41'periodicsync',42'push',43'pushsubscriptionchange',44'sync',45];4647class WorkerWare {48constructor(opt) {49this._opt = Object.assign({}, defaultOpt, opt);50this._middlewares = [];51}52info() {53return {54version: '0.1.0',55middlewares: this._middlewares,56options: this._opt,57};58}59use(middleware) {60let validateMW = this.validateMiddleware(middleware);61if (validateMW.error) throw new WWError(validateMW.error);62// This means the middleware is an anonymous function, or the user is silly and named their function "function"63if (middleware.function.name == 'function')64middleware.name = crypto.randomUUID();65if (!middleware.name) middleware.name = middleware.function.name;66if (this._opt.randomNames) middleware.name = crypto.randomUUID();67if (this._opt.debug) dbg('Adding middleware:', middleware.name);68this._middlewares.push(middleware);69}70// Run all middlewares for the event type passed in.71run(event) {72const middlewares = this._middlewares;73const returnList = [];74let fn = async () => {75for (let i = 0; i < middlewares.length; i++) {76if (middlewares[i].events.includes(event.type)) {77if (this._opt.timing) console.time(middlewares[i].name);78// Add the configuration to the event object.79event.workerware = {80config: middlewares[i].configuration || {},81};82if (!middlewares[i].explicitCall) {83let res = await middlewares[i].function(event);84if (this._opt.timing) console.timeEnd(middlewares[i].name);85returnList.push(res);86}87}88}89return returnList;90};91return fn;92}93deleteByName(middlewareID) {94if (this._opt.debug) dbg('Deleting middleware:', middlewareID);95this._middlewares = this._middlewares.filter(96(mw) => mw.name !== middlewareID97);98}99deleteByEvent(middlewareEvent) {100if (this._opt.debug) dbg('Deleting middleware by event:', middlewareEvent);101this._middlewares = this._middlewares.filter(102(mw) => !mw.events.includes(middlewareEvent)103);104}105get() {106return this._middlewares;107}108/*109Run a single middleware by ID.110This assumes that the user knows what they're doing, and is running the middleware on an event that it's supposed to run on.111*/112runMW(name, event) {113const middlewares = this._middlewares;114if (this._opt.debug) dbg('Running middleware:', name);115// if (middlewares.includes(name)) {116// return middlewares[name](event);117// } else {118// throw new WWError("Middleware not found!");119// }120let didCall = false;121for (let i = 0; i < middlewares.length; i++) {122if (middlewares[i].name == name) {123didCall = true;124event.workerware = {125config: middlewares[i].configuration || {},126};127if (this._opt.timing) console.time(middlewares[i].name);128let call = middlewares[i].function(event);129if (this._opt.timing) console.timeEnd(middlewares[i].name);130return call;131}132}133if (!didCall) {134throw new WWError('Middleware not found!');135}136}137// type middlewareManifest = {138// function: Function,139// name?: string,140// events: string[], // Should be a union of validEvents.141// configuration?: Object // Optional configuration for the middleware.142// }143validateMiddleware(middleware) {144if (!middleware.function)145return {146error: 'middleware.function is required',147};148if (typeof middleware.function !== 'function')149return {150error: 'middleware.function must be typeof function',151};152if (153typeof middleware.configuration !== 'object' &&154middleware.configuration !== undefined155) {156return {157error: 'middleware.configuration must be typeof object',158};159}160if (!middleware.events)161return {162error: 'middleware.events is required',163};164if (!Array.isArray(middleware.events))165return {166error: 'middleware.events must be an array',167};168if (middleware.events.some((ev) => !validEvents.includes(ev)))169return {170error:171'Invalid event type! Must be one of the following: ' +172validEvents.join(', '),173};174if (175middleware.explicitCall &&176typeof middleware.explicitCall !== 'boolean'177) {178return {179error: 'middleware.explicitCall must be typeof boolean',180};181}182return {183error: undefined,184};185}186}187188189