UNPKG

13.7 kBJavaScriptView Raw
1this.workbox = this.workbox || {};
2this.workbox.streams = (function (exports,logger_mjs,assert_mjs) {
3 'use strict';
4
5 try {
6 self.workbox.v['workbox:streams:3.6.2'] = 1;
7 } catch (e) {} // eslint-disable-line
8
9 /*
10 Copyright 2018 Google Inc. All Rights Reserved.
11 Licensed under the Apache License, Version 2.0 (the "License");
12 you may not use this file except in compliance with the License.
13 You may obtain a copy of the License at
14
15 http://www.apache.org/licenses/LICENSE-2.0
16
17 Unless required by applicable law or agreed to in writing, software
18 distributed under the License is distributed on an "AS IS" BASIS,
19 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
20 See the License for the specific language governing permissions and
21 limitations under the License.
22 */
23
24 /**
25 * Takes either a Response, a ReadableStream, or a
26 * [BodyInit](https://fetch.spec.whatwg.org/#bodyinit) and returns the
27 * ReadableStreamReader object associated with it.
28 *
29 * @param {workbox.streams.StreamSource} source
30 * @return {ReadableStreamReader}
31 * @private
32 */
33 function _getReaderFromSource(source) {
34 if (source.body && source.body.getReader) {
35 return source.body.getReader();
36 }
37
38 if (source.getReader) {
39 return source.getReader();
40 }
41
42 // TODO: This should be possible to do by constructing a ReadableStream, but
43 // I can't get it to work. As a hack, construct a new Response, and use the
44 // reader associated with its body.
45 return new Response(source).body.getReader();
46 }
47
48 /**
49 * Takes multiple source Promises, each of which could resolve to a Response, a
50 * ReadableStream, or a [BodyInit](https://fetch.spec.whatwg.org/#bodyinit).
51 *
52 * Returns an object exposing a ReadableStream with each individual stream's
53 * data returned in sequence, along with a Promise which signals when the
54 * stream is finished (useful for passing to a FetchEvent's waitUntil()).
55 *
56 * @param {Array<Promise<workbox.streams.StreamSource>>} sourcePromises
57 * @return {Object<{done: Promise, stream: ReadableStream}>}
58 *
59 * @memberof workbox.streams
60 */
61 function concatenate(sourcePromises) {
62 {
63 assert_mjs.assert.isArray(sourcePromises, {
64 moduleName: 'workbox-streams',
65 funcName: 'concatenate',
66 paramName: 'sourcePromises'
67 });
68 }
69
70 const readerPromises = sourcePromises.map(sourcePromise => {
71 return Promise.resolve(sourcePromise).then(source => {
72 return _getReaderFromSource(source);
73 });
74 });
75
76 let fullyStreamedResolve;
77 let fullyStreamedReject;
78 const done = new Promise((resolve, reject) => {
79 fullyStreamedResolve = resolve;
80 fullyStreamedReject = reject;
81 });
82
83 let i = 0;
84 const logMessages = [];
85 const stream = new ReadableStream({
86 pull(controller) {
87 return readerPromises[i].then(reader => reader.read()).then(result => {
88 if (result.done) {
89 {
90 logMessages.push(['Reached the end of source:', sourcePromises[i]]);
91 }
92
93 i++;
94 if (i >= readerPromises.length) {
95 // Log all the messages in the group at once in a single group.
96 {
97 logger_mjs.logger.groupCollapsed(`Concatenating ${readerPromises.length} sources.`);
98 for (const message of logMessages) {
99 if (Array.isArray(message)) {
100 logger_mjs.logger.log(...message);
101 } else {
102 logger_mjs.logger.log(message);
103 }
104 }
105 logger_mjs.logger.log('Finished reading all sources.');
106 logger_mjs.logger.groupEnd();
107 }
108
109 controller.close();
110 fullyStreamedResolve();
111 return;
112 }
113
114 return this.pull(controller);
115 } else {
116 controller.enqueue(result.value);
117 }
118 }).catch(error => {
119 {
120 logger_mjs.logger.error('An error occurred:', error);
121 }
122 fullyStreamedReject(error);
123 throw error;
124 });
125 },
126
127 cancel() {
128 {
129 logger_mjs.logger.warn('The ReadableStream was cancelled.');
130 }
131
132 fullyStreamedResolve();
133 }
134 });
135
136 return { done, stream };
137 }
138
139 /*
140 Copyright 2018 Google Inc. All Rights Reserved.
141 Licensed under the Apache License, Version 2.0 (the "License");
142 you may not use this file except in compliance with the License.
143 You may obtain a copy of the License at
144
145 http://www.apache.org/licenses/LICENSE-2.0
146
147 Unless required by applicable law or agreed to in writing, software
148 distributed under the License is distributed on an "AS IS" BASIS,
149 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
150 See the License for the specific language governing permissions and
151 limitations under the License.
152 */
153
154 /**
155 * This is a utility method that determines whether the current browser supports
156 * the features required to create streamed responses. Currently, it checks if
157 * [`ReadableStream`](https://developer.mozilla.org/en-US/docs/Web/API/ReadableStream/ReadableStream)
158 * is available.
159 *
160 * @param {HeadersInit} [headersInit] If there's no `Content-Type` specified,
161 * `'text/html'` will be used by default.
162 * @return {boolean} `true`, if the current browser meets the requirements for
163 * streaming responses, and `false` otherwise.
164 *
165 * @memberof workbox.streams
166 */
167 function createHeaders(headersInit = {}) {
168 // See https://github.com/GoogleChrome/workbox/issues/1461
169 const headers = new Headers(headersInit);
170 if (!headers.has('content-type')) {
171 headers.set('content-type', 'text/html');
172 }
173 return headers;
174 }
175
176 /*
177 Copyright 2018 Google Inc. All Rights Reserved.
178 Licensed under the Apache License, Version 2.0 (the "License");
179 you may not use this file except in compliance with the License.
180 You may obtain a copy of the License at
181
182 http://www.apache.org/licenses/LICENSE-2.0
183
184 Unless required by applicable law or agreed to in writing, software
185 distributed under the License is distributed on an "AS IS" BASIS,
186 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
187 See the License for the specific language governing permissions and
188 limitations under the License.
189 */
190
191 /**
192 * Takes multiple source Promises, each of which could resolve to a Response, a
193 * ReadableStream, or a [BodyInit](https://fetch.spec.whatwg.org/#bodyinit),
194 * along with a
195 * [HeadersInit](https://fetch.spec.whatwg.org/#typedefdef-headersinit).
196 *
197 * Returns an object exposing a Response whose body consists of each individual
198 * stream's data returned in sequence, along with a Promise which signals when
199 * the stream is finished (useful for passing to a FetchEvent's waitUntil()).
200 *
201 * @param {Array<Promise<workbox.streams.StreamSource>>} sourcePromises
202 * @param {HeadersInit} [headersInit] If there's no `Content-Type` specified,
203 * `'text/html'` will be used by default.
204 * @return {Object<{done: Promise, response: Response}>}
205 *
206 * @memberof workbox.streams
207 */
208 function concatenateToResponse(sourcePromises, headersInit) {
209 const { done, stream } = concatenate(sourcePromises);
210
211 const headers = createHeaders(headersInit);
212 const response = new Response(stream, { headers });
213
214 return { done, response };
215 }
216
217 /*
218 Copyright 2018 Google Inc. All Rights Reserved.
219 Licensed under the Apache License, Version 2.0 (the "License");
220 you may not use this file except in compliance with the License.
221 You may obtain a copy of the License at
222
223 http://www.apache.org/licenses/LICENSE-2.0
224
225 Unless required by applicable law or agreed to in writing, software
226 distributed under the License is distributed on an "AS IS" BASIS,
227 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
228 See the License for the specific language governing permissions and
229 limitations under the License.
230 */
231
232 let cachedIsSupported = undefined;
233
234 /**
235 * This is a utility method that determines whether the current browser supports
236 * the features required to create streamed responses. Currently, it checks if
237 * [`ReadableStream`](https://developer.mozilla.org/en-US/docs/Web/API/ReadableStream/ReadableStream)
238 * can be created.
239 *
240 * @return {boolean} `true`, if the current browser meets the requirements for
241 * streaming responses, and `false` otherwise.
242 *
243 * @memberof workbox.streams
244 */
245 function isSupported() {
246 if (cachedIsSupported === undefined) {
247 // See https://github.com/GoogleChrome/workbox/issues/1473
248 try {
249 new ReadableStream({ start() {} });
250 cachedIsSupported = true;
251 } catch (error) {
252 cachedIsSupported = false;
253 }
254 }
255
256 return cachedIsSupported;
257 }
258
259 /*
260 Copyright 2018 Google Inc. All Rights Reserved.
261 Licensed under the Apache License, Version 2.0 (the "License");
262 you may not use this file except in compliance with the License.
263 You may obtain a copy of the License at
264
265 http://www.apache.org/licenses/LICENSE-2.0
266
267 Unless required by applicable law or agreed to in writing, software
268 distributed under the License is distributed on an "AS IS" BASIS,
269 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
270 See the License for the specific language governing permissions and
271 limitations under the License.
272 */
273
274 /**
275 * A shortcut to create a strategy that could be dropped-in to Workbox's router.
276 *
277 * On browsers that do not support constructing new `ReadableStream`s, this
278 * strategy will automatically wait for all the `sourceFunctions` to complete,
279 * and create a final response that concatenates their values together.
280 *
281 * @param {
282 * Array<function(workbox.routing.Route~handlerCallback)>} sourceFunctions
283 * Each function should return a {@link workbox.streams.StreamSource} (or a
284 * Promise which resolves to one).
285 * @param {HeadersInit} [headersInit] If there's no `Content-Type` specified,
286 * `'text/html'` will be used by default.
287 * @return {workbox.routing.Route~handlerCallback}
288 *
289 * @memberof workbox.streams
290 */
291 function strategy(sourceFunctions, headersInit) {
292 return (() => {
293 var _ref = babelHelpers.asyncToGenerator(function* ({ event, url, params }) {
294 if (isSupported()) {
295 const { done, response } = concatenateToResponse(sourceFunctions.map(function (sourceFunction) {
296 return sourceFunction({ event, url, params });
297 }), headersInit);
298 event.waitUntil(done);
299 return response;
300 }
301
302 {
303 logger_mjs.logger.log(`The current browser doesn't support creating response ` + `streams. Falling back to non-streaming response instead.`);
304 }
305
306 // Fallback to waiting for everything to finish, and concatenating the
307 // responses.
308 const parts = yield Promise.all(sourceFunctions.map(function (sourceFunction) {
309 return sourceFunction({ event, url, params });
310 }).map((() => {
311 var _ref2 = babelHelpers.asyncToGenerator(function* (responsePromise) {
312 const response = yield responsePromise;
313 if (response instanceof Response) {
314 return response.blob();
315 }
316
317 // Otherwise, assume it's something like a string which can be used
318 // as-is when constructing the final composite blob.
319 return response;
320 });
321
322 return function (_x2) {
323 return _ref2.apply(this, arguments);
324 };
325 })()));
326
327 const headers = createHeaders(headersInit);
328 // Constructing a new Response from a Blob source is well-supported.
329 // So is constructing a new Blob from multiple source Blobs or strings.
330 return new Response(new Blob(parts), { headers });
331 });
332
333 return function (_x) {
334 return _ref.apply(this, arguments);
335 };
336 })();
337 }
338
339 /*
340 Copyright 2018 Google Inc.
341
342 Licensed under the Apache License, Version 2.0 (the "License");
343 you may not use this file except in compliance with the License.
344 You may obtain a copy of the License at
345
346 https://www.apache.org/licenses/LICENSE-2.0
347
348 Unless required by applicable law or agreed to in writing, software
349 distributed under the License is distributed on an "AS IS" BASIS,
350 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
351 See the License for the specific language governing permissions and
352 limitations under the License.
353 */
354
355 /*
356 Copyright 2018 Google Inc.
357
358 Licensed under the Apache License, Version 2.0 (the "License");
359 you may not use this file except in compliance with the License.
360 You may obtain a copy of the License at
361
362 https://www.apache.org/licenses/LICENSE-2.0
363
364 Unless required by applicable law or agreed to in writing, software
365 distributed under the License is distributed on an "AS IS" BASIS,
366 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
367 See the License for the specific language governing permissions and
368 limitations under the License.
369 */
370
371 exports.concatenate = concatenate;
372 exports.concatenateToResponse = concatenateToResponse;
373 exports.isSupported = isSupported;
374 exports.strategy = strategy;
375
376 return exports;
377
378}({},workbox.core._private,workbox.core._private));
379
380//# sourceMappingURL=workbox-streams.dev.js.map