UNPKG

13.8 kBJavaScriptView Raw
1this.workbox = this.workbox || {};
2this.workbox.streams = (function (logger_mjs,assert_mjs) {
3 'use strict';
4
5 try {
6 self.workbox.v['workbox:streams:3.5.0'] = 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.
261
262 Licensed under the Apache License, Version 2.0 (the "License");
263 you may not use this file except in compliance with the License.
264 You may obtain a copy of the License at
265
266 https://www.apache.org/licenses/LICENSE-2.0
267
268 Unless required by applicable law or agreed to in writing, software
269 distributed under the License is distributed on an "AS IS" BASIS,
270 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
271 See the License for the specific language governing permissions and
272 limitations under the License.
273 */
274
275 var publicAPI = /*#__PURE__*/Object.freeze({
276 concatenate: concatenate,
277 concatenateToResponse: concatenateToResponse,
278 isSupported: isSupported
279 });
280
281 /*
282 Copyright 2018 Google Inc. All Rights Reserved.
283 Licensed under the Apache License, Version 2.0 (the "License");
284 you may not use this file except in compliance with the License.
285 You may obtain a copy of the License at
286
287 http://www.apache.org/licenses/LICENSE-2.0
288
289 Unless required by applicable law or agreed to in writing, software
290 distributed under the License is distributed on an "AS IS" BASIS,
291 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
292 See the License for the specific language governing permissions and
293 limitations under the License.
294 */
295
296 /**
297 * A shortcut to create a strategy that could be dropped-in to Workbox's router.
298 *
299 * On browsers that do not support constructing new `ReadableStream`s, this
300 * strategy will automatically wait for all the `sourceFunctions` to complete,
301 * and create a final response that concatenates their values together.
302 *
303 * @param {
304 * Array<function(workbox.routing.Route~handlerCallback)>} sourceFunctions
305 * Each function should return a {@link workbox.streams.StreamSource} (or a
306 * Promise which resolves to one).
307 * @param {HeadersInit} [headersInit] If there's no `Content-Type` specified,
308 * `'text/html'` will be used by default.
309 * @return {workbox.routing.Route~handlerCallback}
310 *
311 * @memberof workbox.streams
312 */
313 function strategy(sourceFunctions, headersInit) {
314 return (() => {
315 var _ref = babelHelpers.asyncToGenerator(function* ({ event, url, params }) {
316 if (isSupported()) {
317 const { done, response } = concatenateToResponse(sourceFunctions.map(function (sourceFunction) {
318 return sourceFunction({ event, url, params });
319 }), headersInit);
320 event.waitUntil(done);
321 return response;
322 }
323
324 {
325 logger_mjs.logger.log(`The current browser doesn't support creating response ` + `streams. Falling back to non-streaming response instead.`);
326 }
327
328 // Fallback to waiting for everything to finish, and concatenating the
329 // responses.
330 const parts = yield Promise.all(sourceFunctions.map(function (sourceFunction) {
331 return sourceFunction({ event, url, params });
332 }).map((() => {
333 var _ref2 = babelHelpers.asyncToGenerator(function* (responsePromise) {
334 const response = yield responsePromise;
335 if (response instanceof Response) {
336 return response.blob();
337 }
338
339 // Otherwise, assume it's something like a string which can be used
340 // as-is when constructing the final composite blob.
341 return response;
342 });
343
344 return function (_x2) {
345 return _ref2.apply(this, arguments);
346 };
347 })()));
348
349 const headers = createHeaders(headersInit);
350 // Constructing a new Response from a Blob source is well-supported.
351 // So is constructing a new Blob from multiple source Blobs or strings.
352 return new Response(new Blob(parts), { headers });
353 });
354
355 return function (_x) {
356 return _ref.apply(this, arguments);
357 };
358 })();
359 }
360
361 var defaultExport = {
362 concatenate,
363 concatenateToResponse,
364 isSupported,
365 strategy
366 };
367
368 /*
369 Copyright 2018 Google Inc.
370
371 Licensed under the Apache License, Version 2.0 (the "License");
372 you may not use this file except in compliance with the License.
373 You may obtain a copy of the License at
374
375 https://www.apache.org/licenses/LICENSE-2.0
376
377 Unless required by applicable law or agreed to in writing, software
378 distributed under the License is distributed on an "AS IS" BASIS,
379 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
380 See the License for the specific language governing permissions and
381 limitations under the License.
382 */
383
384 const finalExport = Object.assign(defaultExport, publicAPI);
385
386 return finalExport;
387
388}(workbox.core._private,workbox.core._private));
389
390//# sourceMappingURL=workbox-streams.dev.js.map