UNPKG

4.11 kBJavaScriptView Raw
1import { isString } from 'type-enforcer';
2import PriorityQueue from './PriorityQueue.js';
3
4const METHOD = {
5 GET: 'GET',
6 PATCH: 'PATCH',
7 PUT: 'PUT',
8 POST: 'POST',
9 DELETE: 'DELETE'
10};
11const CONTENT_TYPE = 'Content-Type';
12const APPLICATION_JSON = 'application/json';
13
14const defaults = { headers: {} };
15defaults.headers[CONTENT_TYPE] = APPLICATION_JSON;
16
17const 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 */
28const 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
167export default prioritize;