1 | import { isString } from 'type-enforcer';
|
2 | import PriorityQueue from './PriorityQueue.js';
|
3 |
|
4 | const METHOD = {
|
5 | GET: 'GET',
|
6 | PATCH: 'PATCH',
|
7 | PUT: 'PUT',
|
8 | POST: 'POST',
|
9 | DELETE: 'DELETE'
|
10 | };
|
11 | const CONTENT_TYPE = 'Content-Type';
|
12 | const APPLICATION_JSON = 'application/json';
|
13 |
|
14 | const defaults = { headers: {} };
|
15 | defaults.headers[CONTENT_TYPE] = APPLICATION_JSON;
|
16 |
|
17 | const priorityQueue = new PriorityQueue();
|
18 |
|
19 | /**
|
20 | * @summary
|
21 | * A light wrapper on fetch to facilitate prioritization of calls.
|
22 | *
|
23 | * ```
|
24 | * npm install prioritize
|
25 | * ```
|
26 | * @module prioritize
|
27 | */
|
28 | const prioritize = {
|
29 | /**
|
30 | * A baseUrl to prepend to the url for each call to fetch
|
31 | *
|
32 | * @memberOf module:prioritize
|
33 | * @default ''
|
34 | */
|
35 | baseUrl: '',
|
36 |
|
37 | /**
|
38 | * Default settings for each call to fetch.
|
39 | *
|
40 | * @memberOf module:prioritize
|
41 | * @default { headers: { 'Content-Type': 'application/json' } }
|
42 | */
|
43 | defaults,
|
44 |
|
45 | /**
|
46 | * Prioritized call to fetch.
|
47 | *
|
48 | * @memberOf module:prioritize
|
49 | * @static
|
50 | *
|
51 | * @param {string} url - URL to call
|
52 | * @param {object} [settings] - All settings available to fetch.<br>
|
53 | * - Adds any default settings from prioritize.defaults.<br>
|
54 | * - settings.body is passed through JSON.stringify() if appropriate.
|
55 | * @param {string} [settings.priority] - If set to "low" then this call is added to a queue until all previously added calls are complete.
|
56 | *
|
57 | * @returns {Promise} Should be handled like a normal call to fetch
|
58 | */
|
59 | fetch(url, settings) {
|
60 | settings = { ...prioritize.defaults, ...settings };
|
61 |
|
62 | if (
|
63 | settings.method !== METHOD.GET &&
|
64 | settings.headers[CONTENT_TYPE] === APPLICATION_JSON &&
|
65 | !isString(settings.body)
|
66 | ) {
|
67 | settings.body = JSON.stringify(settings.body);
|
68 | }
|
69 |
|
70 | return new Promise((resolve) => {
|
71 | const doFetch = () => {
|
72 | priorityQueue.callStarted();
|
73 |
|
74 | fetch(prioritize.baseUrl + url, settings)
|
75 | .then((response) => {
|
76 | priorityQueue.callDone();
|
77 | resolve(response);
|
78 | });
|
79 | };
|
80 |
|
81 | if (settings.priority === 'low') {
|
82 | delete settings.priority;
|
83 | priorityQueue.add(doFetch);
|
84 | }
|
85 | else {
|
86 | doFetch();
|
87 | }
|
88 | });
|
89 | },
|
90 |
|
91 | /**
|
92 | * Shortcut to prioritize.fetch with method: 'GET'.
|
93 | *
|
94 | * @memberOf module:prioritize
|
95 | * @static
|
96 | *
|
97 | * @param {string} url - URL to call
|
98 | * @param {object} [settings] - Passed to prioritize.fetch with method: 'GET'
|
99 | *
|
100 | * @returns {Promise} Should be handled like a normal call to fetch
|
101 | */
|
102 | get(url, settings) {
|
103 | return this.fetch(url, { ...settings, method: METHOD.GET });
|
104 | },
|
105 |
|
106 | /**
|
107 | * Shortcut to prioritize.fetch with method: 'PATCH'.
|
108 | *
|
109 | * @memberOf module:prioritize
|
110 | * @static
|
111 | *
|
112 | * @param {string} url - URL to call.
|
113 | * @param {object} [settings] - Passed to prioritize.fetch with method: 'PATCH'
|
114 | *
|
115 | * @returns {Promise} Should be handled like a normal call to fetch
|
116 | */
|
117 | patch(url, settings) {
|
118 | return this.fetch(url, { ...settings, method: METHOD.PATCH });
|
119 | },
|
120 |
|
121 | /**
|
122 | * Shortcut to prioritize.fetch with method: 'PUT'.
|
123 | *
|
124 | * @memberOf module:prioritize
|
125 | * @static
|
126 | *
|
127 | * @param {string} url - URL to call
|
128 | * @param {object} [settings] - Passed to prioritize.fetch with method: 'PUT'
|
129 | *
|
130 | * @returns {Promise} Should be handled like a normal call to fetch
|
131 | */
|
132 | put(url, settings) {
|
133 | return this.fetch(url, { ...settings, method: METHOD.PUT });
|
134 | },
|
135 |
|
136 | /**
|
137 | * Shortcut to prioritize.fetch with method: 'POST'.
|
138 | *
|
139 | * @memberOf module:prioritize
|
140 | * @static
|
141 | *
|
142 | * @param {string} url - URL to call
|
143 | * @param {object} [settings] - Passed to prioritize.fetch with method: 'POST'
|
144 | *
|
145 | * @returns {Promise} Should be handled like a normal call to fetch
|
146 | */
|
147 | post(url, settings) {
|
148 | return this.fetch(url, { ...settings, method: METHOD.POST });
|
149 | },
|
150 |
|
151 | /**
|
152 | * Shortcut to prioritize.fetch with method: 'DELETE'.
|
153 | *
|
154 | * @memberOf module:prioritize
|
155 | * @static
|
156 | *
|
157 | * @param {string} url - URL to call
|
158 | * @param {object} [settings] - Passed to prioritize.fetch with method: 'DELETE'
|
159 | *
|
160 | * @returns {Promise} Should be handled like a normal call to fetch
|
161 | */
|
162 | delete(url, settings) {
|
163 | return this.fetch(url, { ...settings, method: METHOD.DELETE });
|
164 | }
|
165 | };
|
166 |
|
167 | export default prioritize;
|