Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Fixes servicerworker/client state syncing (#1074)
* Fixes servicerworker/client state syncing Defines the MessageChannel based utility for communicating window <=> window and window <=> worker. Adds receiver in indexedDB when operating from a service worker to listen to keyChanged events. On detection, indexedDB is synced and a response is returned to sender whether the key change was processed. It may be that the key change was already detected. This would return false. Adds a sender when an indexedDB write operation occurs and a service worker is available. The client will send a keyChanged message to the service worker to process the change and blocks on it. On response, the indexedDB write operation will resolve. The operation will resolve on success or failure. This is a best effort approach. If the service worker fails to process, the write operation should still succeed. Updates obsoleted APIs in web worker.
- Loading branch information
1 parent
c74c3b9
commit 2dab48d
Showing
12 changed files
with
4,782 additions
and
8 deletions.
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,81 @@ | ||
/** | ||
* Copyright 2018 Google Inc. | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
|
||
/** | ||
* @fileoverview Defines the MessageChannel common utilities and enums. | ||
*/ | ||
|
||
goog.provide('fireauth.messagechannel.Error'); | ||
goog.provide('fireauth.messagechannel.Status'); | ||
goog.provide('fireauth.messagechannel.TimeoutDuration'); | ||
goog.provide('fireauth.messagechannel.utils'); | ||
|
||
|
||
/** | ||
* Enum for the messagechannel error messages. These errors are not meant to be | ||
* user facing. | ||
* @enum {string} | ||
*/ | ||
fireauth.messagechannel.Error = { | ||
CONNECTION_UNAVAILABLE: 'connection_unavailable', | ||
INVALID_RESPONSE: 'invalid_response', | ||
TIMEOUT: 'timeout', | ||
UNKNOWN: 'unknown_error', | ||
UNSUPPORTED_EVENT: 'unsupported_event' | ||
}; | ||
|
||
|
||
/** | ||
* Enum for the message channel request status labels. | ||
* @enum {string} | ||
*/ | ||
fireauth.messagechannel.Status = { | ||
ACK: 'ack', | ||
DONE: 'done' | ||
}; | ||
|
||
|
||
/** | ||
* Enum for the timeout durations in milliseconds for different contexts. | ||
* @enum {number} | ||
*/ | ||
fireauth.messagechannel.TimeoutDuration = { | ||
ACK: 20, | ||
COMPLETION: 500 | ||
}; | ||
|
||
|
||
/** | ||
* @param {?string=} opt_prefix An optional prefix string to prepend to ID. | ||
* @param {?number=} opt_digits An optional number of digits used for event ID. | ||
* @return {string} The generated event ID used to identify a generic event. | ||
*/ | ||
fireauth.messagechannel.utils.generateEventId = | ||
function(opt_prefix, opt_digits) { | ||
// 0, null and undefined will default to 20. | ||
var digits = opt_digits || 20; | ||
return opt_prefix ? opt_prefix : '' + | ||
Math.floor(Math.random() * Math.pow(10, digits)).toString(); | ||
}; | ||
|
||
|
||
/** | ||
* @return {?MessageChannel} The initialized MessageChannel instance if | ||
* supported. | ||
*/ | ||
fireauth.messagechannel.utils.initializeMessageChannel = function() { | ||
return typeof MessageChannel !== 'undefined' ? new MessageChannel() : null; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,130 @@ | ||
/** | ||
* Copyright 2018 Google Inc. | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
|
||
/** | ||
* @fileoverview Defines the PostMessager interface needed for the | ||
* `fireauth.messagechannel.Sender`, in addition to 2 types of implementations. | ||
*/ | ||
|
||
goog.provide('fireauth.messagechannel.PostMessager'); | ||
goog.provide('fireauth.messagechannel.WindowPostMessager'); | ||
goog.provide('fireauth.messagechannel.WorkerClientPostMessager'); | ||
|
||
|
||
/** | ||
* This is the interface defining the postMessage format of a window which | ||
* takes an additional second parameter for target origin. | ||
* | ||
* @typedef {{ | ||
* postMessage: function(*, string, !Array<!Transferable>) | ||
* }} | ||
*/ | ||
fireauth.messagechannel.Window; | ||
|
||
|
||
/** | ||
* This is the interface defining the postMessage format of a worker or | ||
* ServiceWorkerClient, etc. which just takes a message and a list of | ||
* Transferables. | ||
* | ||
* @typedef {{ | ||
* postMessage: function(*, !Array<!Transferable>) | ||
* }} | ||
*/ | ||
fireauth.messagechannel.WorkerClient; | ||
|
||
|
||
/** | ||
* Defines a common interface to postMessage data to a specified PostMessager. | ||
* @interface | ||
*/ | ||
fireauth.messagechannel.PostMessager = function() {}; | ||
|
||
|
||
/** | ||
* Sends a message to the specified context. | ||
* @param {*} message The message to send. | ||
* @param {!Array<!Transferable>} transfer The list of `Transferable` objects | ||
* that are transferred with the message. The ownsership fo these objects is | ||
* given to the destination side and they are no longer usable on the | ||
* sending side. | ||
*/ | ||
fireauth.messagechannel.PostMessager.prototype.postMessage = | ||
function(message, transfer) {}; | ||
|
||
|
||
|
||
/** | ||
* Defines the implementation for postMessaging to a window context. | ||
* @param {!fireauth.messagechannel.Window} win The window PostMessager. | ||
* @param {?string=} opt_targetOrigin The target origin. | ||
* @constructor | ||
* @implements {fireauth.messagechannel.PostMessager} | ||
*/ | ||
fireauth.messagechannel.WindowPostMessager = function(win, opt_targetOrigin) { | ||
/** | ||
* @const @private {!fireauth.messagechannel.Window} The window PostMessager. | ||
*/ | ||
this.win_ = win; | ||
/** @const @private {string} The postMessage target origin. */ | ||
this.targetOrigin_ = opt_targetOrigin || '*'; | ||
}; | ||
|
||
|
||
/** | ||
* Sends a message to the specified window context. | ||
* @param {*} message The message to send. | ||
* @param {!Array<!Transferable>} transfer The list of `Transferable` objects | ||
* that are transferred with the message. The ownsership fo these objects is | ||
* given to the destination side and they are no longer usable on the | ||
* sending side. | ||
* @override | ||
*/ | ||
fireauth.messagechannel.WindowPostMessager.prototype.postMessage = | ||
function(message, transfer) { | ||
this.win_.postMessage(message, this.targetOrigin_, transfer); | ||
}; | ||
|
||
|
||
/** | ||
* Defines the implementation for postMessaging to a worker/client context. | ||
* @param {!fireauth.messagechannel.WorkerClient} worker The worker/client | ||
* PostMessager. | ||
* @constructor | ||
* @implements {fireauth.messagechannel.PostMessager} | ||
*/ | ||
fireauth.messagechannel.WorkerClientPostMessager = function(worker) { | ||
/** | ||
* @const @private {!fireauth.messagechannel.WorkerClient} The worker/client | ||
* PostMessager. | ||
*/ | ||
this.worker_ = worker; | ||
}; | ||
|
||
|
||
/** | ||
* Sends a message to the specified worker/client context. | ||
* @param {*} message The message to send. | ||
* @param {!Array<!Transferable>} transfer The list of `Transferable` objects | ||
* that are transferred with the message. The ownsership fo these objects is | ||
* given to the destination side and they are no longer usable on the | ||
* sending side. | ||
* @override | ||
*/ | ||
fireauth.messagechannel.WorkerClientPostMessager.prototype.postMessage = | ||
function(message, transfer) { | ||
this.worker_.postMessage(message, transfer); | ||
}; |
Oops, something went wrong.