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