resultingClientExists.js 1.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748
  1. /*
  2. Copyright 2019 Google LLC
  3. Use of this source code is governed by an MIT-style
  4. license that can be found in the LICENSE file or at
  5. https://opensource.org/licenses/MIT.
  6. */
  7. import { timeout } from './timeout.js';
  8. import '../_version.js';
  9. const MAX_RETRY_TIME = 2000;
  10. /**
  11. * Returns a promise that resolves to a window client matching the passed
  12. * `resultingClientId`. For browsers that don't support `resultingClientId`
  13. * or if waiting for the resulting client to apper takes too long, resolve to
  14. * `undefined`.
  15. *
  16. * @param {string} [resultingClientId]
  17. * @return {Promise<Client|undefined>}
  18. * @private
  19. */
  20. export async function resultingClientExists(resultingClientId) {
  21. if (!resultingClientId) {
  22. return;
  23. }
  24. let existingWindows = await self.clients.matchAll({ type: 'window' });
  25. const existingWindowIds = new Set(existingWindows.map((w) => w.id));
  26. let resultingWindow;
  27. const startTime = performance.now();
  28. // Only wait up to `MAX_RETRY_TIME` to find a matching client.
  29. while (performance.now() - startTime < MAX_RETRY_TIME) {
  30. existingWindows = await self.clients.matchAll({ type: 'window' });
  31. resultingWindow = existingWindows.find((w) => {
  32. if (resultingClientId) {
  33. // If we have a `resultingClientId`, we can match on that.
  34. return w.id === resultingClientId;
  35. }
  36. else {
  37. // Otherwise match on finding a window not in `existingWindowIds`.
  38. return !existingWindowIds.has(w.id);
  39. }
  40. });
  41. if (resultingWindow) {
  42. break;
  43. }
  44. // Sleep for 100ms and retry.
  45. await timeout(100);
  46. }
  47. return resultingWindow;
  48. }