-
Notifications
You must be signed in to change notification settings - Fork 140
/
Copy pathProxyTool.ts
107 lines (96 loc) · 3.06 KB
/
ProxyTool.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
import FetchWorkerTool from './FetchWorkerTool';
import {FetchTool} from './FetchTool';
import {ScratchGetRequest, ScratchSendRequest, Tool} from './Tool';
/**
* @typedef {object} Request
* @property {string} url
* @property {*} body
* @property {string} method
* @property {boolean} withCredentials
*/
type ToolFilter = typeof ProxyTool.TOOL_FILTER[keyof typeof ProxyTool.TOOL_FILTER];
/**
* Get and send assets with other tools in sequence.
*/
export default class ProxyTool implements Tool {
public tools: Tool[];
/**
* Constant values that filter the set of tools in a ProxyTool instance.
* @enum {string}
*/
public static TOOL_FILTER = {
/**
* Use all tools.
*/
ALL: 'all',
/**
* Use tools that are ready right now.
*/
READY: 'ready'
} as const;
constructor (filter: ToolFilter = ProxyTool.TOOL_FILTER.ALL) {
let tools: Tool[];
if (filter === ProxyTool.TOOL_FILTER.READY) {
tools = [new FetchTool()];
} else {
tools = [new FetchWorkerTool(), new FetchTool()];
}
/**
* Sequence of tools to proxy.
* @type {Array.<Tool>}
*/
this.tools = tools;
}
/**
* Is get supported? false if all proxied tool return false.
* @returns {boolean} Is get supported?
*/
get isGetSupported (): boolean {
return this.tools.some(tool => tool.isGetSupported);
}
/**
* Request data from with one of the proxied tools.
* @param {Request} reqConfig - Request configuration for data to get.
* @returns {Promise.<Buffer>} Resolve to Buffer of data from server.
*/
get (reqConfig: ScratchGetRequest): Promise<Uint8Array | null> {
let toolIndex = 0;
const nextTool = (err?: unknown): Promise<Uint8Array | null> => {
const tool = this.tools[toolIndex++];
if (!tool) {
throw err;
}
if (!tool.isGetSupported) {
return nextTool(err);
}
return tool.get(reqConfig).catch(nextTool);
};
return nextTool();
}
/**
* Is sending supported? false if all proxied tool return false.
* @returns {boolean} Is sending supported?
*/
get isSendSupported (): boolean {
return this.tools.some(tool => tool.isSendSupported);
}
/**
* Send data to a server with one of the proxied tools.
* @param {Request} reqConfig - Request configuration for data to send.
* @returns {Promise.<Buffer|string|object>} Server returned metadata.
*/
send (reqConfig: ScratchSendRequest): Promise<string> {
let toolIndex = 0;
const nextTool = (err?: unknown): Promise<string> => {
const tool = this.tools[toolIndex++];
if (!tool) {
throw err;
}
if (!tool.isSendSupported) {
return nextTool(err);
}
return tool.send(reqConfig).catch(nextTool);
};
return nextTool();
}
}